支付上海恩美路演学无止境

支付宝支付以及微信支付集成

2016-01-30  本文已影响740人  一铭_

1.支付宝集成
第一步:先签约支付宝,申请应用(别忘了生成的 RSA 密钥的上传)
https://doc.open.alipay.com/doc2/detail.htm?spm=0.0.0.0.6i3qlX&treeId=58&articleId=103542&docType=1
第二步:下载支付宝官方的 SDK, 把第一步申请得到的 sellID,partnerID,私钥(privateKey)放到代码中,为了测试我们配置的 key 是否正确,如果支付宝 demo 能支付成功,就代表我们配置的 key 成功了,反之去重复第一步吧

L:148
    NSString *partner = @"xxxxxxx";
    NSString *seller = @"xxxxxxx";
    NSString *privateKey = @"xxxxxxx" ;//注意空格!!

第三步:配置支付宝到 app
1>配置库,看支付宝官方的就好,比哪都详细
https://doc.open.alipay.com/doc2/detail.htm?spm=0.0.0.0.l0wbHb&treeId=59&articleId=103676&docType=1
但要注意: "Header Search Paths”增加头文件路径:$(SRCROOT)/项目名称!!!!
还有记得设置回调
2>把下图的文件从支付宝官方 demo 中拷贝过来

屏幕快照 2016-01-30 下午3.02.18.png

编译,如果有报错,缺库就导库,头文件就 header search paths,
我还需要一个报错,导了一个 demo 里没有的库:libstdc++.6.0.9. tbd
3>处理支付的商品信息,签名等等
导入头文件

#import "Order.h"
#import <AlipaySDK/AlipaySDK.h>
#import "DataSigner.h"

处理支付业务

 /**
             *  1.生成订单信息
             */
            Order *order = [[Order alloc]init];
            order.partner = PARTNER;
            order.seller = SELLER;
            order.tradeNO = self.orderCode;
            order.productName = @"这是一个支付宝测试";
            order.productDescription = @"我说了这是一个测试数据";
            order.amount = [NSString stringWithFormat:@"%.2f",0.01];
            //回调 URL
            order.notifyURL = @"url url url ";
            order.service = @"mobile.securitypay.pay";
            order.paymentType = @"1";
            order.inputCharset = @"utf-8";
            order.itBPay = @"30m";
            order.showUrl = @"m.alipay.com";
            
            // 应用注册scheme,在当前项目的Info.plist定义URL types
            NSString *appScheme = @"";//同 url types
            //将订单信息拼接成在字符串
            NSString *orderSpec = [order description];

第一步基本上和官方 demo 一样,比微信好多了(不得不吐槽一下)

 /**
             *  2.签名加密
             *  获取私钥并将商户信息签名, 外部商户可以根据情况存放私钥和签名, 只需要遵循 RSA 签名规范, 并将签名字符串 base64 编码和 UrlEncode
             */
            NSString *str = PRIVATE;
            id<DataSigner> signer = CreateRSADataSigner(str);
            NSString *signedString = [signer signString:orderSpec];

请直接copy demo 这一部分

           /**
             *  3. 将签名成功字符串格式化为订单字符串,请严格按照该格式
             */
            NSString *orderString = nil;
            if (signedString != nil) {
                orderString = [NSString stringWithFormat:@"%@&sign=\"%@\"&sign_type=\"%@\"",
                               orderSpec, signedString, @"RSA"];
                
                [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
                    //处理你的支付结果
                    NSLog(@"resuly===%@",resultDic);
                    }
                }];
            }

appDelegate里面需要设置

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
/**
     *  Alipay
     */
    //如果极简开发包不可用,会跳转支付宝钱包进行支付,需要将支付宝钱包的支付结果回传给开 发包
    if ([url.host isEqualToString:@"safepay"]) {
        [[AlipaySDK defaultService]processOrderWithPaymentResult:url
         standbyCallback:^(NSDictionary *resultDic) {
#warning ======支付结果处理
             NSLog(@"ewsult====%@",resultDic);
         }];
    }
    
    //支付宝钱包快登授权返回
    if ([url.host isEqualToString:@"platformapi"]) {
        [[AlipaySDK defaultService]processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
#warning ======支付结果处理
             NSLog(@"ewsult====%@",resultDic);
        }];
    }
}

