• 2020年3月26日

HBuilder X+.Net Core 3.1开发微信APP支付详细流程及相关问题

一、支付流程

二、步骤说明:

1、UniApp向.Net Core服务器发起统一下单请求,.Net Core收到请求后需要做的事情如下:

生成nonce_str、notify_url、out_trade_no等关键参数,生成Sign,将这些数据组成xml向微信统一下单Api发送。

向微信统一下单API发送的XML如下:

 <xml>
  <appid>wx2421b1c4370ec43b</appid> open.weixin.qq.com中获取
  <attach>支付测试</attach> 你要传送的额外信息,例如订单ID之类的
  <body>APP支付测试</body> 产品描述,也就是支付事由
  <mch_id>10000100</mch_id> 你的商户号,需要与open.weixin.qq.com上对应的APP绑定
  <nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str> 生成的随机字符串
  <notify_url>http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php</notify_url> 支付成功后通知处理Url,不能带参数
  <out_trade_no>1415659990</out_trade_no> 订单号,不能重复
  <spbill_create_ip>14.23.150.211</spbill_create_ip> .net core服务器IP
  <total_fee>1</total_fee> 金额单位是分
  <trade_type>APP</trade_type> APP就填写APP
  <sign>0CB01533B8C1EF103065174F50BCA001</sign> 生成的sign
</xml>

sign字串拼凑:对参数按照key=value的格式,并按照参数名ASCII字典序排序

"appid=xml对应的appid&body=xml对应的body&mch_id=xml的mch_id&nonce_str=xml的nonce_str&notify_url=xml的notify_url&out_trade_no=xml的out_trade_no&spbill_create_ip=xml的spbill_create_ip&total_fee=xml的total_fee&trade_type=xml的trade_type&key=商户号的API秘钥"

将上面的字符串MD5并转换为大写就获得了本次的Sign

2、.Net Core向微信服务器发送统一下单请求,也就是将上面的xml内容post给统一下单url

关键代码:

        var timeStamp = Toolkits.ConvertToTimeStamp(DateTime.Now); //获取当前TimeStamp,二次生成Sign要用到
        HttpClient httpClient = new HttpClient();//http对象
        //表头参数
        httpClient.DefaultRequestHeaders.Accept.Clear();
        httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));

        //转为链接需要的格式
        HttpContent httpContent = new StringContent(xml);
        //请求
        HttpResponseMessage response = httpClient.PostAsync("https://api.mch.weixin.qq.com/pay/unifiedorder", httpContent).Result;
        string result = "";

//这里开始进入第3步了
        if (response.IsSuccessStatusCode)
        {
            Task<string> t = response.Content.ReadAsStringAsync();
            if (t != null)
            {
                result = t.Result;
            }
        }

3、微信服务器向.Net Core返回相关参数,返回的数据大概下面这样子:

 <xml>
  <return_code><![CDATA[SUCCESS]]></return_code> SUCCESS表示成功
   <return_msg><![CDATA[OK]]></return_msg>
   <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
   <mch_id><![CDATA[10000100]]></mch_id>
  <nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str> 这是随机串,要用到
  <sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign>
  <result_code><![CDATA[SUCCESS]]></result_code>
  <prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id> 这是prepayid,也是要用到的
   <trade_type><![CDATA[APP]]></trade_type>
</xml>

我们可以用XmlDocument对上面获得的result进行分析:

                 XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(result);
//获取指定节点内容方法:
var x = xmlDoc.DocumentElement.GetElementsByTagName("return_code");

通过上面获得的noncestr、prepayid、和2生成成的timeStamp生成新的sign并回传给uniapp:

Sign字串拼接方法:

appid=跟发起统一下单的appid一致&noncestr=result里的nonce_str&package=Sign=WXPay&partnerid=商户号&prepayid=result的prepay_id&timestamp=前面生成的timestamp&key=微信支付API秘钥

将拼凑起来的字符串MD5并转成大写就是新的SIGN了

4、将关键数据和sign返回给uniapp,例如:

{\"mchId\":\"商户号\",\"appId\":\"应用appid\" ,\"nonce_str\":\"result的nonce_str\" ,\"prepayid\":\"result的prepay_id\" ,\"timestamp\":\"前面生成的timestamp\" ,\"sign\":\"生成的sign\"   }

5、调用uni.requestPayment发起支付,关键代码:

let obj = {
appid: data.appId,
partnerid: data.mchId,
prepayid: data.prepayid,
package: 'Sign=WXPay', // 固定值,以微信支付文档为主
noncestr: data.nonce_str,
timestamp: data.timestamp,
sign: data.sign // 根据签名算法生成签名
}
//上面的这里的data是4返回给uniapp的数据

uni.requestPayment({
provider: 'wxpay',
orderInfo: obj, //上面的obj
success: function (res) {
//这里已经是第6步了
uni.showToast({
title:'感谢您的支持,邮件将尽快发出!'
})//这里偷懒,没有进行判断成功与否,而是等第7步微信支付API服务器向.Net Core服务器发送通知
},
fail: function (err) {
console.log('fail:' + JSON.stringify(err));
}
});

6、微信端等待用户支付并将结果返回给UniApp,返回的数据如下图:

7、微信支付API服务器向1种定义的notify_url发送支付结果,内容如下:

以上是各流程说明,下面其他说明:

1、.net core接收微信支付API发送过来的支付结果代码:

        Stream stream = HttpContext.Request.Body;
        byte[] buffer = new byte[HttpContext.Request.ContentLength.Value];
        stream.ReadAsync(buffer, 0, buffer.Length); //.net core 3.1需要用ReadAsync才不会出错
        string xml = System.Text.Encoding.UTF8.GetString(buffer);

//上面几行是关键的获取POST过来的xml数据的代码

        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(xml);

        if (xmlDoc.DocumentElement.GetElementsByTagName("return_code")[0].InnerText=="SUCCESS")
        {

            string Transaction_Id = xmlDoc.DocumentElement.GetElementsByTagName("transaction_id")[0].InnerText;  //获取指定节点内容
            这里是进行各种逻辑代码,最好对sign进行下验证
 
        }
        else
        {
            
        }
        returnXml += "<xml><return_code>SUCCESS</return_code><return_msg>SUCCESS</return_msg></xml>"; 把这个内容显示出来告诉微信内容已收到

2、使用自己生成的安卓证书并获取md5值:

可以使用java的keytool工具创建证书,再通过微信提供的工具获取到MD5值

3、HBuilder X需要配置下APP SDK配置中的微信支付,填写appid(支付流程中第一步的appid要对应)

4、

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注