您的位置:首页 > Web前端 > React

React Native (IOS和Android) 支付宝和微信支付集成实战(支付宝服务端篇)

2018-01-07 10:35 459 查看
序言:React Native无论是在社区和应用程度上,在国内外是十分广泛和普及的。而支付宝和微信在支付模块上都有或多或少的支持,虽然没有完整的Demo,不过在我做过一个相关集成的项目后,在此我把相关的步骤和方法总结出来和大家分享,希望能够帮助大家少走弯路,快速集成。

支付宝——服务端集成

一、获取你的AppId和配置支付宝公钥私钥

在登录蚂蚁金服开放平台后,获取你App应用对应的APPID (它目前就是在App图标旁的一串数字)。
紧接着你就需要去配置你的公钥私钥了,具体步骤可以参考官方文档,写的很清楚。https://docs.open.alipay.com/291/106097

不过需要注意的有以下几点:

1.如果你的服务端用的是非Java语言的,一定要选择对应的密钥格式,本分享用的是NodeJS写的服务端,至于密钥长度,1024,或者2048均可,建议以2048,所以选择如下图:



2.点击生成密钥后,你会发现密钥已经生成,分别为商户应用私钥和商户应用公钥,两者请都妥善保管至其他文件夹中。

3.在蚂蚁金服开放平台,开发者中心,该APP应用下的接口加签方式中,选择 RSA(SHA256)密钥 方式,并且上传该第二步骤产生的应用公钥并保存

4.再次打开支付宝生成密钥工具,并且切换至【格式转换】选项卡中,将第二步骤产生的商户私钥粘贴至商户应用私钥中,并点击转PKCS1(非JAVA适用)私钥,它会提示该私钥已经为该格式(如果你是JAVA适用的请选择前者),我们重复该步骤的目的是为了生成供NodeJS可以读取并且解析的PEM文件(其他语言亦然),接着打开密钥文件路径,打开私钥文件,你会发现,文件头会有
--BEGIN RSA PRVIATE KEY -- 字样。   

5. 保存该文件并且重命名alipay_private_key.pem。

6. 将私钥和公钥上传至支付宝开发的应用后,获取支付宝公钥,保存并且创建文件为alipay_public_key.pem 在开头和结尾分别加上 

-----BEGIN PUBLIC KEY-----

-----END PUBLIC KEY-----

至此,密钥配置已经完成。







PS: 支付宝也有沙箱应用,其公钥私钥配置一模一样,在此不再赘述

二、编写服务端代码

支付宝生成请求参数可以参考官方文档https://docs.open.alipay.com/204/105465/ 
,其中公共参数和业务参数是一般支付时所需要的。在服务端生成签名其中有几个比较重要的点,一定要牢记,反复检查,避免验签过程一直失败,导致无法支付,浪费开发时间。(如果你的服务端语言是Java,.Net或者Php,那么恭喜你,无需看以下内容,因为支付宝有相关SDK使用,https://docs.open.alipay.com/54/103419

1.生成签名sign之前的参数字符串(暂且称为未签名支付串),一定要ASCII码递增排序

2.生成签名后的sign参数放置未签名支付串末尾(签名支付串),其中未签名支付串的参数个数和值不能有任何改动

3.将签名支付串进行encode。

可参考NodeJS代码如下:

raw = function (args) {
//升序参数,并且拼接为key & value字符串
var keys = Object.keys(args);
keys = keys.sort()
var newArgs = {};
keys.forEach(function (key) {
newArgs[key] = args[key];
});
var string = '';
for (var k in newArgs) {
string += '&' + k + '=' + newArgs[k];
}
string = string.substr(1);
return string;
}
// 支付宝生成签名
var signed = function (order) {
const app_id = ''; //此app_id为你申请的支付宝的应用APPID

//生成一个基本的订单信息,必要的参数和值如下,更多参数和用法请参考官方文档

var biz_content = '{"timeout_express":"60m",' +  //允许支付的最晚时间
'"product_code":"QUICK_MSECURITY_PAY",' +
'"total_amount":"' + order.total_amount + '",' + //支付金额,以元为单位
'"subject":"' + order.subject + '",' +
'"body":"' + order.body + '",' +
'"out_trade_no":"' + order.out_trade_no + '"}'; //自己平台的支付订单号码

var unsigned = {
app_id: app_id,
method: 'alipay.trade.app.pay',
charset: 'utf-8',
sign_type: 'RSA2',
version: '1.0',
timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
biz_content: biz_content,
notify_url: 'http://192.168.1.45:3000/alipay/notify_url' //此处为支付宝服务端调用成功后通知你时会访问的url
}
var unsignedStr = raw(unsigned);

let private_key = fs.readFileSync('./config/alipay_private_key.pem'); //获取商户应用私钥
let signer = crypto.createSign('RSA-SHA256');  //创建RSA2加密算法示例
signer.update(unsignedStr);  //添加需要加密的字符串
let sign = signer.sign(private_key, 'base64');  //加密并且以base64的形式返回

return qs.stringify(unsigned) + '&sign=' + encodeURIComponent(sign)    //encode
}
//收到支付宝异步通知进行验签
var verified = function (response, sign) {
let public_key = fs.readFileSync('./config/alipay_public_key.pem');
var verify = crypto.createVerify('RSA-SHA256');
verify.update(response);
return verify.verify(public_key, sign, 'base64')

}
//支付宝获取签名的订单信息
alipay.post('/pay', function (req, res) {
var signedStr = signed({
body: '测试支付',//预祝春节快乐,1分钱购,赠送IPhone X一人一部
subject: '测试支付',//免费赠送IPhone X
out_trade_no: '70501111111S501115',  //自己平台的支付订单号码
total_amount: '0.01'       //支付金额,以元为单位
})

res.send(signedStr);
})
//接受支付宝通知
alipay.post('/notify_url', function (req, res) {
var obj = req.body
var sign = req.body.sign
delete obj['sign']
delete obj['sign_type']

var verRes = verified(raw(obj), sign)
if (verRes) {
/**
* 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
* 2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额)
* 3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)
* 4、验证app_id是否为该商户本身。上述1、2、3、4有任何一个验证不通过,则表明本次通知是异常通知,务必忽略。在上述验证通过后商户必须根据支付宝不同类型的业务通知,
* 正确的进行不同的业务处理,并且过滤重复的通知结果数据。
* 在支付宝的业务通知中,只有交易通知状态为TRADE_SUCCESS或TRADE_FINISHED时,支付宝才会认定为买家付款成功。
*/
//按照支付结果异步通知中的描述,对支付结果中的业务内容进行1\2\3\4二次校验,校验成功后在response中返回success,校验失败返回failure
res.send('success')
} else {
res.send('failure')
}
})


至此支付宝服务端代码已经完成,由于本地开发notify_url必须为能够被访问的地址,如果想本地测试,建议可以使用ngrok

鸣谢:我是一名来自盛安德的Shinetecher,感谢盛安德公司及同事们对IT技术的支持,分享和热情,让我有时间和动力完成此博文。

联系:欢迎各位朋友有任何问题和建议留言至此博客下,或者添加本人微信号:liyijia428 进行沟通交流学习

源码:https://github.com/likeconan/Alipay_Wechat_Integration
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: