Slide 1

Slide 1 text

What’s new in Google Play Billing potatotips#52 @FOLIO 2018/06/21 @ymnd

Slide 2

Slide 2 text

ࠓ೔ͷ͓඼ॻ͖ • ࠓ೔࿩͢͜ͱ • What’s new in Play Store App • What’s new in Play Billing Library • ࠓ೔࿩͞ͳ͍͜ͱ • What’s new in Play Console • What’s new in Play Billing API • What’s new in Play Billing Test • Getting started with Play Billing Library 2

Slide 3

Slide 3 text

ᶃWhat’s new in Play Store App • ؅ཧը໘ͷมߋ • Discover New • Manage • Backup FOP • ΞϓϦͱͷ࿈ܞ • Deep Link • ղ໿෼ੳͷڧԽ • Cancel Survey 3

Slide 4

Slide 4 text

ᶃ؅ཧը໘ͷมߋ • Discover NewɿఆظߪೖͷϦίϝϯυ 4

Slide 5

Slide 5 text

ᶃ؅ཧը໘ͷมߋ • Manageɿ؅ཧը໘͕࢖͍΍͘͢ͳΓ·ͨ͠ 5

Slide 6

Slide 6 text

ᶃ؅ཧը໘ͷมߋ • ఆظߪೖ৘ใ • ܖ໿ϓϥϯ • ܖ໿ͷߋ৽೔ • ࢧ෷͍৘ใ • ࢧ෷͍ํ๏ͷߋ৽ • ༧උͷࢧ෷͍ํ๏ • ref: Account Hold • ղ໿ͱ࠶։ • RTDN • http://g.co/play/billing-rtdn 6

Slide 7

Slide 7 text

ᶃΞϓϦͱͷ࿈ܞ: Deep Link • https://play.google.com/store/account/subscriptions? sku=XXX&package=YYY • ࠓ·Ͱ͸ΞϓϦ͔Β௚઀؅ཧը໘Λ։͚ͳ͔ͬͨ • ಋઢ͕ඇৗʹ෼͔Γʹ͍͘ • ௚઀ࣗ෼ͷΞϓϦͷఆظߪೖͷ؅ཧը໘ʹભҠՄೳ • ࢧ෷Τϥʔͷमਖ਼΍ղ໿ͳͲ 7

Slide 8

Slide 8 text

ᶃղ໿෼ੳͷڧԽ • Cancel Survey • ղ໿࣌ʹཧ༝Λฉ͘ • PlayConsoleͰ෼ੳ 8

Slide 9

Slide 9 text

ᶄWhat’s new in Play Billing Library: v1.1 • Play Billing Library is updated: 2018/5/7 • ᶃBillingFlowParamsʹproration mode͕ࢦఆͰ͖ΔΑ ͏ʹͳͬͨ • ᶄlaunchBillingFlow()Λߦͬͨͱ͖ʹcallbackʹࣦഊ࣌ ΋Ϩεϙϯε͕౉͞ΕΔΑ͏ʹͳͬͨ 9

Slide 10

Slide 10 text

ᶄproration mode: ൺྫ഑෼ • ఆظߪೖͷΞοϓάϨʔυʗμ΢ϯάϨʔυΛߦ͏ • skuIdΛ৽͍͠঎඼ʹஔ͖׵͑Δ • replaceSkusProrationModeΛ࢖͏ • ैདྷͷreplaceSkusProration͸αϙʔτ͞Εͳ͘ͳͬͨ 10

Slide 11

Slide 11 text

ᶄproration mode 11 val flowParams = BillingFlowParams.newBuilder() .setSku(skuId) .setType(billingType) .setOldSku(oldSkus) .setReplaceSkusProrationMode(replaceSkusProrationMode) .build() public Builder setReplaceSkusProrationMode(@ProrationMode int replaceSkusProrationMode) { this.mReplaceSkusProrationMode = replaceSkusProrationMode; return this; } public Builder setReplaceSkusProration(boolean bReplaceSkusProration) { mParams.mNotReplaceSkusProration = !bReplaceSkusProration; return this; } ☓

Slide 12

Slide 12 text

