Kiếm thêm thu nhập với mobile app như nào? Đây là vấn đề dù đã được bàn luận rất lâu nhưng vẫn không thể hết hot được? Nào là phát triển các app theo xu hướng, nào là các app kết hợp với công nghệ đang phát triển (AI, AR,..), app bảo mật, On-demand apps,… những cách kiếm tiền từ app mobile dễ dàng hơn như In-app advertising hay là in-app-purchase,…
Tiêu đề hào nhoáng câu view vậy thôi chứ hôm nay mình sẽ chia sẻ về cách tích hợp in-app-purchase với react-native
I . Chuẩn bị
Điều đầu tiên các bạn cần là đã có tài khoản developer trên google store và apple store và đã public app.
Cài đặt thư viện
yarn add react-native-iap
reac-native link react-native-iap
Trước khi run ios bạn cần chạy
cd ios && pod install && cd ..
II. Config
1. iOS
Đầu tiên bạn cần vào ItunesConnect và hoàn thành mục Agreements, Tax and Bankings.
Tiếp theo ta cần enable In-app-purchase trên xcode nên (nếu như bạn không thấy nó đâu thì check lại xem tài khoản của bạn đã là tài khoản develop chưa nhá, hoặc đã enable nó trên configuage chưa)
Enable trên console develop
Tiếp theo bạn cần vào version mới nhất với state Ready to Submit ở tab Features và chọn In-App Purchases. Sau đó là điền các product bạn có như dưới hình đây
Các bạn lưu ý các tên item nhá, về sau mình sẽ demo và cần đó: non.consume.prod
, point_1000
, point_5000
1. Android
Android thì lại đơn giản hơn bạn chỉ cần đăng nhập và app và thêm các product của bạn https://play.google.com/apps/publish
Tên các products: point_1000
, 10000_point
, 5000_point
Thêm quyền trong Manifest.xml
<uses-permission android:name="com.android.vending.BILLING" />
II. Setup code và test nào
Do mình chỉ có tài khoản dev trên android nên mình demo trên android nhá, ios bạn chỉ cần bật in-app-purchase trên xcode và thêm sản phẩm như ở trên mình nói là được thôi
Đầu tiên bạn tạo 1 view với 1 button, khi click vào sản phẩm đó thì truyền product id đó để lấy thông tin nó trên store. Ở đây mình truyền 1 product id là android.test.purchased, nó tương đương mấy cái point_1000
, 10000_point
, 5000_point
ở trên mình bảo ấy, mình tạo khác đi thôi
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <span class="token operator">...</span> requestPurchase <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span>sku<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">void</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token punctuation">}</span> <span class="token operator">...</span> <span class="token operator"><</span>View style<span class="token operator">=</span><span class="token punctuation">{</span>styles<span class="token punctuation">.</span>container<span class="token punctuation">}</span><span class="token operator">></span> <span class="token operator"><</span>TouchableOpacity style<span class="token operator">=</span><span class="token punctuation">{</span>styles<span class="token punctuation">.</span>btnBuy<span class="token punctuation">}</span> onPress<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">void</span> <span class="token operator">=></span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">requestPurchase</span><span class="token punctuation">(</span><span class="token string">'android.test.purchased'</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token operator">></span> <span class="token operator"><</span>Text<span class="token operator">></span> <span class="token constant">BUY</span> <span class="token constant">NOW</span><span class="token operator"><</span><span class="token operator">/</span>Text<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>TouchableOpacity<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>View<span class="token operator">></span> <span class="token operator">...</span> <span class="token keyword">const</span> styles <span class="token operator">=</span> StyleSheet<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">{</span> container<span class="token punctuation">:</span> <span class="token punctuation">{</span> flex<span class="token punctuation">:</span> <span class="token number">1</span><span class="token punctuation">,</span> alignItems<span class="token punctuation">:</span> <span class="token string">'center'</span><span class="token punctuation">,</span> justifyContent<span class="token punctuation">:</span> <span class="token string">'center'</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> btnBuy<span class="token punctuation">:</span> <span class="token punctuation">{</span> flex<span class="token punctuation">:</span> <span class="token number">0.5</span><span class="token punctuation">,</span> backgroundColor<span class="token punctuation">:</span> <span class="token string">'#1CB5B4'</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> txtBtn<span class="token punctuation">:</span> <span class="token punctuation">{</span> color<span class="token punctuation">:</span> <span class="token string">'white'</span><span class="token punctuation">,</span> fontSize<span class="token punctuation">:</span> <span class="token number">14</span><span class="token punctuation">,</span> fontWeight<span class="token punctuation">:</span> <span class="token string">"bold"</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token operator">...</span> |
Tiếp theo cần phải config một chút để kiểm tra xem ta connect với store như nào, thanh toán ra sao có lỗi không
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | <span class="token keyword">async</span> <span class="token function">componentDidMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> result <span class="token operator">=</span> <span class="token keyword">await</span> RNIap<span class="token punctuation">.</span><span class="token function">initConnection</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">await</span> RNIap<span class="token punctuation">.</span><span class="token function">consumeAllItemsAndroid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'result'</span><span class="token punctuation">,</span> result<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">err</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">warn</span><span class="token punctuation">(</span>err<span class="token punctuation">.</span>code<span class="token punctuation">,</span> err<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">this</span><span class="token punctuation">.</span>purchaseUpdateSubscription <span class="token operator">=</span> <span class="token function">purchaseUpdatedListener</span><span class="token punctuation">(</span><span class="token punctuation">(</span>purchase<span class="token punctuation">:</span> InAppPurchase <span class="token operator">|</span> SubscriptionPurchase <span class="token operator">|</span> ProductPurchase <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'purchaseUpdatedListener'</span><span class="token punctuation">,</span> purchase<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> receipt <span class="token operator">=</span> purchase<span class="token punctuation">.</span>transactionReceipt<span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>receipt<span class="token punctuation">)</span> <span class="token punctuation">{</span> yourAPI<span class="token punctuation">.</span><span class="token function">deliverOrDownloadFancyInAppPurchase</span><span class="token punctuation">(</span>purchase<span class="token punctuation">.</span>transactionReceipt<span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token punctuation">(</span>deliveryResult<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">isSuccess</span><span class="token punctuation">(</span>deliveryResult<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// Tell the store that you have delivered what has been paid for.</span> <span class="token comment">// Failure to do this will result in the purchase being refunded on Android and</span> <span class="token comment">// the purchase event will reappear on every relaunch of the app until you succeed</span> <span class="token comment">// in doing the below. It will also be impossible for the user to purchase consumables</span> <span class="token comment">// again untill you do this.</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>Platform<span class="token punctuation">.</span><span class="token constant">OS</span> <span class="token operator">===</span> <span class="token string">'ios'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> RNIap<span class="token punctuation">.</span><span class="token function">finishTransactionIOS</span><span class="token punctuation">(</span>purchase<span class="token punctuation">.</span>transactionId<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>Platform<span class="token punctuation">.</span><span class="token constant">OS</span> <span class="token operator">===</span> <span class="token string">'android'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// If consumable (can be purchased again)</span> RNIap<span class="token punctuation">.</span><span class="token function">consumePurchaseAndroid</span><span class="token punctuation">(</span>purchase<span class="token punctuation">.</span>purchaseToken<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// If not consumable</span> RNIap<span class="token punctuation">.</span><span class="token function">acknowledgePurchaseAndroid</span><span class="token punctuation">(</span>purchase<span class="token punctuation">.</span>purchaseToken<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// From <a class="__cf_email__" href="/cdn-cgi/l/email-protection" data-cfemail="ec9e898d8f98c1828d98859a89c1858d9cacd8c2ddc2dc">[email protected]</a> you can simplify above `method`. Try to wrap the statement with `try` and `catch` to also grab the `error` message.</span> RNIap<span class="token punctuation">.</span><span class="token function">finishTransaction</span><span class="token punctuation">(</span>purchase<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// Retry / conclude the purchase is fraudulent, etc...</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>purchaseErrorSubscription <span class="token operator">=</span> <span class="token function">purchaseErrorListener</span><span class="token punctuation">(</span><span class="token punctuation">(</span>error<span class="token punctuation">:</span> PurchaseError<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">warn</span><span class="token punctuation">(</span><span class="token string">'purchaseErrorListener'</span><span class="token punctuation">,</span> error<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">componentWillUnmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>purchaseUpdateSubscription<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>purchaseUpdateSubscription<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>purchaseUpdateSubscription <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>purchaseErrorSubscription<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>purchaseErrorSubscription<span class="token punctuation">.</span><span class="token function">remove</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>purchaseErrorSubscription <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Các bạn nên vào docs đọc các Api để hiểu hơn nhá
Cuối cùng là hàm xử lý của chúng ta
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | requestPurchase <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token punctuation">(</span>sku<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">void</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> products <span class="token operator">=</span> <span class="token keyword">await</span> RNIap<span class="token punctuation">.</span><span class="token function">getProducts</span><span class="token punctuation">(</span> Platform<span class="token punctuation">.</span><span class="token function">select</span><span class="token punctuation">(</span><span class="token punctuation">{</span> ios<span class="token punctuation">:</span> <span class="token punctuation">[</span> sku <span class="token punctuation">]</span><span class="token punctuation">,</span> android<span class="token punctuation">:</span> <span class="token punctuation">[</span> sku <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Products'</span><span class="token punctuation">,</span> products<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">setState</span><span class="token punctuation">(</span><span class="token punctuation">{</span> productList<span class="token punctuation">:</span> products <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">err</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">warn</span><span class="token punctuation">(</span>err<span class="token punctuation">.</span>code<span class="token punctuation">,</span> err<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> RNIap<span class="token punctuation">.</span><span class="token function">requestPurchase</span><span class="token punctuation">(</span>sku<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">err</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> Alert<span class="token punctuation">.</span><span class="token function">alert</span><span class="token punctuation">(</span>err<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">;</span> |
Nếu các bạn làm đúng sẽ được như hình giống mình
Welcome to React Native