iOS 绑定支付宝和支付宝支付(一)

前言

  前段时间公司的 APP 加了一些新需求,其中我负责的钱包模块多增加了支付宝绑定和支付宝支付的功能。所以研究了一番,在此做个记录,如果有说的不对的地方,欢迎大佬指出并纠正。

支付宝授权

  支付宝授权其实就是使用支付宝第三方登录,需要用户同意授权,使用支付宝登录你的 APP,这样你的 APP 就可以通过支付宝 SDK 提供的接口去获取对应的支付宝信息。例如:你的支付宝账户的唯一标示等。

  • 支付宝授权流程图


    授权流程
  • 支付宝授权流程

  1. APP 向自己后台发起授权请求,后台给 APP 返回授权码,其实就是一个带着私钥的字符串。
  2. APP 拿着后台返回的授权码去向支付宝发起授权请求。
  3. 支付宝返回给 APP 当次授权的授权码app_auth_code和开发者的app_id
  4. 拿到支付宝返回的当前授权的授权码app_auth_code发送给自己的后台去换取app_auth_token
  5. 用换取的app_auth_token去调用支付宝提供的alipay.open.auth.token.app接口去获取授权用户的userId
  • 支付宝授权代码示例
      首先你需要去下载支付宝提供的官方 Demo,然后把官方 Demo 里的APAuthInfo拷贝到你的项目里。
#import <Foundation/Foundation.h>

@interface APAuthInfo : NSObject

/*********************************授权必传参数*********************************/

//服务接口名称,常量com.alipay.account.auth。
@property (nonatomic, copy) NSString *apiname;

//调用方app标识 ,mc代表外部商户。
@property (nonatomic, copy) NSString *appName;

//调用业务类型,openservice代表开放基础服务
@property (nonatomic, copy) NSString *bizType;

//产品码,目前只有WAP_FAST_LOGIN
@property (nonatomic, copy) NSString *productID;


//签约平台内的appid
@property (nonatomic, copy) NSString *appID;

//商户签约id
@property (nonatomic, copy) NSString *pid;

//授权类型,AUTHACCOUNT:授权;LOGIN:登录
@property (nonatomic, copy) NSString *authType;

//商户请求id需要为unique,回调使用
@property (nonatomic, copy) NSString *targetID;


/*********************************授权可选参数*********************************/

//oauth里的授权范围,PD配置,默认为kuaijie
@property (nonatomic, copy) NSString *scope;

//固定值,alipay.open.auth.sdk.code.get
@property (nonatomic, copy) NSString *method;

@end

  其中APAuthInfo中的appIDpidtargetID这三个参数是需要我们自己去赋值的。appID就是你申请的 APP 在支付宝平台的唯一标识,pid是你申请的 APP 在支付宝平台对应的商户号,targetID是保证每次请求的时候它的值是唯一的,所以一般赋值为当前时间的时间戳。

 APAuthInfo *authInfo = [APAuthInfo new];
 authInfo.pid = AliPayPid;
 authInfo.appID = AliPayID;
 authInfo.targetID = [NSString stringWithFormat:@"%ld", (long)[[NSDate date] timeIntervalSince1970]];
    
  // 将授权信息拼接成字符串
 NSString *authInfoStr = [authInfo description];
 NSLog(@"authInfoStr = %@",authInfoStr);

  然后向自己后台去请求获取私钥和私钥加密方式,拿到私钥以及私钥加密方式只后拼接成指定格式的字符串,拿这个字符串去发起支付宝授权。

authInfoStr = [NSString stringWithFormat:@"%@&sign=%@&sign_type=%@", authInfoStr, sign, @"RSA2"];
[[AlipaySDK defaultService] auth_V2WithInfo:authInfoStr fromScheme:appScheme callback:^(NSDictionary *resultDic) {
                NSLog(@"resultDic = %@", resultDic);
                // 解析 auth code
                NSString *result = resultDic[@"result"];
                [self handlderAliPayAuthInfo:result];   
}];

  最后,拿到支付宝授权接口的返回值,取result字段所对应的字符串,然后截取出我们需要的auth_codealipay_open_id。然后再把这两个值传给后端,由后端去调取支付宝接口去获取用户信息。

- (void)handlderAliPayAuthInfo:(NSString *)result {
    
    NSString *authCode = nil;
    NSString *openId = 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];
            }
            if (subResult.length > 32 && [subResult hasPrefix:@"alipay_open_id="]) {
                openId = [subResult substringFromIndex:15];
            }
            
            if (openId.length != 0 && authCode.length != 0) {
                break;
            }
        }
    }
    
    NSLog(@"授权结果 authCode = %@, openId = %@", authCode?:@"", openId?:@"");
}

注意

  • 应用授权的app_auth_code是唯一的;app_auth_code使用一次后就会失效,一天(从生成app_auth_code开始的24小时)未被使用就会自动过期; app_auth_token有效期为365天,刷新后重新计时。
  • 支付宝的私钥必须存放在后端,不能存放在前段。因为在支付宝平台申请 APP 的时候就会生产一对私钥和公钥,只有当你穿的私钥和支付宝平台存放的公钥相配对成功之后,授权请求才会成功。所以,如果把私钥存放在前段会存在很大的危险漏洞,因此只能把私钥存放在后端。

推荐阅读更多精彩内容