应用内支付详细流程:
首先是添加StoreKit.framework。
然后是具体的步骤:
1. 决定在程序内出售的商品的类型。
出售商品的类型主要有订阅,服务的,内容的,如果商品类型不再其中,就不能出售。
2. 通过iTunes Connect注册商品
每次添加新商品的时候都需要执行这一步骤,每个商品都需要一个唯一的商品标识。 App Store通过这个标识来查找商品信息并处理支付流程。 注册商品标识的方法和注册程序的方法类似。
3. 检测是否可以进行支付
在发送支付请求之前,程序应该检查该功能是否被开启。程序可在显示商店界面之前就检查该设置(没启用就不显示商店界面了),也可以在用户发送支付请求前再检查,这样用户就可以看到可购买的商品列表了。
例子:
- if([SKPaymentQueue canMakePayments])
- {
- ...//Display a store to the user
- }
- else
- {
- ...//Warn the user that purchases are disabled.
- }
4. 获得商品的信息
程序创建SKProductsRequest对象,用想要出售的商品的标识来初始化, 然后附加上对应的委托对象。 该请求的响应包含了可用商品的本地化信息。
- //这里发送请求
- - (void)requestProductData
- {
- SKProductsRequest *request = [[SKProductsRequest alloc]initWithProductIdentifiers:
- [NSSet setWithObject: kMyFeatureIdentifier]];
- request.delegate = self;
- [request start];
- }
- //这个是响应的delegate方法
- - (void)productsRequest: (SKProductsRequest *)request
- didReceiveResponse: (SKProductsResponse *)response
- {
- NSArray *myProduct = response.products;
- //生成商店的UI
- [request autorelease];
- }
5. 添加一个展示商品的界面
Store Kit不提供界面的类。 这个界面需要我们自己来设计并实现。
6. 为支付队列(payment queue)注册一个观察者对象
程序需要初始化一个transaction observer对象并把它指定为payment queue的观察者。
上代码:
- MyStoreObserver *observer = [[MyStoreObserver alloc]init];
- [[SKPaymentQueue defaultQueue]addTransactionObserver: observer];
应该在程序启动的时候就添加好观察者,原因前面说过,重启后程序会继续上次未完的交易,这时就添加观察者对象就不会漏掉之前的交易信息。
7. 在MyStoreObserver类中执行paymentQueue: updatedTransactions: 方法。
这个方法会在有新的交易被创建,或者交易被更新的时候被调用。
- - (void)paymentQueue: (SKPaymentQueue *)queue updatedTransactions: (NSArray *)transactions
- {
- for(SKPaymentTransaction * transaction in transactions)
- {
- switch(transaction.transactionState)
- {
- case SKPaymentTransactionStatePurchased:
- [self completeTransaction: transaction];
- break;
- case SKPaymentTransactionStateFailed:
- [self failedTransaction: transaction];
- break;
- case SKPaymentTransactionStateRestored:
- [self restoreTransaction: transaction];
- default:
- break;
- }
- }
- }
上面的函数针对不同的交易返回状态,调用对应的处理函数。
8. 观察者对象在用户成功购买一件商品时,提供相应的内容,以下是在交易成功后调用的方法
- - (void) completeTransaction: (SKPaymentTransaction *)transaction
- {
- //你的程序需要实现这两个方法
- [self recordTransaction: transaction];
- [self provideContent: transaction.payment.productIdentifier];
- //将完成后的交易信息移出队列
- [[SKPaymentQueue defaultQueue]finishTransaction: transaction];
- }
交易成功的信息包含transactionIdentifier和transactionReceipt的属性。其中,transactionReceipt记录了支付的详细信息,这个信息可以帮助你跟踪、审(我们的)查交易,如果你的程序是用服务器来交付内容,transactionReceipt可以被传送到服务器,然后通过App Store验证交易。
9. 如果交易是恢复过来的(restore),我们用这个方法来处理:
- - (void) restoreTransaction: (SKPaymentTransaction *)transaction
- {
- [self recordTransaction: transaction];
- [self provideContent: transaction.payment.productIdentifier];
- [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
- }
这个过程完成购买的过程类似。 恢复的购买内容提供一个新的交易信息,这个信息包含了新的transaction的标识和receipt数据。 如果需要的话,你可以把这些信息单独保存下来,供追溯审(我们的)查之用。但更多的情况下,在交易完成时,你可能需要覆盖原始的transaction数据,并使用其中的商品标识。
10. 交易过程失败的话,我们调用如下的方法:
- - (void)failedTransaction: (SKPaymentTransaction *)transaction
- {
- if(transaction.error.code != SKErrorPaymentCancelled)
- {
- //在这类显示除用户取消之外的错误信息
- }
- [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
- }
通常情况下,交易失败的原因是取消购买商品的流程。 程序可以从error中读出交易失败的详细信息。
显示错误信息不是必须的,但在上面的处理方法中,需要将失败的交易从支付队列中移除。 一般来说,我们用一个对话框来显示错误信息,这时就应避免将用户取消购买这个error显示出来。
11. 组织好程序内“商店”的UI。当用户选择一件商品时, 创建一个支付对象,并放到队列中。
- SKPayment *payment = [SKPayment paymentWithProductIdentifier: kMyFeatureIdentifier];
- [[SKPaymentQueue defaultQueue] addPayment: payment];
如果你的商店支持选择同一件商品的数量,你可以设置支付对象的quantity属性
- SKMutablePayment *payment = [SKMutablePayment paymentWithProductIdentifier: kMyFeatureIdentifier];
- payment.quantity = 3;
- [[SKPaymentQueue defaultQueue] addPayment: payment];