ᶄproration mode: v1.1 12 /** * Specifies the mode of proration during subscription upgrade/downgrade. This value will only * be effective if oldSkus is set. * *

If you set this to NO_PRORATION, the user does not receive credit or charge, and the * recurrence date does not change. * *

If you set this to PRORATE_BY_TIME, Google Play swaps out the old SKUs and credits the * user with the unused value of their subscription time on a pro-rated basis. Google Play * applies this credit to the new subscription, and does not begin billing the user for the new * subscription until after the credit is used up. * *

If you set this to PRORATE_BY_PRICE, Google Play swaps out the old SKUs and keeps the * recurrence date not changed. User will be charged for the price differences to cover the * time till next recurrence date. * *

Optional: * *

    *
  • To buy in-app item *
  • To create a new subscription *
  • To replace an old subscription *
*/ public Builder setReplaceSkusProrationMode(@ProrationMode int replaceSkusProrationMode) { this.mReplaceSkusProrationMode = replaceSkusProrationMode; return this; }

Slide 13

Slide 13 text

ᶄproration mode: v1.0 13 /** * Specify an optional flag indicating whether the user should be credited for any unused * subscription time on the SKUs they are upgrading or downgrading. * *

If you set this field to false, the user does not receive credit for any unused * subscription time and the recurrence date does not change. Otherwise, Google Play swaps out * the old SKUs and credits the user with the unused value of their subscription time on a * pro-rated basis. Google Play applies this credit to the new subscription, and does not begin * billing the user for the new subscription until after the credit is used up. * *

Optional: * *

    *
  • To buy in-app item *
  • To create a new subscription *
  • To replace an old subscription *
*/ public Builder setReplaceSkusProration(boolean bReplaceSkusProration) { mParams.mNotReplaceSkusProration = !bReplaceSkusProration; return this; }

Slide 14

Slide 14 text

ᶄproration mode: from document • IMMEDIATE_WITH_TIME_PRORATION: default • ঎඼IDͷஔ͖׵͑͸௚ͪʹ༗ޮʹͳ৽͍͠༗ޮظݶ͸ൺྫ഑ ෼ͯ͠ܭࢉ͞ΕɺϢʔβʔʹ੥ٻ͞ΕΔ • IMMEDIATE_AND_CHARGE_PRORATED_PRICE • ঎඼IDͷஔ͖׵͑͸௚ͪʹ༗ޮʹͳΓɺ੥ٻαΠΫϧ͸ಉ͡ ··Ͱɺ࢒Γͷظؒͷྉ͕ۚ՝ۚ͞ΕΔʢupgrade onlyʣ • IMMEDIATE_WITHOUT_PRORATION • ঎඼IDͷஔ͖׵͑͸௚ͪʹ༗ޮʹͳΓɺ੥ٻαΠΫϧ͸ಉ͡ ··Ͱɺ࣍ͷ੥ٻαΠΫϧ࣌ʹ৽͍͠Ձ͕֨ద༻͞ΕΔ 14

Slide 15

Slide 15 text

ᶄproration mode: example • 4/1͔ΒA($2/month)ͷఆظߪೖΛ։࢝͢Δ • Ϣʔβʔ͸B($3/month)ͷϓϥϯʹΞοϓσʔτ͢Δ 15 4/1 5/1 A B

Slide 16

Slide 16 text

