赞
踩
很多老板与技术团队看了我们的微信小程序支付场景直呼专业,对我们牛卡派系统的支付流程有了一定的认识,那么小编就趁热打铁,将H5页面支付场景的整体流程放到下面了哦~
今天内容可都是满满的干货,有需求的可以私信我们牛卡派哦。
商户拥有一个H5商城或通过H5页面对外提供线上服务,当需要收款时调用牛卡派SAAS支付接口完成收款,下图是微信、支付宝、银联云闪付、手机默认浏览器环境下可以使用的H5页面收款效果。
由于微信和支付宝未开放给三方机构原生H5支付能力,故牛卡派系统通过如下方式实现H5支付:
联调之前需要先获取公私钥;
登录服务商/商户控台后,可在开发设置-开发者信息中,获取sys_id,product_id参数信息;
调用接口,均采取POST形式提交,数据格式统一为JSON格式。
准备一个已认证的公众号(微信内置浏览器)、小程序(第三方浏览器唤醒用)
微信:已开通微信业务,并配置小程序和公众号Appid
商户微信实名认证状态已完成,实名认证状态显示已授权
1)通过服务商控台确认已完成实名认证:新版控台-服务商控台-【商户信息】
2)通过微信实名认证状态查询接口来确认相关配置
3)商家已反馈实际在微信认证通过(由于系统对接的微信接口可能存在更新延迟情况,可按照微信实际认证情况为准)
H5支付方式的整体调用流程建议:
主要有以下几个步骤:
通过授权获取用户 open_id
用前端获取的用户信息调斗拱聚合正扫接口;
聚合正扫接口返回的pay_info提供前端页面发起支付;
牛卡派系统会将交易结果通知到商户后端系统。
接入步骤详细说明:
1.通过授权获取用户 open_id
授权说明见微信官方链接: 网页授权
只为获取 open_id的话静默授权就可以,无需用户同意。
地址:
- /*scope取值:snsapi_base/snsapi_userinfo
- - snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid)
- - snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且, 即使在未关注的情况下,只要用户授权,也能获取其信息 )
- */
- let url=`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${urlNow}&response_type=code&scope=${scope}&state=STATE&connect_redirect=1#wechat_redirect`;
- window.location.replace(url);
如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。
获取code后,请求以下链接获取access_token:
示例代码如下:
- /*https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code*/
-
- url = 'https://api.weixin.qq.com/sns/oauth2/access_token'
- params = {
- 'appid': app_id,
- 'secret': 'wx_secret',
- 'code': wx_code,
- 'grant_type': 'authorization_code',
- }
- resp = requests.get(url, params, timeout=15)
- result_dict = json.loads(resp.text)
- openid=result_dict.get('openid')
2.调用系统聚合正扫接口
交易类型 trade_type 选T_JSAPI,用户子标识 sub_openid 填上一步获取的openid
将接口应答的支付信息pay_info返回前端页面
聚合正扫接口需关注以下字段:
参数 | 中文名 | 必填 | 说明 |
trade_type | 交易类型 | Y | T_JSAPI: 微信JS支付 |
time_expire | 交易有效期 | N | 指定交易失效时间,不指定微信默认是2小时,超过有效时间的订单会默认被关闭 |
+wx_data | 微信拓展参数集合 | N | 通过前端调服微信获取的数据换取pay_info; |
sub_appid | 子商户公众账号ID | N | 微信公众号ID |
openid | 用户标识 | Y | 前端调用微信获取的用户在商户appid下的唯一标识; |
sub_openid | 子商户用户标识 | N | 前端调用微信获取的用户在子商户appid下的唯一标识; |
notify_url | 异步通知地址 | N | 交易异步通知地址,http或https开头 |
*其中wx_data中,如填写openid则无需填写sub_appid+sub_openid。如不填openid,则需填写sub_appid和sub_openid。
同步返回关注以下字段:
参数 | 中文名 | 说明 |
trans_stat | 交易状态 | 同步通常返回“处理中”,交易终态以异步返回为准 |
resp_desc | 业务响应信息 | 关注失败原因 |
bank_message | 通道返回描述 | 关注通道返回的失败原因 |
pay_info | 支付信息 | 这个字段后续调用微信需要用到的 |
nkp_seq_id | 全局流水号 | 系统生成全局流水号,后续可以用这个流水号查询交易 |
3.发起支付
前端页面调用JSAPI 使用聚合正扫返回的pay_info内容发起支付。
示例代码:
- WeixinJSBridge.invoke('getBrandWCPayRequest', {
- "appId": "wx2421b1c4370ec43b",
- "timeStamp": "1395712654",
- "nonceStr": "e61463f8efa94090b1f366cccfbbb444",
- "package": "prepay_id=up_wx21201855730335ac86f8c43d1889123400",
- "signType": "RSA",
- "paySign": "oR9d8PuhnIc+YZ8cBHFCwfgpaK9gd7vaRvkYD7rthRAZ\/X+QBhcCYL21N7cHCTUxbQ+EAt6Uy+lwSN22f5YZvI45MLko8Pfso0jm46v5hqcVwrk6uddkGuT+Cdvu4WBqDzaDjnNa5UK3GfE1Wfl2gHxIIY5lLdUgWFts17D4WuolLLkiFZV+JSHMvH7eaLdT9N5GBovBwu5yYKUR7skR8Fu+LozcSqQixnlEZUfyE55feLOQTUYzLmR9pNtPbPsu6WVhbNHMS3Ss2+AehHvz+n64GDmXxbX++IOBvm2olHu3PsOUGRwhudhVf7UcGcunXt8cqNjKNqZLhLw4jq\/xDg==" //微信签名
- },
- function(res) {
- if (res.err_msg == "get_brand_wcpay_request:ok") {
- // 使用以上方式判断前端返回,微信团队郑重提示:
- //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
- }
- });
- }
- if (typeof WeixinJSBridge == "undefined") {
- if (document.addEventListener) {
- document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
- } else if (document.attachEvent) {
- document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
- document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
- }
- } else {
- onBridgeReady();
- }
调用流程:
接入步骤说明:
1.APP跳转微信小程序
配置准备:
示例代码:以IOS 为例,安卓示例请参考微信官方说明。
- //微信建议应用启动时调用
- [WXApi registerApp:@"wx_app_id"];//wx_app_id 为移动应用的appid
- ...
- ...
- ...
- //跳转小程序部分
- WXLaunchMiniProgramReq *launchMiniProgramReq = [WXLaunchMiniProgramReq object];
- launchMiniProgramReq.userName = @"gh_4fxxxxxx"; //待拉起的小程序原始Id
- launchMiniProgramReq.path = @"pages/index/index?query='test'"; 拉起小程序页面的可带参路径,不填默认拉起小程序首页,对于小游戏,可以只传入 query 部分,来实现传参效果,如:传入 "?foo=bar"。
- launchMiniProgramReq.miniProgramType = WXMiniProgramTypePreview; //拉起小程序的类型
- [WXApi sendReq:launchMiniProgramReq];
- ...
- ...
- ...
2.通过授权获取用户 open_id
a. 小程序端调用 wx.login(Object object)接口 获取登录凭证(code)
- wx.login({
- success (res) {
- if (res.code) {
- //发起网络请求
- wx.request({
- url: 'https://test.com/onLogin',
- data: {
- code: res.code
- }
- })
- } else {
- console.log('登录失败!' + res.errMsg)
- }
- }
- })
b. 商户服务端使用前一步获取的code 换取 open_id ,后台请求以下链接 获取openID;
示例代码如下:
- /*GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code*/
-
- url = 'https://api.weixin.qq.com/sns/jscode2session'
- params = {
- 'appid': app_id,
- 'secret': 'wx_secret',
- 'js_code': wx_code,
- 'grant_type': 'authorization_code',
- }
- resp = requests.get(url, params, timeout=15)
- result_dict = json.loads(resp.text)
- openid=result_dict.get('openid')
3.下单请求支付信息
通过上面的App打开的path是’path/index’, 所以需要把App的onShow事件定义在page/index.js上
这里的options.scene是1069,这个场景id表示从app打开。
options.query.key1和options.query.key2就是app打开小程序传递的参数。
客户服务器端调用聚合支付接口下单拉起支付,需要传入前端调用获得的 open_id 获取微信返回支付 pay_info信息。
聚合正扫接口需关注以下字段:
参数 | 中文名 | 必填 | 说明 |
---|---|---|---|
trade_type | 交易类型 | Y | T_MINIAPP: 微信小程序 |
time_expire | 交易有效期 | N | 指定交易失效时间,不指定微信默认是2小时,超过有效时间的订单会默认被关闭 |
+wx_data | 微信拓展参数集合 | N | 通过前端调服微信获取的数据换取pay_info; |
sub_appid | 子商户公众账号ID | N | 微信小程序app_id |
openid | 用户标识 | Y | 前端调用微信获取的用户在商户appid下的唯一标识; |
sub_openid | 子商户用户标识 | N | 前端调用微信获取的用户在子商户appid下的唯一标识; |
notify_url | 异步通知地址 | N | 交易异步通知地址,http或https开头 |
*其中wx_data中,如填写openid则无需填写sub_appid+sub_openid。如不填openid,则需填写sub_appid和sub_openid。
同步返回关注以下字段:
参数 | 中文名 | 说明 |
---|---|---|
trans_stat | 交易状态 | 同步通常返回“处理中”,交易终态以异步返回为准 |
resp_desc | 业务响应信息 | 关注失败原因 |
bank_message | 通道返回描述 | 关注通道返回的失败原因 |
pay_info | 支付信息 | 这个字段后续调用微信需要用到的 |
nkp_seq_id | 全局流水号 | 系统生成全局流水号,后续可以用这个流水号查询交易 |
4.小程序端发起支付
- wx.requestPayment(
- {
- 'timeStamp': '',
- 'nonceStr': '',
- 'package': '',
- 'signType': 'MD5',
- 'paySign': '',
- 'success':function(res){},
- 'fail':function(res){},
- 'complete':function(res){}
- })
完整的交易流程还要包括退款。由于用户或者商户的原因需要退款时,商户可以通过本接口将支付款退还给用户,退款成功资金将原路返回。微信、支付宝、银联云闪付参见扫码交易退款接口;其它类型的交易退款参见线上交易退款接口。
关注以下请参:
参数 | 中文名 | 必填 | 说明 |
org_req_date | 原交易请求日期 | Y | 用户发起支付的日期 |
org_req_seq_id | 原交易请求流水号 | C | 商户系统发给斗拱的指令流水号 |
org_nkp_seq_id | 原交易全局流水号 | C | 系统生成的系统流水号 |
org_party_order_id | 原交易微信支付宝的商户单号 | C | 该笔交易在微信支付宝端的流水号 |
ord_amt | 申请退款金额 | Y | 退款金额<=原交易金额 |
为了满足商户财务的对账需求,系统提供了对账功能。
方案一:控台下载;
方案二:接口获取;参见交易结算对账单查询接口
针对交易结果,系统会通过异步消息的方式通知客户系统。
调用接口时上送的异步通知地址为http/https路径:服务器为POST回调,默认超时时间为5秒,超时后会重试3次;不支持HTTP重定向;服务器对应答不是200~300之间的错误,会默认重试3次;异步通知服务器对HTTPS不认证验签和ALLOW_ALL_HOSTNAME_VERIFIER;如商户自定义通知端口,请使用8000-9005内端口,否则无法通知;URL 上请勿附带参数;异步回调请求编码集为:UTF-8;收到通知后请返回状态码“200”,响应异步通知。
注意事项:
同样的异步消息可能会通知多次,因此接收异步消息的处理需做好幂等,保障多次接收到同样的消息处理后结果不变。
在实现异步消息接收的同时,都建议您在重要的业务环节,通过反查接口确认 非终态 支付订单的状态,以保证在发生异步消息延迟或无法送达情况下的支付结果一致性。
商户拥有一个H5商城或通过H5页面对外提供线上服务,当需要收款时调用牛卡派SAAS支付接口完成收款,下图是微信、支付宝、银联云闪付、手机默认浏览器环境下可以使用的H5页面收款效果。
由于微信和支付宝未开放给三方机构原生H5支付能力,故汇付是如下实现H5支付
支付宝接入准备与微信接入准备所需要的步骤一致。
调用接口,均采取POST形式提交,数据格式统一为JSON格式。
无需提前准备
已开通支付宝业务
商户支付宝实名认证状态已完成,实名认证状态显示已授权
1)通过服务商控台确认已完成实名认证:新版控台-服务商控台-【商户信息】
2)通过支付宝实名认证状态查询接口来确认相关配置
3)商家已反馈实际在支付宝认证通过(由于斗拱对接的支付宝接口可能存在更新延迟情况,可按照支付宝实际认证情况为准)
H5支付方式的整体调用流程建议:
此种方式的主要原理:
接入步骤:
调用系统聚合正扫接口trade_type = 'A_NATIVE' (支付宝正扫);
取出接口返回的qr_code,在 APP 内通过打开第三方APP的方式打开如下URL,举例:
alipays://platformapi/startapp?saId=10000007&qrcode=支付宝
Android示例代码:
- // 固定前缀
- String topic = "alipays://platformapi/startapp?saId=10000007&qrcode=";
- // 从系统正扫接口获取的参数(以下值仅为示例)
- String qrcodeUrl = "https://qr.alipay.com/bax02911brluc2xieoph6001"
- // 字符串拼接
- String jumpUrl = topic + qrcodeUrl;
- // 按以上示例拼接得出结果
- // jumpUrl 为 alipays://platformapi/startapp?saId=10000007&qrcode=https://qr.alipay.com/bax02911brluc2xieoph6001
- Intent intent = new Intent();
- intent.setAction("android.intent.action.VIEW");
- // jumpUrl 为先前示例中拼装的 url
- Uri contentUrl = Uri.parse(jumpUrl);
- intent.setData(contentUrl);
- activity.startActivity(intent);
IOS 示例代码:
[[UIApplication sharedApplication]openURL:[NSURL URLWithString: jumpUrl]];
如需考虑未安装支付宝的情况,APP端可使用 webview,加载聚合正扫接口返回的链接(例:支付宝 此种方式,如未安装支付宝客户端,会跳转到支付宝下载页面,引导用户安装下载。
RN的方式参考以下示例:
- linkurl = 'alipays://platformapi/startapp?saId=10000007&qrcode='+ {URL}
- Linking.openURL(linkurl);
Union App开发方式:
调用方式可以参考 Uni-app拉起方式说明
同上;
支付宝的退款流程、对账流程、异步通知也与上边微信的步骤一致哦~~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。