栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java企业支付实战 - 微信小程序登录及支付——亲测有效(超级详细)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java企业支付实战 - 微信小程序登录及支付——亲测有效(超级详细)

一、工具准备 微信支付官网

官网:https://pay.weixin.qq.com
注册商家地址:https://pay.weixin.qq.com/index.php/apply/applyment_home/guide_normal
微信小程序支付:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_2.shtml

uniapp官网

https://uniapp.dcloud.io/

小程序官网

https://mp.weixin.qq.com/

工具下载

hbuilderx

https://www.dcloud.io/hbuilderx.html

微信小程序开发工具:

https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html

vscode工具:

https://code.visualstudio.com/

Linux客户端工具FinalShell下载

http://www.hostbuf.com/t/988.html

二、微信支付-申请流程和步骤 01、微信支付图解

02、申请注册流程和文档

官方网址:https://pay.weixin.qq.com/index.php
官方文档:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pages/index.shtml
PC端微信小程序Navtive文档:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_7_0.shtml
微信小程序支付对接文档:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_1.shtml

三、微信支付-注册商家及获取商家mchid 目标

1、注册商家号
2、获取商家号mcid

01、注册成为商家

注册商家地址:https://pay.weixin.qq.com/index.php/apply/applyment_home/guide_normal

以上安装步骤填写即可。

02、进入微信支付后台获取商家号mchid


四、微信支付-商家-配置商家证书及获取API私钥 目标

1:获取API私钥

https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_1.shtml

01、配置商家证书及获取API私钥

02、生成私钥的代码
import java.util.Random;
public class RandomStringGenerator {
    
    public static String getRandomStringByLength(int length) {
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }
}
五、微信支付-商家-签约产品 目标

1:签约微信小程序支付产品
2:签约Native支付产品

01、产品类型表

文档:https://pay.weixin.qq.com/wiki/doc/apiv3/index.shtml

02、签约产品

六、微信支付-配置回调地址 目标

配偶在支付回调地址

配置如下

七、微信支付-微信小程序注册获取APPID 目标

1、注册微信小程序
2、微信支付绑定微信小程序

01、注册微信小程序

申请官网:https://mp.weixin.qq.com/
注册地址:https://mp.weixin.qq.com/cgi-bin/registermidpage?action=index&lang=zh_CN&token=

01-1、申请注册


01-2、获取APPID

02、微信小程序配置及认证

八、微信支付-小程序和微信支付绑定关系 目标

完成小程序和微信支付的绑定关系

01、小程序与微笑支付绑定

九、实战部分 9.1 导入weixinpay工具包

工具包: https://download.csdn.net/download/qq_41096598/43396028

9.2 引入依赖

    com.github.wxpay
    wxpay-sdk
    0.0.3


    commons-codec
    commons-codec
    1.13


    org.jdom
    jdom
    1.1.3


    com.thoughtworks.xstream
    xstream
    1.4.10


    com.google.zxing
    core
    3.1.0


    org.apache.commons
    commons-lang3
    3.6


    org.apache.httpcomponents
    httpclient
    4.5.13


    commons-httpclient
    commons-httpclient
    3.1


9.3 编写wx.properties
# 微信登录网关
weixin.login.info.gateway=https://api.weixin.qq.com/sns/jscode2session
# 微信小程序APPID
weixin.login.info.appid=
# 微信小程序API私钥
weixin.login.info.appsecret=
#微信小程序登录成功回调地址
weixin.login.info.redirectUrl= 

# 微信支付网关
weixin.pay.info.gateway=https://api.mch.weixin.qq.com/pay/unifiedorder
# 微信支付API秘钥
weixin.pay.info.appsecret=
# 微信商户id
weixin.pay.info.mchid=
# 签约产品的类
weixin.pay.info.type=JSAPI
# 微信小程序APPID
weixin.pay.info.appid=
# 支付成功回调地址,如果是微信小程序可以不配置
weixin.pay.info.notifyPath=
9.4 在springmvc.xml中配置



