支付方式说明

支付宝APP支付

支付宝APP 支付可通过多种方式实现。

  • 通过支付宝扫码实现
  • 通过支付宝JS支付实现

1.通过支付宝Native扫码的方式

调用 聚合正扫 接口时trade_type: A_NATIVE(支付宝正扫)

此种方式的主要原理是:通过拉起支付宝APP 然后调用支付宝内said为10000007的扫码功能来发起支付。

前端拿到服务端返回的qr_code,在 APP 内 通过打开第三方APP的方式打开此URL。

a. 取出接口返回的qr_code,在 APP 内 通过打开第三方APP的方式打开如下URL

示例:
alipays://platformapi/startapp?saId=10000007&qrcode=https://qr.alipay.com/bax02911brluc2xieoph6001

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]];

注意:系统会弹出是否允许打开支付宝,点击允许,跳转支付宝进行支付,此种方式没有考虑用户没有装支付宝的情况。

b. 如需考虑未安装支付宝的情况,APP端可使用 webview,加载聚合正扫接口返回的链接(例:https://qr.alipay.com/bax02911brluc2xieoph6001) 此种方式,如未安装支付宝客户端,会跳转到支付宝下载页面,引导用户安装下载。

以上部分是在APP为原生开发的前提下,RN的方式参考以下示例,Union App开发的可参考以上实现思路来实现。

React Native方式

linkurl = 'alipays://platformapi/startapp?saId=10000007&qrcode='+ {URL}
Linking.openURL(linkurl);

2.通过支付宝JS支付的方式

调用 聚合正扫 接口时trade_type: A_JSAPI (支付宝JS),商户可以使用代理商的小程序来下单发起支付.

此种方式的主要原理是:通过拉起支付宝APP,然后跳转到对应支付宝小程序中,在小程序内处理业务逻辑,下单,然后调用支付宝js API 发起支付。

步骤一:APP端打开第三方APP的方式打开如下URL

alipays://platformapi/startapp?appId=app_id&page=page_path"

其中appid 为在支付宝侧申请的小程序appid,page_path 为跳转过去的小程序页面路径

步骤二:获取 buyer_id,即付款用户的支付宝 user_id,详情参考支付宝官方文档: 用户授权

a. 小程序客户端内获取 authorization_code 示例:

my.getAuthCode({
scopes: ['auth_user'],
// 主动授权:auth_user,静默授权:auth_base。或者其它scope。如需同时获取用户多项授权,可在 scopes 中传入多个 scope 值。
success: (res) => {
        if (res.authCode) {
        // 认证成功
        // 调用自己的服务端接口,让服务端进行后端的授权认证,并且利用session,需要解决跨域问题
        my.request({
            url: 'https://isv.com/auth', // 该url是您自己的服务地址,实现的功能是服务端拿到authcode去开放平台进行token验证
            data: {
            authcode: res.authCode,
            },
            success: () => {
            // 授权成功并且服务器端登录成功
            },
            fail: () => {
            // 根据自己的业务场景来进行错误处理
            },
        });
        }
    },
});

b. 商户服务端获取 access_token、user_id

服务器端调用 alipay.system.oauth.token(换取授权访问令牌) 接口换取授权访问令牌,开发者可通过获取到的 auth_code 换取 access_token(授权令牌) 和 user_id (用户支付宝 ID)。

auth_code 作为换取 access_token 的票据,每次用户授权完成,回调地址中的 auth_code 将不一样,auth_cod 只能使用一次,一天未被使用自动过期。

AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2");
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
request.setGrantType("authorization_code");
request.setCode("4b203fe6c11548bcabd8da5bb087a83b");
AlipaySystemOauthTokenResponse response = alipayClient.execute(request);
if(response.isSuccess()){
    System.out.println("调用成功");
} else {
    System.out.println("调用失败");
}

步骤三:小程序内调用商户端接口,获取支付信息,支付信息中应包含tradeNO,该接口由商户自行根据业务内容实现。

步骤四:唤起收银台支付

在小程序端使用 tradeNO,调用 my.tradePay 接口唤起支付宝收银台,引导用户完成支付。详情参见支付宝官方说明: 小程序唤起收银台

my.tradePay({
    tradeNO: '2017111521001104105336677922',
    success: function(res) {
      my.alert({
       content: JSON.stringify(res),
     });
    },
    fail: function(res) {
    my.alert({
      content: JSON.stringify(res),
      });
   },
});

支付宝JS支付

用户通过支付宝扫码的方式进入商家H5页面,由用户输入金额完成付款。

调用此接口会到支付宝进行预下单,调用方根据返回的预支付信息,通过JSAPI的方式在其支付宝H5页面中拉起支付控件,供用户完成支付。

说明:

1、非支付宝的H5支付,是基于支付宝的统一下单提供的聚合支付下单接口。

2、支付宝的买家用户Id由调用方自行获取。

注:获取 buyer_id,即付款用户的支付宝 user_id,详情参考支付宝官方文档: 用户授权

调用 聚合正扫 接口时trade_type: A_JSAPI (支付宝JS),商户可以使用代理商的小程序来下单发起支付.

此种方式的主要原理是:通过拉起支付宝APP,然后跳转到对应支付宝小程序中,在小程序内处理业务逻辑,下单,然后调用支付宝js API 发起支付。

步骤一:APP端打开第三方APP的方式打开如下URL

alipays://platformapi/startapp?appId=app_id&page=page_path"

其中appid 为在支付宝侧申请的小程序appid,page_path 为跳转过去的小程序页面路径

步骤二:获取 buyer_id,即付款用户的支付宝 user_id,详情参考支付宝官方文档: 用户授权

a. 小程序客户端内获取 authorization_code 示例:

my.getAuthCode({
scopes: ['auth_user'],
// 主动授权:auth_user,静默授权:auth_base。或者其它scope。如需同时获取用户多项授权,可在 scopes 中传入多个 scope 值。
success: (res) => {
        if (res.authCode) {
        // 认证成功
        // 调用自己的服务端接口,让服务端进行后端的授权认证,并且利用session,需要解决跨域问题
        my.request({
            url: 'https://isv.com/auth', // 该url是您自己的服务地址,实现的功能是服务端拿到authcode去开放平台进行token验证
            data: {
            authcode: res.authCode,
            },
            success: () => {
            // 授权成功并且服务器端登录成功
            },
            fail: () => {
            // 根据自己的业务场景来进行错误处理
            },
        });
        }
    },
});

b. 商户服务端获取 access_token、user_id

服务器端调用 alipay.system.oauth.token(换取授权访问令牌) 接口换取授权访问令牌,开发者可通过获取到的 auth_code 换取 access_token(授权令牌) 和 user_id (用户支付宝 ID)。

auth_code 作为换取 access_token 的票据,每次用户授权完成,回调地址中的 auth_code 将不一样,auth_cod 只能使用一次,一天未被使用自动过期。

AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2");
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
request.setGrantType("authorization_code");
request.setCode("4b203fe6c11548bcabd8da5bb087a83b");
AlipaySystemOauthTokenResponse response = alipayClient.execute(request);
if(response.isSuccess()){
    System.out.println("调用成功");
} else {
    System.out.println("调用失败");
}

步骤三:小程序内调用商户端接口,获取支付信息,支付信息中应包含tradeNO,该接口由商户自行根据业务内容实现。

步骤四:唤起收银台支付

在小程序端使用 tradeNO,调用 my.tradePay 接口唤起支付宝收银台,引导用户完成支付。详情参见支付宝官方说明: 支付宝交易号唤起支付

<h1>点击以下按钮唤起收银台支付</h1>
    <a href="javascript:void(0)" class="btn tradenoPay">支付宝交易号唤起支付</a>
    <script>
            function ready(callback) {
                    // 如果jsbridge已经注入则直接调用
                    if (window.AlipayJSBridge) {
                            callback && callback();
                    } else {
                            // 如果没有注入则监听注入的事件
                            document.addEventListener('AlipayJSBridgeReady', callback, false);
                    }
            }
            ready(function(){
                    document.querySelector('.tradeno').addEventListener('click', function() {
                            AlipayJSBridge.call("tradePay", {
                                    tradeNO: "201802282100100427058809844"
                            }, function(result) {
                                    alert(JSON.stringify(result));
                            });
                    });
            });
    </script>

支付宝Native支付

此接口用于服务商到支付宝统一下单,展示返回的二维码信息,用户通过支付宝扫描此二维码完成付款。

微信JS支付(微信公众号)

用户通过微信扫码的方式进入商家H5页面,由用户输入金额完成付款。

调用此接口会到微信进行预下单,调用方根据返回的预支付信息,通过JSAPI的方式在其微信公众号页面中拉起支付控件,供用户完成支付。

说明:

1、非微信的H5支付,是基于微信公众号提供的聚合支付下单接口。

2、微信买家的opendId由调用方自行获取。

3、需要关注自己的公众号(非入驻商户的公众号)的,请提前申请微信渠道号,具体流程请咨询商务。

主要有以下几个步骤:

  • 通过授权获取用户 open_id
  • 调用汇付聚合扫码接口到微信预下单,获取支付信息
  • 使用支付信息发起支付

1. 通过授权,获取 open_id

说明见微信官方链接: 网页授权

  • 微信公众号后台配置授权域名,将微信校验文件放到服务器根目录下
  • 用户静默授权获取code,前端页面在微信内打开授权地址,成功后并重定向到自己项目目标地址

只为获取 open_id的话静默授权就可以,无需用户同意。

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);
  • 使用获取到的code,在服务端调用微信接口获取 access_token和 open_id

