$30 off During Our Annual Pro Sale. View Details »

[Android 11 Meetups] Google Play Commerce からのアップデート / Android 11 Meetups Google Play Commerce

syarihu
August 25, 2020

[Android 11 Meetups] Google Play Commerce からのアップデート / Android 11 Meetups Google Play Commerce

Android 11 Meetupsの「アプリ配信と収益化」で発表した資料です。

Android 11 Meetups - JP
https://developersonair.withgoogle.com/events/a11meetups-jp

Android11 Meetups - アプリ配信と収益化
https://gdg-tokyo.connpass.com/event/186603/

syarihu

August 25, 2020
Tweet

More Decks by syarihu

Other Decks in Technology

Transcript

  1. Google Play Commerce
    からのアップデート
    Taichi Sato / syarihu
    Android Engineer
    Money Forward Inc.

    View Slide

  2. 最近のプラットフォームアップ
    デート
    購入画面のアップデート
    メールリマインダー
    アンインストール時の通知

    View Slide

  3. 違反してない例
    明確なオファー条件と請求頻度、
    価格を備えたアプリ
    違反の例
    隠されたオファー条件、
    不明確な請求頻度と価格のアプリ
    詳細はこちら:
    goo.gle/play-trust-blog
    最近のプラットフォームアップ
    デート

    View Slide

  4. 定期購入のカスタムプロモーションコード

    View Slide

  5. 定期購入のカスタムプロモーションコード

    View Slide

  6. 定期購入の価値を伝える

    View Slide

  7. 定期購入の価値を伝える

    View Slide

  8. 価格値下げ時のオプトインを省略

    View Slide

  9. 定期購入のリテンション

    View Slide

  10. Account Hold
    & Grace Period Pause
    定期購入のリテンション

    View Slide

  11. 開発者がAccount Holdにより得られた効果
    8%
    非自発的解約の
    減少
    35%
    支払い失敗からの復
    帰率

    View Slide

  12. 定期購入に関する変更点
    設定 現在 2020年11月1日以降
    Account Hold デフォルト: OFF 必須
    Restore デフォルト: ON 必須
    Pause デフォルト: OFF デフォルト: ON
    Resubscribe(新機能) デフォルト: OFF デフォルト: ON

    View Slide

  13. Grace Period(猶予期間)

    View Slide

  14. Grace Period(猶予期間)
    定期購入の更新時にクレジットカードの期限切
    れなどで支払いに失敗した場合に入る期間
    猶予期間中はユーザーは引き続き定期購入に
    より提供されている機能を利用可能

    View Slide

  15. Grace Period(猶予期間)

    View Slide

  16. 定期購入再購入
    t1 t2
    Is SKU returned in
    queryPurchases()?
    yes
    SUBSCRIPTION_IN_
    GRACE_PERIOD
    Real-time Developer
    Notifications
    Fields in server API,
    Purchase.subscriptions
    expiryTimeMillis:
    time of next renewal (t2)
    paymentState: 1
    autoRenewing: true
    SUBSCRIPTION
    _RENEWED
    定期購入有効期間

    View Slide

  17. 定期購入再購入
    継続課金に失敗
    猶予期間開始
    t1 t2
    Is SKU returned in
    queryPurchases()?
    yes
    SUBSCRIPTION_IN_
    GRACE_PERIOD
    Real-time Developer
    Notifications
    expiryTimeMillis:
    time of next renewal (t2)
    paymentState: 1
    autoRenewing: true
    SUBSCRIPTION
    _RENEWED
    定期購入有効期間
    Fields in server API,
    Purchase.subscriptions

    View Slide

  18. 定期購入再購入
    継続課金に失敗
    猶予期間開始
    猶予期間
    (サービスは継続利用可能)
    t1 t2
    Is SKU returned in
    queryPurchases()?
    yes yes
    SUBSCRIPTION_IN_
    GRACE_PERIOD
    Real-time Developer
    Notifications
    expiryTimeMillis:
    time of next renewal (t2)
    paymentState: 1
    autoRenewing: true
    expiryTimeMillis:
    time of grace period end (t3)
    paymentState: 0
    autoRenewing: true
    SUBSCRIPTION
    _RENEWED
    定期購入有効期間
    t3
    Fields in server API,
    Purchase.subscriptions

    View Slide

  19. 定期購入再購入
    継続課金に失敗
    猶予期間開始
    猶予期間
    (サービスは継続利用可能)
    t1 t2 t3
    Is SKU returned in
    queryPurchases()?
    yes yes no
    定期購入
    自動キャンセル
    SUBSCRIPTION_IN_
    GRACE_PERIOD
    Real-time Developer
    Notifications
    expiryTimeMillis:
    time of next renewal (t2)
    paymentState: 1
    autoRenewing: true
    expiryTimeMillis:
    time of grace period end (t3)
    paymentState: 0
    autoRenewing: true
    SUBSCRIPTION
    _CANCELED
    SUBSCRIPTION
    _RENEWED
    定期購入有効期間
    Fields in server API,
    Purchase.subscriptions

    View Slide

  20. (猶予期間)
    猶予期間に入ったらメールやPlayストアアプリか
    らユーザーに通知はされるが、アプリ上からも通
    知や支払いを促す表示を行うとより効果的
    猶予期間は今回は必須の対応ではないが、非
    自発的な解約を防ぐためには有効な手段
    Account Holdを有効にするタイミングで一緒に
    有効にしておくのがおすすめ

    View Slide

  21. Account Hold(アカウントの一時停止)

    View Slide

  22. (アカウントの一時停止)
    定期購入の更新時にクレジットカードの期限切
    れなどで支払いに失敗した場合になる状態
    猶予期間が有効の場合は猶予期間後にアカウ
    ントの一時停止状態になる
    猶予期間との違いは、定期購入サービスは利用
    できないこと

    View Slide

  23. 2020年11月1日から: 必須
    現在: デフォルトOFF
    (アカウントの一時停止)

    View Slide

  24. t1 t2
    Is SKU returned in
    queryPurchases()?
    yes
    Real-time
    Developer
    Notifications
    Fields in server API,
    Purchase.subscriptions
    expiryTimeMillis:
    time of next renewal (t2)
    paymentState: 1
    autoRenewing: true
    SUBSCRIPTION
    _RENEWED
    定期購入有効期間
    定期購入再購入

    View Slide

  25. 猶予期間
    (サービスは継続利用可能)
    t1 t2 t3
    Is SKU returned in
    queryPurchases()?
    yes yes
    SUBSCRIPTION_IN_
    GRACE_PERIOD
    Real-time
    Developer
    Notifications
    Fields in server API,
    Purchase.subscriptions
    expiryTimeMillis:
    time of next renewal (t2)
    paymentState: 1
    autoRenewing: true
    expiryTimeMillis:
    time of grace period end (t3)
    paymentState: 0
    autoRenewing: true
    SUBSCRIPTION
    _ON_HOLD
    継続課金に失敗
    アカウントの一時停止開始
    SUBSCRIPTION
    _RENEWED
    定期購入有効期間
    定期購入再購入
    継続課金に失敗
    猶予期間開始

    View Slide

  26. 猶予期間
    (サービスは継続利用可能)
    t1 t2 t3
    Is SKU returned in
    queryPurchases()?
    yes yes
    SUBSCRIPTION_IN_
    GRACE_PERIOD
    Real-time
    Developer
    Notifications
    Fields in server API,
    Purchase.subscriptions
    expiryTimeMillis:
    time of next renewal (t2)
    paymentState: 1
    autoRenewing: true
    expiryTimeMillis:
    time of grace period end (t3)
    paymentState: 0
    autoRenewing: true
    アカウントの一時停止
    (サービスは利用不可)
    expiryTimeMillis:
    time of grace period end (t3)
    paymentState: 0
    autoRenewing: true
    t4
    no
    SUBSCRIPTION
    _ON_HOLD
    SUBSCRIPTION
    _RENEWED
    定期購入有効期間
    定期購入再購入
    継続課金に失敗
    猶予期間開始
    継続課金に失敗
    アカウントの一時停止開始

    View Slide

  27. 猶予期間
    (サービスは継続利用可能)
    t1 t2 t3
    Is SKU returned in
    queryPurchases()?
    yes yes no
    定期購入
    自動キャンセル
    SUBSCRIPTION_IN_
    GRACE_PERIOD
    Real-time
    Developer
    Notifications
    Fields in server API,
    Purchase.subscriptions
    expiryTimeMillis:
    time of next renewal (t2)
    paymentState: 1
    autoRenewing: true
    expiryTimeMillis:
    time of grace period end (t3)
    paymentState: 0
    autoRenewing: true
    SUBSCRIPTION
    _CANCELED
    アカウントの一時停止
    (サービスは利用不可)
    expiryTimeMillis:
    time of grace period end (t3)
    paymentState: 0
    autoRenewing: true
    t4
    no
    SUBSCRIPTION
    _ON_HOLD
    SUBSCRIPTION
    _RENEWED
    定期購入有効期間
    定期購入再購入
    継続課金に失敗
    猶予期間開始
    継続課金に失敗
    アカウントの一時停止開始

    View Slide

  28. アカウントの一時停止状態では購入情報が取得
    できず、定期購入サービスの有効期間も切れて
    いるため、課金していないのとほぼ同じ状態
    他プラットフォームで二重課金されないように、
    アカウントの一時停止に入ったときと解決したと
    きに、サービス側で検知できるようになっている
    必要がある
    (アカウントの一時停止)

    View Slide

  29. サービス側で課金状態の変更を自動で検知でき
    るようになっていれば、アカウントの一時停止の
    有効化は可能
    (アカウントの一時停止)

    View Slide

  30. メールやPlayストアアプリから通知はされるが、
    アプリ上からもアカウントの一時停止状態である
    ことを通知し、支払いを促す表示を行うとより効
    果的
    アカウントの一時停止の検知はアプリから行え
    ないため、サーバーとの連携は必須
    (アカウントの一時停止)

    View Slide

  31. Restore(アカウントの復元)

    View Slide

  32. (アカウントの復元)
    ユーザーが自発的にキャンセルした定期購入
    (解約予約)が実際に解約されるまでの間に、
    ユーザーが解約予約をキャンセルできる機能
    解約予約のキャンセルはGoogle Play
    Subscriptions Centerから行える
    RestoreはResubscribeの機能の一部
    2020年11月1日から: 必須
    現在: デフォルトON

    View Slide

  33. t1
    Is SKU returned in
    queryPurchases()?
    yes
    Real-time
    Developer
    Notifications
    Fields in server API,
    Purchase.subscriptions
    expiryTimeMillis:
    time of next renewal (t3)
    paymentState: 1
    autoRenewing: true
    expiryTimeMillis:
    time of grace period end (t3)
    paymentState: 1
    autoRenewing: true
    SUBSCRIPTION
    _RENEWED
    定期購入有効期間
    定期購入再購入
    t3

    View Slide

  34. 解約予約期間
    (この間は復元可能)
    t1 t2 t3
    Is SKU returned in
    queryPurchases()?
    yes yes
    SUBSCRIPTION
    _CANCELED
    Real-time
    Developer
    Notifications
    Fields in server API,
    Purchase.subscriptions
    expiryTimeMillis:
    time of next renewal (t3)
    paymentState: 1
    autoRenewing: true
    expiryTimeMillis:
    time of grace period end (t3)
    paymentState: 1
    autoRenewing: false
    SUBSCRIPTION
    _EXPIRED
    SUBSCRIPTION
    _RENEWED
    定期購入有効期間
    定期購入再購入
    ユーザーが自発的に解約
    (解約予約)

    View Slide

  35. 解約予約期間
    (この間は復元可能)
    t1 t2 t3
    Is SKU returned in
    queryPurchases()?
    yes yes
    SUBSCRIPTION
    _CANCELED
    Real-time
    Developer
    Notifications
    Fields in server API,
    Purchase.subscriptions
    expiryTimeMillis:
    time of next renewal (t3)
    paymentState: 1
    autoRenewing: true
    expiryTimeMillis:
    time of grace period end (t3)
    paymentState: 1
    autoRenewing: false
    定期購入解約
    expiryTimeMillis:
    time of grace period end (t3)
    paymentState: 1
    autoRenewing: false
    no
    SUBSCRIPTION
    _EXPIRED
    SUBSCRIPTION
    _RENEWED
    定期購入有効期間
    定期購入再購入
    ユーザーが自発的に解約
    (解約予約)

    View Slide

  36. 定期購入再購入
    t1
    Real-time Developer
    Notifications
    expiryTimeMillis:
    time of next renewal (t4)
    paymentState: 1
    autoRenewing: true
    SUBSCRIPTION
    _RENEWED
    定期購入有効期間
    Is SKU returned in
    queryPurchases()?
    yes
    t4
    Fields in server API,
    Purchase.subscriptions
    yes
    定期購入再購入

    View Slide

  37. 定期購入再購入
    t1 t2 t4
    SUBSCRIPTION
    _CANCELED
    Real-time Developer
    Notifications
    expiryTimeMillis:
    time of next renewal (t4)
    paymentState: 1
    autoRenewing: true
    expiryTimeMillis:
    time of subscription end (t4)
    paymentState: 1
    autoRenewing: false
    SUBSCRIPTION
    _RENEWED
    定期購入有効期間
    Is SKU returned in
    queryPurchases()?
    yes yes
    SUBSCRIPTION
    _EXPIRED
    解約予約期間
    (この間は復元可能)
    ユーザーが自発的に解約
    (解約予約)
    no
    定期購入解約
    Fields in server API,
    Purchase.subscriptions

    View Slide

  38. 定期購入再購入
    t1 t2 t4
    SUBSCRIPTION
    _CANCELED
    Real-time Developer
    Notifications
    Fields in server API,
    Purchase.subscriptions
    expiryTimeMillis:
    time of next renewal (t4)
    paymentState: 1
    autoRenewing: true
    expiryTimeMillis:
    time of subscription end (t4)
    paymentState: 1
    autoRenewing: false
    SUBSCRIPTION
    _RENEWED
    定期購入有効期間
    Is SKU returned in
    queryPurchases()?
    yes yes
    t3
    SUBSCRIPTION
    _RESTARTED
    解約予約を
    キャンセル
    SUBSCRIPTION
    _RENEWED
    expiryTimeMillis:
    time of next renewal (t4)
    paymentState: 1
    autoRenewing: true
    解約予約期間
    (この間は復元可能)
    ユーザーが自発的に解約
    (解約予約)
    yes

    View Slide

  39. (アカウントの復元)
    Google Play Subscriptions Centerからしか行
    えないことと、Purchase Tokenや定期購入の有
    効期間も変わらないため、基本的には対応しな
    くても問題ない

    View Slide

  40. Resubscribe(定期購入の再開)

    View Slide

  41. (定期購入の再開)
    解約予約した定期購入を再開できる機能
    Resubscribeには3種類のパターンがある

    View Slide

  42. (定期購入の再開)
    ● 解約予約した定期購入の有効期限が切れる前
    ○ アプリ内から定期購入を再開する
    ○ Google Play Subscriptions Centerから定期
    購入を再開する(Restore)
    ● 定期購入の有効期限が切れたあと
    ○ Google Play Subscriptions Centerから最大1
    年の間に同じSKUを再購入する

    View Slide

  43. 有効期限が切れる前
    Restoreとアプリ内から行うResubscribeでは定
    期購入の有効期間が変わらないのは同じ
    アプリ内から行うResubscribeではPurchase
    Tokenが新しく生成されるのがRestoreとの違い

    View Slide

  44. 有効期限が切れる前
    Resubscribeではアプリ内からの再開となるため、
    アプリ内に「再開」ボタンを設置する必要がある
    isAutoRenewingで解約予約中かを判別して導線
    を表示する
    考慮することが増えてしまうため、アプリ内に再開
    導線を出すよりはGoogle Play Subscrition Center
    を開くようにするのがおすすめ
    詳細はこちら:
    developer.android.com/goo
    gle/play/billing/subs#deep-
    link

    View Slide

  45. 有効期限が切れたあと
    Billing Library 2+を使用している場合、ユー
    ザーは定期購入の有効期限が切れてから最大
    1年間、Google Play Subscriptions Centerから
    定期購入を再購入できる
    アプリの外部で行われるアプリ外購入となる
    サービス側でアプリ外購入を検知して、自社
    サーバーで購入情報を処理できるようにしておく
    必要がある

    View Slide

  46. (定期購入の再開)
    2020年11月1日から: デフォルトON
    現在: デフォルトOFF

    View Slide

  47. Pause(定期購入の一時停止)

    View Slide

  48. (定期購入の一時停止)
    ユーザーが一定期間だけ定期購入を一時停止
    できる機能
    一週間から3ヶ月の期間で定期購入を一時停止
    できる
    年間定期購入は一時停止できない

    View Slide

  49. (定期購入の一時停止)
    解約以外の請求を止める選択肢ができた
    海外出張など、一時的に使わないユーザーを
    引き止められる
    ユーザーの自発的な解約を防ぐことが期待でき

    View Slide

  50. 定期購入再購入
    t1 t2
    Real-time Developer
    Notifications
    Fields in server API,
    Purchase.subscription
    s
    expiryTimeMillis:
    time of next renewal (t2)
    autoResumeTimeMillis:
    n/a
    SUBSCRIPTION
    _RENEWED
    Is SKU returned in
    queryPurchases()?
    定期購入
    有効期間

    View Slide

  51. 定期購入再購入
    t1
    Real-time Developer
    Notifications
    Fields in server API,
    Purchase.subscription
    s
    expiryTimeMillis:
    time of next renewal (t2)
    autoResumeTimeMillis:
    n/a
    SUBSCRIPTION
    _RENEWED
    Is SKU returned in
    queryPurchases()?
    SUBSCRIPTION_PAUSE_
    SCHEDULE_CHANGE
    定期購入
    一時停止予約
    定期購入
    有効期間
    expiryTimeMillis:
    time of pause start (t2)
    autoResumeTimeMillis:
    time of pause end (t3)
    t2
    SUBSCRIPTION
    _CANCELED
    定期購入
    一時停止開始

    View Slide

  52. 定期購入再購入
    t1 t2
    SUBSCRIPTION
    _CANCELED
    Real-time Developer
    Notifications
    Fields in server API,
    Purchase.subscription
    s
    expiryTimeMillis:
    time of next renewal (t2)
    autoResumeTimeMillis:
    n/a
    expiryTimeMillis:
    time of pause start (t2)
    autoResumeTimeMillis:
    time of pause end (t3)
    SUBSCRIPTION
    _RENEWED
    Is SKU returned in
    queryPurchases()?
    expiryTimeMillis:
    time of next renewal (t4)
    autoResumeTimeMillis:
    n/a
    SUBSCRIPTION_PAUSE_
    SCHEDULE_CHANGE
    定期購入
    一時停止予約
    t3
    定期購入
    有効期間
    一時停止
    (サービスは利用不可)
    定期購入
    一時停止開始
    定期購入
    有効期間
    SUBSCRIPTION
    _RENEWED
    一時停止終了
    定期購入再購入

    View Slide

  53. 定期購入再購入
    t1 t2
    SUBSCRIPTION
    _CANCELED
    Real-time Developer
    Notifications
    Fields in server API,
    Purchase.subscription
    s
    expiryTimeMillis:
    time of next renewal (t2)
    autoResumeTimeMillis:
    n/a
    expiryTimeMillis:
    time of pause start (t2)
    autoResumeTimeMillis:
    time of pause end (t3)
    SUBSCRIPTION
    _RENEWED
    Is SKU returned in
    queryPurchases()?
    expiryTimeMillis:
    time of pause start (t2)
    autoResumeTimeMillis:
    n/a
    SUBSCRIPTION_PAUSE_
    SCHEDULE_CHANGE
    定期購入
    一時停止予約
    t3
    再購入に失敗
    定期購入の一時停止終了
    アカウントの一時停止開始
    アカウントの一時停止
    (サービスは利用不可)
    定期購入の一時停止
    (サービスは利用不可)
    定期購入
    一時停止開始
    定期購入
    有効期間
    SUBSCRIPTION_
    _ON_HOLD

    View Slide

  54. (定期購入の一時停止)
    2020年11月から: デフォルト ON
    現在: デフォルトOFF

    View Slide

  55. Play Billing Library

    View Slide

  56. AIDLを抽象化した課金ライブラリ
    Play Billingとの接続管理などを内蔵
    アップグレードが簡単
    Recap

    View Slide

  57. 新しい定期購入プロモーション機能
    Purchase attribution
    Kotlin extension、Unity plug-in
    新しいバージョンが利用可能

    View Slide


  58. アップグレードする
    gradleファイルをアップデートする
    compile 'com.android.billingclient:billing:2.0'
    compile 'com.android.billingclient:billing:3.0'
    APIの変更を反映する(リリースノートを参照):
    goo.gle/play-billing-release-notes
    1
    2

    View Slide

  59. 購入を特定のゲーム内キャラクターに関連付ける
    非推奨のdeveloper payloadを回避する

    View Slide

  60. val params = BillingFlowParams.newBuilder()

    View Slide

  61. val params = BillingFlowParams.newBuilder()
    // Specify an obfuscated identifier to uniquely identify the
    // user’s account.
    .setObfuscatedAccountId(obfuscatedAccountId)

    View Slide

  62. val params = BillingFlowParams.newBuilder()
    // Specify an obfuscated identifier to uniquely identify the
    // user’s account.
    .setObfuscatedAccountId(obfuscatedAccountId)
    // Optionally, specify an obfuscated identifier to uniquely
    // identify the character profile with the user’s account.
    .setObfuscatedProfileId(obfuscatedProfileId)

    View Slide

  63. val params = BillingFlowParams.newBuilder()
    // Specify an obfuscated identifier to uniquely identify the
    // user’s account.
    .setObfuscatedAccountId(obfuscatedAccountId)
    // Optionally, specify an obfuscated identifier to uniquely
    // identify the character profile with the user’s account.
    .setObfuscatedProfileId(obfuscatedProfileId)
    billingClient.launchBillingFlow(activity, params.build())

    View Slide

  64. // After a successful purchase
    val accountIds = purchase.getAccountIdentifiers()
    accountIds.getObfuscatedAccountId()
    accountIds.getObfuscatedProfileId()

    View Slide

  65. のサポート
    予測可能なリリース
    2年間のサポート期間
    ユーザーは新しい支払いオプションやUX、パ
    フォーマンス、セキュリティアップデートなどを受
    け取れるメリットがある
    すべてのユーザーにとってより良い体験を

    View Slide

  66. のサポート
    Billing Library 2+では、acknowledgeや
    Pending transactionsなどの新しい仕組みが導
    入されている
    AIDLやBilling Library 1+からアップデートする際
    には注意
    すべてのユーザーにとってより良い体験を

    View Slide

  67. 要件
    June 3 Nov. 1 Aug. 2 Nov. 1
    Billing Library
    version
    requirements
    Billing Library 3
    Launched
    New apps
    require
    Billing Library 3+
    Updates require
    Billing Library
    3+
    2020 2021

    View Slide

  68. June 3 Nov. 1 Aug. 2 Nov. 1
    Billing Library
    version
    requirements
    Billing Library 3
    Launched
    New apps
    require
    Billing Library 3+
    Updates require
    Billing Library
    3+
    2020 2021
    All subscription apps require
    - Account hold
    - Restore
    By default, all subscription apps have
    - Pause
    - Resubscribe
    Subscription
    featurerequirem
    ents
    要件

    View Slide

  69. 新しいドキュメント:
    goo.gle/play-commerce

    View Slide

  70. 詳細はこちら:
    link.medium.com/p52eGFEj58

    View Slide

  71. 詳細はこちら:
    youtu.be/UjZxICZXOa8

    View Slide

  72. Thank you

    View Slide