IAP (In-App purchase)

哪些可以作为IAP商品

  1. 虚拟物品
  2. App某些功能
  3. 服务

IAP产品种类

  1. Non-consumable products
    • 同一个AppleID 只能购买一次,再次购买会提示"已购买";比如某个关卡,或者杂志
  2. consumable products
    • 同一个AppleID 可以购买多次,比如游戏中的金币
  3. Auto-renewable subscriptions
    • 同一Apple ID 在购买时会检查是否购买过,如果购买过并且还在续期权限中,系统会提示已购买而无法再购买;如果购买过之后取消过,则可以再次购买(自动续费购买 实际意义上表示签订协议,之后取消操作类似于关闭;关闭之后可以选择打开,如果你是在续期期限间关闭再打开,是不会重复扣费;如果超出期限再打开,会进行扣费)
  4. Non-renewable subscriptions
    • 同一Apple ID 可以购买多次,如果购买过并且权限未过期,系统会提示续期,可以再次购买。


      productType.png

IAP购买流程

  1. 基本流程


    iapProcess.png
  • 每个IAP产品,都有唯一的ProductId与之对应(可以在itc后台配置,比较坑的是,创建之后无法物理删除,即使在itc后台删除掉产品,用相同的ProductId会提示已被占用)

  • 通过ProductId可以发送请求获取具体的产品信息(描述、价格、时限等)

    //send request 
    SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:productID]];
    request.delegate = self;
    ....
    [request start];
    
      //SKRequestDelegate callback
      - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{....}
      - (void)request:(SKRequest *)request didFailWithError:(NSError *)error{....}
    
  • 系统会弹窗,展示IAP产品信息


    IMG_5314.PNG
  • 用户确认后,发起支付请求

  SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];
  payment.applicationUsername = applicationUsername; //可以唯一标识用户账号即可,是用于apple检测非法活动
  [[SKPaymentQueue defaultQueue] addPayment:payment];
  • 用户支付后,系统处理支付请求,返回此次transaction信息
//需要监听Payment Queue,建议是在didFinishLaunchingWithOptions:时就增加监听
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
//处理回调事件
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
    for (SKPaymentTransaction *transaction in transactions)
    {
        switch (transaction.transactionState)
        {
            case SKPaymentTransactionStatePurchased:
                //购买完成...
                break;
            case SKPaymentTransactionStateFailed:
                //交易失败...
                break;
            case SKPaymentTransactionStateRestored:
                //恢复交易...
                break;
            case SKPaymentTransactionStatePurchasing:
                //交易正在进行..
                break;
            default:
                break;
        }
    }
}

交易信息可能会重复或者伪造;需要进行小票验证,分为两种:本地验证和服务端验证(以下内容会详细介绍)

  • 解锁相关内容,需要关闭此次交易,否则系统会一直返回此次交易
//如果涉及到下载的内容,需要等下载内容完成后关闭交易
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];

如何测试

  1. 测试环境的自动订阅周期和线上是不同的,具体参见链接
    testSubscription.png

小票验证

本地验证

本人没有尝试过本地验证小票的方式,简单看了下官方文档的介绍,以下是摘自官网的步骤,有兴趣的童鞋可以移步wwdc2017_305_advanced_storekit

image.png

服务端验证

主要是将App获取到的小票凭证发送给自己服务器,通过自己服务器和AppStore服务器连接,并发送小票凭证,根据获取之后的响应数据进行判断。

  1. 小票格式
    • iOS6格式: 交易支付结果返回的transactiontransaction.transactionReceipt
    • iOS7格式: 本地获取 [[NSBundle mainBundle] appStoreReceiptURL]
  2. 服务端向AppStore发送数据
    {
          "receipt-data":"", //小票凭证进行base64编码后的数据
          "password":"",  //小票凭证中含有自动续费的内容时,必须有该参数(需要在itc后台生成)
          "exclude-old-transactions":false //仅和 iOS7样式的订阅类小票相关。 如果为 true,结果只包括所有订阅的最新续期交易
    }
    
  3. 响应数据
    • iOS6格式小票凭证验证结果


      iOS6_receiptResult.png
    • iOS7格式小票凭证验证结果


      iOS7_receiptResult..png

