微信支付分为5种:
Jsapi支付,二维码支付,H5支付,小程序支付,App支付
Jsapi支付流程:
(1) 通过oauth协议获取open_id
a.第一步:用户同意授权,获取code
在确保微信公众账号拥有授权作用域(scope参数)的权限的前提下(服务号获得高级接口后,默认拥有scope参数中的snsapi_base和snsapi_userinfo),引导关注者打开如下页面:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
b.第二步:通过code换取网页授权access_token
首先请注意,这里通过code换取的是一个特殊的网页授权access_token,与基础支持中的access_token(该access_token用于调用其他接口)不同。获取code后,请求以下链接获取access_token:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
(2) 调用统一接口
(URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder)必填参数:
trade_type:jsapi,
open_id:用授权获取的open_id
Appid:企业号corpid即为此appId
Mch_id:微信支付分配的商户号
Notify_url:异步回调的url
nonce_str:随机字符串
Sign:签名
Body:商品描述
out_trade_no:商户订单号自己生成的(当前时间加时间戳)
total_fee:金额(分)
(3) 这些参数使用xml格式发送给微信的统一下单接口,并返回两个参数return_code为success时,微信端再次返回result_code为success时返回两个参数prepay_id,trade_type。
简单来说:微信给我们返回两个success时就会给我们返回prepay_id和trade_type。
(4) 返回的参数我们进行处理,处理成我们所需要的参数有:
appId:商户注册具有支付权限的公众号成功后即可获得
timeStamp:时间戳
nonceStr:随机字符串
Package:统一下单接口返回的prepay_id参数值,提交格式如:prepay_id=***
signType:签名类型(HMAC-SHA256)这里的签名方式和统一下单方式一致
Paysign:签名
生成paysign流程:公众账号+设备号+商户号+随机数+key,按照ASCII编码进行排序,键值对形式(key1=value1&key2=value2&key3=value3…),将得到的结果用MD5加密且转换为大写
(5) 微信支付界面调起配置分为两种:
a.一种是使用微信的内置对象WeixinJSBridge,把我们提前处理微信的返回参数放入getBrandWCPayRequest中
b.另一种是调用jssdk包,但是前提需要配置jssdk包wx.config,再配置微信支付,把我们提前处理微信的返回参数放入wx.chooseWXPay,唤起微信支付页面。
发起一个微信支付请求
wx.chooseWXPay({
timestamp: 0, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
nonceStr: '', // 支付签名随机串,不长于 32 位
package: '', // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
signType: '', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
paySign: '', // 支付签名
success: function (res) {
// 支付成功后的回调函数
}
});
备注:prepay_id 通过微信支付统一下单接口拿到,paySign 采用统一的微信支付 Sign 签名生成方法,注意这里 appId 也要参与签名,appId 与 config 中传入的 appId 一致,即最后参与签名的参数有appId, timeStamp, nonceStr, package, signType。
(6) 用户支付成功微信端会向我们填写的异步回调地址发起请求,给我们提示支付状态。我们需要返回一个success,
<xml>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
</xml>
让微信端知道我们知道的微信支付成功了。如果我们没给微信端返回success或超时,微信会判定本次通知失败,重新发送通知,直到成功为止(在通知一直不成功的情况下,微信总共会发起10次通知,通知频率为15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h - 总计 24h4m),但微信不保证通知最终一定能成功。
(7) 当然我不能相信微信给我们的支付状态,因为这个回调url,别人可以模拟出一个url,微信端就会向模拟出来的回调地址发送请求,会发生用户付过钱了但是没有订单的情况,这是很不安全的。所以我们不能相信微信给我们返回的,我们需要异步向微信查询订单接口,查询订单的支付状态
(8) 如果我们使用jssdk包,那么我们还需要通过配置wx.config。而wx.config的参数signature是通过。参考:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
a. 第一步获取access_token
https请求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
b. 第二步获取jsapi_ticket
用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):
https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
c. 第三步生成signature
签名算法
签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。即signature=sha1(string1)。
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名
jsApiList: [] // 必填,需要使用的JS接口列表
});
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。