支付宝就这么多了,很简单的代码,一般的配置,复杂的申请....

2.微信支付
做微信支付是有挺多小坑的,这个坑主要取决于你的后台怎么样,微信不同于支付宝的是,它把支付过程分成了两步,就到导致了后台需要先做第一步,再传数据给前端,然后前端去完成第二步.

第一步是:向微信注册你的应用程序 ID
这一步没什么技术,按照流程就好了(这都是产品经理做的吧.....)
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317780&token=f6e95c1f1c5fd970d5fb3b2425e2d612b6cbce47&lang=zh_CN
照这个流程来就好
第二步:下载官方 demo
https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=11_1
其实不推荐官方的 demo...而且微信的官方 demo 不像支付宝一样还可以用来去检查 appId,等等值是否配好
第三步:配置微信 SDK

屏幕快照 2016-01-31 下午5.28.57.png

需要配置的库好像跟支付宝差不多...
第四步:调用微信支付 SDK
这个第四步就要分情况讨论了
微信的支付流程是先获取prePayid,再加appid,appkey,noncestr,package,partnerId,timestamp去签名完成支付.
第一种情况:如果你的后台去完成获取预支付订单
这种是微信支付官方推荐的,而且这样更加安全,相关的配置信息和 key 都存在服务器更加安全.
这种情况前端需要在用户发起微信支付后吧订单信息传给服务器(传递的信息需要沟通),返回值为

     // 调起微信支付
            PayReq *request = [[PayReq alloc]init];
            request.partnerId = _WXPayModel.partnerid;
            request.prepayId = _WXPayModel.prepayid;
            request.package = @"Sign=WXPay";
            request.nonceStr = _WXPayModel.noncestr;
            request.timeStamp = [_WXPayModel.timestamp intValue];

package 一定要写成那样!
package 一定要写成那样!
package 一定要写成那样!

 // 这里要注意key里的值一定要填对, 微信官方给的参数名是错误的,不是第二个字母大写
            NSMutableDictionary *signParams = [NSMutableDictionary dictionary];
            [signParams setObject: _WXPayModel.appid               forKey:@"appid"];
            [signParams setObject: _WXPayModel.partnerid           forKey:@"partnerid"];
            [signParams setObject: request.nonceStr      forKey:@"noncestr"];
            [signParams setObject: request.package       forKey:@"package"];
            [signParams setObject: _WXPayModel.timestamp forKey:@"timestamp"];
            [signParams setObject: request.prepayId      forKey:@"prepayid"];
            
            //生成签名
            NSString *sign  = [MyUtil genSign:signParams];
            NSLog(@"sign===%@",sign);
            
            //添加签名
            request.sign = sign;
            
            [WXApi sendReq:request];

基本上调起支付的代码就这样...这当然是在服务端完成第一步的情况下.
第二种情况:(如果你家后台又懒又不会而且你又比较闲的话)

