iOS开发经验与心得的积累iOS Developer

关于iOS支付的小结

2017-06-07  本文已影响35人  xymspace

项目中碰到过的支付方式一直以来没有系统的梳理过,今天就开发过程中的问题来做一次详细的总结,为今后的使用提供参考。

目前为止较为广泛使用的支付方式:

三方支付:


  • 感想: 所有三方支付最好写一个单例来封装,便于维护

微信支付

关于微信支付后的回调处理

-(void)onResp:(BaseResp*)resp{
              if ([resp isKindOfClass:[PayResp class]]){
                  PayResp*response=(PayResp*)resp;
                  switch(response.errCode){
                      case WXSuccess:
                                //服务器端查询支付通知或查询API返回的结果再提示成功
                                NSlog(@"支付成功");
                        break;
                        default:
                        NSlog(@"支付失败,retcode=%d",resp.errCode);
                        break;
                  }
                    }
                }

如此一来,我们就无法完整的处理微信支付流程了。

#pragma mark - AppDelegate中发送通知

- (void)applicationWillEnterForeground:(UIApplication *)application 
{
    DTLog(@"applicationWillEnterForeground");

    [[NSNotificationCenter defaultCenter] postNotificationName:@"wxPayBack" object:nil];
}
#pragma mark - 相关接收通知的controller
// 考虑到添加时机的问题,最好是在获取订单信息的回调中添加该通知,确保该通知回调一定会被执行
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(wxPayBack) name:@"wxPayBack" object:nil];
- (void)wxPayBack
{
//判断订单号是否存在,以及当前回调是否为微信支付(若有其它支付,也会调起该通知),然后通过订单号向服务端发起支付结果请求
    if (订单号.length > 0 && _isWxPay)
    {
        [self judgeWxPayStationWithWxPayOrder:订单号];
    }
}
#pragma mark - 对请求结果的处理
- (void)judgeWxPayStationWithWxPayOrder:(NSString *)wxOrder
{
    NSDictionary *dic = 请求体参数;
    [[NetWorkManager shareManager] postDataSourceFromURL:请求订单信息的接口 Dic:dic Success:^(NSDictionary *success) {
        
        // 参考微信SDK自定义PayResp对象
        PayResp *resp = [[PayResp alloc] init];
        resp.errCode = 0;
        resp.errStr = nil;
        resp.type = 0;
        NSString *state = success[支付结果对应的key];
        if (![state isEqualToString:支付成功对应的值])
        {
            resp.errCode = 0;
        }
        [self wxPaySResp:resp];

    } AndFail:^(NSError *fail) {
        
    }];
}

- (void)wxPaySResp:(PayResp *)resp
{
    NSString *strTitle = nil;
    if ([resp isKindOfClass:[PayResp class]]) {
        
        switch (resp.errCode) {
            case WXSuccess:
            {
                strTitle = @"支付成功!";
                break;
            }
            case WXErrCodeUserCancel: //用户点击取消并返回
                strTitle = @"您未成功支付";
                break;
            default:
                break;
        }
    }
    if (strTitle != nil)
    {
        弹出相应的提示
    }
}

  • 微信支付流程(客户端具体实现)

-(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[WXApi registerApp: @"自己的appid替换" withDescription: @"自己定义一个描述"];
}


名称 描述 解决方案
0 成功 展示成功页面
-1 错误 可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等。
-2 用户取消 无需处理。发生场景:用户不支付了,点击取消,返回APP。
支付宝支付
  • 支付宝支付流程(客户端具体实现)
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary*)options
{
    if ([[url absoluteString] hasPrefix:URLScheme])
    {
    // 支付宝客户端二次回调条件
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *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?:@"");
        }];
        
    }
}


银联支付

银联移动支付平台地址:https://open.unionpay.com/ajweb/product/detail?id=3 下载SDK

  1. 导入SDK
    SDK包括两个文件:UPPaymentControl.h文件和libPaymentControl.a,将SDK目录添加到工程.

  2. 添加依赖
    使用UPPaymentControl需要添加CFNetwork.framework、SystemConfiguration.framework 、libz、libPaymentControl.a到工程中,

  3. 修改配置
    3.1 在工程info.plist设置中添加一个URL Types回调协议(在UPPayDemo工程中使用“UPPayDemo”作为协议),用于在支付完成后返回商户客户端。
    3.2 在Xcode7.0之后的版本中进行http请求时,需要在工程对应的plist文件中添加
    NSAppTransportSecurity Dictionary
    并同时设置里面
    NSAllowsArbitraryLoads 属性值为 YES.
    3.3 添加协议白名单
    在Xcode7.0之后的版本中进行开发,需要在工程对应的plist文件中,添加LSApplicationQueriesSchemes Array并加入uppaysdk、uppaywallet、uppayx1、uppayx2、uppayx3五个item
    或者直接添加如下代码到plist文件中:

<key>LSApplicationQueriesSchemes</key>
     <array>
        <string>uppaysdk</string>
        <string>uppaywallet</string>
        <string>uppayx1</string>
        <string>uppayx2</string>
        <string>uppayx3</string>
     </array>

3.4 修改编译选项
选择工程targets——>build settings ->Linking->other linker flags
如果该设置和其他第三方库冲突,或银联客户端莫名失败,则可尝试去掉-ObjC,改为-force_load+空格+控件路径,如:-force_load $(PROJECT_DIR)/xxxx/ libPaymentControl.a
3.5 凡是引入银联头文件UPPaymentControl.h,需要将源文件后缀.m改为.mm

  1. 接口说明
    4.1 支付接口


    支付接口.png

    4.2 回调接口


    返回接口.png
内购

内购实现流程

  1. 客户端向自己公司服务端请求productIds(可能是多个商品)
  2. 使用这些produceId创建SKProductsRequest对象,调用start方法,设置该对象代理,在代理方法中获取可以销售的product(代理方法中获取创建UI所需要的数据)
  3. 当用户点击某个商品后,我们客户端获取被点击商品的SKProduct对象,创建SKPayment票据对象(使用SKProduct对象创建),添加SKPayment对象的监听者,将票据添加到购买队列,在监听商品更新信息回调方法中获取商品购买状态
  4. 如果商品返回状态为:成功 | 失败 | 恢复,那么将该票据从队列移除,成功购买,应返回给本公司服务器商品购买成功信息,用于下次更新商品状态
上一篇下一篇

猜你喜欢

热点阅读