微信JSAPI支付操作需要注意的细节
首先介绍一下我在调用微信支付接口使用的是weixin.senparcSDK,非常方便好用开源的一个微信开发SDK。
weixin.senparcSDK官网:http://weixin.senparc.com/
先去下载下来Senparc.WeixinSDK。
在调起支付接口之前,需要先要调用统一下单接口,商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再在APP里面调起支付。
微信JsApi支付在这个目录下Senparc.Weixin.MP.Sample.Controllers找到JsApi支付。
publicActionResultJsApi(stringcode,stringstate) { if(string.IsNullOrEmpty(code)) { returnContent("您拒绝了授权!"); } if(!state.Contains("|")) { //这里的state其实是会暴露给客户端的,验证能力很弱,这里只是演示一下 //实际上可以存任何想传递的数据,比如用户ID,并且需要结合例如下面的Session["OAuthAccessToken"]进行验证 returnContent("验证失败!请从正规途径进入!1001"); } try { //获取产品信息 varstateData=state.Split('|'); intproductId=0; ProductModelproduct=null; if(int.TryParse(stateData[0],outproductId)) { inthc=0; if(int.TryParse(stateData[1],outhc)) { varproducts=ProductModel.GetFakeProductList(); product=products.FirstOrDefault(z=>z.Id==productId); if(product==null||product.GetHashCode()!=hc) { returnContent("商品信息不存在,或非法进入!1002"); } ViewData["product"]=product; } } //通过,用code换取access_token varopenIdResult=OAuthApi.GetAccessToken(TenPayV3Info.AppId,TenPayV3Info.AppSecret,code); if(openIdResult.errcode!=ReturnCode.请求成功) { returnContent("错误:"+openIdResult.errmsg); } stringsp_billno=Request["order_no"]; if(string.IsNullOrEmpty(sp_billno)) { //生成订单10位序列号,此处用时间和随机数生成,商户根据自己调整,保证唯一 sp_billno=string.Format("{0}{1}{2}",TenPayV3Info.MchId,DateTime.Now.ToString("yyyyMMdd"), TenPayV3Util.BuildRandomStr(10)); } else { sp_billno=Request["order_no"]; } vartimeStamp=TenPayV3Util.GetTimestamp(); varnonceStr=TenPayV3Util.GetNoncestr(); varbody=product==null?"test":product.Name; varprice=product==null?100:product.Price*100; varxmlDataInfo=newTenPayV3UnifiedorderRequestData(TenPayV3Info.AppId,TenPayV3Info.MchId,body,sp_billno,price,Request.UserHostAddress,TenPayV3Info.TenPayV3Notify,TenPayV3Type.JSAPI,openIdResult.openid,TenPayV3Info.Key,nonceStr); varresult=TenPayV3.Unifiedorder(xmlDataInfo);//调用统一订单接口 //JsSdkUiPackagejsPackage=newJsSdkUiPackage(TenPayV3Info.AppId,timeStamp,nonceStr,); varpackage=string.Format("prepay_id={0}",result.prepay_id); ViewData["appId"]=TenPayV3Info.AppId; ViewData["timeStamp"]=timeStamp; ViewData["nonceStr"]=nonceStr; ViewData["package"]=package; ViewData["paySign"]=TenPayV3.GetJsPaySign(TenPayV3Info.AppId,timeStamp,nonceStr,package,TenPayV3Info.Key); returnView(); } catch(Exceptionex) { varmsg=ex.Message; msg+="<br>"+ex.StackTrace; msg+="<br>==Source==<br>"+ex.Source; if(ex.InnerException!=null) { msg+="<br>===InnerException===<br>"+ex.InnerException.Message; } returnContent(msg); } }
先在微信服务后台生成预支付交易单,获得预支付订单号。
先说说在统一下单这里遇到的坑。
1.在统一下单的时候解析返回结果,一直出现以下问题:您没有JSAPI支付权限
<xml> <return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[您没有JSAPI支付权限]]></return_msg> </xml>
1)先看看你的公众号微信支付设置是否正确。
关于如何配置微信支付:可以参考这个http://jingyan.baidu.com/article/77b8dc7fef360d6174eab690.html
2)检查你的授权目录是否正确,格式要这样,后面记得别漏了一个/ 例如:http://test.cn/u/
3)检查需要传过去的账户参数,上公众号还有商户号检查你的账户参数是否正确。我在开发当中就出现,微信公众号商户号,appid是分别不同两个公众号的,坑啊,找了好久,觉得不对劲,原来是给的配置参数密钥不对。
这里详细说一下对应的参数:
MCHID:商户号(必须配置,开户邮件中可查看),商户申请微信支付后,由微信支付分配的商户收款账号。
APPID:微信开放平台审核通过的应用APPID,appid是微信公众账号或开放平台APP的唯一标识,在公众平台申请公众账号或者在开放平台申请APP账号后,微信会自动分配对应的appid用于标识该应用。可在微信公众平台-->开发者中心查看,商户的微信支付审核通过邮件中也会包含该字段值.
KEY:商户支付密钥,参考开户邮件设置(必须配置,登录商户平台自行设置),交易过程生成签名的密钥,仅保留在商户系统和微信支付后台,不会在网络中传播。商户妥善保管该Key,切勿在网络中传输,不能在其他客户端中存储,保证key不会被泄漏。商户可根据邮件提示登录微信商户平台进行设置。也可按一下路径设置:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置.
APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置,登录公众平台,进入开发者中心可设置)
2.在统一下单,解析返回来的结果我出现了商户号mch_id与appid不匹配这个问题
<xml> <return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[商户号mch_id与appid不匹配]]></return_msg> </xml>
原因是我拿到的商户号不是这个公众号的。一定要检查是不是这个公众号的商户号。
3.在统一下单,解析返回来的结果出现appidandopenidnotmatch,appid和openid不匹配。
<xml> <return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[appidandopenidnotmatch]]></return_msg> </xml>
原因是我这个用户的openid不是这个公众号的
4.在统一下单,解析返回来的结果出现CDATA[openidisinvalid],openid无效
<xml> <return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[openidisinvalid]]></return_msg> </xml>
原因是,传过去不是有效的opendid。不小心看错了,把用户id当做openid传过去了。
当统一下单成功,会返回以下格式的参数
<xml> <return_code><![CDATA[SUCCESS]]></return_code> <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> <trade_type><![CDATA[APP]]></trade_type> </xml>
解析获得预支付单号:
stringprepayId=res.Element("xml").Element("prepay_id").Value;//获取预支付订单号
给页面对应地参数
ViewData["appId"]=TenPayV3Info.AppId; ViewData["timeStamp"]=timeStamp; ViewData["nonceStr"]=nonceStr; ViewData["package"]=package; ViewData["paySign"]=TenPayV3.GetJsPaySign(TenPayV3Info.AppId,timeStamp,nonceStr,package,TenPayV3Info.Key);
静态页面js调用:
wx.chooseWXPay({ timestamp:0,//支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 nonceStr:'',//支付签名随机串,不长于32位 package:'',//统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***) signType:'',//签名方式,默认为'SHA1',使用新版支付需传入'MD5' paySign:'',//支付签名 success:function(res){ if(res.err_msg=="get_brand_wcpay_request:ok"){//支付成功 }else{ //支付失败 } //使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。 } });
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。