React-native-iap: DEFERRED ๋ชจ๋“œ๋กœ Android์—์„œ ๊ตฌ๋…์„ ์—…๊ทธ๋ ˆ์ด๋“œ / ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œ ํ•  ๋•Œ ์˜ค๋ฅ˜ ๋ฐœ์ƒ

์— ๋งŒ๋“  2019๋…„ 12์›” 28์ผ  ยท  31์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: dooboolab/react-native-iap

react-native-iap ๋ฒ„์ „

4.3.3

๋ฐ˜์‘ ๋„ค์ดํ‹ฐ๋ธŒ ๋ฒ„์ „

0.59.10

์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ํ”Œ๋žซํผ (IOS ๋˜๋Š” Android ๋˜๋Š” ๋‘˜ ๋‹ค?)

๊ธฐ๊ณ„์  ์ธ์กฐ ์ธ๊ฐ„

์˜ˆ์ƒ๋˜๋Š” ํ–‰๋™

DEFERRED ๋ชจ๋“œ๋กœ ๊ตฌ๋…์„ ์—…๊ทธ๋ ˆ์ด๋“œ / ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œ ํ•  ๋•Œ ๊ตฌ๋งค ์—…๋ฐ์ดํŠธ ๋ฆฌ์Šค๋„ˆ๋ฅผ ์ƒˆ ํŠธ๋žœ์žญ์…˜ ์˜์ˆ˜์ฆ๊ณผ ํ•จ๊ป˜ ํ˜ธ์ถœํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์‹ค์ œ ํ–‰๋™

๊ตฌ๋งค ์˜ค๋ฅ˜ ๋ฆฌ์Šค๋„ˆ๊ฐ€ ๋‹ค์Œ ์˜ค๋ฅ˜์™€ ํ•จ๊ป˜ ํ˜ธ์ถœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

{๋ฉ”์‹œ์ง€ : '๊ตฌ๋งค๊ฐ€ null์ž…๋‹ˆ๋‹ค.',
์ฝ”๋“œ : 'OK',
debugMessage : '',
responseCode : 0}

ํ…Œ์ŠคํŠธ ๋œ ํ™˜๊ฒฝ (์—๋ฎฌ๋ ˆ์ดํ„ฐ? ์‹ค์ œ ์žฅ์น˜?)

์‹ค์ œ ์žฅ์น˜-์ƒŒ๋“œ ๋ฐ•์Šค

ํ–‰๋™์„ ์žฌํ˜„ํ•˜๋Š” ๋‹จ๊ณ„

1. RNIap.requestSubscription (sku)์œผ๋กœ ๊ตฌ๋…์„ ๊ตฌ๋งคํ•˜๋ฉด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

2. RNIap.requestSubscription (newSku, false, sku, 4)์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ๋…์„ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๊ฑฐ๋‚˜ ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œํ•ฉ๋‹ˆ๋‹ค. (4๋Š” ์ง€์—ฐ๋œ ๋น„๋ก€ ๋ฐฐ๋ถ„ ๋ชจ๋“œ์ž…๋‹ˆ๋‹ค.) Google Play ๊ฒฐ์ œ ๋Œ€ํ™” ์ƒ์ž์— ๊ตฌ๋… ์š”๊ธˆ์ œ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ์Œ์„ ํ‘œ์‹œํ•˜๊ณ  ์ด์— ๋Œ€ํ•œ ์•Œ๋ฆผ ์ด๋ฉ”์ผ์„ Google Play์—์„œ ๋ฐ›๊ฒŒ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์œ„์—์„œ ์–ธ๊ธ‰ ํ•œ ์˜ค๋ฅ˜์™€ ํ•จ๊ป˜ ์˜ค๋ฅ˜ ๋ฆฌ์Šค๋„ˆ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

3. RNIap.requestSubscription (newSku, false, sku, 4)๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•˜๋ฉด Google Play ๊ฒฐ์ œ ๋Œ€ํ™” ์ƒ์ž์—์„œ ๊ตฌ๋… ์š”๊ธˆ์ œ๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๋ฉ”์‹œ์ง€๊ฐ€ ํ‘œ์‹œ๋˜๊ณ  ๋‹ค์Œ ์˜ค๋ฅ˜์™€ ํ•จ๊ป˜ ์˜ค๋ฅ˜ ๋ฆฌ์Šค๋„ˆ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

