微信支付流程

要实现微信支付要满足几个条件:
一、有一个服务号,菜单栏里面有微信支付菜单的公众号
在这里插入图片描述

 

二、需要开通商户号,不是公众号,必须和公众号做关联操作
在这里插入图片描述

常用的几个参数 下面例子参数值已经经过处理

public final class WxConfig {
    public final static String appId = "wx98dc29047cexxxx"; // 公众号appid
    public final static String mchId = "1566911111";// 商户ID
    public final static String key = "xxxxxxx4TI4srY33SwkyXYojBzK6Fsp"; // 商户KEY 跟微信支付约定的密钥
    public final static String payUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder"; // 统一下单地址
    public final static String tradeType = "JSAPI"; // 支付方式
    public final static String secret="xxx9b86bdb6637a4ccfaf6e7e2609";//商户APPSECRET
}

以下是微信支付流程,后面会根据流程上响应的代码


在这里插入图片描述
微信工具包下载,其中很多类可以使用

 

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
在这里插入图片描述


1、获取用户code

 

https://open.weixin.qq.com/connect/oauth2/authorize

var code = getUrlParam('code') // 截取路径中的code,如果没有就去微信授权,如果已经获取到了就直接传code给后台获取openId
var local = window.location.href
if (code == null || code === '') {
    window.location.href = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx98dc29047xxxxx&redirect_uri=' + encodeURIComponent(local) +'&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect'
}

   

中间有几个参数
在这里插入图片描述


微信会通过回调的方式跳回原来的页面,code就是用户的会话ID了,某个时段有效。

 

redirect_uri/?code=CODE&state=STATE
2、获取openId

https://api.weixin.qq.com/sns/oauth2/access_token

拿到code以后为了安全性提交到后台,后台我这里是用的java springboot框架

