ios 内购

从开发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

贴上一段苹果本地校验成功的json返回 估计服务器也是相同的

Printing description of jsonResponse:
{
    environment = Sandbox; //购买环境 
    receipt =     {
        "adam_id" = 0;
        "app_item_id" = 0;
        "application_version" = 30;
        "bundle_id" = "com.wesk.PaoBa";
        "download_id" = 0;
        "in_app" =         (
                        {
                "is_trial_period" = false;
                "original_purchase_date" = "2016-09-27 04:52:58 Etc/GMT";
                "original_purchase_date_ms" = 1474951978000;
                "original_purchase_date_pst" = "2016-09-26 21:52:58 America/Los_Angeles";
                "original_transaction_id" = 1000000238538249;
                "product_id" = “com.PaoBa.Product.001";
                "purchase_date" = "2016-09-27 04:52:58 Etc/GMT";
                "purchase_date_ms" = 1474951978000;
                "purchase_date_pst" = "2016-09-26 21:52:58 America/Los_Angeles";
                quantity = 1;
                "transaction_id" = 1000000238538249;
            }
        );
        "original_application_version" = "1.0";
        "original_purchase_date" = "2013-08-01 07:00:00 Etc/GMT";
        "original_purchase_date_ms" = 1375340400000;
        "original_purchase_date_pst" = "2013-08-01 00:00:00 America/Los_Angeles";
        "receipt_creation_date" = "2016-09-27 07:42:18 Etc/GMT";
        "receipt_creation_date_ms" = 1474962138000;
        "receipt_creation_date_pst" = "2016-09-27 00:42:18 America/Los_Angeles";
        "receipt_type" = ProductionSandbox;
        "request_date" = "2016-09-27 07:43:44 Etc/GMT";
        "request_date_ms" = 1474962224281;
        "request_date_pst" = "2016-09-27 00:43:44 America/Los_Angeles";
        "version_external_identifier" = 0;
    };
    status = 0;
}

苹果反馈的状态码;

21000 App Store无法读取你提供的JSON数据
21002 收据数据不符合格式 (踩过坑,越狱机会出现)
21003 收据无法被验证
21004 你提供的共享密钥和账户的共享密钥不一致
21005 收据服务器当前不可用
21006 收据是有效的,但订阅服务已经过期。当收到这个信息时,解码后的收据信息也包含在返回内容中
21007 收据信息是测试用(sandbox),但却被发送到产品环境中验证
21008 收据信息是产品环境中使用,但却被发送到测试环境中验证

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,874评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,102评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,676评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,911评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,937评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,935评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,860评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,660评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,113评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,363评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,506评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,238评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,861评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,486评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,674评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,513评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,426评论 2 352

推荐阅读更多精彩内容