{message : 'Google์—์„œ ๊ฒฐ์ œ ์—ฐ๊ฒฐ์— ๋ฌธ์ œ๊ฐ€ ์žˆ์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.',
์ฝ”๋“œ : 'E_DEVELOPER_ERROR',
debugMessage : '',
responseCode : 5}

ํ•˜์ง€๋งŒ ๋•Œ๋•Œ๋กœ Google Play ๊ฒฐ์ œ ๋Œ€ํ™” ์ƒ์ž์— ์ฃผ๋ฌธ์ด ์ฒ˜๋ฆฌ ์ค‘์ด๋ฉฐ ์ œํ’ˆ์ด ๊ณง ๋ฐฐ์†ก ๋  ๊ฒƒ์ด๋ผ๊ณ  ํ‘œ์‹œ๋˜๋ฉฐ ์˜ค๋ฅ˜ ๋ฆฌ์Šค๋„ˆ๊ฐ€ ๋‹ค์Œ ์˜ค๋ฅ˜์™€ ํ•จ๊ป˜ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

{message : '์ด๋ฏธ์ด ํ•ญ๋ชฉ์„ ์†Œ์œ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.',
์ฝ”๋“œ : 'E_ALREADY_OWNED',
debugMessage : '',
responseCode : 7}

๋‚˜๋Š” ์ด๊ฒƒ์ด 2 ๋‹จ๊ณ„์˜ ๊ฑฐ๋ž˜๊ฐ€ ์Šน์ธ๋˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ 2 ๋‹จ๊ณ„์—์„œ๋Š” ์˜์ˆ˜์ฆ์ด ๋ฐ˜ํ™˜๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ํ™•์ธํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๐Ÿ•ต๏ธโ€โ™‚๏ธ need more investigation ๐Ÿ™ help wanted ๐Ÿค– android

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ๊ณ„ํš์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋ชจ๋“  31 ๋Œ“๊ธ€

๊ตฌ๋…์„ ์—…๊ทธ๋ ˆ์ด๋“œ / ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œ ํ•œ ํ›„ getAvailablePurchases ๋กœ ์ „ํ™” ํ•ด๋ณด์„ธ์š”.
doc , The list of Purchase objects in onPurchasesUpdated() does not contain paused subscriptions. ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๋„์›€์ด๋˜๊ธฐ๋ฅผ ํฌ๋งํ•˜๋Š” ๋งค์šฐ ํž˜๋“ ์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์‹œ๋ จ๊ณผ ํ† ๋ก ์„ ์ž์œ ๋กญ๊ฒŒ ๋– ๋‚˜์‹ญ์‹œ์˜ค.

๊ตฌ๋…์„ ์—…๊ทธ๋ ˆ์ด๋“œ / ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œ ํ•œ ํ›„ getAvailablePurchases ()๋ฅผ ์‹œ๋„ํ–ˆ์ง€๋งŒ ์•ˆํƒ€๊น๊ฒŒ๋„ ์›๋ž˜ ๊ตฌ๋งค์˜ ๊ฑฐ๋ž˜ ์˜์ˆ˜์ฆ ๋งŒ ๋ฐ˜ํ™˜ ๋œ ๋ฐฐ์—ด์— ์žˆ์Šต๋‹ˆ๋‹ค.

RNIap v2.3.19 ๋ฐ v2.5.5๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž‘๋™ํ•˜๋ฉฐ, ๊ตฌ๋…์„ ์—…๊ทธ๋ ˆ์ด๋“œ / ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œ ํ•  ๋•Œ buySubscription ()์ด ์ƒˆ ์˜์ˆ˜์ฆ์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ ๋” ๋‚˜์€ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ๋ชจ๋ธ์„ ๊ฐ€์ง„ v3 ๋˜๋Š” v4๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์€ Android ๊ตฌ๋… ์—…๊ทธ๋ ˆ์ด๋“œ / ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œ ์ž‘๋™ ๋ฐฉ์‹๊ณผ ์—…๊ทธ๋ ˆ์ด๋“œ / ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œ ํ›„ ์ƒˆ ์˜์ˆ˜์ฆ์ด ํ•„์š”ํ•œ ์ด์œ ๋ฅผ ์„ค๋ช…ํ•˜๋Š” ์ฐธ์กฐ ๋ฌธ์„œ ์ž…๋‹ˆ๋‹ค.