String code = json.get("code").toString();
String res = get("https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + WxConfig.appId + "&secret="+ WxConfig.secret + "&code=" + code + "&grant_type=authorization_code");
            JSONObject json1 = JSONObject.parseObject(res);
            String openId = json1.getString("openid");
            System.out.println(openId+"------------------------------");

 

这里使用的 WxConfig 就是文章开头的配置文件类

public String get(String url) throws Exception {
        // 创建HttpClient实例
        CloseableHttpClient client = HttpClientBuilder.create().build();
        // 根据URL创建HttpGet实例
        HttpGet get = new HttpGet(url);
        // 执行get请求,得到返回体
        HttpResponse response = client.execute(get);
        // 判断是否正常返回
        if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            // 解析数据
            String data = EntityUtils.toString(response.getEntity(), Charsets.UTF_8);
            System.out.println(data);
            return data;
        }
        return "";

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.3</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.3</version>
        </dependency>

3、发起订单

https://api.mch.weixin.qq.com/pay/unifiedorder

拿到openId以后就可以发起订单了

@RequestMapping("/payH5")
    @ResponseBody
    public Object payH5(HttpServletRequest request, HttpServletResponse response, @RequestBody Map<String, Object> json)
            throws Exception {
        try {
            String orderNo = UUID.randomUUID().toString().replaceAll("-", "");
            //记得自己把订单id保存下来 orderNo
            String code = json.get("code").toString();

            String res = get("https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + WxConfig.appId + "&secret="
                    + WxConfig.secret + "&code=" + code + "&grant_type=authorization_code");
            JSONObject json1 = JSONObject.parseObject(res);
            String openId = json1.getString("openid"); //获取的用户唯一标识
            System.out.println(openId+"------------------------------");
            Map<String, String> paraMap = new HashMap<>();
            paraMap.put("appid", WxConfig.appId);//公众号appid
            paraMap.put("body", json.get("body").toString());//商品说明
            paraMap.put("mch_id", WxConfig.mchId);//商家id
            paraMap.put("nonce_str", WXPayUtil.generateNonceStr());
            paraMap.put("openid", openId);            
            paraMap.put("out_trade_no", orderNo);
            paraMap.put("spbill_create_ip", "120.79.1.1");
            paraMap.put("total_fee", String.valueOf((int)(Double.parseDouble(kc.getSpjg())*100)));
            paraMap.put("trade_type", WxConfig.tradeType);
            paraMap.put("notify_url","http://yunkt.zmxzc.com//api/wxnotify");
            String apiKey = WxConfig.key;
            System.out.println(WXPayUtil.mapToXml(paraMap));
            String sign = WXPayUtil.generateSignature(paraMap, apiKey);
            paraMap.put("sign", sign);
            String xml = WXPayUtil.mapToXml(paraMap);
            System.out.println(xml);
            // 统一下单 https://api.mch.weixin.qq.com/pay/unifiedorder
            String unifiedorder_url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

            String xmlStr = WXPayReport.httpRequest(unifiedorder_url, xml, 2000, 5000);
            // 以下内容是返回前端页面的json数据
            System.out.println(xmlStr);
            String prepay_id = "";// 预支付id
            if (xmlStr.indexOf("SUCCESS") != -1) {
                Map<String, String> map = WXPayUtil.xmlToMap(xmlStr);
                prepay_id = (String) map.get("prepay_id");
            }
            Map<String, String> payMap = new HashMap<String, String>();
            payMap.put("appId", WxConfig.appId);
            payMap.put("timeStamp", WXPayUtil.getCurrentTimestamp() + "");
            payMap.put("nonceStr", WXPayUtil.generateNonceStr());
            payMap.put("signType", "MD5");
            payMap.put("package", "prepay_id=" + prepay_id);
            String paySign = WXPayUtil.generateSignature(payMap, WxConfig.key);
            payMap.put("paySign", paySign);
            payMap.put("orderNo", orderNo);
            payMap.put("success", "0");
            return payMap;

        } catch (Exception e) {
            e.printStackTrace();
            Map<String, String> payMap = new HashMap<String, String>();
            payMap.put("success", "1");
            return payMap;

        }
//        return new SuccessResponseData();
    }

httpRequest 方法改写新增了 WXPayReport工具包中 的请求方法

public static String httpRequest(String url,String data, int connectTimeoutMs, int readTimeoutMs) throws Exception{
        BasicHttpClientConnectionManager connManager;
        connManager = new BasicHttpClientConnectionManager(
                RegistryBuilder.<ConnectionSocketFactory>create()
                        .register("http", PlainConnectionSocketFactory.getSocketFactory())
                        .register("https", SSLConnectionSocketFactory.getSocketFactory())
                        .build(),
                null,
                null,
                null
        );
        HttpClient httpClient = HttpClientBuilder.create()
                .setConnectionManager(connManager)
                .build();

        HttpPost httpPost = new HttpPost(url);

        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(readTimeoutMs).setConnectTimeout(connectTimeoutMs).build();
        httpPost.setConfig(requestConfig);

        StringEntity postEntity = new StringEntity(data, "UTF-8");
        httpPost.addHeader("Content-Type", "text/xml");
        httpPost.addHeader("User-Agent", WXPayConstants.USER_AGENT);
        httpPost.setEntity(postEntity);

        HttpResponse httpResponse = httpClient.execute(httpPost);
        HttpEntity httpEntity = httpResponse.getEntity();
        return EntityUtils.toString(httpEntity, "UTF-8");
    }

payMap 返回的值就是我们调用支付所需要的参数的,所有的工作就是为了获取这些

4、调用微信支付,必须在微信内置浏览器,不然会失败

WeixinJSBridge.invoke('getBrandWCPayRequest', {
                                "appId": data.appId, //公众号名称,由商户传入
                                "timeStamp": data.timeStamp, //时间戳,自1970年以来的秒数
                                "nonceStr": data.nonceStr, //随机串
                                "package": data.package,
                                "signType": data.signType, //微信签名方式:
                                "paySign": data.paySign //微信签名
                            }, function(res) {
                                console.log(res);
                                //window.location.href = local
                                if (res.err_msg == "get_brand_wcpay_request:ok") {
                                    alert('支付成功');
                                    window.location.href =localStorage.getItem('location');
                                } else if (res.err_msg == "get_brand_wcpay_request:cancel") {
                                    alert('支付取消');
                                    window.location.href =localStorage.getItem('location');
                                } else if (res.err_msg == "get_brand_wcpay_request:fail") {
                                    alert('支付失败');
                                    window.location.href =localStorage.getItem('location');
                                }else{
                                    alert('支付异常');    
                                    window.location.href =localStorage.getItem('location');
                                }
                            })

 

5、查询订单支付状态

Map<String, String> paraMap = new HashMap<>();
                paraMap.put("appid", WxConfig.appId);
                paraMap.put("mch_id", WxConfig.mchId);
                paraMap.put("nonce_str", WXPayUtil.generateNonceStr());
                paraMap.put("out_trade_no", f.getDdid());//前面的 String orderNo = UUID.randomUUID().toString().replaceAll("-", "");
                paraMap.put("spbill_create_ip", "120.79.1.1");
                String apiKey = WxConfig.key;
                String sign = WXPayUtil.generateSignature(paraMap, apiKey);
                paraMap.put("sign", sign);
                String xml = WXPayUtil.mapToXml(paraMap);
                System.out.println(xml);
                // 统一下单 https://api.mch.weixin.qq.com/pay/unifiedorder
                String unifiedorder_url = "https://api.mch.weixin.qq.com/pay/orderquery";

                String xmlStr = WXPayReport.httpRequest(unifiedorder_url, xml, 2000, 5000);
                // 以下内容是返回前端页面的json数据
                System.out.println(xmlStr);
                
                if (xmlStr.indexOf("SUCCESS") != -1) {
                    Map<String, String> map = WXPayUtil.xmlToMap(xmlStr);
                    if(map.get("trade_state")!=null&&((String) map.get("trade_state")).equals("SUCCESS")){
                        //修改本地订单状态
                        //这里的订单就是前面的String orderNo = UUID.randomUUID().toString().replaceAll("-", "");
                    }
                }

 

<xml>
   <return_code><![CDATA[SUCCESS]]></return_code>
   <return_msg><![CDATA[OK]]></return_msg>
   <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
   <mch_id><![CDATA[10000100]]></mch_id>
   <device_info><![CDATA[1000]]></device_info>
   <nonce_str><![CDATA[TN55wO9Pba5yENl8]]></nonce_str>
   <sign><![CDATA[BDF0099C15FF7BC6B1585FBB110AB635]]></sign>
   <result_code><![CDATA[SUCCESS]]></result_code>
   <openid><![CDATA[oUpF8uN95-Ptaags6E_roPHg7AG0]]></openid>
   <is_subscribe><![CDATA[Y]]></is_subscribe>
   <trade_type><![CDATA[MICROPAY]]></trade_type>
   <bank_type><![CDATA[CCB_DEBIT]]></bank_type>
   <total_fee>1</total_fee>
   <fee_type><![CDATA[CNY]]></fee_type>
   <transaction_id><![CDATA[1008450740201411110005820873]]></transaction_id>
   <out_trade_no><![CDATA[1415757673]]></out_trade_no>
   <attach><![CDATA[订单额外描述]]></attach>
   <time_end><![CDATA[20141111170043]]></time_end>
   <trade_state><![CDATA[SUCCESS]]></trade_state>
</xml>

   

这里整个流程就结束了。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值