从开发iOS到如今,内购app也作过两个了,如今好好记录下这个流程。git
首先须要在所属的app下建立物品,这个流程网上不少也不难。这边就详细说明了,可参考下面网址。 http://blog.csdn.net/shenjie12345678/article/details/40978977/github
咱们定义好一个或多个product 后 每一个product id对应着一个product。 咱们拿到一个或多个product id,数据处理后对appstore 发起购物请求,等待appstore处理后的响应(之间不少操做,都是appStore和用户之间,客户端没法干预), 客户端对购物成功的回执单进行校验。 服务器
这个流程基本就是这样,如上图所示。网络
理清整个流程后,咱们对内购就很是清晰了,要注意的就是细节了,对各类异常状况的处理。各类case 见下列枚举,基本和app的sdk保持一致app
typedef enum : NSUInteger { EPaymentTransactionStateNoPaymentPermission, //没有Payment权限 EPaymentTransactionStateAddPaymentFailed, //addPayment失败 EPaymentTransactionStatePurchasing,//正在购买 EPaymentTransactionStatePurchased,//购买完成(销毁交易) EPaymentTransactionStateFailed, //购买失败(销毁交易) EPaymentTransactionStateCancel,//用户取消 EPaymentTransactionStateRestored,//恢复购买(销毁交易) EPaymentTransactionStateDeferred, //最终状态未肯定 } EPaymentTransactionState;
内购有个重要的协议 SKPaymentTransactionObserver 须要特殊特殊处理,很少说废话 直接附上代码测试
#pragma mark - SKPaymentTransactionObserver - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions { for (SKPaymentTransaction *transaction in transactions) { EPaymentTransactionState state; switch (transaction.transactionState){ case SKPaymentTransactionStatePurchasing: { // 链接appStore state = EPaymentTransactionStatePurchasing; } break; case SKPaymentTransactionStatePurchased: { state = EPaymentTransactionStatePurchased; //交易完成 if (isServiceVerify) { [self completeTransaction:transaction]; } else { //本地做校验 [self verifyPurchase:transaction]; } } break; case SKPaymentTransactionStateFailed: { //交易失败 if (transaction.error.code != SKErrorPaymentCancelled) { state = EPaymentTransactionStateFailed; }else { state = EPaymentTransactionStateCancel; } [self finshTransaction:transaction]; } break; case SKPaymentTransactionStateRestored: { state = EPaymentTransactionStateRestored; //已经购买过该商品 [self finshTransaction:transaction]; } break; case SKPaymentTransactionStateDeferred: { state = EPaymentTransactionStateDeferred; } break; default: break; } if (self.delegate && [self.delegate respondsToSelector:@selector(updatedTransactions:)]) { [self.delegate updatedTransactions:state]; } } }
补充一点 :一旦启动了开始购买流程,必需要调用.net
//结束交易 [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
来结束购买流程,否者在下一次调用到 方法code
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
仍是会触发继续购买流程,这个特性能够解决购买过程当中出现的各类异常场景,好比购买完成app crash(没网络了),在下一次启动app时调用上面的方法能够回复购买。 具体类 放在gitHub下 https://github.com/weskhen/InAppPurchasingserver
苹果反馈的状态码;blog
21000 App Store没法读取你提供的JSON数据
21002 收据数据不符合格式 (踩过坑,越狱机会出现)
21003 收据没法被验证
21004 你提供的共享密钥和帐户的共享密钥不一致
21005 收据服务器当前不可用
21006 收据是有效的,但订阅服务已通过期。当收到这个信息时,解码后的收据信息也包含在返回内容中
21007 收据信息是测试用(sandbox),但却被发送到产品环境中验证
21008 收据信息是产品环境中使用,但却被发送到测试环境中验证