@ howg0924 ํ™•์ธํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. v2 ๋ฐ ํ˜„์žฌ ๋ฒ„์ „๊ณผ์˜ ์ฐจ์ด์ ์„ ๋น„๊ตํ•˜๊ณ ์ด ๋ฌธ์ œ๋ฅผ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

์ฃผ๋ง์— # 893์—์„œ ์ฝ”๋“œ๋ฅผ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค.
์ƒˆ ์—…๋ฐ์ดํŠธ๋Š” 4.4.0 ๋ฉ๋‹ˆ๋‹ค.

[email protected] ๋ฒ„์ „์„ ์นœ์ ˆํ•˜๊ฒŒ ํ…Œ์ŠคํŠธ ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

@hyochan ๋ฐฉ๊ธˆ 4.4.0-rc.1์„ ์‹œ๋„ํ–ˆ์ง€๋งŒ ์ƒํ™ฉ์€ ์—ฌ์ „ํžˆ โ€‹โ€‹๋™์ผํ•ฉ๋‹ˆ๋‹ค.

RNIap.requestSubscription (oldSku, false, newSku 4)๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์—…๊ทธ๋ ˆ์ด๋“œ / ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œ๋ฅผ ์™„๋ฃŒํ•˜๋ฉด ๋‹ค์Œ ์˜ค๋ฅ˜์™€ ํ•จ๊ป˜ ์˜ค๋ฅ˜ ๋ฆฌ์Šค๋„ˆ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

{๋ฉ”์‹œ์ง€ : '๊ตฌ๋งค๊ฐ€ null์ž…๋‹ˆ๋‹ค.',
์ฝ”๋“œ : 'OK',
debugMessage : '',
responseCode : 0}

๊ทธ๋ฆฌ๊ณ  getAvailablePurchases ()๋Š” ์˜ค๋ž˜๋œ ์˜์ˆ˜์ฆ ๋งŒ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

๋””๋ฒ„๊น…ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด @ howg0924 android , ๋‚˜๋Š” ๋‹น์‹ ์ด ์–ด๋–ค ํผํŒ… ํ…Œ์ŠคํŠธ๋ฅผ ํฌ๋ง Log.d ํ•˜๊ณ  ํ†ต๊ณผํ•˜๋ฉด ๋ณผ if ์˜ ์กฐ๊ฑด buyItemByType . ๊ทธ๊ฒŒ ๊ฐ€๋Šฅํ• ๊นŒ์š”? ๋‚˜๋Š” ๊ทธ๋“ค์ด ์–ด๋–ป๊ฒŒ ์‹คํ–‰๋˜๊ณ  ์žˆ๋Š”์ง€๋ณด๊ณ  ์‹ถ๋‹ค.

@ howg0924 ์•„ ์ž ๊น ~! ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌ ํ•œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ณง ์—ฐ๋ฝ ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

@ howg0924 4.4.0-rc.2 ์‹œ๋„ํ•ด ์ฃผ ์‹œ๊ฒ ์–ด์š” ? ์ด๋ฒˆ์—๋Š” ํšจ๊ณผ๊ฐ€์žˆ์„ ๊ฒƒ ๊ฐ™์•„์š”.

@hyochan 4.4.0-rc.2 ๋นŒ๋“œ ์‹คํŒจ :

RNIapModule.java:436: error: incompatible types: SkuDetails cannot be converted to String:
   builder.setOldSku(selectedOldSku);
                     ^

@hyochan 4.4.0-rc.1์˜ buyItemByType ()์„ ๋ชจ๋‹ˆํ„ฐ๋งํ–ˆ์Šต๋‹ˆ๋‹ค. ์—…๊ทธ๋ ˆ์ด๋“œ / ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œ ํ•  ๋•Œ ๋‹ค์Œ์„ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.DEFERRED);

๋˜ํ•œ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

BillingResult billingResult = billingClient.launchBillingFlow(activity, flowParams);

ํ๋ฆ„ / ๋ฐ์ดํ„ฐ๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋ง / ๋คํ”„ ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

(์ผ๋ถ€ ์˜คํ•ด๋กœ ์‚ญ์ œ)