9.5 config配置 9.5.1 WeixinLoginProperties
package com.dyt.config;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Component
@PropertySource("classpath:wx.properties")
public class WeixinLoginProperties implements InitializingBean {
    @Value("${weixin.login.info.gateway}")
    private String gateway;
    @Value("${weixin.login.info.appid}")
    private String appid;
    @Value("${weixin.login.info.appsecret}")
    private String appsecret;
    @Value("${weixin.login.info.redirectUrl}")
    private String redirectUrl;

    public static String WX_OPEN_GATEWAY;
    public static String WX_OPEN_APP_ID;
    public static String WX_OPEN_APP_SECRET;
    public static String WX_OPEN_REDIRECT_URL;

    @Override
    public void afterPropertiesSet() throws Exception {
        WX_OPEN_GATEWAY = gateway;
        WX_OPEN_APP_ID = appid;
        WX_OPEN_APP_SECRET = appsecret;
        WX_OPEN_REDIRECT_URL = redirectUrl;
    }
}
9.5.2 WeixinPayProperties
package com.dyt.config;


import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Component
@PropertySource(value = {"classpath:wx.properties"})
public class WeixinPayProperties implements InitializingBean {

    // 微信支付网关
    @Value("${weixin.pay.info.gateway}")
    private String gateway;
    //小程序APPID
    @Value("${weixin.pay.info.appid}")
    private String appid;
    @Value("${weixin.pay.info.type}")
    private String type;
    //小程序APPSceret
    @Value("${weixin.pay.info.appsecret}")
    private String appsecret;
    //商户ID
    @Value("${weixin.pay.info.mchid}")
    private String mchid;
    //回调地址
    @Value("${weixin.pay.info.notifyPath}")
    private String notifyPath;

    public static String WX_GATEWAY;
    public static String WX_APPID;
    public static String WX_TYPE;
    public static String WX_APPSECRET;
    public static String WX_MCHID;
    public static String WX_NOTIFYPATH;


    @Override
    public void afterPropertiesSet() throws Exception {
        WX_GATEWAY = gateway;
        WX_APPID = appid;
        WX_TYPE = type;
        WX_APPSECRET = appsecret;
        WX_MCHID = mchid;
        WX_NOTIFYPATH = notifyPath;
    }
}
9.6 创建ApiPayController
package com.dyt.controller;

import com.alibaba.fastjson.JSONObject;
import com.dyt.common.pay.weixin.ReportReqData;
import com.dyt.common.pay.weixin.request.QrCodeRequest;
import com.dyt.common.pay.weixin.util.RandomStringGenerator;
import com.dyt.common.pay.weixin.util.SnowflakeIdWorker;
import com.dyt.config.WeixinPayProperties;
import com.dyt.vo.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

@Api(tags = "微信小程序支付")
@RestController
public class ApiPayController {