ᶄproration mode • IMMEDIATE_WITH_TIME_PRORATION 16 4/1 5/1 A B 4/15 { $1(15days) { $1(10days) 4/26 $3 طʹࢧ෷ͬͨ෼Λॆ౰

Slide 17

Slide 17 text

ᶄproration mode • IMMEDIATE_AND_CHARGE_PRORATED_PRICE 17 4/1 5/1 A B 4/15 { $1(15days) { $1.5(15days) ࠩ෼ͷ+$0.5Λ੥ٻ $3

Slide 18

Slide 18 text

ᶄproration mode • IMMEDIATE_WITHOUT_PRORATION 18 4/1 5/1 A B 4/15 { $2(15days) ௥Ճ੥ٻͳ͘Ҡߦ $3

Slide 19

Slide 19 text

ᶄproration mode • IMMEDIATE_WITH_TIME_PRORATION • ೔ׂΓܭࢉΛߦ͍࢒೔਺෼ͷΫϨδοτΛॆ౰͢Δ • ΫϨδοτΛ࢖͍੾ͬͨΒ࣍ͷఆظߪೖΛ։࢝͢Δ • ৽͍͠ߪೖαΠΫϧͱͳΔ • IMMEDIATE_AND_CHARGE_PRORATED_PRICE • ࢒೔਺෼ఆظߪೖ͢Δͷʹ͍͘Β͔͔Δ͔ܭࢉ͢Δ • ࠓͷΫϨδοτͱൺֱ͠଍Γͳֹ͍Λ௥Ճ੥ٻ͢Δ • ߪೖαΠΫϧ͸ಉ͡ • IMMEDIATE_WITHOUT_PRORATION • ࢒೔਺෼͸௥Ճ੥ٻ͠ͳ͍ • ߪೖαΠΫϧ͸ಉ͡ 19

Slide 20

Slide 20 text

ᶄproration mode • ݱࡏ͸ఆظߪೖͷֹۚΛมߋ͢ΔࡍʹskuIdΛ৽نʹ࡞ ੒͢Δඞཁ͕͋Δ • I/OͰɺskuIdΛมߋ͠ͳͯ͘΋ֹۚมߋͰ͖Δ৽ػೳ͕ ঺հ͞Εͨ 20

Slide 21

Slide 21 text

ᶄprice charge of existing SKU: EAP 21

Slide 22

Slide 22 text

ᶄlaunchBillingFlow calls listener on fail • launchBillingFlow()Λߦͬͨͱ͖ʹcallbackʹࣦഊ࣌΋ Ϩεϙϯε͕౉͞ΕΔΑ͏ʹͳͬͨ • ࠓ·Ͱ͸੒ޭ͔࣌͠listener͕ݺ͹Εͳ͔ͬͨ 22 public interface PurchasesUpdatedListener { void onPurchasesUpdated(@BillingResponse int responseCode, @Nullable List purchases); }

Slide 23

Slide 23 text

ᶄlaunchBillingFlow: v1.0 23 @Override public int launchBillingFlow(Activity activity, BillingFlowParams params) { if (!isReady()) { return BillingResponse.SERVICE_DISCONNECTED; } @SkuType String skuType = params.getSkuType(); String newSku = params.getSku(); // Checking for mandatory params fields if (newSku == null) { BillingHelper.logWarn(TAG, "Please fix the input params. SKU can't be null."); return BillingResponse.DEVELOPER_ERROR; } … }

Slide 24

Slide 24 text

ᶄlaunchBillingFlow: v1.1 24 private int broadcastFailureAndReturnBillingResponse(@BillingResponse int responseCode) { mBroadcastManager.getListener().onPurchasesUpdated(responseCode, /* List= */null); return responseCode; } @Override public int launchBillingFlow(Activity activity, BillingFlowParams params) { if (!isReady()) { return broadcastFailureAndReturnBillingResponse(BillingResponse.SERVICE_DISCONNECTED); } @SkuType String skuType = params.getSkuType(); String newSku = params.getSku(); // Checking for mandatory params fields if (newSku == null) { BillingHelper.logWarn(TAG, "Please fix the input params. SKU can't be null."); return broadcastFailureAndReturnBillingResponse(BillingResponse.DEVELOPER_ERROR); } … }

Slide 25

Slide 25 text

Note • Grow and optimize your subscriptions with new Google Play features • https://youtu.be/x1AYelepG6o • Code samples: library is v1.0 • https://github.com/googlesamples/android-play- billing/tree/master/ClassyTaxi/android/ClassyTaxi 25

Slide 26

Slide 26 text

whoami • twitter:@ymnd, github:@ymnder • Application Engineer • Android ೔ܦిࢠ൛ΞϓϦ • Android ࢴ໘ϏϡʔΞʔΞϓϦ • ೔ܦిࢠͷຊʢిࢠ൛ʣ͸͜͜ʹ͋Γ·͢ • https://goo.gl/7Qd6Dh • ٕज़ϒϩάʹԣॻ͖ͷهࣄΛܝࡌͯ͋͠Γ·͢ • https://hack.nikkei.com/blog 26

Slide 27

Slide 27 text

ఆظߪೖ΍͍͖ͬͯ