@ howg0924 env ๋””๋ฒ„๊น…์„ ์ž˜ํ•˜์ง€ ๋ชปํ•ด์„œ ์‹ค์ˆ˜๋ฅผ ํ•ด์„œ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. 4.4.0-rc.3 ๋˜๋Œ ๋ ธ์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ๊ฐ€ ๊ฐ€์žฅ ์ค‘์š”ํ•œ builder.setOldSku(oldSku) ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

2.5.5์™€ ๋น„๊ต ํ•œ ๊ฒฐ๊ณผ 2.5.5๊ฐ€

builder.setReplaceSkusProrationMode (BillingFlowParams.ProrationMode.DEFERRED);

DEFERRED ๋ชจ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ.

๊ทธ๋ž˜์„œ 4.4.0-rc.1์—์„œ์ด ์ค„์„ ์ œ๊ฑฐํ•˜๋ ค๊ณ ํ•˜๋Š”๋ฐ, ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค! ํ•˜์ง€๋งŒ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

1. ํ˜„์žฌ ์ž‘์—…์ค‘์ธ ๋น„๋ก€ ๋ฐฐ๋ถ„ ๋ชจ๋“œ.
2. setReplaceSkusProrationMode ()์— ์˜ํ•ด DEFERRED ๋ชจ๋“œ๋กœ ์„ค์ •ํ•˜๋ฉด ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ์ด์œ 

        if (prorationMode != null && prorationMode != -1) {
          if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE) {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE);
            if (type.equals(BillingClient.SkuType.SUBS) == false) {
              String debugMessage = "IMMEDIATE_AND_CHARGE_PRORATED_PRICE for proration mode only works in subscription purchase.";
              WritableMap error = Arguments.createMap();
              error.putString("debugMessage", debugMessage);
              error.putString("code", PROMISE_BUY_ITEM);
              error.putString("message", debugMessage);
              sendEvent(reactContext, "purchase-error", error);
              promise.reject(PROMISE_BUY_ITEM, debugMessage);
              return;
            }
          } else if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_WITHOUT_PRORATION) {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_WITHOUT_PRORATION);
          } else if (prorationMode == BillingFlowParams.ProrationMode.DEFERRED) {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.DEFERRED);
          } else if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_WITH_TIME_PRORATION) {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_WITH_TIME_PRORATION);
          } else {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.UNKNOWN_SUBSCRIPTION_UPGRADE_DOWNGRADE_POLICY);
          }
        }

ํ˜„์žฌ ์œ„์™€ ๊ฐ™์ด ProrationMode ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด DEFERRED ์ œ๊ฑฐํ–ˆ์„ ๋•Œ auto renew subscription ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๊นŒ?

์ฝ”๋“œ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณ€๊ฒฝํ•˜๋ฉด

        if (prorationMode != null && prorationMode != -1) {
          if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE) {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE);
            if (type.equals(BillingClient.SkuType.SUBS) == false) {
              String debugMessage = "IMMEDIATE_AND_CHARGE_PRORATED_PRICE for proration mode only works in subscription purchase.";
              WritableMap error = Arguments.createMap();
              error.putString("debugMessage", debugMessage);
              error.putString("code", PROMISE_BUY_ITEM);
              error.putString("message", debugMessage);
              sendEvent(reactContext, "purchase-error", error);
              promise.reject(PROMISE_BUY_ITEM, debugMessage);
              return;
            }
          } else if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_WITHOUT_PRORATION) {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_WITHOUT_PRORATION);
          } else if (prorationMode == BillingFlowParams.ProrationMode.DEFERRED) {
            // comment following line
            // builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.DEFERRED);
          } else if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_WITH_TIME_PRORATION) {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_WITH_TIME_PRORATION);
          } else {
            builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.UNKNOWN_SUBSCRIPTION_UPGRADE_DOWNGRADE_POLICY);
          }
        }