    @PostMapping ("/weixinpay")
    public R payFood(HttpServletRequest request, String money){
        //1:开始支付,创建数据体
        JSONObject json = new JSONObject();
        //2:生成自定义定义流水号,便于自己查询和统计保证唯一即可
        String orderNo = new SnowflakeIdWorker(1, 2).nextId() + "";
        //3:获取用户openid作为支付的唯一凭证
        String openid = request.getParameter("openid");
        //4:分账接收方用户Id,从session获取即可
        Integer userId = 1;
        //5:组装微信支付数据
        ReportReqData data = new ReportReqData();
        // openid
        data.setOpenid(openid);
        // 签约的类型JSAPI
        data.setTrade_type(WeixinPayProperties.WX_TYPE);
        // 微信小程序的appid
        data.setAppid(WeixinPayProperties.WX_APPID);
        // 商户id
        data.setMch_id(WeixinPayProperties.WX_MCHID);
        // 回调地址 如果是微信小程序不用配置也可以,最好配置
        data.setNotify_url(WeixinPayProperties.WX_NOTIFYPATH);
        // 业务数据
        data.setBody("产品支付");//
        data.setOut_trade_no(orderNo);//订单号
        //data.setProduct_id(saleFoodId+"");//商品ID
        data.setSpbill_create_ip(ip);//ip地址
        data.setTotal_fee(getMoney(money));//金额
        data.setNonce_str(RandomStringGenerator.getRandomStringByLength(32));

        json.put("userId", userId);
        json.put("type", "productpay");
        //创建订单
        String params = json.toString().replace(""", "'");

        data.setAttach(params);

        //微信支付返回的结果
        Map weixinMap = QrCodeRequest.submitWeixinMessage(data);

        return R.ok().data("weixinMap",weixinMap).data("xxx","xxxx");

    }



    
    public static String getMoney(String amount) {
        if (amount == null) {
            return "";
        }
        // 金额转化为分为单位
        // 处理包含, ¥ 或者$的金额
        String currency = amount.replaceAll("\$|\¥|\,", "");
        int index = currency.indexOf(".");
        int length = currency.length();
        Long amLong = 0L;
        if (index == -1) {
            amLong = Long.valueOf(currency + "00");
        } else if (length - index >= 3) {
            amLong = Long.valueOf((currency.substring(0, index + 3)).replace(".", ""));
        } else if (length - index == 2) {
            amLong = Long.valueOf((currency.substring(0, index + 2)).replace(".", "") + 0);
        } else {
            amLong = Long.valueOf((currency.substring(0, index + 1)).replace(".", "") + "00");
        }
        return amLong.toString();
    }

}
9.7 创建ApiLoginController
package com.dyt.controller;

import com.dyt.common.HttpClientUtils;
import com.dyt.common.exception.DYTException;
import com.dyt.config.WeixinLoginProperties;
import com.dyt.vo.R;
import com.google.gson.Gson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@Api(tags = "微信小程序登录")
@RestController
public class ApiLoginController{
    
    @PostMapping("/wxlogin")
    public R callback(String code){
        //1.判断code是否合法
        if(StringUtils.isEmpty(code)){
            throw new DYTException(22008,"登录失败,尝试刷新重新登录!");
        }
        // 2:通过code获取access_token
        String baseAccessTokenUrl = WeixinLoginProperties.WX_OPEN_GATEWAY +
                "?appid=%s" +
                "&secret=%s" +
                "&code=%s" +
                "&grant_type=authorization_code";

        String accessTokenUrl = String.format(baseAccessTokenUrl, WeixinLoginProperties.WX_OPEN_APP_ID, WeixinLoginProperties.WX_OPEN_APP_SECRET, code);
        String result = null;
        try {
            //执行请求,获取微信请求返回得数据  RestTemplate httpClientUtils
            result = new HttpClientUtils().get(accessTokenUrl);
            //对微信返回得数据进行转换
            Gson gson = new Gson();
            Map resultMap = gson.fromJson(result, HashMap.class);
            if (resultMap.get("errcode") != null) {
                throw new DYTException(22006,"微信登录出错!");
            }
            //解析微信用户得唯一凭证openid
            String openid = (String) resultMap.get("openid");
            if (StringUtils.isEmpty(openid)) {
                throw new DYTException(22009,"登录失败,尝试刷新重新登录!");
            }
            //封装返回
   return R.ok().data("openid", openid).data("token",token).data("resultMap",resultMap);
        }catch (Exception e){
            return R.error().code(601).message("微信解析失败");
        }
    }
}
9.8 注意事项
  • ping: api.weixin.qq.com: 未知的名称或服务

  • 服务器网络配置出错

    [root@SSPZ ~]# vi /etc/sysconfig/network-scripts/ifcfg-ens33
    HWADDR="00:0c:29:43:1b:69"           #MAC地址 -> 打开虚拟机设置——网络适配器——高级         
    IPADDR="192.168.88.148"              #IP地址
    GATEWAY="192.168.88.2"               #网关
    NETMASK="255.255.255.0"              #子网掩码
    DNS1="192.168.0.1"                   #访问互联网
    #DNS1和DNS2分别是DNS服务器1和DNS服务器2。DNS服务器1的ip地址是192.168.0.1或者114.114.114.114,DNS服务器2的ip地址是114.114.114.114或者8.8.8.8。
    #Domain Name System简称DNS,是互联网的一项服务。它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。DNS使用UDP端口53。对于每一级域名长度的限制是63个字符,域名总长度则不能超过253个字符。Domain Name System是Internet上解决网上机器命名的一种系统。Internet上当一台主机要访问另外一台主机时,必须首先获知其地址。
    :wq!                                    #保存
    [root@SSPZ ~]# service network restart  #重新网络
    
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/532065.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号