消耗型和非自动订阅型苹果内购(IAP)优化

最近项目内购,每天有用户反馈无法进行内购或者付款成功后商品未到账的情况,于是进行了分析优化.


分析

  • 无法进行内购问题
    原因是在从苹果服务器请求产品信息失败导致的.
    通常返回错误提示:无法连接iTunes store.(沙盒环境)
    即下面请求失败.
 SKProductsRequest *productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:identifiers];
productsRequest.delegate = delegate;
 [productsRequest start];

该问题苹果服务器原因,无解中.(T_T)
但是我们可以曲线救国使用废弃api创建SKPayment进行购买.(亲测可用)

+ (id)paymentWithProductIdentifier:(NSString *)identifier NS_DEPRECATED_IOS(3_0, 5_0, "Use +paymentWithProduct: after fetching the available products using SKProductsRequest");
  • 付款成功后,虚拟币或者会员未到账
    原因是没有和我们的服务器二次验证成功.
    主要有以下两种可能性:
1 . 苹果扣款成功回调后,因为我们服务器或者网络原因等导致二次验证失败.
2 . 苹果扣款成功后,没有进行正确回调.

曾经苹果服务器有两天抽风,导致我们IAP全部失败,奇怪的是别人的虽然也回调失败,但是还是能成功购买.

优化

针对第一种可能:

  • 与我们服务器进行二次验证失败的时候,不能完成苹果订单.(wwdc有强调,消耗型)
    即不要对这个transaction调用以下代码:
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];

后续再进行二次验证成功后在finishTransaction.

  • 灵活进行二次验证
// Only valid if state is SKPaymentTransactionStatePurchased.
@property(nonatomic, readonly, nullable) NSData *transactionReceipt NS_DEPRECATED_IOS(3_0, 7_0, "Use -[NSBundle appStoreReceiptURL]");

iOS7新方法获取的transactionReceipt在多次进行内购后,会变大,甚至达几百KB.
iOS6老方法获取则小很多,只有几KB.
先尝试用iOS6的transactionReceipt进行验证,失败后再用iOS7的transactionReceipt进行验证,以提高二次验证的成功率.

针对第二种可能:

  • 检查购买队列中是否有购买成功但未完成二次验证的transaction
    [SKPaymentQueue defaultQueue] .transactions里面.(该属性不支持KVO)
    1 . 主要在进入含有内购页面时候进行检查.例如购买虚拟币页面.
    2 . 苹果内购addPayment后,定时3~5秒进行检查,以防苹果没有进行正确回调.

其他优化:

  • 不要尝试保存失败信息,维护起来非常困难.(因为内购的容易失败)
    如果有需要将我们的订单和内购交易在购买未成功之前就建立关系,可以利用SKPaymentapplicationUsername属性,来保存我们的订单号或者用户id信息.
    介绍如下:

An opaque identifier for the user’s account on your system.
This is used to help the store detect irregular activity. For example, in a game, it would be unusual for dozens of different iTunes Store accounts making purchases on behalf of the same in-game character.
The recommended implementation is to use a one-way hash of the user’s account name to calculate the value for this property.

  • 建立对成功二次验证SKPaymentTransaction的transactionIdentifier的缓存机制.
    进行二次验证前判断缓存,以防重复的二次验证.(注意在合适的时候清空缓存,例如队列中没有购买成功的SKPaymentTransaction)

上线后,再来更新优化后的效果... C U around.

你可能感兴趣的:(消耗型和非自动订阅型苹果内购(IAP)优化)