//微信支付
- (void)wxpay
{
    //商户号
    NSString *PARTNER_ID    = @"1900000109";
    //商户密钥
    NSString *PARTNER_KEY   = @"8934e7d15453e97507ef794cf7b0519d";
    //APPID
    NSString *APPI_ID       = @"wxd930ea5d5a258f4f";
    //appsecret
    NSString *APP_SECRET = @"db426a9829e4b49a0dcac7b4162da6b6";
    //支付密钥
    NSString *APP_KEY       = @"L8LrMqqeGRxST5reouB0K66CaYAWpqhAVsq7ggKkxHCOastWksvuX1uvmvQclxaHoYd3ElNBrNO2DHnnzgfVG9Qs473M3DTOZug5er46FhuGofumV8H2FVR9qkjSlC5K";
    NSLog(@"%ld,%ld,%ld",PARTNER_KEY.length,APP_SECRET.length,APP_KEY.length);
    //支付结果回调页面
    NSString *NOTIFY_URL    = @"http://localhost/pay/wx/notify_url.asp";
    //订单标题
    NSString *ORDER_NAME    = @"Ios客户端签名支付 测试";
    //订单金额,单位(分)
    NSString *ORDER_PRICE   = @"1";
    
    //创建支付签名对象
    payRequsestHandler *req = [payRequsestHandler alloc];
    //初始化支付签名对象
    [req init:APPI_ID app_secret:APP_SECRET partner_key:PARTNER_KEY app_key:APP_KEY];
    
    //判断Token过期时间,10分钟内不重复获取,测试帐号多个使用,可能造成其他地方获取后不能用,需要即时获取
    time_t  now;
    time(&now);
    //if ( (now - token_time) > 0 )//非测试帐号调试请启用该条件判断
    {
        //获取Token
        Token                   = [req GetToken];
        //设置Token有效期为10分钟
        token_time              = now + 600;
        //日志输出
        NSLog(@"获取Token: %@\n",[req getDebugifo]);
    }
    if ( Token != nil){
        //================================
        //预付单参数订单设置
        //================================
        NSMutableDictionary *packageParams = [NSMutableDictionary dictionary];
        [packageParams setObject: @"WX"                                             forKey:@"bank_type"];
        [packageParams setObject: ORDER_NAME                                        forKey:@"body"];
        [packageParams setObject: @"1"                                              forKey:@"fee_type"];
        [packageParams setObject: @"UTF-8"                                          forKey:@"input_charset"];
        [packageParams setObject: NOTIFY_URL                                        forKey:@"notify_url"];
        [packageParams setObject: [NSString stringWithFormat:@"%ld",time(0)]        forKey:@"out_trade_no"];
        [packageParams setObject: PARTNER_ID                                        forKey:@"partner"];
        [packageParams setObject: @"196.168.1.1"                                    forKey:@"spbill_create_ip"];
        [packageParams setObject: ORDER_PRICE                                       forKey:@"total_fee"];
        
        NSString    *package, *time_stamp, *nonce_str, *traceid;
        //获取package包
        package  = [req genPackage:packageParams];
        
        //输出debug info
        NSString *debug     = [req getDebugifo];
        NSLog(@"gen package: %@\n",package);
        NSLog(@"生成package: %@\n",debug);
        
        //设置支付参数
        time_stamp  = [NSString stringWithFormat:@"%ld", now];
        nonce_str = [TenpayUtil md5:time_stamp];
        traceid  = @"mytestid_001";
        NSMutableDictionary *prePayParams = [NSMutableDictionary dictionary];
        [prePayParams setObject: APPI_ID                                            forKey:@"appid"];
        [prePayParams setObject: APP_KEY                                            forKey:@"appkey"];
        [prePayParams setObject: nonce_str                                          forKey:@"noncestr"];
        [prePayParams setObject: package                                            forKey:@"package"];
        [prePayParams setObject: time_stamp                                         forKey:@"timestamp"];
        [prePayParams setObject: traceid                                            forKey:@"traceid"];
        
        //生成支付签名
        NSString    *sign;
        sign  = [req createSHA1Sign:prePayParams];
        //增加非参与签名的额外参数
        [prePayParams setObject: @"sha1"                                            forKey:@"sign_method"];
        [prePayParams setObject: sign                                               forKey:@"app_signature"];
        
        //获取prepayId
        NSString *prePayid;
        prePayid            = [req sendPrepay:prePayParams];
        //输出debug info
        debug               = [req getDebugifo];
        NSLog(@"提交预付单: %@\n",debug);
        
        if ( prePayid != nil) {
            //重新按提交格式组包,微信客户端5.0.3以前版本只支持package=Sign=***格式,须考虑升级后支持携带package具体参数的情况
            //package       = [NSString stringWithFormat:@"Sign=%@",package];
            package         = @"Sign=WXPay";
            //签名参数列表
            NSMutableDictionary *signParams = [NSMutableDictionary dictionary];
            [signParams setObject: APPI_ID                                          forKey:@"appid"];
            [signParams setObject: APP_KEY                                          forKey:@"appkey"];
            [signParams setObject: nonce_str                                        forKey:@"noncestr"];
            [signParams setObject: package                                          forKey:@"package"];
            [signParams setObject: PARTNER_ID                                       forKey:@"partnerid"];
            [signParams setObject: time_stamp                                       forKey:@"timestamp"];
            [signParams setObject: prePayid                                         forKey:@"prepayid"];
            
            //生成签名
            sign  = [req createSHA1Sign:signParams];
            
            //输出debug info
            debug     = [req getDebugifo];
            NSLog(@"调起支付签名: %@\n",debug);
            
            //调起微信支付
            PayReq* req = [[PayReq alloc] init];
            req.openID      = APPI_ID;
            req.partnerId   = PARTNER_ID;
            req.prepayId    = prePayid;
            req.nonceStr    = nonce_str;
            req.timeStamp   = now;
            req.package     = package;
            req.sign        = sign;
            [WXApi safeSendReq:req];
        }else{
            /*long errcode = [req getLasterrCode];
             if ( errcode == 40001 )
             {//Token实效,重新获取
             Token                   = [req GetToken];
             token_time              = now + 600;
             NSLog(@"获取Token: %@\n",[req getDebugifo]);
             };*/
            NSLog(@"获取prepayid失败\n");
            [self alert:@"提示信息" msg:debug];
        }
    }else{
        NSLog(@"获取Token失败\n");
        [self alert:@"提示信息" msg:@"获取Token失败"];
    }
    
}

