支付SDK集成踩坑实录,从零到上线的关键技术要点
为啥要对比这些支付SDK?
最近做了几个移动端项目,涉及到支付这块,真是踩了不少坑。微信支付、支付宝、银联,每个都有自己的SDK和集成方式,各有各的问题。之前一直凭感觉选,这次专门整理了一下,看看哪个方案更靠谱。
微信支付SDK:稳定但复杂
我比较喜欢用微信支付,毕竟用户覆盖面广,但是集成起来确实麻烦。微信官方提供的SDK需要配置的东西比较多,而且每次版本更新都得重新适配。
这是微信支付的基本集成代码:
// 微信支付集成示例
function wechatPay(orderInfo) {
WeixinJSBridge.invoke('getBrandWCPayRequest', {
appId: orderInfo.appId,
timeStamp: orderInfo.timeStamp,
nonceStr: orderInfo.nonceStr,
package: orderInfo.package,
signType: orderInfo.signType,
paySign: orderInfo.paySign
}, function(res) {
if (res.err_msg === "get_brand_wcpay_request:ok") {
// 支付成功
console.log('支付成功');
} else {
// 支付失败
console.log('支付失败', res.err_msg);
}
});
}
这里面有几个坑需要注意:
- 一定要在微信浏览器里才能调用
- 签名要在服务端生成,前端不能直接调用
- 某些机型兼容性有问题
微信支付的优点是用户接受度高,成功率也比较高。缺点就是集成复杂,而且受微信政策影响比较大。
支付宝SDK:文档齐全但包体积大
支付宝的SDK我用得相对少一些,主要是因为包体积太大了。不过他们的文档确实做得很详细,遇到问题基本都能找到解决方案。
// 支付宝H5支付示例
function alipayH5(payInfo) {
var form = document.createElement('form');
form.style.display = 'none';
form.method = 'POST';
form.action = 'https://openapi.alipay.com/gateway.do';
var input = document.createElement('input');
input.type = 'hidden';
input.name = 'biz_content';
input.value = JSON.stringify(payInfo);
form.appendChild(input);
document.body.appendChild(form);
form.submit();
document.body.removeChild(form);
}
// 支付宝回调处理
window.addEventListener('message', function(event) {
if (event.origin !== 'https://openapi.alipay.com') return;
var data = JSON.parse(event.data);
if (data.resultCode === '9000') {
// 支付成功
console.log('支付宝支付成功');
} else {
console.log('支付宝支付失败', data.resultCode);
}
});
支付宝的优势在于文档完善,支持的支付方式多。但是包体积确实是个问题,特别是对于追求轻量化的项目来说。
银联SDK:小众但稳定
银联SDK用得最少,主要是客户那边要求才接入的。说实话,用户体验不如前两者,但是稳定性确实不错。
// 银联支付示例
function unionpay(paymentData) {
var formData = {
version: '5.1.0',
encoding: 'utf-8',
certId: paymentData.certId,
txnType: '01',
txnSubType: '01',
bizType: '000201',
channelType: '08',
accessType: '0',
merId: paymentData.merId,
orderId: paymentData.orderId,
txnTime: paymentData.txnTime,
txnAmt: paymentData.txnAmt,
currencyCode: '156',
reqReserved: paymentData.reqReserved,
backUrl: paymentData.backUrl
};
// 发送请求到银联系统
fetch('https://gateway.95516.com/gateway/api/appTransReq.do', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(formData)
})
.then(response => response.json())
.then(data => {
if (data.tn) {
// 调起银联控件
location.href = 'https://mobileportal.unionpay.com/jsp/tnaccess?tn=' + data.tn;
}
});
}
银联的坑主要在于用户习惯问题,很多人不太愿意装银联的APP,所以支付转化率相对低一些。
三方聚合SDK:方便快捷但有风险
现在市面上有很多聚合支付SDK,比如Ping++、BeeCloud这些。一个SDK就能支持多种支付方式,确实很方便。
// 聚合支付SDK示例
import PaySDK from 'pay-sdk';
const pay = new PaySDK({
appId: 'your_app_id',
appKey: 'your_app_key'
});
// 统一的支付接口
pay.createPayment({
amount: 100, // 分
subject: '商品名称',
body: '商品描述',
channel: 'wx_pub' // 支付渠道
}, function(result) {
if (result.status === 'success') {
console.log('支付成功');
} else {
console.log('支付失败', result.message);
}
});
这种方案最大的好处就是集成简单,维护成本低。但是也有风险:
- 依赖第三方服务商
- 安全性相对较弱
- 出现问题需要通过中间商处理
谁更灵活?谁更省事?
从灵活性来说,原生的各个支付平台SDK是最灵活的,可以完全按照自己的需求定制。但是开发成本高,维护麻烦。
聚合SDK虽然方便,但是灵活性差一些,如果某个支付方式更新了,你需要等聚合服务商更新。
从省事角度来说,肯定是聚合SDK最省事,一次集成多个支付方式。但是我建议大项目还是用原生的,小项目或者MVP产品可以用聚合SDK。
我的选型逻辑
我现在的选型逻辑是这样的:
- 大型电商类项目:微信+支付宝原生SDK,用户体验最重要
- 中小型项目:聚合SDK快速上线,后续根据数据决定是否拆分
- 特定行业(比如金融类):只用银行相关的支付方式
还有一个重要的考虑因素是合规性。现在支付监管越来越严,原生SDK在这方面更有保障,聚合SDK可能会有政策风险。
另外,我一般会把支付相关代码单独封装成模块,这样后期如果要更换SDK也比较容易:
class PaymentManager {
constructor() {
this.paymentMethods = {};
}
register(method, handler) {
this.paymentMethods[method] = handler;
}
pay(method, options) {
const handler = this.paymentMethods[method];
if (!handler) {
throw new Error(支付方式 ${method} 未注册);
}
return handler(options);
}
}
// 使用示例
const payment = new PaymentManager();
payment.register('wechat', wechatPay);
payment.register('alipay', alipayH5);
payment.pay('wechat', { amount: 100, orderId: 'xxx' });
踩坑提醒:这三点一定注意
这里重点提醒几个坑:
第一个坑是签名问题,不管是哪个支付平台,签名一定要在服务端完成,不要在前端算签名,这是安全要求。
第二个坑是异步通知,很多人只处理前端的同步回调,忽略了服务端的异步通知,这样容易出现支付状态不一致的问题。
第三个坑是错误处理,各种网络异常、支付取消的情况都要考虑到,用户体验会好很多。
以上是我个人对移动端支付SDK的对比分析,主要还是结合实际项目的使用经验。每种方案都有各自适用的场景,关键是要根据项目实际情况来选择。

暂无评论