React-native-iap: ๊ฒฐ์ œ ์ˆ˜๋‹จ์ด ์ด๋ฏธ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ๊ฒฐ์ œ ์ˆ˜๋‹จ์„ ๋ผ์ด๋ธŒ๋กœ ์ถ”๊ฐ€ ํ•  ๋•Œ iOS ์ธ์•ฑ ๊ตฌ๋งค ์‹คํŒจ

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

react-native-iap ๋ฒ„์ „

react-native-iap": "^2.3.17

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

iOS

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

finishTransaction ์ด ํ˜ธ์ถœ ๋  ๋•Œ๋งŒ ๊ฒฐ์ œ๊ฐ€ ์ด๋ฃจ์–ด์ ธ์•ผํ•ฉ๋‹ˆ๋‹ค.

์‹ค์ œ ํ–‰๋™

์‹ ์šฉ ์นด๋“œ์™€ ๊ฐ™์€ ๊ฒฐ์ œ ์ˆ˜๋‹จ์ด ์ถ”๊ฐ€ ๋œ ํ›„ ๊ธˆ์•ก์ด ๊ฐ์ง€๋ฉ๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ RNIap.buyProductWithoutFinishTransaction(sku) ๋ฐฉ๋ฒ•์— ๋„๋‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค.

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

์‹ค์ œ ๊ธฐ๊ธฐ-iPhone 6s

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

  • ๊ฒฐ์ œ ์ˆ˜๋‹จ์ด ์—†์Œ ๋˜๋Š” ์ผ๋ถ€ ์ž˜๋ชป๋œ ๊ฒฐ์ œ ์„ธ๋ถ€ ์ •๋ณด๋กœ ์„ค์ •๋˜์–ด์žˆ๋Š” ๊ธฐ๊ธฐ์˜ Apple ๊ณ„์ •์„ ํ™•์ธํ•˜์„ธ์š”.
  • ์•ฑ์„ ํ†ตํ•ด ์ธ์•ฑ ๊ตฌ๋งคํ•˜๊ธฐ
  • ์‚ฌ์šฉ์ž๋Š” ์œ ํšจํ•œ ๊ฒฐ์ œ ์ˆ˜๋‹จ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด ๊ณ„์ • ์„ค์ • ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ฒฐ์ œ ์ˆ˜๋‹จ์ด ์ฒญ๊ตฌ ๋˜์—ˆ์œผ๋‚˜ ์•„๋ž˜ ์ฝ”๋“œ๋กœ ๊ฑฐ๋ž˜ ์˜์ˆ˜์ฆ์„๋ฐ›์ง€ ๋ชปํ•จ
ComponentDidMount(){
     await RNIap.initConnection();
     await RNIap.consumeAllItems();
     const prod = await RNIap.getProducts(product);

} 

  async componentWillUnmount() {
       RNIap.endConnection()
}

