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

序言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


猜你喜欢

转载自blog.csdn.net/likeconan123/article/details/78993417
今日推荐