IAP开发指南

IAP流程

介绍

这里介绍的IAP使用服务器模式:

  1. 调用服务器接口创建一个商品的订单
  2. 请求Apple的商品列表
  3. 选取商品调用苹果支付
  4. 支付成功(会返回凭证)
  5. 把支付成功的返回凭证上传到APP服务器(带上订单的ID,有利于后台判断是哪个订单支付成功)
  6. APP服务器保存该凭证等数据并像苹果服务器发起凭证验证,验证成功则发送商品

配置

iTunesConnect上创建内购项目。


IAP开发指南_第1张图片

开发流程

客户端流程

1.初始化,添加一个交易队列观察者

    [[SKPaymentQueue defaultQueue] addTransactionObserver:xxxx];

IAP支付的机制,每次支付行为或每笔交易被认为是一个SKPaymentTransation,只有当SKPaymentTransation被finishTransaction:,这次支付(交易)行为才算是正常结束了。即使这次支付途中被中断,其实也并没有丢失。假设支付没有完成 App 就退出了(比如崩溃),那么当下次 App 重启之后,只要设置了监听addTransactionObserver:,之前被中断的支付就会接着进行。

2.去苹果服务器请求产品信息

    NSSet* set = [NSSet setWithObjects:productId, nil];
    SKProductsRequest* skr = [[SKProductsRequest alloc] initWithProductIdentifiers:set];
    self.skProductsRequest = skr;
    self.skProductsRequest.delegate = self;
    [self.skProductsRequest start];

3.请求回调

请求到IAP产品信息,发起购买

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
    if (response.products.count == self.arrayFromatProducts.count) {
        [self parseFromattingPriceData:response.products];
    }else{
        SKPayment* p = [SKPayment paymentWithProduct:[response.products objectAtIndex:0]];
        [[SKPaymentQueue defaultQueue] addPayment:p];
    }
}


请求失败:

- (void)request:(SKRequest *)request didFailWithError:(NSError *)error
{
    if (self.requestProductFailure) {
        self.requestProductFailure(error);
    }
}

购买结果:

#pragma mark SKPaymentTransactionObserver
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{
    
    for (SKPaymentTransaction *transaction in transactions){
        
        switch (transaction.transactionState){
            case SKPaymentTransactionStatePurchased:{
                NSLog(@"transaction.payment.productIdentifier:%@",transaction.payment.productIdentifier);
                [self verifyPuschase:transaction];
                break;
            }
            case SKPaymentTransactionStateRestored:{//已经购买过该商品
                [self verifyPuschase:transaction];
                break;
            }
            case SKPaymentTransactionStateFailed:{
                [[SKPaymentQueue defaultQueue]finishTransaction:tran];
                if(transaction.error.code != SKErrorPaymentCancelled) {
                    NSLog(@"购买失败");
                } else {
                    NSLog(@"用户取消交易");
                }                
                break;
            }
            default:
                break;
        }
    }
}

购买结果发送到服务端。服务端再到苹果服务器验证凭证

收到

- (void)verifyPurchase:(SKPaymentTransaction *)transaction {
        //先发服务端验证
        
        //收到服务端验证成功后,完成苹果订单。
        [[SKPaymentQueue defaultQueue] finishTransaction:transaction];

}

退出时移除观察者

- (void)dealloc {
    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}
服务端流程

服务端收到购买成功,发送到苹果服务器验证。

//沙盒测试环境验证
#define SANDBOX @"https://sandbox.itunes.apple.com/verifyReceipt"
//正式环境验证
#define AppStore @"https://buy.itunes.apple.com/verifyReceipt"

沙盒测试

  1. 在用户与职能中添加沙箱测试账号。


    IAP开发指南_第2张图片
  2. xcode配置项目的bundleid与Apple后台配置的bundleid一致。打开In App Purchase

  3. 退出iPhone的App Store账号(因为我们需要使用沙盒账号登录)

  4. xcode运行App,购买商品,系统会让你进行登录,这里我们点击“使用现有的AppleID”就可以沙盒测试账号进行登录了。

IAP开发指南_第3张图片
image

IAP开发指南_第4张图片
image

IAP开发指南_第5张图片
image

重试机制

IAP在实际使用中会有用户返回内购丢单的情况。分析在整个流程中会有两个环节失败的情况。

  • Apple支付成功后,客户端没有收到Apple支付的回调,无法发起服务端验证。

【解决办法】:App启动后要注册对Apple支付结果回调的观察。这样Apple还会恢复支付状态更新的回调。

  • 收到Apple支付成功后,发起服务端验证失败。这样在Apple那里已经支付完成了,但是用户却没有收到购买的商品。

【解决办法】:增加重试, 延迟对苹果订单的确认。

  • 1、发起服务端验证接口失败(网络错误或者业务错误时),立即间隔一段时间重试
  • 2、延迟对苹果订单的确认,充值完成才确认苹果订单。App启动的时候,对于未验证成功的支付,再次发起服务端验证。

参考文档

iOS Apple内购及掉单问题

iOS开发-内购丢单处理方式

iOS—处理苹果内购(IAP)掉单的坑

收据验证编程指南

你可能感兴趣的:(IAP开发指南)