diff --git a/android/src/main/java/expo/modules/iap/ExpoIapModule.kt b/android/src/main/java/expo/modules/iap/ExpoIapModule.kt index 8bf93b8..cc77dff 100644 --- a/android/src/main/java/expo/modules/iap/ExpoIapModule.kt +++ b/android/src/main/java/expo/modules/iap/ExpoIapModule.kt @@ -388,7 +388,11 @@ class ExpoIapModule : val billingResult = billingClient.launchBillingFlow(currentActivity, flowParams) if (billingResult.responseCode != BillingClient.BillingResponseCode.OK) { - throw Exception("Billing error: ${billingResult.debugMessage}") + promise.reject( + "Billing Error", + billingResult.debugMessage, + null, + ) } promise.resolve(true) diff --git a/example/.vscode/settings.json b/example/.vscode/settings.json index 2c253d8..7d44d2a 100644 --- a/example/.vscode/settings.json +++ b/example/.vscode/settings.json @@ -1,5 +1,6 @@ { "cSpell.words": [ - "Pressable" + "Pressable", + "skus" ] } \ No newline at end of file diff --git a/example/App.tsx b/example/App.tsx index e04acf6..a4c70a1 100644 --- a/example/App.tsx +++ b/example/App.tsx @@ -1,12 +1,16 @@ import { endConnection, getProducts, + getSubscriptions, initConnection, isProductAndroid, isProductIos, + isSubscriptionProductAndroid, + isSubscriptionProductIos, purchaseErrorListener, purchaseUpdatedListener, requestPurchase, + requestSubscription, } from 'expo-iap'; import {useEffect, useState} from 'react'; import { @@ -21,38 +25,68 @@ import { View, } from 'react-native'; -import {Product, ProductPurchase, PurchaseError} from '../src/ExpoIap.types'; +import { + Product, + ProductPurchase, + PurchaseError, + SubscriptionProduct, +} from '../src/ExpoIap.types'; +import {RequestSubscriptionAndroidProps} from '../src/types/ExpoIapAndroid.types'; + +const productSkus = [ + 'com.cooni.point1000', + 'com.cooni.point5000', + 'com.cooni.con5000', +]; -const productSkus = ['com.cooni.point1000', 'com.cooni.point5000', 'com.cooni.con5000']; +const subscriptionSkus = ['com.cooni.subscription1000']; -const operations = ['initConnection', 'getProducts', 'endConnection']; +const operations = [ + 'initConnection', + 'getProducts', + 'getSubscriptions', + 'endConnection', +]; type Operation = (typeof operations)[number]; export default function App() { - const [items, setItems] = useState([]); + const [isConnected, setIsConnected] = useState(false); + const [products, setProducts] = useState([]); + const [subscriptions, setSubscriptions] = useState([]); const handleOperation = async (operation: Operation) => { - if (operation === 'initConnection') { - console.log('Connected', await initConnection()); - return; - } + switch (operation) { + case 'initConnection': + if (await initConnection()) setIsConnected(true); + return; - if (operation === 'endConnection') { - const result = await endConnection(); + case 'endConnection': + if (await endConnection()) { + setProducts([]); + setIsConnected(false); + } + break; - if (result) { - setItems([]); - } - } + case 'getProducts': + try { + const products = await getProducts(productSkus); + setProducts(products); + } catch (error) { + console.error(error); + } + break; - if (operation === 'getProducts') { - try { - const products = await getProducts(productSkus); - console.log('items', products); - setItems(products); - } catch (error) { - console.error(error); - } + case 'getSubscriptions': + try { + const subscriptions = await getSubscriptions(subscriptionSkus); + setSubscriptions(subscriptions); + } catch (error) { + console.error(error); + } + break; + + default: + console.log('Unknown operation'); } }; @@ -65,13 +99,11 @@ export default function App() { }, ); - const purchaseErrorSubs = purchaseErrorListener( - (error: PurchaseError) => { - InteractionManager.runAfterInteractions(() => { - Alert.alert('Purchase error', JSON.stringify(error)); - }); - }, - ); + const purchaseErrorSubs = purchaseErrorListener((error: PurchaseError) => { + InteractionManager.runAfterInteractions(() => { + Alert.alert('Purchase error', JSON.stringify(error)); + }); + }); return () => { purchaseUpdatedSubs.remove(); @@ -98,44 +130,99 @@ export default function App() { - {items.map((item) => { - if (isProductAndroid(item)) { - return ( - - - {item.title} -{' '} - {item.oneTimePurchaseOfferDetails?.formattedPrice} - -