不仅小票格式不同,结果会不一致;根据IAP产品种类的不同,返回结果的字段也会有所差异,比如说pending_renewal_info只有iOS7的小票且包含自动续费内容才会返回,里面字段的内容也是和自动续费相关;如果想知道字段各个含义可以移步
Validating Receipts With the App Store
小票具体字段含义

关于自动订阅

  1. 自动订阅可以提供给用户一段试用期限,试用时长可以自定义(试用之前不会进行扣费)
  2. 订阅可以分组和服务分级
    • 同一个订阅组中订阅时互斥的;用户只能一次订阅一个群组中的一个选项
    • 同一订阅群组中的每个IAP产品都分配到一个订阅等级;订阅可以进行升级、降级、跨级
      • 升级。当顾客从较低等级的订阅切换到更高等级的订阅时。顾客先前的 App 内购买项目金额将会按比例退还到原始的付款方式。新的 App 内购买项目将收取完整价格并立即生效,这会将顾客的续期日期更改为升级日期。
      • 降级。当顾客从较高等级的订阅切换到较低等级的订阅时。在下一个续期日期,会以新费率向顾客收费。
      • 跨级。当顾客在同一等级的订阅间进行切换时。如果 App 内购买项目的时限相同,那么顾客先前的 App 内购买项目金额将会按比例退还到原始的付款方式。新的 App 内购买项目将收取完整价格并立即生效,这会将顾客的续期日期更改为升级日期。如果 App 内购买项目的时限不同,那么跨级将会在顾客的下一个续期日期生效。
        如下图itc管理后台,配置有三个等级,每个等级有两项内容
        subscriptionGroup.png
  3. 以自然月进行扣费;Apple 会在过期时间前24h进行尝试自动订阅
  4. 查看自己购买过的自动订阅内容
    • 可以进行取消;但即使取消订阅,订阅项一直会展示,随时可以再重新订阅,如果此次点击购买时间在你上次订阅周期且不在上面升降级条件中,不会进行扣费,等到下个周期才会扣费
    • 设置 - [iTunes Store与App Store] - 点击[Apple ID]- 选择[查看Apple ID] - 点击[帐户设置]-点击[订阅]
    • 另一种方式跳转到管理订阅:https://buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/manageSubscriptions
  5. 想要了解自动续费配置流程可以移步创建自动续期订阅
  6. 自动续费整体流程


    autoRenew.png
statusUpdateNotification

上面介绍的自动续费验证流程依靠客户端App的开启,Apple为自动续费提供了一种server-to-server的通知

  • 需要在itunes connect后台中填入处理notification的url(ATS;具体操作步骤见启用针对自动续期订阅的服务器通知
  • 针对自动订阅通知类型:
    • INITIAL_BUY
    • CANCEL
    • RENEWAL
    • INTERACTIVE_RENEWAL (取消后又重新订阅)
    • DID_CHANGE_RENEWAL_PREFERENCE(修改自动订阅,升降级)
  • 但是我们在测试环境测试时,发现并不是每次都能收到通知,具体什么原因还不是清楚
    最近看到论坛上statusUpdateNotification not getting renewal notification type,感觉有点坑,这些通知类型,不是字面上理解的意思
    If you read the description of the RENEWAL event, you will note - "Automatic renewal was successful for an expired subscription. Check Subscription Expiration Date to determine the next renewal date and time." In general, iTunes will attempt to charge the user account a day before an auto-renewing subscription is scheduled to expire. If the renewal is successful, there is no server-to server notification because the auto-renewing subscription did not enter into an expired state. However, in the few cases that iTunes is unable to renew the subscription (generally there was a connection problem with the credit card server) and the auto-renewing subscription is not renewed before the expiration_date passes, the auto-renewing subscription is technically considered “expired”. However, iTunes will still continue to attempt to renew the subscription. It iTunes is successful, then the “RENEWAL” event is sent. for this reason, the advice is presented - “Check Subscription Expiration Date to determine the next renewal date and time.”
    
SKReceiptRefreshRequest
  1. 可以刷新本地的小票数据,获取到最新的小票数据
  2. 可以看下它和RestoreCompletedTransactions区别

参考资料

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

推荐阅读更多精彩内容