๊ทธ๋Ÿฐ ๋‹ค์Œ RNIap.requestSubscription (newSku, false, sku, 4 / * DEFERRED ๋ชจ๋“œ * /)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ๋…์„ ์—…๊ทธ๋ ˆ์ด๋“œ / ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. v2.5.5์ฒ˜๋Ÿผ builder.setReplaceSkusProrationMode ()๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์ œ๋กœ ์ž‘๋™ํ•˜๋Š” ๋น„๋ก€ ๋ฐฐ๋ถ„ ๋ชจ๋“œ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ์ฝ”๋“œ๋Š” v2.5.5์—์„œ ๊ฐ€์ ธ์˜จ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

        if (type.equals(BillingClient.SkuType.SUBS) && oldSku != null && !oldSku.isEmpty()) {
          // Subscription upgrade/downgrade
          if (prorationMode != null && prorationMode != 0) {
            builder.setOldSku(oldSku);
            if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE) {
              builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE);
            } else if (prorationMode == BillingFlowParams.ProrationMode.IMMEDIATE_WITHOUT_PRORATION) {
              builder.setReplaceSkusProrationMode(BillingFlowParams.ProrationMode.IMMEDIATE_WITHOUT_PRORATION);
            } else {
              builder.addOldSku(oldSku);
            }
          } else {
            builder.addOldSku(oldSku);
          }
        }

@ howg0924 ํ˜„์žฌ ๋งˆ์Šคํ„ฐ ๋ธŒ๋žœ์น˜ ์ธ 4.3.4 ์—์„œ DEFFERED ์กฐ์ฐจ ์„ค์ •ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์€ ๋งค์šฐ ์ด์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด ์ฝ”๋“œ๋ฅผ 4.4.0+ .

์ด์œ ๊ฐ€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์†Œ์‹์ด ์žˆ์œผ๋ฉด ๋‹ค์‹œ ์˜ค์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๊ด€๋ จ # 391 # 555

์ข‹์•„์š”, ๋” ์‹œ๋„ํ•˜๊ณ  ๋‹ค์‹œ๋ณด๊ณ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๊ด€๋ จ # 707

@hyochan 4.4.0-rc.1์—์„œ ์ถ”๊ฐ€ ํ…Œ์ŠคํŠธ ํ›„ :

IMMEDIATE_WITH_TIME_PRORATION => ์ž‘๋™
IMMEDIATE_AND_CHARGE_PRORATED_PRICE => ์ž‘๋™
IMMEDIATE_WITHOUT_PRORATION => ์ž‘๋™
์ง€์—ฐ๋จ => ์ž‘๋™ํ•˜์ง€ ์•Š์Œ (์ด์œ ๋ฅผ ๋ชจ๋ฆ„)

ํ˜„์žฌ ๋งˆ์Šคํ„ฐ ๋ธŒ๋žœ์น˜ ์ธ 4.3.4์—์„œ DEFFERED๋ฅผ ์„ค์ •ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์€ ๋งค์šฐ ์ด์ƒํ•ฉ๋‹ˆ๋‹ค. ์ด ์ฝ”๋“œ๋ฅผ 4.4.0 ์ด์ƒ์— ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

4.3.0 ์˜

  if (prorationMode != 0 && prorationMode != -1) {
    builder.setReplaceSkusProrationMode(prorationMode);
  }

๊ทธ๋Ÿฌ๋‚˜ ์œ„์˜ ์ฝ”๋“œ๋Š” 2.3.19 ๋ฐ 2.5.5์—๋Š” ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ 2.3.19 ๋ฐ 2.5.5์—์„œ RNIap.requestSubscription (newSku, false, sku, 4 / * DEFERRED * /)์„ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ ์ด์ „์—๋Š” ์ž‘๋™ํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์ง€๋งŒ ์ด์ œ ์‹ค์ œ๋กœ ๊ธฐ๋ณธ IMMEDIATE_WITH_TIME_PRORATION ๋ชจ๋“œ์—์„œ ์ž‘๋™ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ Deffered ๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋ฅผ ์•Œ์•„์•ผํ•ฉ๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ ์ด์œ ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ฐ™์€ ๋ฌธ์ œ๊ฐ€ ์žˆ์ง€๋งŒ ํ–‰๋™์ด ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

requestSubscription(newSku, false, oldSku, 4) ํ˜ธ์ถœํ•˜๋ฉด ์˜ค๋ฅ˜ ์ฝ”๋“œ OK ๋ฐ ๋นˆ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€์™€ ํ•จ๊ป˜ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. Google Play ์ธก์—์„œ ๊ฒฐ์ œ๊ฐ€ ์˜ˆ์ƒ๋Œ€๋กœ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค (์ง€์—ฐ๋จ). ๋‹ค์Œ ๊ตฌ๋… ์š”๊ธˆ์ด ๋ฐœ์ƒํ•˜๋ฉด ์•ฑ ์‹œ์ž‘์‹œ purchaseUpdatedListener ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€๋งŒ ๊ตฌ๋งค๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค ( finishTransaction() ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ). finishTransaction() ๋Š” DEVELOPER_ERROR ์˜ค๋ฅ˜๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