获取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

将接口应答的支付信息返回前端页面

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.通过授权获取用户 open_id

wx.login({
    success (res) {
        if (res.code) {
            //发起网络请求
            wx.request({
                url: 'https://test.com/onLogin',
                data: {
                code: res.code
                }
            })
        } else {
            console.log('登录失败!' + res.errMsg)
        }
    }
})
  • 2.商户服务端使用第一步获取的code 换取 open_id ,后台调用接口 获取openID
GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

2.商户服务端使用 open_id 下单

商户服务端通过调用 聚合正扫 接口下单。

3.小程序端发起支付

小程序端使用汇付返回的pay_info 发起支付

调用wx.requestPayment(OBJECT)发起微信支付

wx.requestPayment(
{
    'timeStamp': '',
    'nonceStr': '',
    'package': '',
    'signType': 'MD5',
    'paySign': '',
    'success':function(res){},
    'fail':function(res){},
    'complete':function(res){}
})

微信APP支付

由于微信不支持间联的 APP支付,但可以通过APP跳转微信小程序,小程序处理支付逻辑来实现。

前提条件

1.在微信开放平台上有账号而且有通过的移动应用。

2.在微信公众平台有账号而且有小程序,开发阶段可以使用体验版本,最终上线,小程序需上线审核通过。

