我的APP不可能这么胖之支付宝支付

简介

这一系列讲述的是免SDK实现分享、登录、支付等业务。

将会使用ShareSDK Demo进行部分试验。

一、获取支付参数

因涉及到敏感数据所以后面参数全部省略

----------open url: 0----------
alipay://alipayclient/?一大串参数(URL编码的)

2、参数解释

以下为支付宝支付参数

//支付宝 URL Scheme
alipay

//固定写法
alipayclient

//一大串参数(URL编码的)看下文

二、构造支付参数

代码仅供参考,部分代码做了封装,需要到demo里的TAliPayPlatform类查看。

支付参数全部通过服务端获取,本地不做任何处理

+ (NSString *)payToAliPayUrlScheme:(NSString *)urlScheme orderString:(NSString *)orderString onStateChanged:(TPayStateChangedHandler)stateChangedHandler {
    
    if (stateChangedHandler) {
        [TAliPayPlatform shareInstance].payStateChangedHandler = stateChangedHandler;
    }
    
    //对敏感数据进行处理
    //alipay://alipayclient/?{
    //    "fromAppUrlScheme" : "{URL scheme}",
    //    "requestType" : "SafePay",
    //    "dataString" : "payment_type=\"1\"&out_trade_no=\"{订单编号}\"&partner=\"{partner}\"&subject=\"{subject}\"&service=\"mobile.securitypay.pay\"&_input_charset=\"UTF-8\"&total_fee=\"5.0\"&body=\"{body}\"¬ify_url=\"{回调地址}\"&seller_id=\"{seller_id}\"&sign=\"{sign}\"&sign_type=\"RSA\"&bizcontext=\"{\"appkey\":\"{appkey}\"}\""
    //}
    
    NSDictionary * aliPayDic = @{@"fromAppUrlScheme" : urlScheme,
                                 @"requestType" : @"SafePay",
                                 @"dataString" : orderString};
    NSError * error;
    NSData * aliPayJsonData = [NSJSONSerialization dataWithJSONObject:aliPayDic
                                                             options:NSJSONWritingPrettyPrinted
                                                               error:&error];
    NSString * aliPayJsonString = [[NSString alloc] initWithData:aliPayJsonData encoding:NSUTF8StringEncoding];
    NSString * aliPayInfo = [NSString stringWithFormat:@"alipay://alipayclient/?%@",aliPayJsonString];
    NSString * aliPayUrl = [aliPayInfo stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    return aliPayUrl;
}

三、发起请求

代码仅供参考,部分代码做了封装,需要到demo里的Trochilus类查看。

//支付宝支付
+ (void)payToAliPayUrlScheme:(NSString *)urlScheme orderString:(NSString *)orderString onStateChanged:(TPayStateChangedHandler)stateChangedHandler {
    
    [Trochilus shareInstance].isPayment = YES;
    
    NSString * aliPayInfo = [TAliPayPlatform payToAliPayUrlScheme:urlScheme
                                                      orderString:orderString
                                                   onStateChanged:^(TResponseState state, TUser *user, NSError *error) {
                                                       if (stateChangedHandler) {
                                                           stateChangedHandler(state,user,error);
                                                       }
    }];
    
    [Trochilus sendToURL:aliPayInfo];
}

+ (void)sendToURL:(NSString *)url {
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.001 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
    });
    
}

四、支付宝户端回调

代码仅供参考,部分代码做了封装,需要到demo里的TAliPayPlatform类查看。

+ (BOOL)handleUrlWithAliPay:(NSURL *)url {
    
    if ([url.absoluteString rangeOfString:@"//safepay/"].location != NSNotFound) {
        NSError *err;
        NSDictionary *ret=[NSJSONSerialization JSONObjectWithData:[[NSString urlDecode:url.query]dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:&err];
        if (err||ret[@"memo"]==[NSNull null]||[ret[@"memo"][@"ResultStatus"] intValue]!=9000) {
            //支付失败
            NSError * err = [NSError errorWithDomain:@"alipay_pay" code:ret[@"memo"]!=[NSNull null]?[ret[@"memo"][@"ResultStatus"] intValue]:-1 userInfo:ret];
            
            if ([TAliPayPlatform shareInstance].payStateChangedHandler) {
                [TAliPayPlatform shareInstance].payStateChangedHandler(TResponseStateFail,nil,err);
            }
        }
        else if (err||ret[@"memo"]==[NSNull null]||[ret[@"memo"][@"ResultStatus"] intValue] == 6001) {
            //用户取消
            NSError * err = [NSError errorWithDomain:@"alipay_pay" code:ret[@"memo"]!=[NSNull null]?[ret[@"memo"][@"ResultStatus"] intValue]:-1 userInfo:ret];
            if ([TAliPayPlatform shareInstance].payStateChangedHandler) {
                [TAliPayPlatform shareInstance].payStateChangedHandler(TResponseStateCancel,nil,err);
            }
        }
        else{
            //支付成功
            if ([TAliPayPlatform shareInstance].payStateChangedHandler) {
                [TAliPayPlatform shareInstance].payStateChangedHandler(TResponseStateSuccess,nil,nil);
            }
        }
        return YES;
    }
    
    return NO;
}

五、iOS9起状态栏返回回调处理

iOS9起在状态栏左右两侧增加了返回APP的功能,通过这个功能微信客户端是不会发信息给我们APP的,因此需要做特殊处理。

我们看看微信返回我们APP时,我们APP的appDelegate方法执行顺序是什么

applicationWillEnterForeground:-> application:openURL:options: || application:openURL:sourceApplication:annotation:

因此我们在applicationWillEnterForeground做文章,代码如下:

- (void)t_applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    
    [self t_applicationWillEnterForeground:application];
    
    dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5/*延迟执行时间*/ * NSEC_PER_SEC));
    dispatch_after(delayTime, dispatch_get_main_queue(), ^{
        //延迟0.5s执行
        if ([Trochilus isURLResponse] == NO && [Trochilus isPay] == YES) {
            [[NSNotificationCenter defaultCenter] postNotificationName:kTrochilusPayment object:self userInfo:nil];
        }
    });
}

这里做了 method swizzle 具体看UIApplication+Trochilus类,实现了ShareSDK那个效果

同时做了延迟处理 判断客户端是否有返回信息,没有就去自己服务器请求结果吧

[Trochilus isURLResponse] == YES 说明微信有返回信息 反之 微信没返回信息,那么我们需要去自己服务器查支付结果

[Trochilus isPay] == YES 说明是支付类型,因为我这还有分享、授权,为了避免发送不必要的通知

六、参考资料

https://github.com/100apps/openshare

http://www.jianshu.com/p/8930b4496023

七、Demo

https://github.com/quanweiwang/Trochilus

目录

分享篇
1、我的APP不可能这么胖之QQ好友分享
2、我的APP不可能这么胖之QQ空间分享
3、我的APP不可能这么胖之微信好友分享
4、我的APP不可能这么胖之微信朋友圈分享
5、我的APP不可能这么胖之新浪微博分享
登录篇
6、我的APP不可能这么胖之QQ登录
7、我的APP不可能这么胖之微信登录
8、我的APP不可能这么胖之新浪微博登录
支付篇
9、我的APP不可能这么胖之微信支付
10、我的APP不可能这么胖之支付宝支付

你可能感兴趣的:(我的APP不可能这么胖之支付宝支付)