4.4.0 ๋ฐ 4.3.4 ๋ฒ„์ „ ๋ชจ๋‘์—์„œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” @hyochan , https://github.com/dooboolab/react-native-iap/pull/893 ์—์„œ์ด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ ๋œ ๊ฒƒ์œผ๋กœ ํ‘œ์‹œํ–ˆ์ง€๋งŒ react-native-iap์„ ์ตœ์‹  ๋ฒ„์ „์œผ๋กœ ์—…๋ฐ์ดํŠธํ–ˆ์ง€๋งŒ ์•„์ง ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฒฐ์ •๋œ. ์—ฌ์ „ํžˆ error {"code": "OK", "debugMessage": "", "message": "purchases are null.", "responseCode": 0} ๋ฆฌ์Šค๋„ˆ์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  You updated your subscription purchase ์ด๋ฉ”์ผ์„ ์ •์ƒ์ ์œผ๋กœ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋‚ด ์งˆ๋ฌธ์€ DEFERRED ๋ชจ๋“œ์— ๋Œ€ํ•œ ์˜ฌ๋ฐ”๋ฅธ ํ•ด๊ฒฐ์ฑ…์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์ง€๋‚œ๋ฒˆ์—๋„์ด ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ƒํ•˜๊ฒŒ๋„ deferred ๋ชจ๋“œ์—์„œ๋งŒ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ์กฐ์‚ฌํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” @ howg0924 ๋‹˜ , ์•„์ง์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์„ ์–ป์—ˆ์Šต๋‹ˆ๊นŒ?

@ nenjamin2405 ์•„๋‹ˆ์š”, ์—ฌ์ „ํžˆ ๊ธฐ๋ณธ IMMEDIATE_WITH_TIME_PRORATION ๋ชจ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ 

์•ˆ๋…•ํ•˜์„ธ์š” @hyochan , ์ด๊ฒƒ์— ๋Œ€ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚ด ์•ฑ์˜ ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด์ด ๋ฌธ์ œ๋กœ ์ธํ•ด ๋ฉˆ์ท„์Šต๋‹ˆ๋‹ค. ์กฐ์‚ฌํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

์•„์ง. ์ด ๋ฌธ์ œ๋ฅผ ๋‹ค๋ฃฐ ์‹œ๊ฐ„์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค.
๋ˆ„๊ตฐ๊ฐ€๊ฐ€์ด ๋ฌธ์ œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ์œ ์šฉํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.
Google ๋˜๋Š” StackOverflow ๋ฅผ ์š”์ฒญํ•˜๊ณ ์ด ์Šค๋ ˆ๋“œ์—์„œ ๊ณต์œ ํ•˜๋ฉด ์ •๋ง ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š”. ์ตœ๊ทผ์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ™œ๋™์ด์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ ๋˜์—ˆ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ์—ฌ์ „ํžˆ ์ปค๋ฎค๋‹ˆํ‹ฐ์˜์ฃผ์˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๊นŒ? ์ด ๋ฌธ์ œ๋Š” ๋” ์ด์ƒ ํ™œ๋™์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š์œผ๋ฉด ์ข…๊ฒฐ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ "ํ† ๋ก  ์šฉ"๋˜๋Š” "์ข‹์€ ์ฒซ ๋ฒˆ์งธ ๋ฌธ์ œ"๋กœ ํ‘œ์‹œ ํ•  ์ˆ˜๋„ ์žˆ์œผ๋ฉฐ ์—ด์–ด ๋‘๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ท€ํ•˜์˜ ๊ธฐ์—ฌ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š”์ด ๋ฌธ์ œ๋ฅผ ์‚ดํŽด๋ณด๊ณ  ์ปค๋ฎค๋‹ˆํ‹ฐ์™€ ๊ณต์œ ํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋Š” Android๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹ ์ธ ์ง€์—ฐ๋œ ๊ตฌ๋… ๊ต์ฒด์—์„œ ๋นˆ ๊ตฌ๋งค ๋ชฉ๋ก๊ณผ ํ•จ๊ป˜ ๊ตฌ๋งค ์—…๋ฐ์ดํŠธ ๋œ ๋ฆฌ์Šค๋„ˆ๊ฐ€ ํ˜ธ์ถœ ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค (์—ฌ๊ธฐ ์—์„œ "์ง€์—ฐ๋œ ๊ต์ฒด ๋ชจ๋“œ์˜ ๊ฒฝ์šฐ ..."์ฐธ์กฐ).

