(转)iOS 集成支付宝、微信、银联支付 (2017)

一、支付宝支付
1、下载SDK:支付宝SDK下载地址
2、支付流程图请好好看一看,你就会明白你应该做什么

T1TkxgXcBjXXXXXXXX.png

好了,看完了发其实我们需要做的就是(ps:为了安全起见,签名都在后台处理):
• 调用支付宝支付接口
• 处理支付宝返回的支付结果
3、把下载的demo中以下文件(如图)的导入到自己的工程中

屏幕快照 2017-04-12 下午3.32.01.png

4、在Build Phases选项卡的Link Binary With Libraries中,增加以下依赖: 添加支付宝依赖官方链接
LB1PlBHKpXXXXXoXXXXXXXXXXXX.png

5、Xcode设置URL scheme和LSApplicationQueriesSchemes
(LSApplicationQueriesSchemes中alipay是针对于支付宝的其他的是针对于微信和银联的,如果不继承可以不添加,只添加alipay即可)
1402122-c474da5111068cfe.png

屏幕快照 2017-04-12 下午3.38.12.png

6、在需要的地方导入#import <AlipaySDK/AlipaySDK.h>,#import "Order.h",#import "RSADataSigner.h"
7、AppDelegate.m文件中,增加引用代码:

//9.0前的方法
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    
    if ([url.host isEqualToString:@"safepay"]) {
        // 支付跳转支付宝钱包进行支付,处理支付结果
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@",resultDic);
        }];
        
        // 授权跳转支付宝钱包进行支付,处理支付结果
        [[AlipaySDK defaultService] processAuth_V2Result:url standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@",resultDic);
            // 解析 auth code
            NSString *result = resultDic[@"result"];
            NSString *authCode = nil;
            if (result.length>0) {
                NSArray *resultArr = [result componentsSeparatedByString:@"&"];
                for (NSString *subResult in resultArr) {
                    if (subResult.length > 10 && [subResult hasPrefix:@"auth_code="]) {
                        authCode = [subResult substringFromIndex:10];
                        break;
                    }
                }
            }
            NSLog(@"授权结果 authCode = %@", authCode?:@"");
        }];
    }
    return YES;
}

//9.0后的方法
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
    //支付宝处理支付结果
    if ([url.host isEqualToString:@"safepay"]) {
        // 支付跳转支付宝钱包进行支付,处理支付结果
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@",resultDic);
        }];
        
        // 授权跳转支付宝钱包进行支付,处理支付结果
        [[AlipaySDK defaultService] processAuth_V2Result:url standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@",resultDic);
            // 解析 auth code
            NSString *result = resultDic[@"result"];
            NSString *authCode = nil;
            if (result.length>0) {
                NSArray *resultArr = [result componentsSeparatedByString:@"&"];
                for (NSString *subResult in resultArr) {
                    if (subResult.length > 10 && [subResult hasPrefix:@"auth_code="]) {
                        authCode = [subResult substringFromIndex:10];
                        break;
                    }
                }
            }
            NSLog(@"授权结果 authCode = %@", authCode?:@"");
        }];
    }
    return YES;
}

8、根据订单信息发起支付调用方法,orderString和appScheme。appScheme是app在info.plist注册的scheme,建议用支付宝注册的appid。orderstring是一个订单的字符串,由后台拼接生成的,还需要签名的

[[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
            NSDictionary *dic = resultDic;
            NSString *resultStr = EncodeFormDic(dic, @"resultStatus");
            NSLog(@"resultStr_%@",resultStr);
            [self paymentResult:resultStr];
        }];

-(void)paymentResult:(NSString *)resultd {
    NSLog(@" = %@",resultd);
    //结果处理
    if ([resultd isEqualToString:@"9000"]) {
        //支付宝回调显示支付成功后调用自己的后台的借口确认是否支付成功
        [self payOrdCallback:@"1"];
    }else if ([resultd isEqualToString:@"6001"]){
        [self payCancel];
        
    }else{
        [self payFail];
    }
}

9、支付宝集成过程中一些错误的解决办法请参考文章

