三方支付 -- 支付宝集成

在iOS开发中有两种支付方式,一种是内购,一种是三方支付(支付宝、微信、银联支付)。

内购:当用户所买的商品是和App本身相关的,如Q币、游戏道具、在线书籍等一些虚拟商品,那你必须用内购, 否则不能上架到App Store。更蛋疼的是你要和苹果三七分账,意思是有用户花100元买你的游戏道具,那么就有30元是给苹果的,你拿到手的只有70.。。。

三方支付:当用户购买的东西和App本身没啥关系,如卫龙辣条、老干妈等实物,那你就可以用三方支付。当然三方支付也要收费,但是这个费用就很少很少了。。。

本文只介绍支付宝的集成使用

一、准备工作

1、首先你的公司要和支付宝签约,获取商户ID、收款支付宝用户ID、私钥。最新的支付宝SDK要求appID。

appID:支付宝首页 -> 登录 -> 开发者中心 -> 创建应用 ,创建完应用后就可以获取到appID
商户ID:支付宝 -> 我的商家服务 -> 签约管理 -> 签约订单 -> 查看PID|key
私钥:RSA私钥生成的命令和步骤

三方支付 -- 支付宝集成_第1张图片

用记事本打开上述文件夹中的rsa_public_key.pem文件,并将内容复制下来(注意这里需要一个字符串,要去掉换行)上传到你创建的应用中,若公钥生成正确如下图

三方支付 -- 支付宝集成_第2张图片


2、在项目中集成支付宝SDK,你可以用cocoapods,也可以手动添加。推荐使用cocoapods,这样你就不用导入那些恶心的依赖库。然后下载支付宝提供的Demo,参考并应用到你的项目中。

这里以我自己的Demo为例。在项目中新建一个文件夹,用于存放关于支付宝的代码,并将下图中的文件(可以从下载的支付宝Demo中找到)拖入到你的工程中。

三方支付 -- 支付宝集成_第3张图片

command + B运行这时项目会报几个错误

2.1. 这是因为没有导入#import 《Foundation/Foundation.h>的原因(有两处需要添加,这里只给出一个地方)。支付宝Demo中没报错是因为支付宝Demo中有个.pch文件,它把Foundation框架头文件导入到.pch文件中了。

这里写图片描述

2.2. 这是由于找不到openssl/asn1.h文件,也就是找不到openssl/asn1.h文件所在的文件夹。

这里写图片描述

解决办法如下,$(SRCROOT)表示动态相对路径,能获取到当前项目的路径,然后拼接上openssl所在的文件夹路径

三方支付 -- 支付宝集成_第4张图片

2.3. 在info.plist文件中修改App Transport Security,使其能加载http请求

这里写图片描述

2.4.设置URL Schemes,用于支付宝跳转回到App。注意URL Schemes的唯一性

三方支付 -- 支付宝集成_第5张图片

来到这里command + B 运行基本上就没有错误了。


二、代码实现

- (void)generateOrderInfo
{
    NSString *appID = @"";
    NSString *rsa2PrivateKey = @"";
    // 生成的pkcs8私钥
    NSString *rsaPrivateKey = @"";

    //将商品信息赋予AlixPayOrder的成员变量
    Order* order = [Order new];
    // NOTE: app_id设置
    order.app_id = appID;
    // NOTE: sign_type 根据商户设置的私钥来决定
    order.sign_type = (rsa2PrivateKey.length > 1)?@"RSA2":@"RSA";

    /**** 以下是固定写法 ***/
    // NOTE: 支付接口名称
    order.method = @"alipay.trade.app.pay";
    // NOTE: 参数编码格式
    order.charset = @"utf-8";
    // NOTE: 当前时间点
    NSDateFormatter* formatter = [NSDateFormatter new];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    order.timestamp = [formatter stringFromDate:[NSDate date]];
    // NOTE: 支付版本
    order.version = @"1.0";


    // NOTE: 商品数据
    order.biz_content = [BizContent new];
    // 商品信息描述
    order.biz_content.body = @"卫龙辣条 30年精心制作 走过路过不要错过";
    // 商品标题
    order.biz_content.subject = @"卫龙辣条";
    //订单ID(由公司自行制定)
    order.biz_content.out_trade_no = [self generateTradeNO];
    //超时时间设置
    order.biz_content.timeout_express = @"30m";
    //商品价格
    order.biz_content.total_amount = [NSString stringWithFormat:@"%.2f", 0.5];

    // 设置URL schemes,用于支付成功后 跳转回来
    NSString *appScheme = @"TestAlipayDemoZhao";
    // 支付宝会将支付结果异步通知到这个网址(问后台要),为了安全起见支付结果以这个为准,或者拿到这个结果和下面的回调结果比较在判断有没有支付成功
    order.notify_url = @"";

    //将商品信息拼接成字符串
    NSString *orderInfo = [order orderInfoEncoded:NO];
    NSString *orderInfoEncoded = [order orderInfoEncoded:YES];
    NSLog(@"orderSpec = %@",orderInfo);

    // NOTE: 获取私钥并将商户信息签名,外部商户的加签过程请务必放在服务端,防止公私钥数据泄露;
    // 需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode
    NSString *signedString = nil;
    RSADataSigner* signer = [[RSADataSigner alloc] initWithPrivateKey:((rsa2PrivateKey.length > 1)?rsa2PrivateKey:rsaPrivateKey)];
    if ((rsa2PrivateKey.length > 1)) {
        signedString = [signer signString:orderInfo withRSA2:YES];
    } else {
        signedString = [signer signString:orderInfo withRSA2:NO];
    }

    // NOTE: 如果加签成功,则继续执行支付
    if (signedString != nil)
    {
        // NOTE: 将签名成功字符串格式化为订单字符串,请严格按照该格式
        // 若用户未安装支付宝客户端,则以网页的形式登录支付宝,支付结果从下面这个方法返回
        NSString *orderString = [NSString stringWithFormat:@"%@&sign=%@", orderInfoEncoded, signedString];

        // NOTE: 调用支付结果开始支付
        [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {

            NSLog(@"reslut = %@",  resultDic);
        }];
    }
}

/**
 * 生成订单号
 */
- (NSString *)generateTradeNO
{
    static int kNumber = 15;

    NSString *sourceStr = @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    NSMutableString *resultStr = [[NSMutableString alloc] init];
    srand((unsigned)time(0));
    for (int i = 0; i < kNumber; i++)
    {
        unsigned index = rand() % [sourceStr length];
        NSString *oneStr = [sourceStr substringWithRange:NSMakeRange(index, 1)];
        [resultStr appendString:oneStr];
    }
    return resultStr;
}

AppDelegate.m文件

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionaryid> *)options
{
    if ([url.host isEqualToString:@"safepay"]) {
        // 支付跳转支付宝钱包进行支付,处理支付结果
         // 若用户安装支付宝客户端,则直接跳转到支付宝,支付结果从下面这个方法返回
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@",resultDic);
        }];
    }
    return YES;
}

关于支付跳转到支付宝客户端的流程可以看 这里

到这里点击支付按钮基本上就可以实现跳转到支付宝客户端完成支付了。具体细节请异步支付宝SDK文档。

你可能感兴趣的:(iOS开发)