buyProduct(sku){
await RNIap.clearTransaction();

RNIap.buyProductWithoutFinishTransaction(sku)
.then(purchase => {
  // not reached
 if(calltoserverisSuccess){
    RNIap.finishTransaction();
 }
})
.catch(error => {
 // code enters catch case if ever
}}
๐Ÿ“ฑ iOS ๐Ÿ™ help wanted

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

apple ์— ๋ฌธ์˜ํ•ด์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š”๋ฐ sandbox ํ™˜๊ฒฝ์—์„œ ์žฌํ˜„ ํ•  ์ˆ˜์—†๋Š” ๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๊ฐ€ ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์ด ์ •๋ง ๋”์ฐํ•ด ๋ณด์ž…๋‹ˆ๋‹ค. ๋ฌธ์ œ๋ฅผ ์ดํ•ดํ•˜๊ณ  ์‹ถ์€ ๋ถ„๋“ค์„ ์œ„ํ•ด ํ™”๋ฉด์„ ๋…นํ™”ํ–ˆ๊ณ  ์—ฌ๊ธฐ ์—์„œ ์žˆ์Šต๋‹ˆ๋‹ค . @anandwahed Apple์— ๋ฌธ์˜ ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๊ทธ๋“ค์ด ๊ทธ๋ ‡๊ฒŒ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋” ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ๊ทธ๋“ค๊ณผ ์ ‘์ด‰ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋ชจ์—ฌ ๋ด…์‹œ๋‹ค.

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

์ฃ„์†กํ•˜์ง€๋งŒ ์ฝ”๋“œ์— ๊ตฌ๋ฌธ ์˜ค๋ฅ˜๊ฐ€ ๋งŽ์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์˜ ์˜ˆ์ œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ๋จผ์ € ์ฝ”๋“œ์™€ ๋น„๊ตํ•˜์‹ญ์‹œ์˜ค.

๋ฟก ๋นต๋€จ
๋‹ต์žฅ์„ ๋ณด๋‚ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์— ๊ฒŒ์‹œ ๋œ ์ฝ”๋“œ๋Š” ๋‹จ์ง€ ์˜ˆ์ผ ๋ฟ์ด๋ฉฐ ์‹ค์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์ •ํ™•ํ•œ ์ฝ”๋“œ๋Š” ์•„๋‹™๋‹ˆ๋‹ค.
๋‚˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์„ค๋ช…ํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค

  1. componentDidMount

    • RNIap.initConnection(); ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์‹œ์ž‘๋œ ์—ฐ๊ฒฐ

    • ๊ทธ๋Ÿฐ ๋‹ค์Œ RNIap.getProducts(product) ํ˜ธ์ถœํ•˜์—ฌ ์ œํ’ˆ์„ ๊ฐ€์ ธ ์™€์„œ ์ƒํƒœ์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

  1. ์‚ฌ์šฉ์ž๊ฐ€ ๊ตฌ๋งค ๋ฒ„ํŠผ์„ ํด๋ฆญ ํ•  ๋•Œ

    • RNIap.clearTransaction(); ๋Š” ๋ณด๋ฅ˜์ค‘์ธ ํŠธ๋žœ์žญ์…˜์ด ๋‚จ์•„ ์žˆ์ง€ ์•Š์€์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
    • RNIap.buyProductWithoutFinishTransaction(sku) ๋Š” ์„ฑ๊ณตํ•œ ๊ฒฝ์šฐ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„๊ฐ€ ์„ฑ๊ณต ์‚ฌ๋ก€๋ฅผ true๋กœ ์ œ๊ณตํ•˜๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„์— ๋Œ€ํ•œ ํ˜ธ์ถœ์ด ํŠธ๋ฆฌ๊ฑฐ๋˜๊ณ  ์ง€๋ถˆ์„ ์™„๋ฃŒํ•˜๊ธฐ ์œ„ํ•ด RNIap.finishTransaction(); ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
  2. componentWillUnmount ()

    • ์—ฐ๊ฒฐ์„ ์ข…๋ฃŒํ•˜๋ ค๋ฉด RNIap.endConnection() .

์ด ํ”„๋กœ์„ธ์Šค๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋ฏธ ๊ฒฐ์ œ ์ˆ˜๋‹จ์„ ์ถ”๊ฐ€ ํ•œ ๊ฒฝ์šฐ ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๊ฒฐ์ œ ์ˆ˜๋‹จ์„ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๊ฒฐ์ œ ์ˆ˜๋‹จ ํŽ˜์ด์ง€๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผํ•˜๋ฉฐ RNIap.finishTransaction(); ๋„๋‹ฌํ•˜๊ธฐ ์ „์— ๊ธˆ์•ก์ด ์ฒญ๊ตฌ๋ฉ๋‹ˆ๋‹ค.

์„ธ๋ถ€ ์‚ฌํ•ญ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ ๋ฌธ์ œ๊ฐ€ ๋ช…ํ™• ํ•ด ๋ณด์ž…๋‹ˆ๋‹ค. cc @JJMoon

์ซ‘๋ผ๋ฆฌ

@ zohaibahmed-22์ด ์ƒŒ๋“œ ๋ฐ•์Šค ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์ž…๋‹ˆ๊นŒ?

@JJMoon ์•„๋‹ˆ์š”, ์‹ค์ œ ํ™˜๊ฒฝ ์‚ฌ๋ก€์ž…๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ ์•„์›ƒ ์ƒํƒœ์ด๊ฑฐ๋‚˜ ์‹ ์šฉ ์นด๋“œ ์ •๋ณด๊ฐ€ ์—†์„ ๋•Œ์ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค.
๋ฐฉ๋ฒ•์ด ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜๋ฉด์ด ์˜ค๋ฅ˜์˜ ์›์ธ์€ ๋‹ค๋ฅธ ๊ณณ์— ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ์ž‘์—…์„ ์ค€๋น„ํ•ด์•ผ ์•ฑ, viewDidDisappear ๋“ฑ์ด ์ข…๋ฃŒ๋ฉ๋‹ˆ๋‹ค.
์ƒŒ๋“œ ๋ฐ•์Šค ๋ชจ๋“œ์—์„œ์ด ์ฆ์ƒ์€ ๋‹ค์†Œ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
์ƒˆ ์ƒŒ๋“œ ๋ฐ•์Šค ๊ณ„์ •์„ ๋งŒ๋“ค ๋•Œ ์ฒซ ๋ฒˆ์งธ ๊ตฌ๋งค๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๋‘ ๋ฒˆ์งธ๋กœ ์žฅ์น˜๋Š” ๋กœ๊ทธ์ธ ์ƒํƒœ์ด๋ฉฐ ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
์ด ์˜ค๋ฅ˜์— ๋Œ€ํ•œ ๋‹จ์„œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

@dooboolab @JJMoon ์ด๊ฑฐ ํ•œ ๋ฒˆ๋ณด์„ธ์š”
https://forums.developer.apple.com/thread/6431
https://forums.developer.apple.com/thread/64489

@dooboolab ๊ณผ @JJMoon ๋„ iOS ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณผ ๋•Œ ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ–ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์—์„œ updatedTransactions์˜ ๋ฐฉ๋ฒ• ์šฐ๋ฆฌ๋Š”์˜ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๊ฐ€ ๋‚˜ํƒ€๋‚  ๋•Œ SKPaymentTransactionStateDeferred ๋˜๋Š” SKPaymentTransactionStateFailed ์šฐ๋ฆฌ๊ฐ€ ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค finishTransaction .

๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ SKPaymentTransactionStateFailed ๊ฒฐ๊ณผ ๋’ค์—๋Š” ์œ„์˜ ์Šค๋ ˆ๋“œ 6431 ์—์„œ ์–ธ๊ธ‰ ํ•œ๋Œ€๋กœ SKPaymentTransactionStatePurchased ๊ฐ€์˜ต๋‹ˆ๋‹ค. Objective-C ์ฝ”๋“œ์— ๋Œ€ํ•ด ์ž˜ ๋ชจ๋ฅด๊ฒ ์œผ๋ฏ€๋กœ ์‹คํŒจ์‹œ ํŠธ๋žœ์žญ์…˜์„ ์ง€์šฐ๋Š” ์ง€ ์นœ์ ˆํ•˜๊ฒŒ ํ™•์ธํ•˜๊ณ  ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

@anandwahed ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋‚ด ์ž˜๋ชป์ด์•ผ. ๊ทธ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค.
Apple์˜ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ดํŽด๋ณด๊ณ  ๋ฌธ์ œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

@anandwahed ์‹คํŒจํ–ˆ์„ ๋•Œ finish transaction ์˜ฌ๋ฐ”๋ฅธ ๋ฐฉ๋ฒ•์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด ์Šค๋ ˆ๋“œ๋ฅผ ์ฐพ์•„๋ณด์„ธ์š”. https://stackoverflow.com/questions/11008636/inapp-purchase-skpaymentqueue-finish-transaction-doesnt-work
์‹คํŒจ์‹œ ์˜์ˆ˜์ฆ์ด ์—†์–ด ๊ตฌ๋งค ์ƒํ’ˆ์„ ์ ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋งˆ์ง€๋ง‰ ๊ฑฐ๋ž˜๊ฐ€ ํ•ญ์ƒ '๊ตฌ๋งค'๋ฅผ ์˜๋ฏธํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค.
ํ•œํŽธ ์Šค๋ ˆ๋“œ 6431์„ ์กฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ฐฉ๊ธˆ ์Šค๋ ˆ๋“œ 6431์„ ์ฝ์—ˆ์Šต๋‹ˆ๋‹ค (https://forums.developer.apple.com/thread/6431#14562).
๊ฒฐ๋ก . 2015 ๋…„ ์ดํ›„๋กœ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์™€์šฐ ..
์ด '์ƒ์  ํ‚คํŠธ ํ๋ฆ„'ํšจ๊ณผ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์—๋Š” ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ์‚ฌ์šฉ์ž ๊ฒฝ๊ณ ๋ฅผ ํ‘œ์‹œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  2. ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์ฃผ์„ธ์š”.

๊ทธ๋ฆฌ๊ณ  ๋‘ ๊ฐ€์ง€๋ฅผ ๋ฐฐ์› ์Šต๋‹ˆ๋‹ค.
A. ์‹คํŒจํ•˜๋ฉด finishTransaction ์„ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. (์˜ต์…˜์˜ ์œ ๋ฌด์— ๊ด€๊ณ„์—†์ด ํ•ญ์ƒ)
B. Storekit ํ๋ฆ„์€ ์‹คํŒจ์™€ ์„ฑ๊ณต์„ ๋ชจ๋‘๋ฐ›์Šต๋‹ˆ๋‹ค. (๊ทธ๊ฒƒ์€ ๋‚˜์œ)

์ด ์Šค๋ ˆ๋“œ๋ฅผ ์ฝ๊ณ ์ด ๋ฌธ์ œ๋กœ ๋Œ์•„๊ฐ€๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

์–ด๋Š ์ชฝ์„ ์„ ํƒ ํ•˜๋Š๋ƒ (1 ๋˜๋Š” 2)๋Š” ์Šค์Šค๋กœ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.
์‹คํŒจ ์‘๋‹ต์„ ์œ„ํ•ด ์ฝœ๋ฐฑ์ด ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@JJMoon ์€ ์šฐ๋ฆฌ๊ฐ€ buyProductWithoutFinishTransaction์„ ์‚ฌ์šฉํ•ด์„œ๋Š” ์•ˆ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๊นŒ?

@ maxs15 ๊ทธ๋Ÿฐ ๋œป์ด ์•„๋‹™๋‹ˆ๋‹ค. ํ˜ผ๋ž€์Šค๋Ÿฌ์›Œ์„œ ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค.
StoreKit ํ๋ฆ„์€ ๋ชจ๋“  ๊ตฌ๋งค์—์„œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ชจ๋“ˆ์ด ์•„๋‹ˆ๋ผ iOS ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.
์ง€๊ธˆ์€ ๋‚˜๋„ ๋‹จ์„œ๊ฐ€ ์—†๋‹ค. ์ด๊ฒƒ์€ ๋ชจ๋“  ๊ธฐ๋ณธ iOS ์•ฑ์—์„œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ถŒ๋ฆฌ?
์šฐ๋ฆฌ๋Š” ์ž์œ  ์‹œ๊ฐ„์— ๋” ๋งŽ์ด ๋ฐœ๊ตด ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ค๋Š˜์ด ๋ฌธ์ œ๋ฅผ ์ƒ์„ฑํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—์ด ๋ฌธ์ œ๋ฅผ ๋””๋ฒ„๊น…ํ•˜๋ ค๊ณ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ง€๋ถˆ finishTransanction ๋ฐ ์™„๋ฃŒ๋˜์—ˆ์ง€๋งŒ payMethod๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์„ ๋•Œ callback ๋ฐ›์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. console.log ์ž‘์„ฑ์„ ๋””๋ฒ„๊ทธํ•˜๋ ค๊ณ ํ–ˆ์ง€๋งŒ dev ํ™˜๊ฒฝ์—์„œ ์‹ค์ œ ์ฒญ๊ตฌ๋ฅผ ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฌ๋“ ์ง€์ด ํ”„๋กœ์„ธ์Šค๋ฅผ ๋””๋ฒ„๊น…ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ์•ˆํ•˜์—ฌ debug real purchase ์ด๊ฒƒ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? sandbox ๋ชจ๋“œ์—์„œ ์‚ฌ์šฉํ•ด์•ผํ•ฉ๋‹ˆ๊นŒ? ์ƒŒ๋“œ ๋ฐ•์Šค์—์„œ ์™„๋ฒฝํ•˜๊ฒŒ ์ž‘๋™ํ•˜๋ฏ€๋กœ ์ด๊ฒƒ์„ ๋””๋ฒ„๊น…ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ชจ๋ฆ…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋งค์šฐ ๊บผ๋ คํ•ฉ๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ์ค‘์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฏ€๋กœ ๋ช‡ ๊ฐ€์ง€ ์•„์ด๋””์–ด๋ฅผ ์ˆ˜์ง‘ ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ƒŒ๋“œ ๋ฐ•์Šค ์‚ฌ์šฉ์ž๊ฐ€ ์•„๋‹Œ ์‚ฌ์šฉ์ž๋กœ ๊ตฌ๋งค๋ฅผ ์‹œ๋„ ํ•  ๋•Œ ํ•ญ์ƒ ์ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒ ํ•ฉ๋‹ˆ๋‹ค.

@hyochan ์‹ค์ œ ์„œ๋ฒ„ (๊ท€ํ•˜์˜)๋ฅผ ์—ฐ๊ฒฐํ•˜๋ฉด ๋””๋ฒ„๊ทธ ๋ชจ๋“œ์ด๋“  ๋ฆด๋ฆฌ์Šค ๋ชจ๋“œ์ด๋“  ์ƒ๊ด€ ์—†์Šต๋‹ˆ๋‹ค. ๋‘ ๊ฐ€์ง€ ์˜ต์…˜์ด ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

  1. Xcode์—์„œ ๋””๋ฒ„๊ทธ ๋ชจ๋“œ๋กœ ์‹ค์ œ ์žฅ์น˜์—์„œ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. JS ์ฝ˜์†” ๋กœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.
  2. Xcode์˜ ๋ฆด๋ฆฌ์Šค ๋ชจ๋“œ์—์„œ ์‹ค์ œ ์žฅ์น˜์—์„œ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. Objective-C ์ฝ”๋“œ์—์„œ NSLog๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.
    ๋‘ ๋ฐฉ๋ฒ• ๋ชจ๋‘ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

@JJMoon ๊ทธ๋ž˜, ๋‚˜๋Š” ์ด๋ฏธ ๊ทธ๊ฒƒ์„ ์•Œ์•„ ๋ƒˆ์ง€๋งŒ ์—ฌ์ „ํžˆ ios์—์„œ ๋ผ์ด๋ธŒ ๊ตฌ๋งค ํ…Œ์ŠคํŠธ๋ฅผ ํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ์ด stackoverflow๊ฐ€ ์‚ฌ์‹ค์ž…๋‹ˆ๊นŒ? ๊ทธ๋ ‡๋‹ค๋ฉด์ด ๋ฌธ์ œ๋ฅผ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๋ผ์ด๋ธŒ ๊ตฌ๋งค๋ฅผ ํ…Œ์ŠคํŠธํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ์— ์ง๋ฉด ํ•œ ์‚ฌ๋žŒ์€ ๋ˆ„๊ตฌ๋‚˜์ด ๋ฌธ์ œ์— ์ง๋ฉด ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ™•์‹ ํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์ œ ์ œ๋ชฉ์— ์„ค๋ช… ๋œ in-app purchase fail when payment method added live . ์ด๊ฒƒ์„ ์–ด๋–ป๊ฒŒ ๋””๋ฒ„๊น… ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? @anandwahed ์ด ๋ฌธ์ œ์— ๋Œ€ํ•ด Apple์— ์—ฐ๋ฝ ํ•œ ์ ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@hyochan ์•„๋‹ˆ์š”, Apple ์ง€์›ํŒ€์— ์—ฐ๋ฝํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

apple ์— ๋ฌธ์˜ํ•ด์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋Š”๋ฐ sandbox ํ™˜๊ฒฝ์—์„œ ์žฌํ˜„ ํ•  ์ˆ˜์—†๋Š” ๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๊ฐ€ ์žˆ๋‹ค๋Š” ์‚ฌ์‹ค์ด ์ •๋ง ๋”์ฐํ•ด ๋ณด์ž…๋‹ˆ๋‹ค. ๋ฌธ์ œ๋ฅผ ์ดํ•ดํ•˜๊ณ  ์‹ถ์€ ๋ถ„๋“ค์„ ์œ„ํ•ด ํ™”๋ฉด์„ ๋…นํ™”ํ–ˆ๊ณ  ์—ฌ๊ธฐ ์—์„œ ์žˆ์Šต๋‹ˆ๋‹ค . @anandwahed Apple์— ๋ฌธ์˜ ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๊ทธ๋“ค์ด ๊ทธ๋ ‡๊ฒŒ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋” ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ๊ทธ๋“ค๊ณผ ์ ‘์ด‰ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋ชจ์—ฌ ๋ด…์‹œ๋‹ค.

์˜ค๋Š˜ ์šฐ๋ฆฌ๋Š” Apple๋กœ๋ถ€ํ„ฐ ๋‹ต๋ณ€ ์„ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค. failure ์ดํ›„์— ์ฝœ๋ฐฑ์ด ๋‹ค์‹œ ๋ฐ˜ํ™˜ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” # 348์—์„œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์—ฐ๊ตฌํ•˜๊ณ  ์žˆ์ง€๋งŒ ์ด๊ฒƒ์ด ๋งค์šฐ ๋ถˆ์พŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด 2.4.0-beta1 ๋กœ ๋ฆด๋ฆฌ์Šคํ–ˆ์Šต๋‹ˆ๋‹ค. PR # 348์ด์ด ๋ฒ„์ „์— ์ถ”๊ฐ€๋˜์—ˆ์œผ๋ฉฐ์ด ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ •๋ณด๋„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ํ…Œ์ŠคํŠธ ์ค‘์ž…๋‹ˆ๋‹ค.

๋ผ์ด๋ธŒ ๊ตฌ๋งค์—์„œ ์ด๊ฒƒ์„ ํ…Œ์ŠคํŠธํ–ˆ์œผ๋ฉฐ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‹คํŒจ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ์—๋งŒ ๋ฆฌ์Šค๋„ˆ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์„ฑ๊ณต์ ์ธ ๊ฒฐ๊ณผ๋กœ ๋ณต์ œ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ๋ถ„,์ด ๋ฌธ์ œ์— ์‹œ๊ฐ„์„ ํˆฌ์ž ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ๐Ÿ™

ํ˜„์žฌ ๋ฌธ์„œ๋Š” addAdditionalSuccessPurchaseListenerIOS ์‚ฌ์šฉ์— ๋Œ€ํ•ด ๋” ๋ช…ํ™•ํ•ด์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ์ œ๊ฐ€ 414 ๋ฒˆ์—์„œ ๋‹ค๋ฃจ๋ ค๊ณ  ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ API ๊ฐœ์„ ์˜ ์—ฌ์ง€๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์†Œ์œ„ '์ƒ์  ํ‚คํŠธ ํ๋ฆ„'์„ ๋” ์ž˜ ์ˆ˜์šฉ ํ•  ์ˆ˜์žˆ๋Š” API์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•ด ํ† ๋ก  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์˜ˆ๋ฅผ ๋“ค์–ด, RxJS๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ :

const observable = RNIap.buyProduct('com.example.coins100')
                        .subscribe(
                            purchase => console.log(purchase), // successful payment
                            err => console.log(err) // err.code and err.message are available
                        )

์•„๋‹ˆ๋ฉด iOS์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ๊ตฌ๋…์„ ๋” ์ž˜ ์ˆจ๊ธฐ๋Š” ๋‹ค๋ฅธ ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@Edgpaez ํ›Œ๋ฅญํ•˜์ง€๋งŒ android ์—์„œ ์ˆ˜ํ–‰๋˜๋Š” ๊ตฌ๋งค ๋™์ž‘์ด ๋ณ€๊ฒฝ๋ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ์กฐ์‚ฌ ํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค version 3 ์—์„œ์ด ๋ชจ๋“ˆ์˜ 2019 .

์•ˆ๋…•ํ•˜์„ธ์š” @hyochan , AFAICT, ํŒจํ‚ค์ง€์˜ ๋‚ด๋ถ€ ๋™์ž‘์„ ๋ณ€๊ฒฝํ•  ํ•„์š”๋Š” ์—†์œผ๋ฉฐ ๊ณต์šฉ ์ธํ„ฐํŽ˜์ด์Šค ๋งŒ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” promise๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” buyItemByType ๋ฉ”์†Œ๋“œ๋ฅผ ์œ ์ง€ํ•˜๊ณ  index.js ์— Rx๋ฅผ ์ถ”๊ฐ€ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด index.js์— ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‚ด์šฉ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

export const buyProduct = (sku) => Platform.select({
  android: () => Observable.of(RNIapModule.buyItemByType(ANDROID_ITEM_TYPE_IAP, sku, null, 0)), // returns an observable that emits when the RNIapModule.buyItemByType promise resolves
  ios: ... // ios would do the same but taking into account the usage of addAdditionalSuccessPurchaseListenerIOS
})();

๋‚ด ๋ชฉํ‘œ๋Š”์ด ํŠน์ • ๊ตฌํ˜„์ด ์•„๋‹ˆ๋ผ '์ƒ์  ํ‚คํŠธ ํ๋ฆ„'์— ๋Œ€ํ•œ ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ์ˆจ๊ธฐ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด๊ฒƒ์ด ์ข‹์€ ์ƒ๊ฐ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ?
PR์— ๊ด€์‹ฌ์ด ์žˆ์œผ์‹ญ๋‹ˆ๊นŒ?

@Edgpaez ์ข‹์•„. ์ด์ œ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ RxJS ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ feature ๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ์—๋Š” ๋„ˆ๋ฌด ๋งŽ์€ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ์•„๋ž˜ ๋‚ด์šฉ์ด ๋‹ค๋ฅผ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

RNIap.buyProduct('com.example.coins100')
                        .subscribe(
                            purchase => console.log(purchase), // successful payment
                            err => console.log(err) // err.code and err.message are available
                        )

์•„๋ž˜์™€ ๊ฐ™์€ ๋‘ ๊ฐ€์ง€ ํ•ญ๋ชฉ์— ๋Œ€ํ•ด buyProduct ๋กœ ์ „ํ™”ํ•˜๋ฉด

RNIap.buyProduct('com.example.coins100');
RNIap.buyProduct('com.example.coins200');

์–ด๋Š ๊ฒƒ์ด ๋จผ์ € ๋๋‚ ์ง€ ๋ณด์žฅ ํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ sendEvent ์—์„œ JS ๊นŒ์ง€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๊ตฌํ˜„์ด ๋‹ค์Œ๊ณผ ๊ฐ™์•„์•ผํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

RNIap.buyProduct('com.example.coins100');
RNIap.buyProduct('com.example.coins200');

// receiving events
const subs =  RNIap.purchaseUpdateListener(purchase => {
  ...
});

๋‚ด๊ฐ€ ๋†“์นœ ๊ฒƒ์ด ์žˆ์œผ๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š”.

# 423์—์„œ ์ถ”๊ฐ€ ๋…ผ์˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

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