美文网首页
支付宝支付

支付宝支付

作者: 学而不思则罔思而不学则殆 | 来源:发表于2016-07-23 20:32 被阅读50次
支付宝流程图

流程

  1. 用户像服务器发送一个付款请求.
  2. 服务返回一个带签名的订单.
  3. 客户端通过这个订单 App SDK 请求付款.
  4. App SDK 调用出支付宝界面进行支付.
  5. 支付成功了支付宝向前端返回支付成功结果, 并像服务器发送通知.
  6. 服务器接收通知并且验证是支付宝发送成功结果.
App 客户端要做的事情很简单:
  1. 像自己的服务器发送订单.
    NSMutableDictionary *parmers =[[NSMutableDictionary alloc] initWithCapacity:0];
    parmers[@"type"]= @(payType);
    parmers[@"amount"] =price;
    if (payType == 4) {
        parmers[@"spreadId"] = spreadID;
    }
    [[HTTPManager defaultManager]requesturl:@"/pay/newGetPaySign" params:parmers showHUD:YES successBlock:^(id returnData) {
        if ([returnData[@"code"] intValue] == 12000) {
            //请求成功
            if (![returnData[@"data"] isKindOfClass:[NSNull class]]) {
                [WXPayManager payWithData:returnData[@"data"]];
            }
        }else{
            [JRToast showWithText:returnData[@"msg"]];
        }

    } failureBlock:^(NSError *error) {
        
    }];
  1. 接收到订单后像 SDK 发送一个支付请求, 监听交易结束后返回支付状态(成功, 失败......)
    //应用注册scheme,在AlixPayDemo-Info.plist定义URL types
    NSString *appScheme = @"alisdkdemo";    
    //        发送订单的方法
    [[AlipaySDK defaultService] payOrder:orderStr fromScheme:appScheme callback:^(NSDictionary *resultDic) {

        //            9000 订单支付成功
        //            8000 正在处理中
        //            4000 订单支付失败
        //            6001 用户中途取消
        //            6002 网络连接出错

        if ([resultDic[@"resultStatus"] isEqualToString:@"9000"]) {
            if (paySuccess) {
                paySuccess();
            }
        }

        if ([resultDic[@"resultStatus"] isEqualToString:@"8000"]) {   
            [JRToast showWithText:@"订单正在处理中" duration:1.0];
        }
        
        if ([resultDic[@"resultStatus"] isEqualToString:@"4000"]) {
            [JRToast showWithText:@"订单支付失败" duration:1.0];
        }
        
        if ([resultDic[@"resultStatus"] isEqualToString:@"6001"]) {
            [JRToast showWithText:@"用户中途取消" duration:1.0];
        }
        
        if ([resultDic[@"resultStatus"] isEqualToString:@"6002"]) {
            [JRToast showWithText:@"网络连接出错" duration:1.0];
        }
    }];
}
服务器做的事情就多一些 (注意: 为了项目的安全性, 私钥要放在服务器)
  1. 接到客户端的请求是, 把数据处理成一个数组, 再把数组处理有序的字符串.

① 对应配置参数数据生成一个数组, 再把数组的数据生成一个有序的字符串.

//将支付宝发来的数据生成有序数列
function getVerifyParams(params) {
    var sPara = [];
    if(!params) return null;
    for(var key in params) {
        if((!params[key]) || key == "sign" || key == "sign_type") {
            continue;
        };
        sPara.push([key, params[key]]);
    }
    sPara = sPara.sort();
    var prestr = '';
    for(var i2 = 0; i2 < sPara.length; i2++) {
        var obj = sPara[i2];
        if(i2 == sPara.length - 1) {
            prestr = prestr + obj[0] + '=' + obj[1] + '';
        } else {
            prestr = prestr + obj[0] + '=' + obj[1] + '&';
        }
    }
    return prestr;
}

② 把这组数据进行 RSA-SHA1 算法, 得到的结果在于存在服务器的私钥进行签名.

//验签
function veriySign(params) {
    try {
        var publicPem = fs.readFileSync('./rsa_public_key.pem');
        var publicKey = publicPem.toString();
        var prestr = getVerifyParams(params);
        var sign = params['sign'] ? params['sign'] : "";
        var verify = crypto.createVerify('RSA-SHA1');
        verify.update(prestr);
        return verify.verify(publicKey, sign, 'base64')

    } catch(err) {
        console.log('veriSign err', err)
    }
}

③ 有序的字符串 + 得到的签名 + 签名方法就是生成的订单, 将这组订单返回客户端.