二、微信支付(官方开发文档)
1、下载SDK:微信SDK下载地址
2、看完支付流程图,你会我们要做的也是调起微信客户端发起支付和处理支付结果,和支付宝基本一样

chapter8_3_1.png

3、导入SDK


屏幕快照 2017-04-12 下午3.58.48.png

4、导入依赖
1. SystemConfiguration.framework
2. libz.tbd
3. libsqlite3.0.tbd
4.CoreTelephony.framework
5. QuartzCore.framework
5、Xcode设置URL scheme和LSApplicationQueriesSchemes,参照支付宝,图片中有微信的


111.png

6、在需要的地方导入#import "WXApi.h"
7、AppDelegate.m文件中,增加引用代码:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    /**
     *  向微信终端注册ID,这里的APPID一般建议写成宏,容易维护。@“测试demo”不需用管。这里的id是假的,需要改这里还有target里面的URL Type
     */
    [WXApi registerApp:@"wxd930ea5d5a258f4f" withDescription:@"测试demo"];

    return YES;
}
//9.0前的方法,为了适配低版本 保留
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
    return [WXApi handleOpenURL:url delegate:self];
}

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
    return [WXApi handleOpenURL:url delegate:self];
}

//9.0后的方法
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
    //这里判断是否发起的请求为微信支付,如果是的话,用WXApi的方法调起微信客户端的支付页面(://pay 之前的那串字符串就是你的APPID,)
        return  [WXApi handleOpenURL:url delegate:self];
}


//微信SDK自带的方法,处理从微信客户端完成操作后返回程序之后的回调方法,显示支付结果的
-(void) onResp:(BaseResp*)resp
{  
    if ([resp isKindOfClass:[PayResp class]]) {
        PayResp *response = (PayResp *)resp;
        switch (response.errCode) {
            case WXSuccess:
                //服务器端查询支付通知或查询API返回的结果再提示成功
                NSLog(@"支付成功");
               //通过通知告诉支付界面该做哪些操作
                [[NSNotificationCenter defaultCenter] postNotificationName:@"WEIXINPAYS" object:nil];
                break;
            case WXErrCodeCommon:
                NSLog(@"支付失败");
                [[NSNotificationCenter defaultCenter] postNotificationName:@"WEIXINPAYF" object:nil];
                break;
            case WXErrCodeUserCancel:
                NSLog(@"用户取消");
                [[NSNotificationCenter defaultCenter] postNotificationName:@"WEIXINPAYC" object:nil];
                break;
            default:
                NSLog(@"支付结果:失败!retcode = %d, retstr = %@", resp.errCode,resp.errStr);
                break;
        }
    }
}

8、根据后台返回数据发起支付,需要的参数在方法中有详细注释

- (void)gotoWXPay {
    PayReq* req             = [[PayReq alloc] init];
    
    req.openID              = @"wxf7c591d3fdd34070";//appid换成自己的
    req.partnerId           = @"1245663002";
    req.prepayId            = @"wx2015060917151801798122a30971214164";//预支付订单ID
    req.nonceStr            = @"3Lnr21zhhGO2DwwFbI2amMq0cJcggLGe";//参与签名的随机字符串,随机编码,为了防止重复的,在后台生成
    req.timeStamp           = 1433841320;//参与签名的时间戳,也是在后台生成的,为了验证支付的
    req.sign                = @"B7C57CCAA2236764E281DA94966046B7";//签名字符串,也是后台做的
    req.package             = @"Sign=WXPay";//这个比较特殊,是固定的,只能是即req.package = Sign=WXPay
    
    [WXApi sendReq:req];
}

在发起支付的界面做微信回调的监听,并在监听返回支付成功(也就是payOk:方法中)是调用自己后台的接口再次确认是否真正支付成功

/* 微信支付回调监听 */
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(payOk:) name:@"WEIXINPAYS" object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(payCancel) name:@"WEIXINPAYC" object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(payFail) name:@"WEIXINPAYF" object:nil];

9、注意微信支付只能调用App进行支付,所以需要判断

if ([WXApi isWXAppInstalled]) {//判断是否有微信
      [self gotoWXPay];//微信支付
}