3.在微信开放平台把对应的移动应用和小程序建立关联。

主要步骤:

1.APP跳转微信小程序

下载微信SDK 并参考 微信官方说明 接入SDK

示例代码: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

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
  • c.下单请求支付信息

通过上面的App打开的path是’path/index’, 所以需要把App的onLaunch事件定义在page/index.js上

_images/wxAppOrderDemo1.png

这里的options.scene是1069,这个场景id表示从app打开。

options.query.key1和options.query.key2就是app打开小程序传递的参数。

通过接口调用服务端 聚合正扫 接口下单,传入 open_id 获取支付 pay_info信息。

  • d.小程序端发起支付

使用聚合正扫返回的pay_info 调用wx.requestPayment(OBJECT)发起微信支付

wx.requestPayment(
{
    'timeStamp': '',
    'nonceStr': '',
    'package': '',
    'signType': 'MD5',
    'paySign': '',
    'success':function(res){},
    'fail':function(res){},
    'complete':function(res){}
})
  • e.小程序返回APP

支付成功以后,附带支付结果跳转回APP。 返回APP说明

<button open-type="launchApp" app-parameter="wechat" binderror="launchAppError">打开APP</button>
Page({
    launchAppError (e) {
        console.log(e.detail.errMsg)
    }
})

注意:APP端需要设置正确URL scheme才能从微信正确回调。

