iOS 内购

◇◆丶佛笑我妖孽 提交于 2020-12-29 07:56:53

从开发iOS到现在,内购app也做过两个了,现在好好记录下这个流程。

首先需要在所属的app下创建物品,这个流程网上很多也不难。这边就详细说明了,可参考下面网址。 http://blog.csdn.net/shenjie12345678/article/details/40978977/

我们定义好一个或多个product 后 每个product id对应着一个product。 我们拿到一个或多个product id,数据处理后对appstore 发起购物请求,等待appstore处理后的响应(之间很多操作,都是appStore和用户之间,客户端无法干预), 客户端对购物成功的回执单进行校验。 内购流程示意图.png

这个流程基本就是这样,如上图所示。

理清整个流程后,我们对内购就非常清晰了,要注意的就是细节了,对各种异常情况的处理。各种case 见下列枚举,基本和app的sdk保持一致

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];
        }

    }
}

补充一点 :一旦启动了开始购买流程,必须要调用

    //结束交易
    [[SKPaymentQueue defaultQueue] finishTransaction: transaction];

来结束购买流程,否者在下一次调用到 方法

[[SKPaymentQueue defaultQueue] addTransactionObserver:self];

还是会触发继续购买流程,这个特性可以解决购买过程中出现的各种异常场景,比如购买完成app crash(没网络了),在下一次启动app时调用上面的方法可以回复购买。 具体类 放在gitHub下 https://github.com/weskhen/InAppPurchasing

苹果反馈的状态码;

21000 App Store无法读取你提供的JSON数据

21002 收据数据不符合格式 (踩过坑,越狱机会出现)

21003 收据无法被验证

21004 你提供的共享密钥和账户的共享密钥不一致

21005 收据服务器当前不可用

21006 收据是有效的,但订阅服务已经过期。当收到这个信息时,解码后的收据信息也包含在返回内容中

21007 收据信息是测试用(sandbox),但却被发送到产品环境中验证

21008 收据信息是产品环境中使用,但却被发送到测试环境中验证

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!