支付类型:
一次性支付
自动续费(支付宝周期扣款、微信委托扣款):1.支付并签约 2.先签约后扣费
注:微信委托扣款中先签约后扣费:自动续费、授权扣款、免密支付
支付宝
支付流程中各端交互逻辑
支付流程中商户APP端交互逻辑
先签约后扣费流程中各端交互逻辑:
1. 支付/签约前准备
导入aar集成支付宝客户端SDK,权限声明(网络,网络状态,WiFi状态)
对于先签约后扣费:判断是否安装支付宝。
根据用户ID、商品ID、支付平台等请求后台生成调起支付/签约所需参数:1.一次性支付、支付并签约:String orderInfo
,订单号:String orderId
。2.先签约后扣费:String signParams
注:一次性支付、支付并签约:对APP调起支付来说没区别。区别在于后台请求生成订单时传入更多参数:如周期规则参数(首次扣费时间、扣费周期单位、扣费周期数量…)
// 判断是否安装支付宝:检查包名com.eg.android.AlipayGphone是否存在
List<PackageInfo> packageInfoList = context.getPackageManager().getInstalledPackages(0);
boolean hasWallet = packageInfoList.stream()
.map(packageInfo -> packageInfo.packageName)
.anyMatch(s -> s.equals("com.eg.android.AlipayGphone"));
2. 调起支付/签约
-
一次性支付 、支付并签约
根据后台生成的订单信息,子线程中通过同步方法PayTask#payV2(String orderInfo, boolean isShowPayLoading)
调起支付,完成同步支付与异步签约。
String orderInfo
:支付参数字符串,主要包含商户的订单信息,key=value形式,以&连接。
boolean isShowPayLoading
:调起支付宝时是否显示一个loading,建议为true
// 服务器获取的订单信息
final String orderInfo = info;
// 调起支付逻辑
Runnable payRunnable = new Runnable() {
@Override
public void run() {
PayTask payTask = new PayTask(activity);
Map<String, String> result = payTask.payV2(orderInfo, true);
// 支付结果处理......
// handler.sendMessage()
}
};
// 调起支付
Thread payThread = new Thread(payRunnable);
payThread.start();
-
先签约后扣费
将后台生成的签约参数拼接到下面链接之后(该链接里面的appid为固定值,不可修改),APP通过scheme唤起支付宝进行签约。
“alipays://platformapi/startapp?appId=60000157&appClearTop=false&startMultApp=YES&sign_params=”
3. 支付/签约结果处理
-
一次性支付、支付并签约
支付完成之后会自动回到app中。
同步通知:PayTask#payV2()
方法同步返回的结果Map<String, String>去后台验签解析获取支付结果。
异步通知:后台创建订单的请求参数包含异步通知地址notify_url、sign_notify_url,支付完成后支付宝服务器会发送异步通知,后台也可查询接口确认结果。
Map<String, String>
:
{
"memo" : "xxxxx",
"result" : "{
\"alipay_trade_app_pay_response\":{
\"code\":\"10000\",
\"msg\":\"Success\",
\"app_id\":\"2014072300007148\",
\"out_trade_no\":\"081622560194853\",
\"trade_no\":\"2016081621001004400236957647\",
\"total_amount\":\"0.01\",
\"seller_id\":\"2088702849871851\",
\"charset\":\"utf-8\",
\"timestamp\":\"2016-10-11 17:43:36\"
},
\"sign\":\"NGfStJf3i3ooWBuCDIQSumOpaGBcQz+aoAqyGh3W6EqA/gmyPYwLJ2REFijY9XPTApI9YglZyMw+ZMhd3kb0mh4RAXMrb6mekX4Zu8Nf6geOwIa9kLOnw0IMCjxi4abDIfXhxrXyj********\",
\"sign_type\":\"RSA2\"
}",
"resultStatus" : "9000"
}
resultStatus
:
9000 |
订单支付成功 |
8000 |
正在处理中,支付结果未知(有可能已经支付成功),请查询商户订单列表中订单的支付状态 |
4000 |
订单支付失败 |
5000 |
重复请求 |
6001 |
用户中途取消 |
6002 |
网络连接出错 |
6004 |
支付结果未知(有可能已经支付成功),请查询商户订单列表中订单的支付状态 |
其它 |
其它支付错误 |
有些时候会出现商户app 在支付宝支付阶段被关闭导致无法正确收到同步结果,此时支付结果可以完全依赖服务端的异步通知。 由于同步通知和异步通知都可以作为支付完成的凭证,且异步通知支付宝一定会确保发送给商户服务端。为了简化集成流程,商户可以将同步结果仅仅作为一个支付结束的通知(忽略执行校验),实际支付是否成功,完全依赖服务端异步通知。
-
先签约后扣费
同步通知:后台调用支付宝个人协议页面签约接口时传入return_url;如果没有传入 return_url,那么签约完成后不再返回APP,直接回到支付宝首页。签约成功的情况下,可以在return_url里面设置APP的scheme地址去返回APP。同步通知会在return_url 后面拼接返回参数,可将参数去后台验签。
异步通知:异步通知(notify_url/应用网关地址)仅当用户签约成功或解约成功时触发。后台也可通过查询接口确认签约结果。
微信
支付流程中各端交互逻辑
支付流程中商户APP端交互逻辑
1. 支付/签约前准备
添加依赖:implementation 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
,权限声明:android.permission.INTERNET
。
判断微信是否可用。
根据用户ID、商品ID、支付平台等请求后台生成调起支付/签约所需参数:1.一次性支付、支付并签约:prepay_id…。2.先签约后扣费:pre_entrustweb_id(两个小时内有效)。
注:一次性支付、支付并签约:对APP调起支付来说没区别。区别在于后台请求不同的接口生成prepay_id。
// 微信接口
IWXAPI wxapi = WXAPIFactory.createWXAPI(context, null);
// 未安装微信
if (!wxapi.isWXAppInstalled()) {}
// 微信版本低不支持支付
if (wxapi.getWXAppSupportAPI() < Build.PAY_SUPPORTED_SDK_INT) {}
// 需要服务器返回的订单信息
// 1.调起支付所需参数
private String appId; // APP ID
private String partnerId; // 商户号
private String prepayId; // 后台去微信服务器请求生成的预支付ID:有效期2小时
private String packageValue; // 扩展字段,暂填写固定值"Sign=WXPay"
private String nonceStr; // 随机字符串
private String timeStamp; // 时间戳:自1970年1月1日 0点0分0秒以来的秒数
private String sign; // 签名:签名方式一定要与统一下单接口使用的一致
// 2.订单号,用于支付结果查询
private String orderId;
2. 调起支付/签约
-
一次性付费、支付并签约
根据服务器获取的相关信息,创建PayReq,IWXAPI调起支付
// 微信API
IWXAPI wxapi = WXAPIFactory.createWXAPI(context, null);
// 注册APP
wxapi.registerApp(appId);
// 调起支付对象PayReq
PayReq payReq = new PayReq();
payReq.appId = "";
payReq.partnerId = "";
payReq.prepayId = "";
payReq.packageValue = "";
payReq.nonceStr = "";
payReq.timeStamp = "";
payReq.sign = "";
payReq.extData = ""; // 可附加的额外数据(如加入订单号)。会在微信回调Activity中返回
// 调起支付
// PayReq参数不正确会导致调起微信支付失败,返回false;
// PayReq参数正确则调起微信支付成功,返回true。
wxapi.sendReq(payReq);
-
先签约后扣费
后台预签约生成pre_entrustweb_id。
WXOpenBusinessWebview.Req req = new WXOpenBusinessWebview.Req();
req.businessType = 12; // 固定值
HashMap queryInfo = new HashMap<>();
queryInfo.put("pre_entrustweb_id","......";
req.queryInfo = queryInfo;
api.sendReq(req);
3. 支付/签约结果处理