๊ตฌ๋… ๊ต์ฒด์‹œ purchases are null ์˜ค๋ฅ˜์™€ ํ•จ๊ป˜ ์˜ค๋ฅ˜ ๋ฆฌ์Šค๋„ˆ๊ฐ€ ํ˜ธ์ถœ ๋  ๋•Œ๋ฅผ ์ฐพ๋Š” ์ˆ˜์ •์„ ์ˆ˜ํ–‰ํ•˜์—ฌ react-native-iaphub ์—์„œ Android ์ง€์—ฐ ๊ตฌ๋… ๊ต์ฒด ์ง€์›์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ( ์ปค๋ฐ‹ ์ฐธ์กฐ )

๋ฌผ๋ก  ์˜์ˆ˜์ฆ์„ ํ™•์ธํ•˜๋Š” ์„œ๋ฒ„ ์ธก์—์„œ๋„ ์•ฝ๊ฐ„์˜ ์ˆ˜์ •์„ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ง€์—ฐ๋œ ๊ตฌ๋…์„ ์ฒ˜๋ฆฌ ํ•  ๋•Œ ์˜์ˆ˜์ฆ์„ ์ƒˆ๋กœ ๊ณ ์น˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋Š” ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๊ตฌ๋… ๊ต์ฒด๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”์‹œ๊ธฐ๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ์ƒˆ ํ† ํฐ์„ ์ฒ˜๋ฆฌํ•˜๋ ค๋ฉด Android ์‹ค์‹œ๊ฐ„ ์•Œ๋ฆผ์„ ๊ตฌํ˜„ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์•„๋‹ˆ๋ฉด ๋‹น์‹ ์„ ์œ„ํ•ด ๋ชจ๋“  ๊ฒƒ์„ํ•˜๋Š” IAPHUB ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ๐Ÿ™‚

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ๊ณ„ํš์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@iaphub์—์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด ๋ฌธ์ œ๋Š” DEFERRED ๋ชจ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ purchases ์ธ์ˆ˜๋ฅผ null ๋กœ ์‚ฌ์šฉํ•˜์—ฌ onPurchasesUpdated ๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Google ๋ฌธ์„œ์—์„œ :

์ง€์—ฐ๋œ ๊ต์ฒด ๋ชจ๋“œ์˜ ๊ฒฝ์šฐ ์•ฑ์€ ๋นˆ ๊ตฌ๋งค ๋ชฉ๋ก๊ณผ ์—…๊ทธ๋ ˆ์ด๋“œ ๋˜๋Š” ๋‹ค์šด ๊ทธ๋ ˆ์ด๋“œ ์„ฑ๊ณต ์—ฌ๋ถ€์— ๋Œ€ํ•œ ์ƒํƒœ๊ฐ€ ํฌํ•จ ๋œ PurchasesUpdatedListener์— ๋Œ€ํ•œ ํ˜ธ์ถœ์„ ์ˆ˜์‹ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๊ทธ๊ฒƒ์€ ๊ทธ ์ฒญ์ทจ์ž ์•ˆ์—์„œ ๊ทธ ์‚ฌ๊ฑด์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฌธ์ œ ์ผ๋ฟ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ๊ทธ ์ƒํ™ฉ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์ ์ ˆํ•œ ๋ฐฉ๋ฒ•์ด ๋ฌด์—‡์ธ์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • ์ด์ „ ๊ตฌ๋… ์ •๋ณด๋กœ ์•ฝ์† ํ•ด๊ฒฐ
  • undefined ์•ฝ์† ํ•ด๊ฒฐ
  • PURCHASE_DEFERRED ์ฝ”๋“œ๋กœ ํ”„๋ผ ๋ฏธ์Šค ๊ฑฐ๋ถ€

์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•ด?

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