银联JS支付

服务商通过此接口到银联进行下单并于H5页面唤起银联支付控件供用户付款。银联JS支付需要获取银联用户标识,请求汇付提供的获取银联用户标识接口。

需通过以下几个步骤实现。

获取临时授权码、调用获取银联用户标识接口获取用户ID、调用聚合正扫接口下单、发起支付,用户支付

获取临时授权码

浏览器跳转云闪付授权地址, 传入参数: version=1.0.0, redirectUrl=回调地址(商户备案域名下地址),

银联返回两个参数: respCode(00为成功)、userAuthCode(临时授权码,有效期5分钟)

window.location = "https://qr.95516.com/qrcGtwWeb-web/api/userAuth?version=1.0.0&redirectUrl=https://spin-test-java.cloudpnr.com/api/test";

获取银联云闪付用户标识

调用 「获取银联用户标识」 接口,传入上一步获取到的授权码,返回用户标识

下单

调用 「聚合正扫」 下单接口,传入用户标识,返回pay_info(支付链接)

发起支付

前端页面拿到支付链接后进行跳转

window.location = data.pay_info;

银联Native正扫支付

此接口用于服务商到银联下单,展示返回的二维码信息,用户通过银联云闪付app扫描此二维码完成付款。

支付宝条码支付

商家通过扫码设备,扫描用户出示的支付宝付款码完成收款。

微信条码支付

商家通过扫码设备,扫描用户出示的微信付款码完成收款。

银联条码支付

商家通过扫码设备,扫描用户出示的银联云闪付付款码完成收款。

网银支付/充值

网银支付是指用户需要开通网上银行后在线完成支付,主要对象是国内主要银行借记卡和信用卡,是银行系统为企业或个人提供的安全、快捷、稳定的支付服务。

本API为页面版接口,用于用户、商户进行网银支付及充值,用户付款银行卡需要预先在银行网银或柜面开通在线支付功能才可进行支付,本接口的银行同步回调不作为交易结果判断仅供页面跳转使用。

涉及到的接口包括: 网银支付页面版接口、 线上交易查询接口 、 线上交易退款接口、 线上退款查询接口。

手机网页支付

手机网页支付是指用户需要开通网上银行后移动端完成支付,主要对象是国内主要银行借记卡和信用卡,是银行系统为企业或个人提供的安全、快捷、稳定的支付服务。

本API为后台版接口,用于用户、商户进行移动端的网银支付及充值,用户付款银行卡需要预先在银行网银或柜面开通在线支付功能才可进行支付,form_html字段返回银行提供的html,由商户自行展示,同时可以承接普通消费和分期消费交易。

涉及到的接口包括: 手机网页支付接口、 线上交易查询接口 、 线上交易退款接口、 线上退款查询接口。

快捷三合一支付

快捷支付指用户购买商品时,不需开通网银,只需提供银行卡卡号、户名、手机号码等信息,银行验证手机号码正确性后,发送手机动态口令到用户手机号上,用户输入正确的手机动态口令,即可完成支付。

本API为页面版接口, 提供了开户、绑卡和支付三合一的接口,并且提供页面让用户录入身份和卡号信息,商户不需要额外调用开户和绑卡接口, 也不需要开发页面采集用户信息,可以快速接入快捷支付功能。这种接入方式支持贷记卡支付。 涉及到的接口包括: 快捷支付三合一页面版接口、 线上交易查询接口 、 线上交易退款接口、 线上退款查询接口。

出金交易

出金交易是指将留存资金从汇付划入银行账户的操作,涉及接口包括:取现、出金交易查询。

取现用于从汇付将自由资金取现到事先绑定的银行卡中。

在发起取现交易后,当交易结果不明确时,可以通过出金交易查询来查询该笔取现的详细交易情况。

余额支付

余额支付是指用户在汇付账户中提前支付的预存金额,或是在汇付中消费的剩余金额,可用于支付您在汇付的购买行为。

本API为后台版接口,用于用户、商户使用账户内的金额进行交易。涉及到的接口包括:余额支付接口、余额支付查询接口、余额支付退款接口、余额支付退款查询接口