JKIAPHelp 1.1.0

JKIAPHelp 1.1.0

kane 维护。



JKIAPHelp 1.1.0

  • SPkay

JKIAPHelp

JKIAPHelp用于Apple内购,解决内购中遇到的丢单问题。(用户支付成功,无法得到对应的商品)

本方案目前只适用于从自己的服务器获取到订单后再开始进入苹果的内购流程。

内购有很多坑,一般来说会出现的问题有

  1. 用户购买,IAP无回调响应,用户退出程序导致订单异常。
  2. 用户购买成功,自己的服务器网络发生错误,无法及时到账。
  3. SKPaymentTransaction.applicationUsername丢失的问题。
  4. 用户卸载程序导致本地订单号丢失。
  5. 获取本地苹果票据为空。

解决方案基本逻辑

在系统支付回调

-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transaction

SKPaymentTransactionStatePurchasing时将订单相关信息加入到钥匙串中,保证订单信息的完整性与可靠性,然后在SKPaymentTransactionStatePurchased的时候来验证订单。验证是通过开发者实现JKIAP代理

-(void)verifyWithModel:(JKIAPTransactionModel *)model resultAction:(VerifyRsultBlock)resultAction

来向开发者自己的服务器完成订单的验证。如果验证出现失效或完成,那么就判断当前用户是否和创建订单时的用户一致,如果一致,那么就删除钥匙串中对应的订单完成购买;如果不一致,就将状态同步到钥匙串中,当下次用户注册时通过补发货的回调来通知开发者。如果服务器验证网络错误,就同步钥匙串订单状态。当用户点击购买,从后台进入程序,重新注册JKIAP时就会检测当前未完成的订单,将未完成的订单再次验证,如果再次发生错误就进行下一次验证,有多个未完成的话就继续验证下一个订单。

一般来说,SKPaymentTransaction.applicationUsername是存储外部订单信息的唯一位置,在iOS 12之前还可以使用requestData来存储,但现在苹果禁止了。相信许多开发者都遇到过SKPaymentTransaction.applicationUsername丢失的问题。在JKIAP中,如果发生丢失,处理方式是通过比较UserID和productIdentifier来确定一个以前在SKPaymentTransactionStatePurchasing时存储的订单。看起来比较粗鲁,但由于苹果的交易是串行的,JKIAP内部的验证也是串行的,因此通过UserID和productIdentifier就能确定是同一个订单。

使用方法

  1. pod 'JKIAPHelp'或拖入JKIAPHelp文件夹
  2. 实现代理JKIAPPayDelegate,用于向自己的服务器进行订单验证
-(void)verifyWithModel:(JKIAPTransactionModel *)model resultAction:(VerifyRsultBlock)resultAction{

//验证完成后调用resultAction来通知JKIAPManager完成验证.

      //例如 resultAction(JKIAPVerifyValid);
} 
  1. 实现发货的回调,通过回调来进行发货操作。
// 发货成功回调
-(void)onDistributeGoodsFinish:(JKIAPTransactionModel*)model;

//发货失败回调
-(void)onDistributeGoodsFailue:(JKIAPTransactionModel*)model withError:(NSError *)error;

//补发货成功回调
-(void)onRedistributeGoodsFinish:(JKIAPTransactionModel*)model;

//补发货失败回调
-(void)onRedistributeGoodsFailue:(JKIAPTransactionModel*)model withError:(NSError *)error;
  1. 注册 [[JKIAPManager sharedManager] registerPayWithUserID:@"userOne"];
  2. 购买 方法1 [[JKIAPManager sharedManager] buyProductWithProductIdentifier:@"com.objId.com" appproductType:AppleProductType_Consumable orderId:@"orderId"]; 方法2 - (void)buyProductWithSKPayment:(SKPayment *)payment;