三、银联支付(APP集成官网
1、下载SDK:银联SDK下载地址
2、支付流程图

yinlian.png

3、导入SDK中的UPPaymentControl.h和libPaymentControl.a文件
屏幕快照 2017-04-12 下午4.56.44.png

4、导入依赖
屏幕快照 2017-04-12 下午5.04.28.png

5、Xcode设置URL scheme和LSApplicationQueriesSchemes,参照支付宝
屏幕快照 2017-04-12 下午5.06.48.png

屏幕快照 2017-04-12 下午5.07.54.png

6、在需要的地方导入#import "UPPaymentControl.h"
7、AppDelegate.m文件中,增加引用代码:

//9.0前的方法
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    //银联支付处理支付结果
    if([url.host isEqualToString:@"uppayresult"]){
        [[UPPaymentControl defaultControl] handlePaymentResult:url completeBlock:^(NSString *code, NSDictionary *data) {
            if([code isEqualToString:@"success"]) {
                
                //            //如果想对结果数据验签,可使用下面这段代码,但建议不验签,直接去商户后台查询交易结果
                //            if(data != nil){
                //                //数据从NSDictionary转换为NSString
                //                NSData *signData = [NSJSONSerialization dataWithJSONObject:data
                //                                                                   options:0
                //                                                                     error:nil];
                //                NSString *sign = [[NSString alloc] initWithData:signData encoding:NSUTF8StringEncoding];
                //
                //                //此处的verify建议送去商户后台做验签,如要放在手机端验,则代码必须支持更新证书
                //                if([self verify:sign]) {
                //                    //验签成功
                //                }
                //                else {
                //                    //验签失败
                //                }
                //            }
                //
                //            //结果code为成功时,去商户后台查询一下确保交易是成功的再展示成功
                [[NSNotificationCenter defaultCenter] postNotificationName:@"YINLIANPAYS" object:nil];
            }else if([code isEqualToString:@"fail"]) {
                //交易失败
                [[NSNotificationCenter defaultCenter] postNotificationName:@"YINLIANPAYF" object:nil];
            }else if([code isEqualToString:@"cancel"]) {
                //交易取消
                [[NSNotificationCenter defaultCenter] postNotificationName:@"YINLIANPAYC" object:nil];
            }
        }];
    }
    return YES;
}

//9.0后的方法
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
    //银联支付处理支付结果
    if([url.host isEqualToString:@"uppayresult"]){
        [[UPPaymentControl defaultControl] handlePaymentResult:url completeBlock:^(NSString *code, NSDictionary *data) {
            if([code isEqualToString:@"success"]) {
                [[NSNotificationCenter defaultCenter] postNotificationName:@"YINLIANPAYS" object:nil];
            }else if([code isEqualToString:@"fail"]) {
                //交易失败
                [[NSNotificationCenter defaultCenter] postNotificationName:@"YINLIANPAYF" object:nil];
            }else if([code isEqualToString:@"cancel"]) {
                //交易取消
                [[NSNotificationCenter defaultCenter] postNotificationName:@"YINLIANPAYC" object:nil];
            }
        }];
    }

    return YES;
}

8、根据后台返回数据发起支付

if (tn.length > 0) {
        //当获得的tn不为空时,调用支付接口
        [[UPPaymentControl defaultControl] startPay:tn fromScheme:@"UPPayDemo" mode:respCode viewController:self];
    }else{
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"银联参数配置不正确" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
        [alert show];

}

在发起支付的界面做银联回调的监听,并在监听返回支付成功(也就是payOk:方法中)时调用自己后台的接口再次确认是否真正支付成功

/* 银联支付回调监听 */
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(payOk:) name:@"YINLIANPAYS" object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(payCancel) name:@"YINLIANPAYC" object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(payFail) name:@"YINLIANPAYF" object:nil];

9、官方集成文档写的不错,在你下载的demo里面

屏幕快照 2017-04-12 下午5.28.29.png


作者:orilme
链接:https://www.jianshu.com/p/92e47254e308

猜你喜欢

转载自blog.csdn.net/wujakf/article/details/80855811