expo-iap 2.2.0 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/ExpoIap.types.d.ts.map +1 -1
- package/build/ExpoIap.types.js.map +1 -1
- package/build/index.d.ts +2 -3
- package/build/index.d.ts.map +1 -1
- package/build/index.js +16 -16
- package/build/index.js.map +1 -1
- package/build/types/ExpoIapIos.types.d.ts +1 -0
- package/build/types/ExpoIapIos.types.d.ts.map +1 -1
- package/build/types/ExpoIapIos.types.js.map +1 -1
- package/build/useIap.d.ts.map +1 -1
- package/build/useIap.js +2 -1
- package/build/useIap.js.map +1 -1
- package/iap.md +399 -93
- package/ios/ExpoIapModule.swift +2 -2
- package/package.json +2 -5
- package/src/ExpoIap.types.ts +1 -1
- package/src/index.ts +28 -41
- package/src/types/ExpoIapIos.types.ts +1 -0
- package/src/useIap.ts +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoIap.types.d.ts","sourceRoot":"","sources":["../src/ExpoIap.types.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,2BAA2B,EAC3B,+BAA+B,EAC/B,0BAA0B,EAC3B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,uBAAuB,EACvB,2BAA2B,EAC3B,sBAAsB,EACvB,MAAM,0BAA0B,CAAC;AAElC,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,WAAW,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAGF,MAAM,MAAM,WAAW,GAAG;IAAC,QAAQ,EAAE,KAAK,CAAA;CAAC,CAAC;AAC5C,MAAM,MAAM,eAAe,GAAG;IAAC,QAAQ,EAAE,SAAS,CAAA;CAAC,CAAC;AAEpD,oBAAY,WAAW;IACrB,aAAa,UAAU;IACvB,YAAY,SAAS;CACtB;AAGD,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAGF,MAAM,MAAM,OAAO,GACf,CAAC,cAAc,GAAG,eAAe,CAAC,GAClC,CAAC,UAAU,GAAG,WAAW,CAAC,CAAC;AAG/B,MAAM,MAAM,eAAe,GACvB,CAAC,sBAAsB,GAAG,eAAe,CAAC,GAC1C,CAAC,kBAAkB,GAAG,WAAW,CAAC,CAAC;AAGvC,MAAM,MAAM,oBAAoB,GAC5B,CAAC,sBAAsB,GAAG,eAAe,GAAG;
|
|
1
|
+
{"version":3,"file":"ExpoIap.types.d.ts","sourceRoot":"","sources":["../src/ExpoIap.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoIap.types.js","sourceRoot":"","sources":["../src/ExpoIap.types.ts"],"names":[],"mappings":"AAqCA,MAAM,CAAN,IAAY,WAGX;AAHD,WAAY,WAAW;IACrB,sCAAuB,CAAA;IACvB,oCAAqB,CAAA;AACvB,CAAC,EAHW,WAAW,KAAX,WAAW,QAGtB;AAgDD,MAAM,CAAN,IAAY,SAkBX;AAlBD,WAAY,SAAS;IACnB,oCAAuB,CAAA;IACvB,kDAAqC,CAAA;IACrC,0CAA6B,CAAA;IAC7B,sDAAyC,CAAA;IACzC,8CAAiC,CAAA;IACjC,gDAAmC,CAAA;IACnC,gDAAmC,CAAA;IACnC,kDAAqC,CAAA;IACrC,oEAAuD,CAAA;IACvD,8CAAiC,CAAA;IACjC,wCAA2B,CAAA;IAC3B,gDAAmC,CAAA;IACnC,oDAAuC,CAAA;IACvC,wFAA2E,CAAA;IAC3E,sDAAyC,CAAA;IACzC,4CAA+B,CAAA;IAC/B,wDAA2C,CAAA;AAC7C,CAAC,EAlBW,SAAS,KAAT,SAAS,QAkBpB;AAED,MAAM,OAAO,aAAa;IAEf;IACA;IACA;IACA;IACA;IACA;IANT,YACS,IAAY,EACZ,OAAe,EACf,YAAqB,EACrB,YAAqB,EACrB,IAAgB,EAChB,SAAkB;QALlB,SAAI,GAAJ,IAAI,CAAQ;QACZ,YAAO,GAAP,OAAO,CAAQ;QACf,iBAAY,GAAZ,YAAY,CAAS;QACrB,iBAAY,GAAZ,YAAY,CAAS;QACrB,SAAI,GAAJ,IAAI,CAAY;QAChB,cAAS,GAAT,SAAS,CAAS;QAEzB,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;QACxC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;CACF","sourcesContent":["import {\n ProductAndroid,\n ProductPurchaseAndroid,\n RequestPurchaseAndroidProps,\n RequestSubscriptionAndroidProps,\n SubscriptionProductAndroid,\n} from './types/ExpoIapAndroid.types';\nimport {\n ProductIos,\n ProductPurchaseIos,\n RequestPurchaseIosProps,\n RequestSubscriptionIosProps,\n SubscriptionProductIos,\n} from './types/ExpoIapIos.types';\n\nexport type ChangeEventPayload = {\n value: string;\n};\n\n/**\n * Base product type with common properties shared between iOS and Android\n */\nexport type ProductBase = {\n id: string;\n title: string;\n description: string;\n type: ProductType;\n displayName?: string;\n displayPrice?: string;\n price?: number;\n currency?: string;\n};\n\n// Define literal platform types for better type discrimination\nexport type IosPlatform = {platform: 'ios'};\nexport type AndroidPlatform = {platform: 'android'};\n\nexport enum ProductType {\n InAppPurchase = 'inapp',\n Subscription = 'subs',\n}\n\n// Common base purchase type\nexport type PurchaseBase = {\n id: string;\n transactionId?: string;\n transactionDate: number;\n transactionReceipt: string;\n purchaseToken?: string;\n};\n\n// Union type for platform-specific product types with proper discriminators\nexport type Product =\n | (ProductAndroid & AndroidPlatform)\n | (ProductIos & IosPlatform);\n\n// Union type for platform-specific purchase types with proper discriminators\nexport type ProductPurchase =\n | (ProductPurchaseAndroid & AndroidPlatform)\n | (ProductPurchaseIos & IosPlatform);\n\n// Union type for platform-specific subscription purchase types with proper discriminators\nexport type SubscriptionPurchase =\n | (ProductPurchaseAndroid & AndroidPlatform & {
|
|
1
|
+
{"version":3,"file":"ExpoIap.types.js","sourceRoot":"","sources":["../src/ExpoIap.types.ts"],"names":[],"mappings":"AAqCA,MAAM,CAAN,IAAY,WAGX;AAHD,WAAY,WAAW;IACrB,sCAAuB,CAAA;IACvB,oCAAqB,CAAA;AACvB,CAAC,EAHW,WAAW,KAAX,WAAW,QAGtB;AAgDD,MAAM,CAAN,IAAY,SAkBX;AAlBD,WAAY,SAAS;IACnB,oCAAuB,CAAA;IACvB,kDAAqC,CAAA;IACrC,0CAA6B,CAAA;IAC7B,sDAAyC,CAAA;IACzC,8CAAiC,CAAA;IACjC,gDAAmC,CAAA;IACnC,gDAAmC,CAAA;IACnC,kDAAqC,CAAA;IACrC,oEAAuD,CAAA;IACvD,8CAAiC,CAAA;IACjC,wCAA2B,CAAA;IAC3B,gDAAmC,CAAA;IACnC,oDAAuC,CAAA;IACvC,wFAA2E,CAAA;IAC3E,sDAAyC,CAAA;IACzC,4CAA+B,CAAA;IAC/B,wDAA2C,CAAA;AAC7C,CAAC,EAlBW,SAAS,KAAT,SAAS,QAkBpB;AAED,MAAM,OAAO,aAAa;IAEf;IACA;IACA;IACA;IACA;IACA;IANT,YACS,IAAY,EACZ,OAAe,EACf,YAAqB,EACrB,YAAqB,EACrB,IAAgB,EAChB,SAAkB;QALlB,SAAI,GAAJ,IAAI,CAAQ;QACZ,YAAO,GAAP,OAAO,CAAQ;QACf,iBAAY,GAAZ,YAAY,CAAS;QACrB,iBAAY,GAAZ,YAAY,CAAS;QACrB,SAAI,GAAJ,IAAI,CAAY;QAChB,cAAS,GAAT,SAAS,CAAS;QAEzB,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;QACxC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;CACF","sourcesContent":["import {\n ProductAndroid,\n ProductPurchaseAndroid,\n RequestPurchaseAndroidProps,\n RequestSubscriptionAndroidProps,\n SubscriptionProductAndroid,\n} from './types/ExpoIapAndroid.types';\nimport {\n ProductIos,\n ProductPurchaseIos,\n RequestPurchaseIosProps,\n RequestSubscriptionIosProps,\n SubscriptionProductIos,\n} from './types/ExpoIapIos.types';\n\nexport type ChangeEventPayload = {\n value: string;\n};\n\n/**\n * Base product type with common properties shared between iOS and Android\n */\nexport type ProductBase = {\n id: string;\n title: string;\n description: string;\n type: ProductType;\n displayName?: string;\n displayPrice?: string;\n price?: number;\n currency?: string;\n};\n\n// Define literal platform types for better type discrimination\nexport type IosPlatform = {platform: 'ios'};\nexport type AndroidPlatform = {platform: 'android'};\n\nexport enum ProductType {\n InAppPurchase = 'inapp',\n Subscription = 'subs',\n}\n\n// Common base purchase type\nexport type PurchaseBase = {\n id: string;\n transactionId?: string;\n transactionDate: number;\n transactionReceipt: string;\n purchaseToken?: string;\n};\n\n// Union type for platform-specific product types with proper discriminators\nexport type Product =\n | (ProductAndroid & AndroidPlatform)\n | (ProductIos & IosPlatform);\n\n// Union type for platform-specific purchase types with proper discriminators\nexport type ProductPurchase =\n | (ProductPurchaseAndroid & AndroidPlatform)\n | (ProductPurchaseIos & IosPlatform);\n\n// Union type for platform-specific subscription purchase types with proper discriminators\nexport type SubscriptionPurchase =\n | (ProductPurchaseAndroid & AndroidPlatform & {autoRenewingAndroid: boolean})\n | (ProductPurchaseIos & IosPlatform);\n\nexport type Purchase = ProductPurchase | SubscriptionPurchase;\n\nexport type RequestPurchaseProps =\n | RequestPurchaseIosProps\n | RequestPurchaseAndroidProps;\n\nexport type SubscriptionProduct =\n | (SubscriptionProductAndroid & AndroidPlatform)\n | (SubscriptionProductIos & IosPlatform);\n\nexport type RequestSubscriptionProps =\n | RequestSubscriptionAndroidProps\n | RequestSubscriptionIosProps;\n\nexport type PurchaseResult = {\n responseCode?: number;\n debugMessage?: string;\n code?: string;\n message?: string;\n purchaseToken?: string;\n};\n\nexport enum ErrorCode {\n E_UNKNOWN = 'E_UNKNOWN',\n E_USER_CANCELLED = 'E_USER_CANCELLED',\n E_USER_ERROR = 'E_USER_ERROR',\n E_ITEM_UNAVAILABLE = 'E_ITEM_UNAVAILABLE',\n E_REMOTE_ERROR = 'E_REMOTE_ERROR',\n E_NETWORK_ERROR = 'E_NETWORK_ERROR',\n E_SERVICE_ERROR = 'E_SERVICE_ERROR',\n E_RECEIPT_FAILED = 'E_RECEIPT_FAILED',\n E_RECEIPT_FINISHED_FAILED = 'E_RECEIPT_FINISHED_FAILED',\n E_NOT_PREPARED = 'E_NOT_PREPARED',\n E_NOT_ENDED = 'E_NOT_ENDED',\n E_ALREADY_OWNED = 'E_ALREADY_OWNED',\n E_DEVELOPER_ERROR = 'E_DEVELOPER_ERROR',\n E_BILLING_RESPONSE_JSON_PARSE_ERROR = 'E_BILLING_RESPONSE_JSON_PARSE_ERROR',\n E_DEFERRED_PAYMENT = 'E_DEFERRED_PAYMENT',\n E_INTERRUPTED = 'E_INTERRUPTED',\n E_IAP_NOT_AVAILABLE = 'E_IAP_NOT_AVAILABLE',\n}\n\nexport class PurchaseError implements Error {\n constructor(\n public name: string,\n public message: string,\n public responseCode?: number,\n public debugMessage?: string,\n public code?: ErrorCode,\n public productId?: string,\n ) {\n this.name = '[expo-iap]: PurchaseError';\n this.message = message;\n this.responseCode = responseCode;\n this.debugMessage = debugMessage;\n this.code = code;\n this.productId = productId;\n }\n}\n"]}
|
package/build/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export declare enum IapEvent {
|
|
|
10
10
|
PurchaseError = "purchase-error",
|
|
11
11
|
TransactionIapUpdated = "iap-transaction-updated"
|
|
12
12
|
}
|
|
13
|
-
export declare function setValueAsync(value: string):
|
|
13
|
+
export declare function setValueAsync(value: string): any;
|
|
14
14
|
export declare const emitter: EventEmitter;
|
|
15
15
|
export declare const purchaseUpdatedListener: (listener: (event: Purchase) => void) => import("expo-modules-core").Subscription;
|
|
16
16
|
export declare const purchaseErrorListener: (listener: (error: PurchaseError) => void) => import("expo-modules-core").Subscription;
|
|
@@ -28,10 +28,9 @@ export declare const getAvailablePurchases: ({ alsoPublishToEventListener, onlyI
|
|
|
28
28
|
}) => Promise<ProductPurchase[]>;
|
|
29
29
|
export declare const requestPurchase: (request: RequestPurchaseIosProps | RequestPurchaseAndroidProps) => Promise<ProductPurchase | ProductPurchase[] | void>;
|
|
30
30
|
export declare const requestSubscription: (request: RequestSubscriptionProps) => Promise<SubscriptionPurchase | SubscriptionPurchase[] | null | void>;
|
|
31
|
-
export declare const finishTransaction: ({ purchase, isConsumable,
|
|
31
|
+
export declare const finishTransaction: ({ purchase, isConsumable, }: {
|
|
32
32
|
purchase: Purchase;
|
|
33
33
|
isConsumable?: boolean;
|
|
34
|
-
developerPayloadAndroid?: string;
|
|
35
34
|
}) => Promise<PurchaseResult | boolean>;
|
|
36
35
|
export * from './useIap';
|
|
37
36
|
//# sourceMappingURL=index.d.ts.map
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAqB,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAEnE,OAAO,EACL,OAAO,EACP,eAAe,EAEf,QAAQ,EACR,aAAa,EACb,cAAc,EACd,wBAAwB,EACxB,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,2BAA2B,EAE5B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAEL,uBAAuB,EAExB,MAAM,0BAA0B,CAAC;AAOlC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAG9B,eAAO,MAAM,EAAE,KAAmB,CAAC;AAEnC,oBAAY,QAAQ;IAClB,eAAe,qBAAqB;IACpC,aAAa,mBAAmB;IAChC,qBAAqB,4BAA4B;CAClD;AAED,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAqB,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAEnE,OAAO,EACL,OAAO,EACP,eAAe,EAEf,QAAQ,EACR,aAAa,EACb,cAAc,EACd,wBAAwB,EACxB,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,2BAA2B,EAE5B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAEL,uBAAuB,EAExB,MAAM,0BAA0B,CAAC;AAOlC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAG9B,eAAO,MAAM,EAAE,KAAmB,CAAC;AAEnC,oBAAY,QAAQ;IAClB,eAAe,qBAAqB;IACpC,aAAa,mBAAmB;IAChC,qBAAqB,4BAA4B;CAClD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,OAE1C;AAED,eAAO,MAAM,OAAO,cAEnB,CAAC;AAEF,eAAO,MAAM,uBAAuB,aACxB,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,6CAOpC,CAAC;AAEF,eAAO,MAAM,qBAAqB,aACtB,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,6CAGzC,CAAC;AAEF,wBAAgB,cAAc,QAE7B;AAED,eAAO,MAAM,WAAW,SAAgB,MAAM,EAAE,KAAG,QAAQ,OAAO,EAAE,CAsBnE,CAAC;AAEF,eAAO,MAAM,gBAAgB,SACrB,MAAM,EAAE,KACb,QAAQ,mBAAmB,EAAE,CAkC/B,CAAC;AAEF,wBAAsB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAEtD;AAED,eAAO,MAAM,kBAAkB,6DAG5B;IACD,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC,KAAQ,QAAQ,eAAe,EAAE,CAmB7B,CAAC;AAEN,eAAO,MAAM,qBAAqB,6DAG/B;IACD,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC,KAAQ,QAAQ,eAAe,EAAE,CAkB7B,CAAC;AAiBN,eAAO,MAAM,eAAe,YACjB,uBAAuB,GAAG,2BAA2B,KAC7D,QAAQ,eAAe,GAAG,eAAe,EAAE,GAAG,IAAI,CA8ChD,CAAC;AAEN,eAAO,MAAM,mBAAmB,YACrB,wBAAwB,KAChC,QAAQ,oBAAoB,GAAG,oBAAoB,EAAE,GAAG,IAAI,GAAG,IAAI,CA8CjE,CAAC;AAEN,eAAO,MAAM,iBAAiB,gCAG3B;IACD,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,KAAG,QAAQ,cAAc,GAAG,OAAO,CA2BnC,CAAC;AAEF,cAAc,UAAU,CAAC"}
|
package/build/index.js
CHANGED
|
@@ -16,10 +16,10 @@ export var IapEvent;
|
|
|
16
16
|
IapEvent["PurchaseError"] = "purchase-error";
|
|
17
17
|
IapEvent["TransactionIapUpdated"] = "iap-transaction-updated";
|
|
18
18
|
})(IapEvent || (IapEvent = {}));
|
|
19
|
-
export
|
|
20
|
-
return
|
|
19
|
+
export function setValueAsync(value) {
|
|
20
|
+
return ExpoIapModule.setValueAsync(value);
|
|
21
21
|
}
|
|
22
|
-
export const emitter = new EventEmitter(ExpoIapModule
|
|
22
|
+
export const emitter = new EventEmitter(ExpoIapModule || NativeModulesProxy.ExpoIap);
|
|
23
23
|
export const purchaseUpdatedListener = (listener) => {
|
|
24
24
|
const emitterSubscription = emitter.addListener(IapEvent.PurchaseUpdated, listener);
|
|
25
25
|
return emitterSubscription;
|
|
@@ -31,14 +31,12 @@ export function initConnection() {
|
|
|
31
31
|
return ExpoIapModule.initConnection();
|
|
32
32
|
}
|
|
33
33
|
export const getProducts = async (skus) => {
|
|
34
|
-
console.log('getProducts', skus);
|
|
35
34
|
if (!skus?.length) {
|
|
36
35
|
return Promise.reject(new Error('"skus" is required'));
|
|
37
36
|
}
|
|
38
37
|
return Platform.select({
|
|
39
38
|
ios: async () => {
|
|
40
39
|
const items = await ExpoIapModule.getItems(skus);
|
|
41
|
-
console.log('items', items);
|
|
42
40
|
return items.filter((item) => isProductIos(item));
|
|
43
41
|
},
|
|
44
42
|
android: async () => {
|
|
@@ -118,9 +116,9 @@ export const requestPurchase = (request) => (Platform.select({
|
|
|
118
116
|
if (!('sku' in request)) {
|
|
119
117
|
throw new Error('sku is required for iOS purchase');
|
|
120
118
|
}
|
|
121
|
-
const { sku, appAccountToken, quantity, withOffer } = request;
|
|
119
|
+
const { sku, andDangerouslyFinishTransactionAutomaticallyIOS = false, appAccountToken, quantity, withOffer, } = request;
|
|
122
120
|
const offer = offerToRecordIos(withOffer);
|
|
123
|
-
const purchase = await ExpoIapModule.buyProduct(sku, appAccountToken, quantity ?? -1, offer);
|
|
121
|
+
const purchase = await ExpoIapModule.buyProduct(sku, andDangerouslyFinishTransactionAutomaticallyIOS, appAccountToken, quantity ?? -1, offer);
|
|
124
122
|
return Promise.resolve(purchase);
|
|
125
123
|
},
|
|
126
124
|
android: async () => {
|
|
@@ -145,9 +143,9 @@ export const requestSubscription = (request) => (Platform.select({
|
|
|
145
143
|
if (!('sku' in request)) {
|
|
146
144
|
throw new Error('sku is required for iOS subscriptions');
|
|
147
145
|
}
|
|
148
|
-
const { sku, appAccountToken, quantity, withOffer } = request;
|
|
146
|
+
const { sku, andDangerouslyFinishTransactionAutomaticallyIOS = false, appAccountToken, quantity, withOffer, } = request;
|
|
149
147
|
const offer = offerToRecordIos(withOffer);
|
|
150
|
-
const purchase = await ExpoIapModule.buyProduct(sku, appAccountToken, quantity ?? -1, offer);
|
|
148
|
+
const purchase = await ExpoIapModule.buyProduct(sku, andDangerouslyFinishTransactionAutomaticallyIOS, appAccountToken, quantity ?? -1, offer);
|
|
151
149
|
return Promise.resolve(purchase);
|
|
152
150
|
},
|
|
153
151
|
android: async () => {
|
|
@@ -164,7 +162,7 @@ export const requestSubscription = (request) => (Platform.select({
|
|
|
164
162
|
});
|
|
165
163
|
},
|
|
166
164
|
}) || (() => Promise.resolve(null)))();
|
|
167
|
-
export const finishTransaction = ({ purchase, isConsumable,
|
|
165
|
+
export const finishTransaction = ({ purchase, isConsumable, }) => {
|
|
168
166
|
return (Platform.select({
|
|
169
167
|
ios: async () => {
|
|
170
168
|
const transactionId = purchase.transactionId;
|
|
@@ -175,13 +173,15 @@ export const finishTransaction = ({ purchase, isConsumable, developerPayloadAndr
|
|
|
175
173
|
return Promise.resolve(true);
|
|
176
174
|
},
|
|
177
175
|
android: async () => {
|
|
178
|
-
if (purchase?.purchaseToken) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
return ExpoIapModule.consumeProduct(purchase.purchaseToken
|
|
176
|
+
if (!purchase?.purchaseToken) {
|
|
177
|
+
return Promise.reject(new Error('purchaseToken is required to finish transaction'));
|
|
178
|
+
}
|
|
179
|
+
if (isConsumable) {
|
|
180
|
+
return ExpoIapModule.consumeProduct(purchase.purchaseToken);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
return ExpoIapModule.acknowledgePurchase(purchase.purchaseToken);
|
|
183
184
|
}
|
|
184
|
-
return Promise.reject(new Error('purchase is not suitable to be purchased'));
|
|
185
185
|
},
|
|
186
186
|
}) || (() => Promise.reject(new Error('Unsupported Platform'))))();
|
|
187
187
|
};
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// Import the native module. On web, it will be resolved to ExpoIap.web.ts\n// and on native platforms to ExpoIap.ts\nimport {NativeModulesProxy, EventEmitter} from 'expo-modules-core';\nimport {Platform} from 'react-native';\nimport {\n Product,\n ProductPurchase,\n ProductType,\n Purchase,\n PurchaseError,\n PurchaseResult,\n RequestSubscriptionProps,\n SubscriptionProduct,\n SubscriptionPurchase,\n} from './ExpoIap.types';\nimport ExpoIapModule from './ExpoIapModule';\nimport {\n RequestPurchaseAndroidProps,\n RequestSubscriptionAndroidProps,\n} from './types/ExpoIapAndroid.types';\nimport {\n PaymentDiscount,\n RequestPurchaseIosProps,\n RequestSubscriptionIosProps,\n} from './types/ExpoIapIos.types';\nimport {isProductIos, isSubscriptionProductIos} from './modules/ios';\nimport {\n isProductAndroid,\n isSubscriptionProductAndroid,\n} from './modules/android';\n\nexport * from './modules/android';\nexport * from './modules/ios';\n\n// Get the native constant value.\nexport const PI = ExpoIapModule.PI;\n\nexport enum IapEvent {\n PurchaseUpdated = 'purchase-updated',\n PurchaseError = 'purchase-error',\n TransactionIapUpdated = 'iap-transaction-updated',\n}\n\nexport async function setValueAsync(value: string) {\n return await ExpoIapModule.setValueAsync(value);\n}\n\nexport const emitter = new EventEmitter(\n ExpoIapModule ?? NativeModulesProxy.ExpoIap,\n);\n\nexport const purchaseUpdatedListener = (\n listener: (event: Purchase) => void,\n) => {\n const emitterSubscription = emitter.addListener(\n IapEvent.PurchaseUpdated,\n listener,\n );\n return emitterSubscription;\n};\n\nexport const purchaseErrorListener = (\n listener: (error: PurchaseError) => void,\n) => {\n return emitter.addListener<PurchaseError>(IapEvent.PurchaseError, listener);\n};\n\nexport function initConnection() {\n return ExpoIapModule.initConnection();\n}\n\nexport const getProducts = async (skus: string[]): Promise<Product[]> => {\n console.log('getProducts', skus);\n if (!skus?.length) {\n return Promise.reject(new Error('\"skus\" is required'));\n }\n\n return Platform.select({\n ios: async () => {\n const items = await ExpoIapModule.getItems(skus);\n console.log('items', items);\n return items.filter((item: unknown) => isProductIos<Product>(item));\n },\n android: async () => {\n const products = await ExpoIapModule.getItemsByType(\n ProductType.InAppPurchase,\n skus,\n );\n return products.filter((product: unknown) =>\n isProductAndroid<Product>(product),\n );\n },\n default: () => Promise.reject(new Error('Unsupported Platform')),\n })();\n};\n\nexport const getSubscriptions = async (\n skus: string[],\n): Promise<SubscriptionProduct[]> => {\n if (!skus?.length) {\n return Promise.reject(new Error('\"skus\" is required'));\n }\n\n return Platform.select({\n ios: async () => {\n const rawItems = await ExpoIapModule.getItems(skus);\n\n return rawItems.filter((item: unknown) => {\n if (!isSubscriptionProductIos(item)) return false;\n return (\n typeof item === 'object' &&\n item !== null &&\n 'id' in item &&\n typeof item.id === 'string' &&\n skus.includes(item.id)\n );\n }) as SubscriptionProduct[];\n },\n android: async () => {\n const rawItems = await ExpoIapModule.getItemsByType('subs', skus);\n\n return rawItems.filter((item: unknown) => {\n if (!isSubscriptionProductAndroid(item)) return false;\n return (\n typeof item === 'object' &&\n item !== null &&\n 'id' in item &&\n typeof item.id === 'string' &&\n skus.includes(item.id)\n );\n }) as SubscriptionProduct[];\n },\n default: () => Promise.reject(new Error('Unsupported Platform')),\n })();\n};\n\nexport async function endConnection(): Promise<boolean> {\n return ExpoIapModule.endConnection();\n}\n\nexport const getPurchaseHistory = ({\n alsoPublishToEventListener = false,\n onlyIncludeActiveItems = false,\n}: {\n alsoPublishToEventListener?: boolean;\n onlyIncludeActiveItems?: boolean;\n} = {}): Promise<ProductPurchase[]> =>\n (\n Platform.select({\n ios: async () => {\n return ExpoIapModule.getAvailableItems(\n alsoPublishToEventListener,\n onlyIncludeActiveItems,\n );\n },\n android: async () => {\n const products = await ExpoIapModule.getPurchaseHistoryByType(\n ProductType.InAppPurchase,\n );\n\n const subscriptions = await ExpoIapModule.getPurchaseHistoryByType(\n ProductType.Subscription,\n );\n\n return products.concat(subscriptions);\n },\n }) || (() => Promise.resolve([]))\n )();\n\nexport const getAvailablePurchases = ({\n alsoPublishToEventListener = false,\n onlyIncludeActiveItems = true,\n}: {\n alsoPublishToEventListener?: boolean;\n onlyIncludeActiveItems?: boolean;\n} = {}): Promise<ProductPurchase[]> =>\n (\n Platform.select({\n ios: () =>\n ExpoIapModule.getAvailableItems(\n alsoPublishToEventListener,\n onlyIncludeActiveItems,\n ),\n android: async () => {\n const products = await ExpoIapModule.getAvailableItemsByType(\n ProductType.InAppPurchase,\n );\n\n const subscriptions = await ExpoIapModule.getAvailableItemsByType(\n ProductType.Subscription,\n );\n\n return products.concat(subscriptions);\n },\n }) || (() => Promise.resolve([]))\n )();\n\nconst offerToRecordIos = (\n offer: PaymentDiscount | undefined,\n): Record<keyof PaymentDiscount, string> | undefined => {\n if (!offer) {\n return undefined;\n }\n return {\n identifier: offer.identifier,\n keyIdentifier: offer.keyIdentifier,\n nonce: offer.nonce,\n signature: offer.signature,\n timestamp: offer.timestamp.toString(),\n };\n};\n\nexport const requestPurchase = (\n request: RequestPurchaseIosProps | RequestPurchaseAndroidProps,\n): Promise<ProductPurchase | ProductPurchase[] | void> =>\n (\n Platform.select({\n ios: async () => {\n if (!('sku' in request)) {\n throw new Error('sku is required for iOS purchase');\n }\n\n const {sku, appAccountToken, quantity, withOffer} = request;\n\n const offer = offerToRecordIos(withOffer);\n\n const purchase = await ExpoIapModule.buyProduct(\n sku,\n appAccountToken,\n quantity ?? -1,\n offer,\n );\n\n return Promise.resolve(purchase);\n },\n android: async () => {\n if (!('skus' in request) || !request.skus.length) {\n throw new Error('skus is required for Android purchase');\n }\n\n const {\n skus,\n obfuscatedAccountIdAndroid,\n obfuscatedProfileIdAndroid,\n isOfferPersonalized,\n } = request;\n\n return ExpoIapModule.buyItemByType({\n type: ProductType.InAppPurchase,\n skuArr: skus,\n purchaseToken: undefined,\n replacementMode: -1,\n obfuscatedAccountId: obfuscatedAccountIdAndroid,\n obfuscatedProfileId: obfuscatedProfileIdAndroid,\n offerTokenArr: [],\n isOfferPersonalized: isOfferPersonalized ?? false,\n });\n },\n }) || Promise.resolve\n )();\n\nexport const requestSubscription = (\n request: RequestSubscriptionProps,\n): Promise<SubscriptionPurchase | SubscriptionPurchase[] | null | void> =>\n (\n Platform.select({\n ios: async () => {\n if (!('sku' in request)) {\n throw new Error('sku is required for iOS subscriptions');\n }\n\n const {sku, appAccountToken, quantity, withOffer} =\n request as RequestSubscriptionIosProps;\n\n const offer = offerToRecordIos(withOffer);\n\n const purchase = await ExpoIapModule.buyProduct(\n sku,\n appAccountToken,\n quantity ?? -1,\n offer,\n );\n\n return Promise.resolve(purchase as SubscriptionPurchase);\n },\n android: async () => {\n const {\n skus,\n isOfferPersonalized,\n obfuscatedAccountIdAndroid,\n obfuscatedProfileIdAndroid,\n subscriptionOffers,\n replacementModeAndroid,\n purchaseTokenAndroid,\n } = request as RequestSubscriptionAndroidProps;\n\n return ExpoIapModule.buyItemByType({\n type: ProductType.Subscription,\n skuArr: skus.map((so) => so),\n purchaseToken: purchaseTokenAndroid,\n replacementMode: replacementModeAndroid,\n obfuscatedAccountId: obfuscatedAccountIdAndroid,\n obfuscatedProfileId: obfuscatedProfileIdAndroid,\n offerTokenArr: subscriptionOffers.map((so) => so.offerToken),\n isOfferPersonalized: isOfferPersonalized ?? false,\n });\n },\n }) || (() => Promise.resolve(null))\n )();\n\nexport const finishTransaction = ({\n purchase,\n isConsumable,\n developerPayloadAndroid,\n}: {\n purchase: Purchase;\n isConsumable?: boolean;\n developerPayloadAndroid?: string;\n}): Promise<PurchaseResult | boolean> => {\n return (\n Platform.select({\n ios: async () => {\n const transactionId = purchase.transactionId;\n\n if (!transactionId) {\n return Promise.reject(\n new Error('transactionId required to finish iOS transaction'),\n );\n }\n await ExpoIapModule.finishTransaction(transactionId);\n return Promise.resolve(true);\n },\n android: async () => {\n if (purchase?.purchaseToken) {\n if (!isConsumable) {\n return Promise.reject(\n new Error('purchase is not suitable to be purchased'),\n );\n }\n\n return ExpoIapModule.consumeProduct(\n purchase.purchaseToken,\n developerPayloadAndroid,\n );\n }\n return Promise.reject(\n new Error('purchase is not suitable to be purchased'),\n );\n },\n }) || (() => Promise.reject(new Error('Unsupported Platform')))\n )();\n};\n\nexport * from './useIap';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// Import the native module. On web, it will be resolved to ExpoIap.web.ts\n// and on native platforms to ExpoIap.ts\nimport {NativeModulesProxy, EventEmitter} from 'expo-modules-core';\nimport {Platform} from 'react-native';\nimport {\n Product,\n ProductPurchase,\n ProductType,\n Purchase,\n PurchaseError,\n PurchaseResult,\n RequestSubscriptionProps,\n SubscriptionProduct,\n SubscriptionPurchase,\n} from './ExpoIap.types';\nimport ExpoIapModule from './ExpoIapModule';\nimport {\n RequestPurchaseAndroidProps,\n RequestSubscriptionAndroidProps,\n} from './types/ExpoIapAndroid.types';\nimport {\n PaymentDiscount,\n RequestPurchaseIosProps,\n RequestSubscriptionIosProps,\n} from './types/ExpoIapIos.types';\nimport {isProductIos, isSubscriptionProductIos} from './modules/ios';\nimport {\n isProductAndroid,\n isSubscriptionProductAndroid,\n} from './modules/android';\n\nexport * from './modules/android';\nexport * from './modules/ios';\n\n// Get the native constant value.\nexport const PI = ExpoIapModule.PI;\n\nexport enum IapEvent {\n PurchaseUpdated = 'purchase-updated',\n PurchaseError = 'purchase-error',\n TransactionIapUpdated = 'iap-transaction-updated',\n}\n\nexport function setValueAsync(value: string) {\n return ExpoIapModule.setValueAsync(value);\n}\n\nexport const emitter = new EventEmitter(\n ExpoIapModule || NativeModulesProxy.ExpoIap,\n);\n\nexport const purchaseUpdatedListener = (\n listener: (event: Purchase) => void,\n) => {\n const emitterSubscription = emitter.addListener(\n IapEvent.PurchaseUpdated,\n listener,\n );\n return emitterSubscription;\n};\n\nexport const purchaseErrorListener = (\n listener: (error: PurchaseError) => void,\n) => {\n return emitter.addListener<PurchaseError>(IapEvent.PurchaseError, listener);\n};\n\nexport function initConnection() {\n return ExpoIapModule.initConnection();\n}\n\nexport const getProducts = async (skus: string[]): Promise<Product[]> => {\n if (!skus?.length) {\n return Promise.reject(new Error('\"skus\" is required'));\n }\n\n return Platform.select({\n ios: async () => {\n const items = await ExpoIapModule.getItems(skus);\n return items.filter((item: unknown) => isProductIos<Product>(item));\n },\n android: async () => {\n const products = await ExpoIapModule.getItemsByType(\n ProductType.InAppPurchase,\n skus,\n );\n\n return products.filter((product: unknown) =>\n isProductAndroid<Product>(product),\n );\n },\n default: () => Promise.reject(new Error('Unsupported Platform')),\n })();\n};\n\nexport const getSubscriptions = async (\n skus: string[],\n): Promise<SubscriptionProduct[]> => {\n if (!skus?.length) {\n return Promise.reject(new Error('\"skus\" is required'));\n }\n\n return Platform.select({\n ios: async () => {\n const rawItems = await ExpoIapModule.getItems(skus);\n return rawItems.filter((item: unknown) => {\n if (!isSubscriptionProductIos(item)) return false;\n return (\n typeof item === 'object' &&\n item !== null &&\n 'id' in item &&\n typeof item.id === 'string' &&\n skus.includes(item.id)\n );\n }) as SubscriptionProduct[];\n },\n android: async () => {\n const rawItems = await ExpoIapModule.getItemsByType('subs', skus);\n return rawItems.filter((item: unknown) => {\n if (!isSubscriptionProductAndroid(item)) return false;\n return (\n typeof item === 'object' &&\n item !== null &&\n 'id' in item &&\n typeof item.id === 'string' &&\n skus.includes(item.id)\n );\n }) as SubscriptionProduct[];\n },\n default: () => Promise.reject(new Error('Unsupported Platform')),\n })();\n};\n\nexport async function endConnection(): Promise<boolean> {\n return ExpoIapModule.endConnection();\n}\n\nexport const getPurchaseHistory = ({\n alsoPublishToEventListener = false,\n onlyIncludeActiveItems = false,\n}: {\n alsoPublishToEventListener?: boolean;\n onlyIncludeActiveItems?: boolean;\n} = {}): Promise<ProductPurchase[]> =>\n (\n Platform.select({\n ios: async () => {\n return ExpoIapModule.getAvailableItems(\n alsoPublishToEventListener,\n onlyIncludeActiveItems,\n );\n },\n android: async () => {\n const products = await ExpoIapModule.getPurchaseHistoryByType(\n ProductType.InAppPurchase,\n );\n const subscriptions = await ExpoIapModule.getPurchaseHistoryByType(\n ProductType.Subscription,\n );\n return products.concat(subscriptions);\n },\n }) || (() => Promise.resolve([]))\n )();\n\nexport const getAvailablePurchases = ({\n alsoPublishToEventListener = false,\n onlyIncludeActiveItems = true,\n}: {\n alsoPublishToEventListener?: boolean;\n onlyIncludeActiveItems?: boolean;\n} = {}): Promise<ProductPurchase[]> =>\n (\n Platform.select({\n ios: () =>\n ExpoIapModule.getAvailableItems(\n alsoPublishToEventListener,\n onlyIncludeActiveItems,\n ),\n android: async () => {\n const products = await ExpoIapModule.getAvailableItemsByType(\n ProductType.InAppPurchase,\n );\n const subscriptions = await ExpoIapModule.getAvailableItemsByType(\n ProductType.Subscription,\n );\n return products.concat(subscriptions);\n },\n }) || (() => Promise.resolve([]))\n )();\n\nconst offerToRecordIos = (\n offer: PaymentDiscount | undefined,\n): Record<keyof PaymentDiscount, string> | undefined => {\n if (!offer) {\n return undefined;\n }\n return {\n identifier: offer.identifier,\n keyIdentifier: offer.keyIdentifier,\n nonce: offer.nonce,\n signature: offer.signature,\n timestamp: offer.timestamp.toString(),\n };\n};\n\nexport const requestPurchase = (\n request: RequestPurchaseIosProps | RequestPurchaseAndroidProps,\n): Promise<ProductPurchase | ProductPurchase[] | void> =>\n (\n Platform.select({\n ios: async () => {\n if (!('sku' in request)) {\n throw new Error('sku is required for iOS purchase');\n }\n const {\n sku,\n andDangerouslyFinishTransactionAutomaticallyIOS = false,\n appAccountToken,\n quantity,\n withOffer,\n } = request;\n const offer = offerToRecordIos(withOffer);\n const purchase = await ExpoIapModule.buyProduct(\n sku,\n andDangerouslyFinishTransactionAutomaticallyIOS,\n appAccountToken,\n quantity ?? -1,\n offer,\n );\n return Promise.resolve(purchase);\n },\n android: async () => {\n if (!('skus' in request) || !request.skus.length) {\n throw new Error('skus is required for Android purchase');\n }\n const {\n skus,\n obfuscatedAccountIdAndroid,\n obfuscatedProfileIdAndroid,\n isOfferPersonalized,\n } = request;\n return ExpoIapModule.buyItemByType({\n type: ProductType.InAppPurchase,\n skuArr: skus,\n purchaseToken: undefined,\n replacementMode: -1,\n obfuscatedAccountId: obfuscatedAccountIdAndroid,\n obfuscatedProfileId: obfuscatedProfileIdAndroid,\n offerTokenArr: [],\n isOfferPersonalized: isOfferPersonalized ?? false,\n });\n },\n }) || Promise.resolve\n )();\n\nexport const requestSubscription = (\n request: RequestSubscriptionProps,\n): Promise<SubscriptionPurchase | SubscriptionPurchase[] | null | void> =>\n (\n Platform.select({\n ios: async () => {\n if (!('sku' in request)) {\n throw new Error('sku is required for iOS subscriptions');\n }\n const {\n sku,\n andDangerouslyFinishTransactionAutomaticallyIOS = false,\n appAccountToken,\n quantity,\n withOffer,\n } = request as RequestSubscriptionIosProps;\n const offer = offerToRecordIos(withOffer);\n const purchase = await ExpoIapModule.buyProduct(\n sku,\n andDangerouslyFinishTransactionAutomaticallyIOS,\n appAccountToken,\n quantity ?? -1,\n offer,\n );\n return Promise.resolve(purchase as SubscriptionPurchase);\n },\n android: async () => {\n const {\n skus,\n isOfferPersonalized,\n obfuscatedAccountIdAndroid,\n obfuscatedProfileIdAndroid,\n subscriptionOffers,\n replacementModeAndroid,\n purchaseTokenAndroid,\n } = request as RequestSubscriptionAndroidProps;\n return ExpoIapModule.buyItemByType({\n type: ProductType.Subscription,\n skuArr: skus.map((so) => so),\n purchaseToken: purchaseTokenAndroid,\n replacementMode: replacementModeAndroid,\n obfuscatedAccountId: obfuscatedAccountIdAndroid,\n obfuscatedProfileId: obfuscatedProfileIdAndroid,\n offerTokenArr: subscriptionOffers.map((so) => so.offerToken),\n isOfferPersonalized: isOfferPersonalized ?? false,\n });\n },\n }) || (() => Promise.resolve(null))\n )();\n\nexport const finishTransaction = ({\n purchase,\n isConsumable,\n}: {\n purchase: Purchase;\n isConsumable?: boolean;\n}): Promise<PurchaseResult | boolean> => {\n return (\n Platform.select({\n ios: async () => {\n const transactionId = purchase.transactionId;\n if (!transactionId) {\n return Promise.reject(\n new Error('transactionId required to finish iOS transaction'),\n );\n }\n await ExpoIapModule.finishTransaction(transactionId);\n return Promise.resolve(true);\n },\n android: async () => {\n if (!purchase?.purchaseToken) {\n return Promise.reject(\n new Error('purchaseToken is required to finish transaction'),\n );\n }\n if (isConsumable) {\n return ExpoIapModule.consumeProduct(purchase.purchaseToken);\n } else {\n return ExpoIapModule.acknowledgePurchase(purchase.purchaseToken);\n }\n },\n }) || (() => Promise.reject(new Error('Unsupported Platform')))\n )();\n};\n\nexport * from './useIap';\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoIapIos.types.d.ts","sourceRoot":"","sources":["../../src/types/ExpoIapIos.types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ExpoIapIos.types.d.ts","sourceRoot":"","sources":["../../src/types/ExpoIapIos.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoIapIos.types.js","sourceRoot":"","sources":["../../src/types/ExpoIapIos.types.ts"],"names":[],"mappings":"","sourcesContent":["import {PurchaseBase, ProductBase} from '../ExpoIap.types';\n\ntype SubscriptionIosPeriod = 'DAY' | 'WEEK' | 'MONTH' | 'YEAR' | '';\ntype PaymentMode = '' | 'FREETRIAL' | 'PAYASYOUGO' | 'PAYUPFRONT';\n\ntype SubscriptionOffer = {\n displayPrice: string;\n id: string;\n paymentMode: PaymentMode;\n period: SubscriptionIosPeriod;\n periodCount: number;\n price: number;\n type: 'introductory' | 'promotional';\n};\n\ntype SubscriptionInfo = {\n introductoryOffer?: SubscriptionOffer;\n promotionalOffers?: SubscriptionOffer[];\n subscriptionGroupID: string;\n subscriptionPeriod: SubscriptionIosPeriod;\n};\n\nexport type ProductIos = ProductBase & {\n displayName: string;\n displayPrice: string;\n isFamilyShareable: boolean;\n jsonRepresentation: string;\n subscription: SubscriptionInfo;\n introductoryPriceNumberOfPeriodsIOS?: string;\n introductoryPriceSubscriptionPeriodIOS?: SubscriptionIosPeriod;\n};\n\nexport type Discount = {\n identifier: string;\n type: string;\n numberOfPeriods: string;\n price: string;\n localizedPrice: string;\n paymentMode: PaymentMode;\n subscriptionPeriod: string;\n};\n\nexport type SubscriptionProductIos = ProductIos & {\n discounts?: Discount[];\n introductoryPrice?: string;\n introductoryPriceAsAmountIOS?: string;\n introductoryPricePaymentModeIOS?: PaymentMode;\n introductoryPriceNumberOfPeriodsIOS?: string;\n introductoryPriceSubscriptionPeriodIOS?: SubscriptionIosPeriod;\n subscriptionPeriodNumberIOS?: string;\n subscriptionPeriodUnitIOS?: SubscriptionIosPeriod;\n};\n\nexport type PaymentDiscount = {\n /**\n * A string used to uniquely identify a discount offer for a product.\n */\n identifier: string;\n /**\n * A string that identifies the key used to generate the signature.\n */\n keyIdentifier: string;\n /**\n * A universally unique ID (UUID) value that you define.\n */\n nonce: string;\n /**\n * A UTF-8 string representing the properties of a specific discount offer, cryptographically signed.\n */\n signature: string;\n /**\n * The date and time of the signature's creation in milliseconds, formatted in Unix epoch time.\n */\n timestamp: number;\n};\n\nexport type RequestPurchaseIosProps = {\n sku: string;\n /**\n * UUID representing user account\n */\n appAccountToken?: string;\n quantity?: number;\n withOffer?: PaymentDiscount;\n};\n\nexport type RequestSubscriptionIosProps = RequestPurchaseIosProps;\n\ntype SubscriptionStatus =\n | 'expired'\n | 'inBillingRetryPeriod'\n | 'inGracePeriod'\n | 'revoked'\n | 'subscribed';\n\ntype RenewalInfo = {\n jsonRepresentation?: string;\n willAutoRenew: boolean;\n autoRenewPreference?: string;\n};\n\nexport type ProductStatusIos = {\n state: SubscriptionStatus;\n renewalInfo?: RenewalInfo;\n};\n\nexport type ProductPurchaseIos = PurchaseBase & {\n // iOS basic fields\n quantityIos?: number;\n originalTransactionDateIos?: number;\n originalTransactionIdentifierIos?: string;\n verificationResultIos?: string;\n appAccountToken?: string;\n // iOS additional fields from StoreKit 2\n expirationDateIos?: number;\n webOrderLineItemIdIos?: number;\n environmentIos?: string;\n storefrontCountryCodeIos?: string;\n appBundleIdIos?: string;\n productTypeIos?: string;\n subscriptionGroupIdIos?: string;\n isUpgradedIos?: boolean;\n ownershipTypeIos?: string;\n reasonIos?: string;\n reasonStringRepresentationIos?: string;\n transactionReasonIos?: 'PURCHASE' | 'RENEWAL' | string;\n revocationDateIos?: number;\n revocationReasonIos?: string;\n offerIos?: {\n id: string;\n type: string;\n paymentMode: string;\n };\n priceIos?: number;\n currencyIos?: string;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"ExpoIapIos.types.js","sourceRoot":"","sources":["../../src/types/ExpoIapIos.types.ts"],"names":[],"mappings":"","sourcesContent":["import {PurchaseBase, ProductBase} from '../ExpoIap.types';\n\ntype SubscriptionIosPeriod = 'DAY' | 'WEEK' | 'MONTH' | 'YEAR' | '';\ntype PaymentMode = '' | 'FREETRIAL' | 'PAYASYOUGO' | 'PAYUPFRONT';\n\ntype SubscriptionOffer = {\n displayPrice: string;\n id: string;\n paymentMode: PaymentMode;\n period: SubscriptionIosPeriod;\n periodCount: number;\n price: number;\n type: 'introductory' | 'promotional';\n};\n\ntype SubscriptionInfo = {\n introductoryOffer?: SubscriptionOffer;\n promotionalOffers?: SubscriptionOffer[];\n subscriptionGroupID: string;\n subscriptionPeriod: SubscriptionIosPeriod;\n};\n\nexport type ProductIos = ProductBase & {\n displayName: string;\n displayPrice: string;\n isFamilyShareable: boolean;\n jsonRepresentation: string;\n subscription: SubscriptionInfo;\n introductoryPriceNumberOfPeriodsIOS?: string;\n introductoryPriceSubscriptionPeriodIOS?: SubscriptionIosPeriod;\n};\n\nexport type Discount = {\n identifier: string;\n type: string;\n numberOfPeriods: string;\n price: string;\n localizedPrice: string;\n paymentMode: PaymentMode;\n subscriptionPeriod: string;\n};\n\nexport type SubscriptionProductIos = ProductIos & {\n discounts?: Discount[];\n introductoryPrice?: string;\n introductoryPriceAsAmountIOS?: string;\n introductoryPricePaymentModeIOS?: PaymentMode;\n introductoryPriceNumberOfPeriodsIOS?: string;\n introductoryPriceSubscriptionPeriodIOS?: SubscriptionIosPeriod;\n subscriptionPeriodNumberIOS?: string;\n subscriptionPeriodUnitIOS?: SubscriptionIosPeriod;\n};\n\nexport type PaymentDiscount = {\n /**\n * A string used to uniquely identify a discount offer for a product.\n */\n identifier: string;\n /**\n * A string that identifies the key used to generate the signature.\n */\n keyIdentifier: string;\n /**\n * A universally unique ID (UUID) value that you define.\n */\n nonce: string;\n /**\n * A UTF-8 string representing the properties of a specific discount offer, cryptographically signed.\n */\n signature: string;\n /**\n * The date and time of the signature's creation in milliseconds, formatted in Unix epoch time.\n */\n timestamp: number;\n};\n\nexport type RequestPurchaseIosProps = {\n sku: string;\n andDangerouslyFinishTransactionAutomaticallyIOS?: boolean;\n /**\n * UUID representing user account\n */\n appAccountToken?: string;\n quantity?: number;\n withOffer?: PaymentDiscount;\n};\n\nexport type RequestSubscriptionIosProps = RequestPurchaseIosProps;\n\ntype SubscriptionStatus =\n | 'expired'\n | 'inBillingRetryPeriod'\n | 'inGracePeriod'\n | 'revoked'\n | 'subscribed';\n\ntype RenewalInfo = {\n jsonRepresentation?: string;\n willAutoRenew: boolean;\n autoRenewPreference?: string;\n};\n\nexport type ProductStatusIos = {\n state: SubscriptionStatus;\n renewalInfo?: RenewalInfo;\n};\n\nexport type ProductPurchaseIos = PurchaseBase & {\n // iOS basic fields\n quantityIos?: number;\n originalTransactionDateIos?: number;\n originalTransactionIdentifierIos?: string;\n verificationResultIos?: string;\n appAccountToken?: string;\n // iOS additional fields from StoreKit 2\n expirationDateIos?: number;\n webOrderLineItemIdIos?: number;\n environmentIos?: string;\n storefrontCountryCodeIos?: string;\n appBundleIdIos?: string;\n productTypeIos?: string;\n subscriptionGroupIdIos?: string;\n isUpgradedIos?: boolean;\n ownershipTypeIos?: string;\n reasonIos?: string;\n reasonStringRepresentationIos?: string;\n transactionReasonIos?: 'PURCHASE' | 'RENEWAL' | string;\n revocationDateIos?: number;\n revocationReasonIos?: string;\n offerIos?: {\n id: string;\n type: string;\n paymentMode: string;\n };\n priceIos?: number;\n currencyIos?: string;\n};\n"]}
|
package/build/useIap.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useIap.d.ts","sourceRoot":"","sources":["../src/useIap.ts"],"names":[],"mappings":"AAYA,OAAO,EACL,OAAO,EACP,eAAe,EACf,QAAQ,EACR,aAAa,EACb,cAAc,EACd,mBAAmB,EAEpB,MAAM,iBAAiB,CAAC;AAIzB,KAAK,UAAU,GAAG;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,mBAAmB,EAAE,eAAe,EAAE,CAAC;IACvC,aAAa,EAAE,mBAAmB,EAAE,CAAC;IACrC,iBAAiB,EAAE,eAAe,EAAE,CAAC;IACrC,kBAAkB,EAAE,eAAe,EAAE,CAAC;IACtC,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,oBAAoB,CAAC,EAAE,aAAa,CAAC;IACrC,iBAAiB,EAAE,CAAC,EAClB,QAAQ,EACR,YAAY,EACZ,uBAAuB,GACxB,EAAE;QACD,QAAQ,EAAE,QAAQ,CAAC;QACnB,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,uBAAuB,CAAC,EAAE,MAAM,CAAC;KAClC,KAAK,OAAO,CAAC,MAAM,GAAG,OAAO,GAAG,cAAc,GAAG,IAAI,CAAC,CAAC;IACxD,qBAAqB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,oBAAoB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD,CAAC;AAMF,wBAAgB,MAAM,IAAI,UAAU,
|
|
1
|
+
{"version":3,"file":"useIap.d.ts","sourceRoot":"","sources":["../src/useIap.ts"],"names":[],"mappings":"AAYA,OAAO,EACL,OAAO,EACP,eAAe,EACf,QAAQ,EACR,aAAa,EACb,cAAc,EACd,mBAAmB,EAEpB,MAAM,iBAAiB,CAAC;AAIzB,KAAK,UAAU,GAAG;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,mBAAmB,EAAE,eAAe,EAAE,CAAC;IACvC,aAAa,EAAE,mBAAmB,EAAE,CAAC;IACrC,iBAAiB,EAAE,eAAe,EAAE,CAAC;IACrC,kBAAkB,EAAE,eAAe,EAAE,CAAC;IACtC,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,oBAAoB,CAAC,EAAE,aAAa,CAAC;IACrC,iBAAiB,EAAE,CAAC,EAClB,QAAQ,EACR,YAAY,EACZ,uBAAuB,GACxB,EAAE;QACD,QAAQ,EAAE,QAAQ,CAAC;QACnB,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,uBAAuB,CAAC,EAAE,MAAM,CAAC;KAClC,KAAK,OAAO,CAAC,MAAM,GAAG,OAAO,GAAG,cAAc,GAAG,IAAI,CAAC,CAAC;IACxD,qBAAqB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,oBAAoB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD,CAAC;AAMF,wBAAgB,MAAM,IAAI,UAAU,CAqInC"}
|
package/build/useIap.js
CHANGED
|
@@ -39,7 +39,8 @@ export function useIAP() {
|
|
|
39
39
|
if (purchase.id === currentPurchase?.id) {
|
|
40
40
|
setCurrentPurchase(undefined);
|
|
41
41
|
}
|
|
42
|
-
if (purchase.id === currentPurchaseError?.productId) {
|
|
42
|
+
if (purchase.id === currentPurchaseError?.productId) {
|
|
43
|
+
// Note that PurchaseError still uses productId
|
|
43
44
|
setCurrentPurchaseError(undefined);
|
|
44
45
|
}
|
|
45
46
|
}
|
package/build/useIap.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useIap.js","sourceRoot":"","sources":["../src/useIap.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,cAAc,EACd,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,WAAW,EACX,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,IAAI,CAAC;AACZ,OAAO,EAAC,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AAqCvD,IAAI,0BAAwC,CAAC;AAC7C,IAAI,yBAAuC,CAAC;AAC5C,IAAI,4BAA0C,CAAC;AAE/C,MAAM,UAAU,MAAM;IACpB,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IAC3D,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAY,EAAE,CAAC,CAAC;IACxD,MAAM,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG,QAAQ,CAE5D,EAAE,CAAC,CAAC;IACN,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAwB,EAAE,CAAC,CAAC;IAC9E,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,QAAQ,CACxD,EAAE,CACH,CAAC;IACF,MAAM,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,GAAG,QAAQ,CAE1D,EAAE,CAAC,CAAC;IACN,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,GAAG,QAAQ,EAAmB,CAAC;IAC1E,MAAM,CAAC,oBAAoB,EAAE,uBAAuB,CAAC,GACnD,QAAQ,EAAiB,CAAC;IAE5B,MAAM,eAAe,GAAG,WAAW,CAAC,KAAK,EAAE,IAAc,EAAiB,EAAE;QAC1E,WAAW,CAAC,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;IACvC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,oBAAoB,GAAG,WAAW,CACtC,KAAK,EAAE,IAAc,EAAiB,EAAE;QACtC,gBAAgB,CAAC,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;IACjD,CAAC,EACD,EAAE,CACH,CAAC;IAEF,MAAM,yBAAyB,GAAG,WAAW,CAAC,KAAK,IAAmB,EAAE;QACtE,qBAAqB,CAAC,MAAM,qBAAqB,EAAE,CAAC,CAAC;IACvD,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,wBAAwB,GAAG,WAAW,CAAC,KAAK,IAAmB,EAAE;QACrE,oBAAoB,CAAC,MAAM,kBAAkB,EAAE,CAAC,CAAC;IACnD,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,iBAAiB,GAAG,WAAW,CACnC,KAAK,EAAE,EACL,QAAQ,EACR,YAAY,EACZ,uBAAuB,GAKxB,EAAqD,EAAE;QACtD,IAAI,CAAC;YACH,OAAO,MAAM,iBAAiB,CAAC;gBAC7B,QAAQ;gBACR,YAAY;gBACZ,uBAAuB;aACxB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,CAAC;QACZ,CAAC;gBAAS,CAAC;YACT,IAAI,QAAQ,CAAC,EAAE,KAAK,eAAe,EAAE,EAAE,EAAE,CAAC;gBACxC,kBAAkB,CAAC,SAAS,CAAC,CAAC;YAChC,CAAC;YAED,IAAI,QAAQ,CAAC,EAAE,KAAK,oBAAoB,EAAE,SAAS,EAAE,CAAC
|
|
1
|
+
{"version":3,"file":"useIap.js","sourceRoot":"","sources":["../src/useIap.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n endConnection,\n initConnection,\n purchaseErrorListener,\n purchaseUpdatedListener,\n transactionUpdatedIos,\n getProducts,\n getAvailablePurchases,\n getPurchaseHistory,\n getSubscriptions,\n} from './';\nimport {useCallback, useEffect, useState} from 'react';\nimport {\n Product,\n ProductPurchase,\n Purchase,\n PurchaseError,\n PurchaseResult,\n SubscriptionProduct,\n SubscriptionPurchase,\n} from './ExpoIap.types';\nimport {TransactionEvent} from './modules/ios';\nimport {Subscription} from 'expo-modules-core';\n\ntype IAP_STATUS = {\n connected: boolean;\n products: Product[];\n promotedProductsIOS: ProductPurchase[];\n subscriptions: SubscriptionProduct[];\n purchaseHistories: ProductPurchase[];\n availablePurchases: ProductPurchase[];\n currentPurchase?: ProductPurchase;\n currentPurchaseError?: PurchaseError;\n finishTransaction: ({\n purchase,\n isConsumable,\n developerPayloadAndroid,\n }: {\n purchase: Purchase;\n isConsumable?: boolean;\n developerPayloadAndroid?: string;\n }) => Promise<string | boolean | PurchaseResult | void>;\n getAvailablePurchases: () => Promise<void>;\n getPurchaseHistories: () => Promise<void>;\n getProducts: (skus: string[]) => Promise<void>;\n getSubscriptions: (skus: string[]) => Promise<void>;\n};\n\nlet purchaseUpdateSubscription: Subscription;\nlet purchaseErrorSubscription: Subscription;\nlet promotedProductsSubscription: Subscription;\n\nexport function useIAP(): IAP_STATUS {\n const [connected, setConnected] = useState<boolean>(false);\n const [products, setProducts] = useState<Product[]>([]);\n const [promotedProductsIOS, setPromotedProductsIOS] = useState<\n ProductPurchase[]\n >([]);\n const [subscriptions, setSubscriptions] = useState<SubscriptionProduct[]>([]);\n const [purchaseHistories, setPurchaseHistories] = useState<ProductPurchase[]>(\n [],\n );\n const [availablePurchases, setAvailablePurchases] = useState<\n ProductPurchase[]\n >([]);\n const [currentPurchase, setCurrentPurchase] = useState<ProductPurchase>();\n const [currentPurchaseError, setCurrentPurchaseError] =\n useState<PurchaseError>();\n\n const requestProducts = useCallback(async (skus: string[]): Promise<void> => {\n setProducts(await getProducts(skus));\n }, []);\n\n const requestSubscriptions = useCallback(\n async (skus: string[]): Promise<void> => {\n setSubscriptions(await getSubscriptions(skus));\n },\n [],\n );\n\n const requestAvailablePurchases = useCallback(async (): Promise<void> => {\n setAvailablePurchases(await getAvailablePurchases());\n }, []);\n\n const requestPurchaseHistories = useCallback(async (): Promise<void> => {\n setPurchaseHistories(await getPurchaseHistory());\n }, []);\n\n const finishTransaction = useCallback(\n async ({\n purchase,\n isConsumable,\n developerPayloadAndroid,\n }: {\n purchase: ProductPurchase;\n isConsumable?: boolean;\n developerPayloadAndroid?: string;\n }): Promise<string | boolean | PurchaseResult | void> => {\n try {\n return await finishTransaction({\n purchase,\n isConsumable,\n developerPayloadAndroid,\n });\n } catch (err) {\n throw err;\n } finally {\n if (purchase.id === currentPurchase?.id) {\n setCurrentPurchase(undefined);\n }\n\n if (purchase.id === currentPurchaseError?.productId) {\n // Note that PurchaseError still uses productId\n setCurrentPurchaseError(undefined);\n }\n }\n },\n [\n currentPurchase?.id,\n currentPurchaseError?.productId,\n setCurrentPurchase,\n setCurrentPurchaseError,\n ],\n );\n\n const initIapWithSubscriptions = useCallback(async (): Promise<void> => {\n const result = await initConnection();\n\n setConnected(result);\n\n if (result) {\n purchaseUpdateSubscription = purchaseUpdatedListener(\n async (purchase: Purchase | SubscriptionPurchase) => {\n setCurrentPurchaseError(undefined);\n setCurrentPurchase(purchase);\n },\n );\n\n purchaseErrorSubscription = purchaseErrorListener(\n (error: PurchaseError) => {\n setCurrentPurchase(undefined);\n setCurrentPurchaseError(error);\n },\n );\n\n promotedProductsSubscription = transactionUpdatedIos(\n (event: TransactionEvent) => {\n setPromotedProductsIOS((prevProducts) =>\n event.transaction\n ? [...prevProducts, event.transaction]\n : prevProducts,\n );\n },\n );\n }\n }, []);\n\n useEffect(() => {\n initIapWithSubscriptions();\n\n return (): void => {\n if (purchaseUpdateSubscription) purchaseUpdateSubscription.remove();\n if (purchaseErrorSubscription) purchaseErrorSubscription.remove();\n if (promotedProductsSubscription) promotedProductsSubscription.remove();\n\n endConnection();\n setConnected(false);\n };\n }, [initIapWithSubscriptions]);\n\n return {\n connected,\n products,\n promotedProductsIOS,\n subscriptions,\n purchaseHistories,\n finishTransaction,\n availablePurchases,\n currentPurchase,\n currentPurchaseError,\n getProducts: requestProducts,\n getSubscriptions: requestSubscriptions,\n getAvailablePurchases: requestAvailablePurchases,\n getPurchaseHistories: requestPurchaseHistories,\n };\n}\n"]}
|
package/iap.md
CHANGED
|
@@ -1,14 +1,44 @@
|
|
|
1
1
|
# Expo IAP Documentation
|
|
2
2
|
|
|
3
|
+
> **Key Feature**: `expo-iap` works seamlessly with Expo's managed workflow—no bare setup or native code required! This is a major improvement over `react-native-iap`, making it ideal for small teams using Expo SDK.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
`expo-iap` is an Expo module for handling in-app purchases (IAP) on iOS (StoreKit 2) and Android (Google Play Billing). It supports consumables, non-consumables, and subscriptions. While it’s functional in managed workflows, it’s still under active development—test thoroughly before deploying to production. For a fully stable alternative, consider RevenueCat.
|
|
8
|
+
|
|
3
9
|
## Installation in Managed Expo Projects
|
|
4
10
|
|
|
5
|
-
For [managed](https://docs.expo.dev/archive/managed-vs-bare/) Expo projects,
|
|
11
|
+
For [managed](https://docs.expo.dev/archive/managed-vs-bare/) Expo projects, add `expo-iap` and configure it via the Expo config plugin. It’s compatible with Expo SDK 51+ (check the [API documentation](#api-documentation) for official inclusion). If no documentation is available, it’s awaiting a future SDK release.
|
|
12
|
+
|
|
13
|
+
### Steps
|
|
14
|
+
|
|
15
|
+
1. **Add the Package**
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install expo-iap
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
2. **Configure with Expo Config Plugin** Add `'expo-iap'` to the `plugins` array in your `app.json` or `app.config.js`:
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"expo": {
|
|
26
|
+
"plugins": ["expo-iap"]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
This automatically configures Android BILLING permissions and iOS setup.
|
|
32
|
+
|
|
33
|
+
3. **Run Your App** Use `expo run:android` or `expo run:ios` to build and test.
|
|
34
|
+
|
|
35
|
+
> **Example**: See a working sample at [example/App.tsx](https://github.com/hyochan/expo-iap/blob/main/example/App.tsx).
|
|
6
36
|
|
|
7
37
|
## Installation in Bare React Native Projects
|
|
8
38
|
|
|
9
|
-
For bare
|
|
39
|
+
For bare projects, ensure the [`expo` package is installed and configured](https://docs.expo.dev/bare/installing-expo-modules/).
|
|
10
40
|
|
|
11
|
-
### Add the Package
|
|
41
|
+
### Add the Package
|
|
12
42
|
|
|
13
43
|
```bash
|
|
14
44
|
npm install expo-iap
|
|
@@ -16,7 +46,7 @@ npm install expo-iap
|
|
|
16
46
|
|
|
17
47
|
### Configure for iOS
|
|
18
48
|
|
|
19
|
-
Run `npx pod-install
|
|
49
|
+
Run `npx pod-install`. Set `deploymentTarget` to `15.0` or higher (StoreKit 2 requirement):
|
|
20
50
|
|
|
21
51
|
```json
|
|
22
52
|
"ios": {
|
|
@@ -26,7 +56,7 @@ Run `npx pod-install` after installing the npm package. Since `expo-iap` uses `S
|
|
|
26
56
|
|
|
27
57
|
### Configure for Android
|
|
28
58
|
|
|
29
|
-
No additional configuration is
|
|
59
|
+
No additional configuration is needed—Google Play Billing is handled internally.
|
|
30
60
|
|
|
31
61
|
### Configure with Expo Config Plugin
|
|
32
62
|
|
|
@@ -35,9 +65,7 @@ Add 'expo-iap' to the plugins array in your app.json or app.config.js file:
|
|
|
35
65
|
```json
|
|
36
66
|
{
|
|
37
67
|
"expo": {
|
|
38
|
-
"plugins": [
|
|
39
|
-
"expo-iap"
|
|
40
|
-
]
|
|
68
|
+
"plugins": ["expo-iap"]
|
|
41
69
|
}
|
|
42
70
|
}
|
|
43
71
|
```
|
|
@@ -50,128 +78,406 @@ This plugin automatically sets up the necessary Android configuration, including
|
|
|
50
78
|
|
|
51
79
|
### Consumable
|
|
52
80
|
|
|
53
|
-
- **Description**: Items that are
|
|
54
|
-
- **Behavior**: Requires
|
|
55
|
-
- **Platforms**: Supported on
|
|
81
|
+
- **Description**: Items that are consumed after purchase and can be repurchased (e.g., in-game currency, boosts).
|
|
82
|
+
- **Behavior**: Requires acknowledgment to enable repurchasing.
|
|
83
|
+
- **Platforms**: Supported on Android and iOS.
|
|
56
84
|
|
|
57
85
|
### Non-Consumable
|
|
58
86
|
|
|
59
|
-
- **Description**: One-time purchases
|
|
60
|
-
- **Behavior**: Supports restoration
|
|
61
|
-
- **Platforms**: Supported on
|
|
87
|
+
- **Description**: One-time purchases owned permanently (e.g., ad removal, premium features).
|
|
88
|
+
- **Behavior**: Supports restoration; cannot be repurchased.
|
|
89
|
+
- **Platforms**: Supported on Android and iOS.
|
|
62
90
|
|
|
63
91
|
### Subscription
|
|
64
92
|
|
|
65
|
-
- **Description**: Recurring purchases for ongoing access
|
|
66
|
-
- **Behavior**: Includes auto-renewing options and
|
|
67
|
-
- **Platforms**: Supported on
|
|
93
|
+
- **Description**: Recurring purchases for ongoing access (e.g., monthly memberships).
|
|
94
|
+
- **Behavior**: Includes auto-renewing options and restoration.
|
|
95
|
+
- **Platforms**: Supported on Android and iOS.
|
|
68
96
|
|
|
69
97
|
## Product Type
|
|
70
98
|
|
|
71
|
-
This section outlines the properties of products supported by `expo-iap
|
|
72
|
-
|
|
73
|
-
### Common Product Types
|
|
99
|
+
This section outlines the properties of products supported by `expo-iap`.
|
|
74
100
|
|
|
75
|
-
|
|
101
|
+
### Common Product Types (`BaseProduct`)
|
|
76
102
|
|
|
77
|
-
| Property | Type | Description
|
|
78
|
-
| -------------- | ------------- |
|
|
79
|
-
| `id` | `string` | Unique
|
|
80
|
-
| `title` | `string` |
|
|
81
|
-
| `description` | `string` |
|
|
82
|
-
| `type` | `ProductType` |
|
|
83
|
-
| `displayName` | `string?` |
|
|
84
|
-
| `displayPrice` | `string?` |
|
|
85
|
-
| `price` | `number?` |
|
|
86
|
-
| `currency` | `string?` | Currency code (optional)
|
|
103
|
+
| Property | Type | Description |
|
|
104
|
+
| -------------- | ------------- | -------------------------- |
|
|
105
|
+
| `id` | `string` | Unique product identifier |
|
|
106
|
+
| `title` | `string` | Product title |
|
|
107
|
+
| `description` | `string` | Product description |
|
|
108
|
+
| `type` | `ProductType` | `inapp` or `subs` |
|
|
109
|
+
| `displayName` | `string?` | UI display name (optional) |
|
|
110
|
+
| `displayPrice` | `string?` | Formatted price (optional) |
|
|
111
|
+
| `price` | `number?` | Price value (optional) |
|
|
112
|
+
| `currency` | `string?` | Currency code (optional) |
|
|
87
113
|
|
|
88
114
|
### Android-Only Product Types
|
|
89
115
|
|
|
90
116
|
- **`ProductAndroid`**
|
|
91
|
-
|
|
92
|
-
- `
|
|
93
|
-
- `oneTimePurchaseOfferDetails?: OneTimePurchaseOfferDetails`: Details for one-time purchases (e.g., price, currency).
|
|
117
|
+
- `name: string`: Product name (replaces `displayName` on Android).
|
|
118
|
+
- `oneTimePurchaseOfferDetails?: OneTimePurchaseOfferDetails`: One-time purchase details.
|
|
94
119
|
- `subscriptionOfferDetails?: SubscriptionOfferDetail[]`: Subscription offer details.
|
|
95
|
-
|
|
96
120
|
- **`SubscriptionProductAndroid`**
|
|
97
|
-
- `subscriptionOfferDetails: SubscriptionOfferAndroid[]`: Subscription-specific offers
|
|
121
|
+
- `subscriptionOfferDetails: SubscriptionOfferAndroid[]`: Subscription-specific offers.
|
|
98
122
|
|
|
99
123
|
### iOS-Only Product Types
|
|
100
124
|
|
|
101
125
|
- **`ProductIos`**
|
|
102
|
-
|
|
103
|
-
- `
|
|
104
|
-
- `
|
|
105
|
-
- `
|
|
106
|
-
- `subscription: SubscriptionInfo`: Subscription details (e.g., introductory offers, group ID).
|
|
107
|
-
|
|
126
|
+
- `displayPrice: string`: Formatted price.
|
|
127
|
+
- `isFamilyShareable: boolean`: Family sharing support.
|
|
128
|
+
- `jsonRepresentation: string`: StoreKit 2 JSON data.
|
|
129
|
+
- `subscription: SubscriptionInfo`: Subscription details.
|
|
108
130
|
- **`SubscriptionProductIos`**
|
|
109
|
-
- `discounts?: Discount[]`: Discount details
|
|
110
|
-
- `introductoryPrice?: string`: Introductory pricing
|
|
131
|
+
- `discounts?: Discount[]`: Discount details.
|
|
132
|
+
- `introductoryPrice?: string`: Introductory pricing info.
|
|
111
133
|
|
|
112
134
|
## Purchase Type
|
|
113
135
|
|
|
114
|
-
This section describes
|
|
115
|
-
|
|
116
|
-
### Common Purchase Types
|
|
136
|
+
This section describes purchase properties in `expo-iap`.
|
|
117
137
|
|
|
118
|
-
|
|
138
|
+
### Common Purchase Types (`ProductPurchase`)
|
|
119
139
|
|
|
120
|
-
| Property | Type | Description
|
|
121
|
-
| -------------------- | --------- |
|
|
122
|
-
| `id` | `string` |
|
|
123
|
-
| `transactionId` | `string?` |
|
|
124
|
-
| `transactionDate` | `number` |
|
|
125
|
-
| `transactionReceipt` | `string` |
|
|
126
|
-
| `purchaseToken` | `string?` | Purchase token (optional)
|
|
140
|
+
| Property | Type | Description |
|
|
141
|
+
| -------------------- | --------- | ------------------------- |
|
|
142
|
+
| `id` | `string` | Purchased product ID |
|
|
143
|
+
| `transactionId` | `string?` | Transaction ID (optional) |
|
|
144
|
+
| `transactionDate` | `number` | Unix timestamp |
|
|
145
|
+
| `transactionReceipt` | `string` | Receipt data |
|
|
146
|
+
| `purchaseToken` | `string?` | Purchase token (optional) |
|
|
127
147
|
|
|
128
148
|
### Android-Only Purchase Types
|
|
129
149
|
|
|
130
|
-
- **`ProductPurchase`
|
|
131
|
-
|
|
132
|
-
- `ids?: string[]`: List of purchased product IDs.
|
|
133
|
-
- `dataAndroid?: string`: Payment data.
|
|
134
|
-
- `signatureAndroid?: string`: Signature data.
|
|
135
|
-
- `autoRenewingAndroid?: boolean`: Auto-renewal status.
|
|
136
|
-
- `purchaseStateAndroid?: PurchaseStateAndroid`: Purchase state (e.g., PURCHASED, PENDING).
|
|
137
|
-
|
|
138
|
-
- **`SubscriptionPurchase` (Android Extensions)**
|
|
139
|
-
- `autoRenewingAndroid?: boolean`: Subscription auto-renewal status.
|
|
150
|
+
- **`ProductPurchase`**: Adds `ids`, `dataAndroid`, `signatureAndroid`, `purchaseStateAndroid`.
|
|
151
|
+
- **`SubscriptionPurchase`**: Includes `autoRenewingAndroid`.
|
|
140
152
|
|
|
141
153
|
### iOS-Only Purchase Types
|
|
142
154
|
|
|
143
|
-
- **`ProductPurchase`
|
|
144
|
-
|
|
145
|
-
- `quantityIos?: number`: Purchase quantity.
|
|
146
|
-
- `originalTransactionDateIos?: number`: Original transaction date.
|
|
147
|
-
- `originalTransactionIdentifierIos?: string`: Original transaction ID.
|
|
148
|
-
- `verificationResultIos?: string`: Verification result.
|
|
149
|
-
- `appAccountToken?: string`: App account token.
|
|
150
|
-
- `expirationDateIos?: number`: Expiration date for subscriptions.
|
|
151
|
-
- `webOrderLineItemIdIos?: number`: Web order line item ID.
|
|
152
|
-
- `environmentIos?: string`: App Store environment.
|
|
153
|
-
- `storefrontCountryCodeIos?: string`: App Store storefront country code.
|
|
154
|
-
- `appBundleIdIos?: string`: App bundle ID.
|
|
155
|
-
- `productTypeIos?: string`: Product type (e.g., "autoRenewable").
|
|
156
|
-
- `subscriptionGroupIdIos?: string`: Subscription group ID.
|
|
157
|
-
- `isUpgradedIos?: boolean`: Whether the subscription was upgraded.
|
|
158
|
-
- `ownershipTypeIos?: string`: Ownership type (e.g., individual, family sharing).
|
|
159
|
-
- `reasonIos?: string`: Transaction reason.
|
|
160
|
-
- `transactionReasonIos?: string`: Detailed transaction reason.
|
|
161
|
-
- `revocationDateIos?: number`: Date of revocation if refunded.
|
|
162
|
-
- `revocationReasonIos?: string`: Reason for revocation.
|
|
163
|
-
|
|
164
|
-
- **`SubscriptionPurchase` (iOS Extensions)**
|
|
165
|
-
- All the iOS-specific fields from `ProductPurchase`
|
|
166
|
-
- Automatic subscription-specific handling based on product type
|
|
155
|
+
- **`ProductPurchase`**: Adds fields like `quantityIos`, `expirationDateIos`, `subscriptionGroupIdIos`.
|
|
156
|
+
- **`SubscriptionPurchase`**: Extends with subscription-specific handling.
|
|
167
157
|
|
|
168
158
|
## Implementation Notes
|
|
169
159
|
|
|
170
160
|
### Platform-Uniform Purchase Handling
|
|
171
161
|
|
|
172
|
-
|
|
162
|
+
Transactions are mapped directly to `Purchase` or `SubscriptionPurchase` with platform-specific fields (e.g., `expirationDateIos`, `purchaseStateAndroid`).
|
|
163
|
+
|
|
164
|
+
### Status
|
|
165
|
+
|
|
166
|
+
This module is under development—expect occasional bugs (e.g., Android acknowledgment issues). Test thoroughly and consider contributing fixes!
|
|
167
|
+
|
|
168
|
+
> **Sample Code**: See [example/App.tsx](https://github.com/hyochan/expo-iap/blob/main/example/App.tsx).
|
|
169
|
+
|
|
170
|
+
## Implementation
|
|
171
|
+
|
|
172
|
+
Below is a simple example of fetching products and making a purchase with `expo-iap` in a managed workflow:
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
import {useEffect, useState} from 'react';
|
|
176
|
+
import {Button, Text, View} from 'react-native';
|
|
177
|
+
import {
|
|
178
|
+
initConnection,
|
|
179
|
+
endConnection,
|
|
180
|
+
getProducts,
|
|
181
|
+
requestPurchase,
|
|
182
|
+
purchaseUpdatedListener,
|
|
183
|
+
finishTransaction,
|
|
184
|
+
} from 'expo-iap';
|
|
185
|
+
|
|
186
|
+
export default function SimpleIAP() {
|
|
187
|
+
const [isConnected, setIsConnected] = useState(false);
|
|
188
|
+
const [product, setProduct] = useState(null);
|
|
189
|
+
|
|
190
|
+
// Initialize IAP and fetch products
|
|
191
|
+
useEffect(() => {
|
|
192
|
+
const setupIAP = async () => {
|
|
193
|
+
if (await initConnection()) {
|
|
194
|
+
setIsConnected(true);
|
|
195
|
+
const products = await getProducts(['my.consumable.item']); // Replace with your product SKU
|
|
196
|
+
if (products.length > 0) setProduct(products[0]);
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
setupIAP();
|
|
200
|
+
|
|
201
|
+
// Handle purchase updates
|
|
202
|
+
const purchaseListener = purchaseUpdatedListener(async (purchase) => {
|
|
203
|
+
if (purchase.transactionReceipt) {
|
|
204
|
+
await finishTransaction({purchase, isConsumable: true});
|
|
205
|
+
alert('Purchase completed!');
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
return () => {
|
|
210
|
+
purchaseListener.remove();
|
|
211
|
+
endConnection();
|
|
212
|
+
};
|
|
213
|
+
}, []);
|
|
214
|
+
|
|
215
|
+
// Trigger a purchase
|
|
216
|
+
const buyItem = async () => {
|
|
217
|
+
if (!product) return;
|
|
218
|
+
await requestPurchase({skus: [product.id]});
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
return (
|
|
222
|
+
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
|
|
223
|
+
<Text>{isConnected ? 'Connected' : 'Connecting...'}</Text>
|
|
224
|
+
{product ? (
|
|
225
|
+
<>
|
|
226
|
+
<Text>{`${product.title} - ${product.displayPrice}`}</Text>
|
|
227
|
+
<Button title="Buy Now" onPress={buyItem} />
|
|
228
|
+
</>
|
|
229
|
+
) : (
|
|
230
|
+
<Text>Loading product...</Text>
|
|
231
|
+
)}
|
|
232
|
+
</View>
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
```
|
|
173
236
|
|
|
174
|
-
|
|
175
|
-
|
|
237
|
+
## Using useIAP Hook
|
|
238
|
+
|
|
239
|
+
The `useIAP` hook simplifies managing in-app purchases with `expo-iap`. Below is an example that fetches products and subscriptions, and allows purchasing them, styled similarly to the `expo-iap` example app. It assumes you’ve implemented the custom `useIAP` hook in your project.
|
|
240
|
+
|
|
241
|
+
```tsx
|
|
242
|
+
import {useEffect, useState} from 'react';
|
|
243
|
+
import {
|
|
244
|
+
SafeAreaView,
|
|
245
|
+
ScrollView,
|
|
246
|
+
StyleSheet,
|
|
247
|
+
Text,
|
|
248
|
+
View,
|
|
249
|
+
Pressable,
|
|
250
|
+
Button,
|
|
251
|
+
InteractionManager,
|
|
252
|
+
Alert,
|
|
253
|
+
} from 'react-native';
|
|
254
|
+
import {useIap} from 'expo-iap';
|
|
255
|
+
import type {
|
|
256
|
+
PurchaseError,
|
|
257
|
+
ProductPurchase,
|
|
258
|
+
SubscriptionProduct,
|
|
259
|
+
} from 'expo-iap';
|
|
260
|
+
import {RequestSubscriptionAndroidProps} from './types/ExpoIapAndroid.types'; // Adjust path as needed
|
|
261
|
+
|
|
262
|
+
// Define SKUs
|
|
263
|
+
const productSkus = [
|
|
264
|
+
'cpk.points.1000',
|
|
265
|
+
'cpk.points.5000',
|
|
266
|
+
'cpk.points.10000',
|
|
267
|
+
'cpk.points.30000',
|
|
268
|
+
];
|
|
269
|
+
|
|
270
|
+
const subscriptionSkus = [
|
|
271
|
+
'cpk.membership.monthly.bronze',
|
|
272
|
+
'cpk.membership.monthly.silver',
|
|
273
|
+
];
|
|
274
|
+
|
|
275
|
+
// Define operations
|
|
276
|
+
const operations = [
|
|
277
|
+
'initConnection',
|
|
278
|
+
'getProducts',
|
|
279
|
+
'getSubscriptions',
|
|
280
|
+
'endConnection',
|
|
281
|
+
];
|
|
282
|
+
type Operation = (typeof operations)[number];
|
|
283
|
+
|
|
284
|
+
export default function IAPWithHook() {
|
|
285
|
+
const {
|
|
286
|
+
connected,
|
|
287
|
+
products,
|
|
288
|
+
subscriptions,
|
|
289
|
+
currentPurchase,
|
|
290
|
+
currentPurchaseError,
|
|
291
|
+
getProducts,
|
|
292
|
+
getSubscriptions,
|
|
293
|
+
finishTransaction,
|
|
294
|
+
requestPurchase,
|
|
295
|
+
requestSubscription,
|
|
296
|
+
} = useIAP();
|
|
297
|
+
|
|
298
|
+
const [isConnected, setIsConnected] = useState(connected);
|
|
299
|
+
|
|
300
|
+
// Handle operations
|
|
301
|
+
const handleOperation = async (operation: Operation) => {
|
|
302
|
+
switch (operation) {
|
|
303
|
+
case 'initConnection':
|
|
304
|
+
setIsConnected(true); // Connection is handled by useIAP hook
|
|
305
|
+
break;
|
|
306
|
+
case 'endConnection':
|
|
307
|
+
setIsConnected(false); // Cleanup is handled by useIAP hook
|
|
308
|
+
break;
|
|
309
|
+
case 'getProducts':
|
|
310
|
+
try {
|
|
311
|
+
await getProducts(productSkus);
|
|
312
|
+
} catch (error) {
|
|
313
|
+
console.error('Error fetching products:', error);
|
|
314
|
+
}
|
|
315
|
+
break;
|
|
316
|
+
case 'getSubscriptions':
|
|
317
|
+
try {
|
|
318
|
+
await getSubscriptions(subscriptionSkus);
|
|
319
|
+
} catch (error) {
|
|
320
|
+
console.error('Error fetching subscriptions:', error);
|
|
321
|
+
}
|
|
322
|
+
break;
|
|
323
|
+
default:
|
|
324
|
+
console.log('Unknown operation');
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
// Handle purchase updates and errors
|
|
329
|
+
useEffect(() => {
|
|
330
|
+
if (currentPurchase?.transactionReceipt) {
|
|
331
|
+
InteractionManager.runAfterInteractions(async () => {
|
|
332
|
+
try {
|
|
333
|
+
await finishTransaction({
|
|
334
|
+
purchase: currentPurchase,
|
|
335
|
+
isConsumable: true,
|
|
336
|
+
});
|
|
337
|
+
Alert.alert('Purchase updated', JSON.stringify(currentPurchase));
|
|
338
|
+
} catch (error) {
|
|
339
|
+
console.error('Error finishing transaction:', error);
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
if (currentPurchaseError) {
|
|
345
|
+
InteractionManager.runAfterInteractions(() => {
|
|
346
|
+
Alert.alert('Purchase error', JSON.stringify(currentPurchaseError));
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
}, [currentPurchase, currentPurchaseError, finishTransaction]);
|
|
350
|
+
|
|
351
|
+
return (
|
|
352
|
+
<SafeAreaView style={styles.container}>
|
|
353
|
+
<Text style={styles.title}>Expo IAP with useIAP Hook</Text>
|
|
354
|
+
<View style={styles.buttons}>
|
|
355
|
+
<ScrollView contentContainerStyle={styles.buttonsWrapper} horizontal>
|
|
356
|
+
{operations.map((operation) => (
|
|
357
|
+
<Pressable
|
|
358
|
+
key={operation}
|
|
359
|
+
onPress={() => handleOperation(operation)}
|
|
360
|
+
>
|
|
361
|
+
<View style={styles.buttonView}>
|
|
362
|
+
<Text>{operation}</Text>
|
|
363
|
+
</View>
|
|
364
|
+
</Pressable>
|
|
365
|
+
))}
|
|
366
|
+
</ScrollView>
|
|
367
|
+
</View>
|
|
368
|
+
<View style={styles.content}>
|
|
369
|
+
{!isConnected ? (
|
|
370
|
+
<Text>Not connected</Text>
|
|
371
|
+
) : (
|
|
372
|
+
<View style={{gap: 12}}>
|
|
373
|
+
<Text style={{fontSize: 20}}>Products</Text>
|
|
374
|
+
{products.map((item) => {
|
|
375
|
+
if (item.platform === 'android') {
|
|
376
|
+
return (
|
|
377
|
+
<View key={item.title} style={{gap: 12}}>
|
|
378
|
+
<Text>
|
|
379
|
+
{item.title} -{' '}
|
|
380
|
+
{item.oneTimePurchaseOfferDetails?.formattedPrice}
|
|
381
|
+
</Text>
|
|
382
|
+
<Button
|
|
383
|
+
title="Buy"
|
|
384
|
+
onPress={() => requestPurchase({skus: [item.id]})}
|
|
385
|
+
/>
|
|
386
|
+
</View>
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
if (item.platform === 'ios') {
|
|
390
|
+
return (
|
|
391
|
+
<View key={item.id} style={{gap: 12}}>
|
|
392
|
+
<Text>
|
|
393
|
+
{item.title} - {item.displayPrice}
|
|
394
|
+
</Text>
|
|
395
|
+
<Button
|
|
396
|
+
title="Buy"
|
|
397
|
+
onPress={() => requestPurchase({sku: item.id})}
|
|
398
|
+
/>
|
|
399
|
+
</View>
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
})}
|
|
403
|
+
|
|
404
|
+
<Text style={{fontSize: 20}}>Subscriptions</Text>
|
|
405
|
+
{subscriptions.map((item) => {
|
|
406
|
+
if (item.platform === 'android') {
|
|
407
|
+
return item.subscriptionOfferDetails?.map((offer) => (
|
|
408
|
+
<View key={offer.offerId} style={{gap: 12}}>
|
|
409
|
+
<Text>
|
|
410
|
+
{item.title} -{' '}
|
|
411
|
+
{offer.pricingPhases.pricingPhaseList
|
|
412
|
+
.map((ppl) => ppl.billingPeriod)
|
|
413
|
+
.join(',')}
|
|
414
|
+
</Text>
|
|
415
|
+
<Button
|
|
416
|
+
title="Subscribe"
|
|
417
|
+
onPress={() =>
|
|
418
|
+
requestSubscription({
|
|
419
|
+
skus: [item.id],
|
|
420
|
+
...(offer.offerToken && {
|
|
421
|
+
subscriptionOffers: [
|
|
422
|
+
{sku: item.id, offerToken: offer.offerToken},
|
|
423
|
+
],
|
|
424
|
+
}),
|
|
425
|
+
} as RequestSubscriptionAndroidProps)
|
|
426
|
+
}
|
|
427
|
+
/>
|
|
428
|
+
</View>
|
|
429
|
+
));
|
|
430
|
+
}
|
|
431
|
+
if (item.platform === 'ios') {
|
|
432
|
+
return (
|
|
433
|
+
<View key={item.id} style={{gap: 12}}>
|
|
434
|
+
<Text>
|
|
435
|
+
{item.displayName} - {item.displayPrice}
|
|
436
|
+
</Text>
|
|
437
|
+
<Button
|
|
438
|
+
title="Subscribe"
|
|
439
|
+
onPress={() => requestSubscription({sku: item.id})}
|
|
440
|
+
/>
|
|
441
|
+
</View>
|
|
442
|
+
);
|
|
443
|
+
}
|
|
444
|
+
})}
|
|
445
|
+
</View>
|
|
446
|
+
)}
|
|
447
|
+
</View>
|
|
448
|
+
</SafeAreaView>
|
|
449
|
+
);
|
|
450
|
+
}
|
|
176
451
|
|
|
177
|
-
|
|
452
|
+
const styles = StyleSheet.create({
|
|
453
|
+
container: {
|
|
454
|
+
flex: 1,
|
|
455
|
+
backgroundColor: '#fff',
|
|
456
|
+
alignItems: 'center',
|
|
457
|
+
},
|
|
458
|
+
title: {
|
|
459
|
+
marginTop: 24,
|
|
460
|
+
fontSize: 20,
|
|
461
|
+
fontWeight: 'bold',
|
|
462
|
+
},
|
|
463
|
+
buttons: {
|
|
464
|
+
height: 90,
|
|
465
|
+
},
|
|
466
|
+
buttonsWrapper: {
|
|
467
|
+
padding: 24,
|
|
468
|
+
gap: 8,
|
|
469
|
+
},
|
|
470
|
+
buttonView: {
|
|
471
|
+
borderRadius: 8,
|
|
472
|
+
borderWidth: 1,
|
|
473
|
+
borderColor: '#000',
|
|
474
|
+
padding: 8,
|
|
475
|
+
},
|
|
476
|
+
content: {
|
|
477
|
+
flex: 1,
|
|
478
|
+
alignSelf: 'stretch',
|
|
479
|
+
padding: 24,
|
|
480
|
+
gap: 12,
|
|
481
|
+
},
|
|
482
|
+
});
|
|
483
|
+
```
|
package/ios/ExpoIapModule.swift
CHANGED
|
@@ -308,7 +308,7 @@ public class ExpoIapModule: Module {
|
|
|
308
308
|
return purchasedItems.map { serializeTransaction($0) }
|
|
309
309
|
}
|
|
310
310
|
|
|
311
|
-
AsyncFunction("buyProduct") { (sku: String,
|
|
311
|
+
AsyncFunction("buyProduct") { (sku: String, andDangerouslyFinishTransactionAutomatically: Bool, appAccountToken: String?, quantity: Int, discountOffer: [String: String]?) -> [String: Any?]? in
|
|
312
312
|
guard let productStore = self.productStore else {
|
|
313
313
|
throw NSError(domain: "ExpoIapModule", code: 1, userInfo: [NSLocalizedDescriptionKey: "Connection not initialized"])
|
|
314
314
|
}
|
|
@@ -345,7 +345,7 @@ public class ExpoIapModule: Module {
|
|
|
345
345
|
switch result {
|
|
346
346
|
case .success(let verification):
|
|
347
347
|
let transaction = try self.checkVerified(verification)
|
|
348
|
-
if
|
|
348
|
+
if andDangerouslyFinishTransactionAutomatically {
|
|
349
349
|
await transaction.finish()
|
|
350
350
|
return nil
|
|
351
351
|
} else {
|
package/package.json
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-iap",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.2",
|
|
4
4
|
"description": "In App Purchase module in Expo",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"build
|
|
9
|
-
"build:copy": "mkdir -p build && rsync -a --include '*/' --include '*.ts' --exclude '*' src/ build/",
|
|
10
|
-
"build": "npm run build:compile && npm run build:copy",
|
|
11
|
-
"build:watch": "expo-module build",
|
|
8
|
+
"build": "expo-module build",
|
|
12
9
|
"clean": "expo-module clean",
|
|
13
10
|
"lint": "eslint --ext .ts,.tsx,.js,.jsx src",
|
|
14
11
|
"lint:eslint": "eslint --fix '**/*.{ts,tsx}'",
|
package/src/ExpoIap.types.ts
CHANGED
|
@@ -61,7 +61,7 @@ export type ProductPurchase =
|
|
|
61
61
|
|
|
62
62
|
// Union type for platform-specific subscription purchase types with proper discriminators
|
|
63
63
|
export type SubscriptionPurchase =
|
|
64
|
-
| (ProductPurchaseAndroid & AndroidPlatform & {
|
|
64
|
+
| (ProductPurchaseAndroid & AndroidPlatform & {autoRenewingAndroid: boolean})
|
|
65
65
|
| (ProductPurchaseIos & IosPlatform);
|
|
66
66
|
|
|
67
67
|
export type Purchase = ProductPurchase | SubscriptionPurchase;
|
package/src/index.ts
CHANGED
|
@@ -41,12 +41,12 @@ export enum IapEvent {
|
|
|
41
41
|
TransactionIapUpdated = 'iap-transaction-updated',
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
export
|
|
45
|
-
return
|
|
44
|
+
export function setValueAsync(value: string) {
|
|
45
|
+
return ExpoIapModule.setValueAsync(value);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
export const emitter = new EventEmitter(
|
|
49
|
-
ExpoIapModule
|
|
49
|
+
ExpoIapModule || NativeModulesProxy.ExpoIap,
|
|
50
50
|
);
|
|
51
51
|
|
|
52
52
|
export const purchaseUpdatedListener = (
|
|
@@ -70,7 +70,6 @@ export function initConnection() {
|
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
export const getProducts = async (skus: string[]): Promise<Product[]> => {
|
|
73
|
-
console.log('getProducts', skus);
|
|
74
73
|
if (!skus?.length) {
|
|
75
74
|
return Promise.reject(new Error('"skus" is required'));
|
|
76
75
|
}
|
|
@@ -78,7 +77,6 @@ export const getProducts = async (skus: string[]): Promise<Product[]> => {
|
|
|
78
77
|
return Platform.select({
|
|
79
78
|
ios: async () => {
|
|
80
79
|
const items = await ExpoIapModule.getItems(skus);
|
|
81
|
-
console.log('items', items);
|
|
82
80
|
return items.filter((item: unknown) => isProductIos<Product>(item));
|
|
83
81
|
},
|
|
84
82
|
android: async () => {
|
|
@@ -86,6 +84,7 @@ export const getProducts = async (skus: string[]): Promise<Product[]> => {
|
|
|
86
84
|
ProductType.InAppPurchase,
|
|
87
85
|
skus,
|
|
88
86
|
);
|
|
87
|
+
|
|
89
88
|
return products.filter((product: unknown) =>
|
|
90
89
|
isProductAndroid<Product>(product),
|
|
91
90
|
);
|
|
@@ -104,7 +103,6 @@ export const getSubscriptions = async (
|
|
|
104
103
|
return Platform.select({
|
|
105
104
|
ios: async () => {
|
|
106
105
|
const rawItems = await ExpoIapModule.getItems(skus);
|
|
107
|
-
|
|
108
106
|
return rawItems.filter((item: unknown) => {
|
|
109
107
|
if (!isSubscriptionProductIos(item)) return false;
|
|
110
108
|
return (
|
|
@@ -118,7 +116,6 @@ export const getSubscriptions = async (
|
|
|
118
116
|
},
|
|
119
117
|
android: async () => {
|
|
120
118
|
const rawItems = await ExpoIapModule.getItemsByType('subs', skus);
|
|
121
|
-
|
|
122
119
|
return rawItems.filter((item: unknown) => {
|
|
123
120
|
if (!isSubscriptionProductAndroid(item)) return false;
|
|
124
121
|
return (
|
|
@@ -157,11 +154,9 @@ export const getPurchaseHistory = ({
|
|
|
157
154
|
const products = await ExpoIapModule.getPurchaseHistoryByType(
|
|
158
155
|
ProductType.InAppPurchase,
|
|
159
156
|
);
|
|
160
|
-
|
|
161
157
|
const subscriptions = await ExpoIapModule.getPurchaseHistoryByType(
|
|
162
158
|
ProductType.Subscription,
|
|
163
159
|
);
|
|
164
|
-
|
|
165
160
|
return products.concat(subscriptions);
|
|
166
161
|
},
|
|
167
162
|
}) || (() => Promise.resolve([]))
|
|
@@ -185,11 +180,9 @@ export const getAvailablePurchases = ({
|
|
|
185
180
|
const products = await ExpoIapModule.getAvailableItemsByType(
|
|
186
181
|
ProductType.InAppPurchase,
|
|
187
182
|
);
|
|
188
|
-
|
|
189
183
|
const subscriptions = await ExpoIapModule.getAvailableItemsByType(
|
|
190
184
|
ProductType.Subscription,
|
|
191
185
|
);
|
|
192
|
-
|
|
193
186
|
return products.concat(subscriptions);
|
|
194
187
|
},
|
|
195
188
|
}) || (() => Promise.resolve([]))
|
|
@@ -219,32 +212,33 @@ export const requestPurchase = (
|
|
|
219
212
|
if (!('sku' in request)) {
|
|
220
213
|
throw new Error('sku is required for iOS purchase');
|
|
221
214
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
215
|
+
const {
|
|
216
|
+
sku,
|
|
217
|
+
andDangerouslyFinishTransactionAutomaticallyIOS = false,
|
|
218
|
+
appAccountToken,
|
|
219
|
+
quantity,
|
|
220
|
+
withOffer,
|
|
221
|
+
} = request;
|
|
225
222
|
const offer = offerToRecordIos(withOffer);
|
|
226
|
-
|
|
227
223
|
const purchase = await ExpoIapModule.buyProduct(
|
|
228
224
|
sku,
|
|
225
|
+
andDangerouslyFinishTransactionAutomaticallyIOS,
|
|
229
226
|
appAccountToken,
|
|
230
227
|
quantity ?? -1,
|
|
231
228
|
offer,
|
|
232
229
|
);
|
|
233
|
-
|
|
234
230
|
return Promise.resolve(purchase);
|
|
235
231
|
},
|
|
236
232
|
android: async () => {
|
|
237
233
|
if (!('skus' in request) || !request.skus.length) {
|
|
238
234
|
throw new Error('skus is required for Android purchase');
|
|
239
235
|
}
|
|
240
|
-
|
|
241
236
|
const {
|
|
242
237
|
skus,
|
|
243
238
|
obfuscatedAccountIdAndroid,
|
|
244
239
|
obfuscatedProfileIdAndroid,
|
|
245
240
|
isOfferPersonalized,
|
|
246
241
|
} = request;
|
|
247
|
-
|
|
248
242
|
return ExpoIapModule.buyItemByType({
|
|
249
243
|
type: ProductType.InAppPurchase,
|
|
250
244
|
skuArr: skus,
|
|
@@ -268,19 +262,21 @@ export const requestSubscription = (
|
|
|
268
262
|
if (!('sku' in request)) {
|
|
269
263
|
throw new Error('sku is required for iOS subscriptions');
|
|
270
264
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
265
|
+
const {
|
|
266
|
+
sku,
|
|
267
|
+
andDangerouslyFinishTransactionAutomaticallyIOS = false,
|
|
268
|
+
appAccountToken,
|
|
269
|
+
quantity,
|
|
270
|
+
withOffer,
|
|
271
|
+
} = request as RequestSubscriptionIosProps;
|
|
275
272
|
const offer = offerToRecordIos(withOffer);
|
|
276
|
-
|
|
277
273
|
const purchase = await ExpoIapModule.buyProduct(
|
|
278
274
|
sku,
|
|
275
|
+
andDangerouslyFinishTransactionAutomaticallyIOS,
|
|
279
276
|
appAccountToken,
|
|
280
277
|
quantity ?? -1,
|
|
281
278
|
offer,
|
|
282
279
|
);
|
|
283
|
-
|
|
284
280
|
return Promise.resolve(purchase as SubscriptionPurchase);
|
|
285
281
|
},
|
|
286
282
|
android: async () => {
|
|
@@ -293,7 +289,6 @@ export const requestSubscription = (
|
|
|
293
289
|
replacementModeAndroid,
|
|
294
290
|
purchaseTokenAndroid,
|
|
295
291
|
} = request as RequestSubscriptionAndroidProps;
|
|
296
|
-
|
|
297
292
|
return ExpoIapModule.buyItemByType({
|
|
298
293
|
type: ProductType.Subscription,
|
|
299
294
|
skuArr: skus.map((so) => so),
|
|
@@ -311,17 +306,14 @@ export const requestSubscription = (
|
|
|
311
306
|
export const finishTransaction = ({
|
|
312
307
|
purchase,
|
|
313
308
|
isConsumable,
|
|
314
|
-
developerPayloadAndroid,
|
|
315
309
|
}: {
|
|
316
310
|
purchase: Purchase;
|
|
317
311
|
isConsumable?: boolean;
|
|
318
|
-
developerPayloadAndroid?: string;
|
|
319
312
|
}): Promise<PurchaseResult | boolean> => {
|
|
320
313
|
return (
|
|
321
314
|
Platform.select({
|
|
322
315
|
ios: async () => {
|
|
323
316
|
const transactionId = purchase.transactionId;
|
|
324
|
-
|
|
325
317
|
if (!transactionId) {
|
|
326
318
|
return Promise.reject(
|
|
327
319
|
new Error('transactionId required to finish iOS transaction'),
|
|
@@ -331,21 +323,16 @@ export const finishTransaction = ({
|
|
|
331
323
|
return Promise.resolve(true);
|
|
332
324
|
},
|
|
333
325
|
android: async () => {
|
|
334
|
-
if (purchase?.purchaseToken) {
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
new Error('purchase is not suitable to be purchased'),
|
|
338
|
-
);
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
return ExpoIapModule.consumeProduct(
|
|
342
|
-
purchase.purchaseToken,
|
|
343
|
-
developerPayloadAndroid,
|
|
326
|
+
if (!purchase?.purchaseToken) {
|
|
327
|
+
return Promise.reject(
|
|
328
|
+
new Error('purchaseToken is required to finish transaction'),
|
|
344
329
|
);
|
|
345
330
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
331
|
+
if (isConsumable) {
|
|
332
|
+
return ExpoIapModule.consumeProduct(purchase.purchaseToken);
|
|
333
|
+
} else {
|
|
334
|
+
return ExpoIapModule.acknowledgePurchase(purchase.purchaseToken);
|
|
335
|
+
}
|
|
349
336
|
},
|
|
350
337
|
}) || (() => Promise.reject(new Error('Unsupported Platform')))
|
|
351
338
|
)();
|
package/src/useIap.ts
CHANGED
|
@@ -109,7 +109,8 @@ export function useIAP(): IAP_STATUS {
|
|
|
109
109
|
setCurrentPurchase(undefined);
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
if (purchase.id === currentPurchaseError?.productId) {
|
|
112
|
+
if (purchase.id === currentPurchaseError?.productId) {
|
|
113
|
+
// Note that PurchaseError still uses productId
|
|
113
114
|
setCurrentPurchaseError(undefined);
|
|
114
115
|
}
|
|
115
116
|
}
|