Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Promoting IAP対応から学ぶ外部アプリ内課金実装 / Promoting IAP and others

uzzu
April 10, 2019

Promoting IAP対応から学ぶ外部アプリ内課金実装 / Promoting IAP and others

In-tamachi Billing Night 登壇資料
https://billing-night.connpass.com/event/125510/

uzzu

April 10, 2019
Tweet

More Decks by uzzu

Other Decks in Technology

Transcript

  1. Promoting IAP対応から学ぶ
    外部アプリ内課金実装
    @uzzu

    View full-size slide

  2. About me
    @uzzu (GitHub, Twtter, etc…)

    Cookpad Inc.

    ユーザ・決済基盤部 エンジニア


    アプリ内課金とは

    前職(スマホゲーム開発)からの

    お付き合い(iOS/Android)


    https://uzzu.co

    View full-size slide

  3. https://speakerdeck.com/uzzu/xin-gui-apurikai-fa-wozhi-eruyuzajue-ji-ji-pan

    View full-size slide

  4. はとりあえず置いといて、Promoting IAPについて説明します
    外部アプリ内課金実装?????

    View full-size slide

  5. Promoting IAPとは
    •App Storeアプリから

    アプリ内課金アイテムの購入を
    実施する為の機能

    View full-size slide

  6. Promoting IAPとは

    View full-size slide

  7. Promoting IAPとは
    未インストールユーザも利用できる

    View full-size slide

  8. Promoting IAPに対応するには
    •まずはアプリ内課金実装をする
    •protocol SKPaymentTransactionObserverの

    optional func paymentQueue(_ queue: SKPaymentQueue,

    shouldAddStorePayment: SKPayment,

    for: SKProduct) -> Bool

    を実装する
    •AppStore ConnectでPromoting IAP用の商品設定をする
    •(任意) SKProductPromotionControllerで表示制御をする
    ※正確な情報はApp内課金プログラミングガイドを参照してね

    View full-size slide

  9. テスト
    itms-services://

    ?action=purchaseIntent

    &bundleId={Bundle Identifier}

    &productIdentifier={Product Identifier}
    ※正確な情報はApp内課金プログラミングガイドを参照してね

    View full-size slide

  10. shouldAddStorePayment
    public func paymentQueue(
    _ queue: SKPaymentQueue,
    shouldAddStorePayment payment: SKPayment,
    for product: SKProduct) -> Bool {
    return true // PaymentQueueʹੵ·ΕΔ
    }
    最短実装。だがしかし…

    View full-size slide

  11. 俺たちには利用規約がある
    •return trueとしてしまうと、アプリ遷移後にすぐに

    IAP決済処理が走ってしまう

    (正確にはSKPaymentQueue#add後、任意のタイミング)
    •利用規約に同意してもらうタイミングがない

    アプリ内課金商品によっては年齢確認も必要
    •利用規約がなくても、アプリの初期化処理はしばしある

    その後に処理するようにしないといけない

    View full-size slide

  12. どうする?
    // shouldAddStorePaymentͷύϥϝʔλΛ࣋ͭstructΛ༻ҙ
    public struct PromotingPurchasePayment {
    public var product: SKProduct
    public var payment: SKPayment
    init(payment: SKPayment, product: SKProduct) {
    assert(payment.productIdentifier == product.productIdentifier)
    self.payment = payment
    self.product = product
    }
    }
    // Promoting IAPͷ৘ใΛஷΊΔprotocol
    public protocol PromotingPurchasePaymentHolder {
    func add(_ storePayment: StorePayment)
    func pendingPayments() -> [StorePayment]
    func consume(_ storePayment: StorePayment)
    }

    View full-size slide

  13. どうする?
    let holder: PromotingPurchasePaymentHolder
    public func paymentQueue(
    _ queue: SKPaymentQueue,
    shouldAddStorePayment payment: SKPayment,
    for product: SKProduct) -> Bool {
    // ͱΓ͋͑ͣஷΊΔ!!
    holder.add(
    StorePayment(payment: payment, product: product)
    )
    return false
    }

    View full-size slide

  14. どうする?
    •アプリ初期化後、トップ画面の
    ViewController上で

    未処理のPromoting IAPがあれば

    決済処理開始
    •クックパッドでは

    トップ画面とは別の

    UIViewControllerに遷移して処理している
    •決済処理が終わったらHolderから破棄

    View full-size slide

  15. Promoting IAPまとめ
    •超カジュアル実装ならtrue
    •アプリ初期化処理や利用規約があるならfalse
    •個人プロダクトでないアプリであれば

    だいたいfalseになるんじゃないか?
    •貯めて特定画面で処理が柔軟

    View full-size slide

  16. Promoting IAPだけが
    特別?

    View full-size slide

  17. アプリ外に決済起点のある
    アプリ内課金機能は
    他にもある
    (実際に決済が走っているかはさておき)

    View full-size slide

  18. 例えば
    •Promotion Code(iOS, Android)
    •Google Play Points(Android)

    View full-size slide

  19. 一旦貯めるのは柔軟
    •iOSの場合はこれまでにお話した通り
    •Google Play(Android)においては特に貯めずとも

    BillingClient#queryPurchases を

    特定画面で呼び出して購入状況を確認すれば良い

    iOSと違い決済は既に走っているので

    決済後の処理(いわゆる復元処理)をやれば良さそう

    View full-size slide

  20. まとめ
    •アプリ外部からのトリガーによるアプリ内課金を処理する前に

    (時には)サービス利用規約への同意が必要(利用規約の更新もあるよね)

    その後に

     都度課金であれば(時には)年齢確認が必要

     定期購読であれば定期購読サービス利用規約の同意が必要
    •どのケースにおいても

    プラットフォームからの通知は貯めておいて

    特定画面(アプリ起動後のTOP画面等)でまとめて処理すると

    柔軟で良い (Realtime notificationが使えるなら使いたいが未検証)

    View full-size slide


  21. ありがとうございました

    View full-size slide