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¬ify_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×tamp=前面生成的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、