//发送订单号
    sendAlipay: function(req, res) {
        var code = ""
        for(var i = 0; i < 4; i++) {
            code += Math.floor(Math.random() * 10);
        }

        //订单号暂时由时间戳与四位随机码生成
        AlipayConfig.out_trade_no = Date.now().toString() + code;
        var myParam = getParams(AlipayConfig);
        var mySign = getSign(AlipayConfig)
        var last = myParam + '&sign="' + mySign + '"&sign_type="RSA"';
        console.log(last)
        return res.send(last)
    }
  1. 生成了订单, 如果前端支付成功, 支付宝会给我们预留好一个 POST 接口, 谈我们验证用户是否成功.
    ① 将支付宝发过来的数据生成一个有序的字符串
//将支付宝发来的数据生成有序数列
function getVerifyParams(params) {
    var sPara = [];
    if(!params) return null;
    for(var key in params) {
        if((!params[key]) || key == "sign" || key == "sign_type") {
            continue;
        };
        sPara.push([key, params[key]]);
    }
    sPara = sPara.sort();
    var prestr = '';
    for(var i2 = 0; i2 < sPara.length; i2++) {
        var obj = sPara[i2];
        if(i2 == sPara.length - 1) {
            prestr = prestr + obj[0] + '=' + obj[1] + '';
        } else {
            prestr = prestr + obj[0] + '=' + obj[1] + '&';
        }
    }
    return prestr;
}

② 将获取的数据进行 hash 然后根据公钥进行对签名有效验证, 返回 true 和 false.


//验签
function veriySign(params) {
    try {
        var publicPem = fs.readFileSync('./rsa_public_key.pem');
        var publicKey = publicPem.toString();
        var prestr = getVerifyParams(params);
        var sign = params['sign'] ? params['sign'] : "";
        var verify = crypto.createVerify('RSA-SHA1');
        verify.update(prestr);
        return verify.verify(publicKey, sign, 'base64')

    } catch(err) {
        console.log('veriSign err', err)
    }
}

③ 如果验签成功再生成支付宝通知url,来验证是否是支付宝发来的通知(支付宝的验证一大堆,脑壳都痛了),如果有数据则说明确实是支付宝发来的通知,这次交易有效

//回调验签
    getAlipay: function(req, res) {
        console.log(req.body)
        var params = req.body
        var mysign = veriySign(params);
        //验证支付宝签名mysign为true表示签名正确
        console.log(mysign)
        try {
            //验签成功
            if(mysign) {
                if(params['notify_id']) {
                    var partner = AlipayConfig.partner;
                    //生成验证支付宝通知的url
                    var url = 'https://mapi.alipay.com/gateway.do?service=notify_verify&' + 'partner=' + partner + '&notify_id=' + params['notify_id'];
                    console.log('url:' + url)
                    //验证是否是支付宝发来的通知
                    https.get(url, function(text) {
                        //有数据表示是由支付宝发来的通知
                        if(text) {
                            //交易成功
                            console.log('success')
                        } else {
                            //交易失败
                            console.log('err')
                        }
                    })
                }
            }
        } catch(err) {
            console.log(err);
        }
    }

相关文章

  • Android支付宝支付集成

    Android支付宝支付 标签: android Android支付宝支付使用的流程介绍 支付宝流程介绍 支付宝流...

  • ## [iOS 支付宝支付]

    [iOS开发系列-支付宝支付] 概述 开发中支付通常都会集成支付宝支付,下面讲解支付宝的整体流程。 集成支付宝支付...

  • 三方支付流程总结

    支付宝支付和微信支付 支付宝支付流程图: 支付宝支付: 当我们选择点击了支付宝支付按钮开始 1.app选择商品进行...

  • iOS支付

    支付宝支付 支付宝支付支付宝补充 微信支付 微信支付 内购 iOS开发 内购流程

  • 奖品合集

    支付宝44.44x12 支付宝200x1 支付宝121x1 支付宝111x1 支付宝100x1 支付宝88x1 支...

  • 对接支付宝支付接口开发笔记

    支付宝对接学习笔记: 功能介绍: 支付宝对接 支付宝回调 查询支付状态(略过不讲) 要求: 熟悉支付宝对接核心文档...

  • iOS集成支付宝支付

    一、支付宝支付,首先利用CocoaPods,导入支付宝SDK 二、 创建支付宝支付管理类 AlipayManag...

  • 历害word哥,支付宝AR红包风靡朋友圈

    支付宝又来搞事情,2016年12月22日,支付宝又出新玩法:支付宝AR红包! 支付宝用户可以利用支付宝的红包功能:...

  • iOS支付宝功能集成

    iOS快速集成支付宝详解/支付宝集成获取私钥与公钥 在集成支付宝功能前,我们必须了解下什么支付宝流程,下图是支付宝...

  • iOS第三方支付(支付宝、微信)

    这里会详细讲解支付宝和微信支付 一、支付宝支付 1.准备工作 1> 向支付宝”签约" 成为支付宝的”商户”, 签约...

网友评论

      本文标题:支付宝支付

      本文链接:https://www.haomeiwen.com/subject/rqewjttx.html