第四步:设置 url回调以及等等琐碎的东西
1.info URL Types 设置app回调
2.appdelegate中注册 app

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    [WXApi registerApp:@"xxxxxxxxxxxx" withDescription:@"xxxxxx"];

微信支付完成后会通过 appdelegate 中的代理方法发送通知,处理支付结果

if ([resp isKindOfClass:[PayResp class]]) {
        PayResp *response = (PayResp *)resp;
        NSLog(@"response.errCoderesponse.errCoderesponse.errCode%d",response.errCode);
        
        switch (response.errCode) {
            case WXSuccess:{
                NSLog(@"successWXPay");
                NSNotification *notification = [NSNotification notificationWithName:@"orderPay" object:@"success"];
                [[NSNotificationCenter defaultCenter]postNotification:notification];
                break;
            }
            case WXErrCodeCommon:
                [SVProgressHUD showErrorWithStatus:@"发送错误"];
                break;
            
            case WXErrCodeUserCancel:
                [SVProgressHUD showErrorWithStatus:@"支付已取消"];
                break;
                
            case WXErrCodeSentFail:
                [SVProgressHUD showErrorWithStatus:@"发送失败"];
                break;
                
            case WXErrCodeUnsupport:
                [SVProgressHUD showErrorWithStatus:@"微信不支持"];
                break;
//                WXErrCodeCommon     = -1,   /**< 普通错误类型    */
//                WXErrCodeUserCancel = -2,   /**< 用户点击取消并返回    */
//                WXErrCodeSentFail   = -3,   /**< 发送失败    */
//                WXErrCodeAuthDeny   = -4,   /**< 授权失败    */
//                WXErrCodeUnsupport  = -5,   /**< 微信不支持    */
            default:{
                NSLog(@"wxpay");
                break;
            }
        }
    }

到这里微信支付就差不多完成了,如果出现微信的各种报错,简书上有很多,就不啰嗦了.
再说说做第三方支付的感受吧,其实我以后打算直接用 ping++了.......

上一篇 下一篇

猜你喜欢

热点阅读