capacitor-native-purchases 0.1.1

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.
@@ -0,0 +1,88 @@
1
+ import type { PluginListenerHandle } from '@capacitor/core';
2
+ export interface PurchasesPlugin {
3
+ /**
4
+ * A test method which just returns what is passed in
5
+ */
6
+ echo(options: {
7
+ value: string;
8
+ }): Promise<{
9
+ value: string;
10
+ }>;
11
+ /**
12
+ * Receives a product ID and returns the product details
13
+ * @param options.productId The product ID to lookup
14
+ */
15
+ getProductDetails(options: {
16
+ productIdentifier: string;
17
+ }): Promise<ProductDetailsResponse>;
18
+ /**
19
+ * Receives the product ID which the user wants to purchase and returns the transaction ID
20
+ * @param options.productId contains the productIdentifier
21
+ * @param options.userId contains userId linked to your system, must by UUID.
22
+ */
23
+ purchaseProduct(options: {
24
+ productIdentifier: string;
25
+ userId?: string;
26
+ }): Promise<PurchaseProductResponse>;
27
+ getCurrentEntitlements(): Promise<CurrentEntitlementsResponse>;
28
+ getLatestTransaction(options: {
29
+ productIdentifier: string;
30
+ }): Promise<LatestTransactionResponse>;
31
+ manageSubscriptions(): any;
32
+ setGoogleVerificationDetails(options: {
33
+ googleVerifyEndpoint: string;
34
+ bid: string;
35
+ }): void;
36
+ addListener(eventName: 'ANDROID-PURCHASE-RESPONSE', listenerFunc: (response: AndroidPurchasedTrigger) => void): Promise<PluginListenerHandle>;
37
+ restorePurchases(): Promise<RestorePurchasesResponse>;
38
+ }
39
+ export interface Product {
40
+ productIdentifier: string;
41
+ price: string;
42
+ displayName: string;
43
+ description: string;
44
+ }
45
+ export interface Transaction {
46
+ productIdentifier: string;
47
+ expiryDate: string;
48
+ originalId: string;
49
+ transactionId: string;
50
+ originalStartDate: string;
51
+ isTrial?: boolean;
52
+ purchaseToken?: string;
53
+ }
54
+ export interface LatestTransactionResponse {
55
+ responseCode: LatestTransactionResponseCode;
56
+ responseMessage: LatestTransactionResponseMessage;
57
+ data?: Transaction;
58
+ }
59
+ export interface RestorePurchasesResponse {
60
+ completed: boolean;
61
+ }
62
+ export type LatestTransactionResponseCode = -1 | 0 | 1 | 2 | 3;
63
+ export type LatestTransactionResponseMessage = 'Incompatible with web' | 'Successfully found the latest transaction matching given productIdentifier' | 'Could not find a product matching the given productIdentifier' | 'No transaction for given productIdentifier, or it could not be verified' | 'Unknown problem trying to retrieve latest transaction';
64
+ export interface CurrentEntitlementsResponse {
65
+ responseCode: CurrentEntitlementsResponseCode;
66
+ responseMessage: CurrentEntitlementsResponseMessage;
67
+ data?: Transaction[];
68
+ }
69
+ export type CurrentEntitlementsResponseCode = -1 | 0 | 1 | 2;
70
+ export type CurrentEntitlementsResponseMessage = 'Incompatible with web' | 'Successfully found all entitlements across all product types' | 'No entitlements were found' | 'Unknown problem trying to retrieve entitlements';
71
+ export interface PurchaseProductResponse {
72
+ responseCode: PurchaseProductIOSResponseCode | PurchaseProductAndroidResponseCode;
73
+ responseMessage: PurchaseProductIOSResponseMessage | PurchaseProductAndroidResponseMessage;
74
+ }
75
+ export type PurchaseProductIOSResponseCode = -1 | 0 | 1 | 2 | 3 | 4 | 5;
76
+ export type PurchaseProductIOSResponseMessage = 'Incompatible with web' | 'Successfully purchased product' | 'Could not find a product matching the given productIdentifier' | 'Product seems to have been purchased but the transaction failed verification' | 'User closed the native popover before purchasing' | 'Product request made but is currently pending - likely due to parental restrictions' | 'An unknown error occurred whilst in the purchasing process';
77
+ export type PurchaseProductAndroidResponseCode = -1 | 0 | 1;
78
+ export type PurchaseProductAndroidResponseMessage = 'Incompatible with web' | 'Successfully opened native popover' | 'Failed to open native popover';
79
+ export interface ProductDetailsResponse {
80
+ responseCode: ProductDetailsResponseCode;
81
+ responseMessage: ProductDetailsResponseMessage;
82
+ data?: Product;
83
+ }
84
+ export type ProductDetailsResponseCode = -1 | 0 | 1;
85
+ export type ProductDetailsResponseMessage = 'Incompatible with web' | 'Successfully found the product details for given productIdentifier' | 'Could not find a product matching the given productIdentifier';
86
+ export interface AndroidPurchasedTrigger {
87
+ fired: boolean;
88
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=definitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PluginListenerHandle } from '@capacitor/core';\n\nexport interface PurchasesPlugin {\n /**\n * A test method which just returns what is passed in\n */\n echo(options: { value: string }): Promise<{ value: string }>;\n\n /**\n * Receives a product ID and returns the product details\n * @param options.productId The product ID to lookup\n */\n getProductDetails(options: { productIdentifier: string }): Promise<ProductDetailsResponse>;\n\n /**\n * Receives the product ID which the user wants to purchase and returns the transaction ID\n * @param options.productId contains the productIdentifier\n * @param options.userId contains userId linked to your system, must by UUID.\n */\n purchaseProduct(options: { productIdentifier: string; userId?: string }): Promise<PurchaseProductResponse>;\n\n getCurrentEntitlements(): Promise<CurrentEntitlementsResponse>;\n\n getLatestTransaction(options: { productIdentifier: string }): Promise<LatestTransactionResponse>;\n\n manageSubscriptions(): any;\n\n setGoogleVerificationDetails(options: { googleVerifyEndpoint: string; bid: string }): void;\n\n addListener(\n eventName: 'ANDROID-PURCHASE-RESPONSE',\n listenerFunc: (response: AndroidPurchasedTrigger) => void,\n ): Promise<PluginListenerHandle>;\n\n restorePurchases(): Promise<RestorePurchasesResponse>;\n}\n\n// Response data types\n\nexport interface Product {\n productIdentifier: string;\n price: string;\n displayName: string;\n description: string;\n}\n\nexport interface Transaction {\n productIdentifier: string;\n expiryDate: string;\n originalId: string;\n transactionId: string;\n originalStartDate: string;\n isTrial?: boolean;\n purchaseToken?: string;\n}\n\n// latestTransactions interface and types\n\nexport interface LatestTransactionResponse {\n responseCode: LatestTransactionResponseCode;\n responseMessage: LatestTransactionResponseMessage;\n data?: Transaction;\n}\n\nexport interface RestorePurchasesResponse {\n completed: boolean;\n}\n\nexport type LatestTransactionResponseCode = -1 | 0 | 1 | 2 | 3;\nexport type LatestTransactionResponseMessage =\n | 'Incompatible with web'\n | 'Successfully found the latest transaction matching given productIdentifier'\n | 'Could not find a product matching the given productIdentifier'\n | 'No transaction for given productIdentifier, or it could not be verified'\n | 'Unknown problem trying to retrieve latest transaction';\n\n// currentEntitlements interface and types\n\nexport interface CurrentEntitlementsResponse {\n responseCode: CurrentEntitlementsResponseCode;\n responseMessage: CurrentEntitlementsResponseMessage;\n data?: Transaction[];\n}\n\nexport type CurrentEntitlementsResponseCode = -1 | 0 | 1 | 2;\nexport type CurrentEntitlementsResponseMessage =\n | 'Incompatible with web'\n | 'Successfully found all entitlements across all product types'\n | 'No entitlements were found'\n | 'Unknown problem trying to retrieve entitlements';\n\n// purchaseProduct interface and types\n\nexport interface PurchaseProductResponse {\n responseCode: PurchaseProductIOSResponseCode | PurchaseProductAndroidResponseCode;\n responseMessage: PurchaseProductIOSResponseMessage | PurchaseProductAndroidResponseMessage;\n}\n\nexport type PurchaseProductIOSResponseCode = -1 | 0 | 1 | 2 | 3 | 4 | 5;\nexport type PurchaseProductIOSResponseMessage =\n | 'Incompatible with web'\n | 'Successfully purchased product'\n | 'Could not find a product matching the given productIdentifier'\n | 'Product seems to have been purchased but the transaction failed verification'\n | 'User closed the native popover before purchasing'\n | 'Product request made but is currently pending - likely due to parental restrictions'\n | 'An unknown error occurred whilst in the purchasing process';\n\nexport type PurchaseProductAndroidResponseCode = -1 | 0 | 1;\nexport type PurchaseProductAndroidResponseMessage =\n | 'Incompatible with web'\n | 'Successfully opened native popover'\n | 'Failed to open native popover';\n\nexport interface ProductDetailsResponse {\n responseCode: ProductDetailsResponseCode;\n responseMessage: ProductDetailsResponseMessage;\n data?: Product;\n}\n\nexport type ProductDetailsResponseCode = -1 | 0 | 1;\nexport type ProductDetailsResponseMessage =\n | 'Incompatible with web'\n | 'Successfully found the product details for given productIdentifier'\n | 'Could not find a product matching the given productIdentifier';\n\nexport interface AndroidPurchasedTrigger {\n fired: boolean;\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import type { PurchasesPlugin } from './definitions';
2
+ declare const Purchases: PurchasesPlugin;
3
+ export * from './definitions';
4
+ export { Purchases };
@@ -0,0 +1,7 @@
1
+ import { registerPlugin } from '@capacitor/core';
2
+ const Purchases = registerPlugin('Purchases', {
3
+ web: () => import('./web').then((m) => new m.PurchasesWeb()),
4
+ });
5
+ export * from './definitions';
6
+ export { Purchases };
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,SAAS,GAAG,cAAc,CAAkB,WAAW,EAAE;IAC7D,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC;CAC7D,CAAC,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAE,CAAC","sourcesContent":["import { registerPlugin } from '@capacitor/core';\n\nimport type { PurchasesPlugin } from './definitions';\n\nconst Purchases = registerPlugin<PurchasesPlugin>('Purchases', {\n web: () => import('./web').then((m) => new m.PurchasesWeb()),\n});\n\nexport * from './definitions';\nexport { Purchases };\n"]}
@@ -0,0 +1,26 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+ import type { CurrentEntitlementsResponse, LatestTransactionResponse, ProductDetailsResponse, PurchaseProductResponse, PurchasesPlugin, RestorePurchasesResponse } from './definitions';
3
+ export declare class PurchasesWeb extends WebPlugin implements PurchasesPlugin {
4
+ setGoogleVerificationDetails(options: {
5
+ googleVerifyEndpoint: string;
6
+ bid: string;
7
+ }): void;
8
+ echo(options: {
9
+ value: string;
10
+ }): Promise<{
11
+ value: string;
12
+ }>;
13
+ getProductDetails(options: {
14
+ productIdentifier: string;
15
+ }): Promise<ProductDetailsResponse>;
16
+ purchaseProduct(options: {
17
+ productIdentifier: string;
18
+ userId?: string;
19
+ }): Promise<PurchaseProductResponse>;
20
+ getCurrentEntitlements(): Promise<CurrentEntitlementsResponse>;
21
+ getLatestTransaction(options: {
22
+ productIdentifier: string;
23
+ }): Promise<LatestTransactionResponse>;
24
+ manageSubscriptions(): void;
25
+ restorePurchases(): Promise<RestorePurchasesResponse>;
26
+ }
@@ -0,0 +1,43 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+ export class PurchasesWeb extends WebPlugin {
3
+ setGoogleVerificationDetails(options) {
4
+ console.info(options);
5
+ }
6
+ async echo(options) {
7
+ return options;
8
+ }
9
+ async getProductDetails(options) {
10
+ console.info(options);
11
+ return {
12
+ responseCode: -1,
13
+ responseMessage: 'Incompatible with web',
14
+ };
15
+ }
16
+ async purchaseProduct(options) {
17
+ console.info(options);
18
+ return {
19
+ responseCode: -1,
20
+ responseMessage: 'Incompatible with web',
21
+ };
22
+ }
23
+ async getCurrentEntitlements() {
24
+ return {
25
+ responseCode: -1,
26
+ responseMessage: 'Incompatible with web',
27
+ };
28
+ }
29
+ async getLatestTransaction(options) {
30
+ console.info(options);
31
+ return {
32
+ responseCode: -1,
33
+ responseMessage: 'Incompatible with web',
34
+ };
35
+ }
36
+ manageSubscriptions() {
37
+ // Do nothing
38
+ }
39
+ async restorePurchases() {
40
+ return { completed: false };
41
+ }
42
+ }
43
+ //# sourceMappingURL=web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAW5C,MAAM,OAAO,YAAa,SAAQ,SAAS;IACzC,4BAA4B,CAAC,OAAsD;QACjF,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,OAA0B;QACnC,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,KAAK,CAAC,iBAAiB,CAAC,OAAsC;QAC5D,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtB,OAAO;YACL,YAAY,EAAE,CAAC,CAAC;YAChB,eAAe,EAAE,uBAAuB;SACzC,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,eAAe,CAAC,OAAuD;QAC3E,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtB,OAAO;YACL,YAAY,EAAE,CAAC,CAAC;YAChB,eAAe,EAAE,uBAAuB;SACzC,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,sBAAsB;QAC1B,OAAO;YACL,YAAY,EAAE,CAAC,CAAC;YAChB,eAAe,EAAE,uBAAuB;SACzC,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,oBAAoB,CAAC,OAAsC;QAC/D,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtB,OAAO;YACL,YAAY,EAAE,CAAC,CAAC;YAChB,eAAe,EAAE,uBAAuB;SACzC,CAAC;IACJ,CAAC;IACD,mBAAmB;QACjB,aAAa;IACf,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC;CACF","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type {\n CurrentEntitlementsResponse,\n LatestTransactionResponse,\n ProductDetailsResponse,\n PurchaseProductResponse,\n PurchasesPlugin,\n RestorePurchasesResponse,\n} from './definitions';\n\nexport class PurchasesWeb extends WebPlugin implements PurchasesPlugin {\n setGoogleVerificationDetails(options: { googleVerifyEndpoint: string; bid: string }): void {\n console.info(options);\n }\n async echo(options: { value: string }): Promise<{ value: string }> {\n return options;\n }\n async getProductDetails(options: { productIdentifier: string }): Promise<ProductDetailsResponse> {\n console.info(options);\n return {\n responseCode: -1,\n responseMessage: 'Incompatible with web',\n };\n }\n async purchaseProduct(options: { productIdentifier: string; userId?: string }): Promise<PurchaseProductResponse> {\n console.info(options);\n return {\n responseCode: -1,\n responseMessage: 'Incompatible with web',\n };\n }\n async getCurrentEntitlements(): Promise<CurrentEntitlementsResponse> {\n return {\n responseCode: -1,\n responseMessage: 'Incompatible with web',\n };\n }\n async getLatestTransaction(options: { productIdentifier: string }): Promise<LatestTransactionResponse> {\n console.info(options);\n return {\n responseCode: -1,\n responseMessage: 'Incompatible with web',\n };\n }\n manageSubscriptions(): void {\n // Do nothing\n }\n\n async restorePurchases(): Promise<RestorePurchasesResponse> {\n return { completed: false };\n }\n}\n"]}
@@ -0,0 +1,57 @@
1
+ 'use strict';
2
+
3
+ var core = require('@capacitor/core');
4
+
5
+ const Purchases = core.registerPlugin('Purchases', {
6
+ web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.PurchasesWeb()),
7
+ });
8
+
9
+ class PurchasesWeb extends core.WebPlugin {
10
+ setGoogleVerificationDetails(options) {
11
+ console.info(options);
12
+ }
13
+ async echo(options) {
14
+ return options;
15
+ }
16
+ async getProductDetails(options) {
17
+ console.info(options);
18
+ return {
19
+ responseCode: -1,
20
+ responseMessage: 'Incompatible with web',
21
+ };
22
+ }
23
+ async purchaseProduct(options) {
24
+ console.info(options);
25
+ return {
26
+ responseCode: -1,
27
+ responseMessage: 'Incompatible with web',
28
+ };
29
+ }
30
+ async getCurrentEntitlements() {
31
+ return {
32
+ responseCode: -1,
33
+ responseMessage: 'Incompatible with web',
34
+ };
35
+ }
36
+ async getLatestTransaction(options) {
37
+ console.info(options);
38
+ return {
39
+ responseCode: -1,
40
+ responseMessage: 'Incompatible with web',
41
+ };
42
+ }
43
+ manageSubscriptions() {
44
+ // Do nothing
45
+ }
46
+ async restorePurchases() {
47
+ return { completed: false };
48
+ }
49
+ }
50
+
51
+ var web = /*#__PURE__*/Object.freeze({
52
+ __proto__: null,
53
+ PurchasesWeb: PurchasesWeb
54
+ });
55
+
56
+ exports.Purchases = Purchases;
57
+ //# sourceMappingURL=plugin.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst Purchases = registerPlugin('Purchases', {\n web: () => import('./web').then((m) => new m.PurchasesWeb()),\n});\nexport * from './definitions';\nexport { Purchases };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class PurchasesWeb extends WebPlugin {\n setGoogleVerificationDetails(options) {\n console.info(options);\n }\n async echo(options) {\n return options;\n }\n async getProductDetails(options) {\n console.info(options);\n return {\n responseCode: -1,\n responseMessage: 'Incompatible with web',\n };\n }\n async purchaseProduct(options) {\n console.info(options);\n return {\n responseCode: -1,\n responseMessage: 'Incompatible with web',\n };\n }\n async getCurrentEntitlements() {\n return {\n responseCode: -1,\n responseMessage: 'Incompatible with web',\n };\n }\n async getLatestTransaction(options) {\n console.info(options);\n return {\n responseCode: -1,\n responseMessage: 'Incompatible with web',\n };\n }\n manageSubscriptions() {\n // Do nothing\n }\n async restorePurchases() {\n return { completed: false };\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;;AACK,MAAC,SAAS,GAAGA,mBAAc,CAAC,WAAW,EAAE;AAC9C,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC;AAChE,CAAC;;ACFM,MAAM,YAAY,SAASC,cAAS,CAAC;AAC5C,IAAI,4BAA4B,CAAC,OAAO,EAAE;AAC1C,QAAQ,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;AAC7B,IAAI;AACJ,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE;AACxB,QAAQ,OAAO,OAAO;AACtB,IAAI;AACJ,IAAI,MAAM,iBAAiB,CAAC,OAAO,EAAE;AACrC,QAAQ,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;AAC7B,QAAQ,OAAO;AACf,YAAY,YAAY,EAAE,EAAE;AAC5B,YAAY,eAAe,EAAE,uBAAuB;AACpD,SAAS;AACT,IAAI;AACJ,IAAI,MAAM,eAAe,CAAC,OAAO,EAAE;AACnC,QAAQ,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;AAC7B,QAAQ,OAAO;AACf,YAAY,YAAY,EAAE,EAAE;AAC5B,YAAY,eAAe,EAAE,uBAAuB;AACpD,SAAS;AACT,IAAI;AACJ,IAAI,MAAM,sBAAsB,GAAG;AACnC,QAAQ,OAAO;AACf,YAAY,YAAY,EAAE,EAAE;AAC5B,YAAY,eAAe,EAAE,uBAAuB;AACpD,SAAS;AACT,IAAI;AACJ,IAAI,MAAM,oBAAoB,CAAC,OAAO,EAAE;AACxC,QAAQ,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;AAC7B,QAAQ,OAAO;AACf,YAAY,YAAY,EAAE,EAAE;AAC5B,YAAY,eAAe,EAAE,uBAAuB;AACpD,SAAS;AACT,IAAI;AACJ,IAAI,mBAAmB,GAAG;AAC1B;AACA,IAAI;AACJ,IAAI,MAAM,gBAAgB,GAAG;AAC7B,QAAQ,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE;AACnC,IAAI;AACJ;;;;;;;;;"}
package/dist/plugin.js ADDED
@@ -0,0 +1,60 @@
1
+ var capacitorPurchases = (function (exports, core) {
2
+ 'use strict';
3
+
4
+ const Purchases = core.registerPlugin('Purchases', {
5
+ web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.PurchasesWeb()),
6
+ });
7
+
8
+ class PurchasesWeb extends core.WebPlugin {
9
+ setGoogleVerificationDetails(options) {
10
+ console.info(options);
11
+ }
12
+ async echo(options) {
13
+ return options;
14
+ }
15
+ async getProductDetails(options) {
16
+ console.info(options);
17
+ return {
18
+ responseCode: -1,
19
+ responseMessage: 'Incompatible with web',
20
+ };
21
+ }
22
+ async purchaseProduct(options) {
23
+ console.info(options);
24
+ return {
25
+ responseCode: -1,
26
+ responseMessage: 'Incompatible with web',
27
+ };
28
+ }
29
+ async getCurrentEntitlements() {
30
+ return {
31
+ responseCode: -1,
32
+ responseMessage: 'Incompatible with web',
33
+ };
34
+ }
35
+ async getLatestTransaction(options) {
36
+ console.info(options);
37
+ return {
38
+ responseCode: -1,
39
+ responseMessage: 'Incompatible with web',
40
+ };
41
+ }
42
+ manageSubscriptions() {
43
+ // Do nothing
44
+ }
45
+ async restorePurchases() {
46
+ return { completed: false };
47
+ }
48
+ }
49
+
50
+ var web = /*#__PURE__*/Object.freeze({
51
+ __proto__: null,
52
+ PurchasesWeb: PurchasesWeb
53
+ });
54
+
55
+ exports.Purchases = Purchases;
56
+
57
+ return exports;
58
+
59
+ })({}, capacitorExports);
60
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst Purchases = registerPlugin('Purchases', {\n web: () => import('./web').then((m) => new m.PurchasesWeb()),\n});\nexport * from './definitions';\nexport { Purchases };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class PurchasesWeb extends WebPlugin {\n setGoogleVerificationDetails(options) {\n console.info(options);\n }\n async echo(options) {\n return options;\n }\n async getProductDetails(options) {\n console.info(options);\n return {\n responseCode: -1,\n responseMessage: 'Incompatible with web',\n };\n }\n async purchaseProduct(options) {\n console.info(options);\n return {\n responseCode: -1,\n responseMessage: 'Incompatible with web',\n };\n }\n async getCurrentEntitlements() {\n return {\n responseCode: -1,\n responseMessage: 'Incompatible with web',\n };\n }\n async getLatestTransaction(options) {\n console.info(options);\n return {\n responseCode: -1,\n responseMessage: 'Incompatible with web',\n };\n }\n manageSubscriptions() {\n // Do nothing\n }\n async restorePurchases() {\n return { completed: false };\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;AACK,UAAC,SAAS,GAAGA,mBAAc,CAAC,WAAW,EAAE;IAC9C,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC;IAChE,CAAC;;ICFM,MAAM,YAAY,SAASC,cAAS,CAAC;IAC5C,IAAI,4BAA4B,CAAC,OAAO,EAAE;IAC1C,QAAQ,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;IAC7B,IAAI;IACJ,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE;IACxB,QAAQ,OAAO,OAAO;IACtB,IAAI;IACJ,IAAI,MAAM,iBAAiB,CAAC,OAAO,EAAE;IACrC,QAAQ,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;IAC7B,QAAQ,OAAO;IACf,YAAY,YAAY,EAAE,EAAE;IAC5B,YAAY,eAAe,EAAE,uBAAuB;IACpD,SAAS;IACT,IAAI;IACJ,IAAI,MAAM,eAAe,CAAC,OAAO,EAAE;IACnC,QAAQ,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;IAC7B,QAAQ,OAAO;IACf,YAAY,YAAY,EAAE,EAAE;IAC5B,YAAY,eAAe,EAAE,uBAAuB;IACpD,SAAS;IACT,IAAI;IACJ,IAAI,MAAM,sBAAsB,GAAG;IACnC,QAAQ,OAAO;IACf,YAAY,YAAY,EAAE,EAAE;IAC5B,YAAY,eAAe,EAAE,uBAAuB;IACpD,SAAS;IACT,IAAI;IACJ,IAAI,MAAM,oBAAoB,CAAC,OAAO,EAAE;IACxC,QAAQ,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;IAC7B,QAAQ,OAAO;IACf,YAAY,YAAY,EAAE,EAAE;IAC5B,YAAY,eAAe,EAAE,uBAAuB;IACpD,SAAS;IACT,IAAI;IACJ,IAAI,mBAAmB,GAAG;IAC1B;IACA,IAAI;IACJ,IAAI,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE;IACnC,IAAI;IACJ;;;;;;;;;;;;;;;"}
@@ -0,0 +1,341 @@
1
+ import Foundation
2
+ import StoreKit
3
+ import Capacitor
4
+ import UIKit
5
+
6
+ @objc public class Purchases: NSObject {
7
+ override init() {
8
+ super.init();
9
+ if #available(iOS 15.0.0, *) {
10
+ let transactionListener = listenForTransactions();
11
+ let unfinishedListener = finishTransactions();
12
+ } else {
13
+ // Fallback on earlier versions
14
+ };
15
+ }
16
+
17
+ @objc public func echo(_ value: String) -> String {
18
+ print(value)
19
+ return value
20
+ }
21
+
22
+ // When the subscription renews at the end of the month, a transaction will
23
+ // be queued for when the app is next opened. This listener handles any transactions
24
+ // within the queue and finishes verified purchases to clear the queue and prevent
25
+ // any bugs or performance issues occuring
26
+ @available(iOS 15.0.0, *)
27
+ private func listenForTransactions() -> Task<Void, Error> {
28
+ return Task.detached {
29
+
30
+ //Iterate through any transactions that don't come from a direct call to `purchase()`.
31
+ for await verification in Transaction.updates {
32
+
33
+ guard let transaction: Transaction = self.checkVerified(verification)
34
+ as? Transaction else {
35
+ print("checkVerified failed");
36
+ return
37
+
38
+ };
39
+
40
+ await transaction.finish();
41
+ print("Transaction finished and removed from paymentQueue - Transactions.updates");
42
+ }
43
+
44
+ }
45
+ }
46
+
47
+ @available(iOS 15.0.0, *)
48
+ private func finishTransactions() -> Task<Void, Error> {
49
+ return Task.detached {
50
+
51
+ //Iterate through any transactions that don't come from a direct call to `purchase()`.
52
+ for await verification in Transaction.unfinished {
53
+
54
+ guard let transaction: Transaction = self.checkVerified(verification)
55
+ as? Transaction else {
56
+ print("checkVerified failed");
57
+ return
58
+
59
+ };
60
+
61
+ await transaction.finish();
62
+ print("Transaction finished and removed from paymentQueue - transactions.unfinished");
63
+ }
64
+ }
65
+ }
66
+
67
+ @available(iOS 15.0.0, *)
68
+ @objc public func getProductDetails(_ productIdentifier: String) async -> PluginCallResultData {
69
+
70
+ guard let product: Product = await getProduct(productIdentifier) as? Product else {
71
+ return [
72
+ "responseCode": 1,
73
+ "responseMessage": "Could not find a product matching the given productIdentifier"
74
+ ]
75
+ };
76
+
77
+ let displayName = product.displayName;
78
+ let description = product.description;
79
+ let price = product.displayPrice;
80
+
81
+ return [
82
+ "responseCode": 0,
83
+ "responseMessage": "Successfully found the product details for given productIdentifier",
84
+ "data": [
85
+ "productIdentifier": productIdentifier,
86
+ "displayName": displayName,
87
+ "description": description,
88
+ "price": price
89
+ ]
90
+ ];
91
+ }
92
+
93
+ @available(iOS 15.0.0, *)
94
+ @objc public func purchaseProduct(_ productIdentifier: String, userId: String?) async -> PluginCallResultData {
95
+
96
+ do {
97
+
98
+ guard let product: Product = await getProduct(productIdentifier) as? Product else {
99
+ return [
100
+ "responseCode": 1,
101
+ "responseMessage": "Could not find a product matching the given productIdentifier"
102
+ ];
103
+ };
104
+
105
+ let userUUID = UUID(uuidString: userId ?? "") ?? UUID()
106
+
107
+ let result: Product.PurchaseResult = try await product.purchase(options: [
108
+ .appAccountToken(userUUID)
109
+ ]);
110
+
111
+ switch result {
112
+
113
+ case .success(let verification):
114
+
115
+ guard let transaction: Transaction = checkVerified(verification) as? Transaction else {
116
+ return [
117
+ "responseCode": 2,
118
+ "responseMessage": "Product seems to have been purchased but the transaction failed verification"
119
+ ];
120
+ };
121
+
122
+ await transaction.finish();
123
+ return [
124
+ "responseCode": 0,
125
+ "responseMessage": "Successfully purchased product"
126
+ ];
127
+
128
+ case .userCancelled:
129
+
130
+ return [
131
+ "responseCode": 3,
132
+ "responseMessage": "User closed the native popover before purchasing"
133
+ ];
134
+
135
+ case .pending:
136
+
137
+ return [
138
+ "responseCode": 4,
139
+ "responseMessage": "Product request made but is currently pending - likely due to parental restrictions"
140
+ ];
141
+
142
+ default:
143
+
144
+ return [
145
+ "responseCode": 5,
146
+ "responseMessage": "An unknown error occurred whilst in the purchasing process",
147
+ ]
148
+
149
+ }
150
+
151
+ } catch {
152
+ print(error.localizedDescription);
153
+ return [
154
+ "responseCode": 5,
155
+ "responseMessage": "An unknown error occurred whilst in the purchasing process"
156
+ ]
157
+ }
158
+
159
+ }
160
+
161
+ @available(iOS 15.0.0, *)
162
+ @objc public func getCurrentEntitlements() async -> PluginCallResultData {
163
+
164
+ do {
165
+
166
+ var transactionDictionary = [String: [String: Any]]();
167
+
168
+ // Loop through each verification result in currentEntitlements, verify the transaction
169
+ // then add it to the transactionDictionary if verified.
170
+ for await verification in Transaction.currentEntitlements {
171
+
172
+ let transaction: Transaction? = checkVerified(verification) as? Transaction
173
+ if(transaction != nil) {
174
+
175
+ transactionDictionary[String(transaction!.id)] = [
176
+ "productIdentifier": transaction!.productID,
177
+ "originalStartDate": transaction!.originalPurchaseDate,
178
+ "originalId": transaction!.originalID,
179
+ "transactionId": transaction!.id,
180
+ "expiryDate": transaction!.expirationDate!,
181
+ "purchaseToken": ""
182
+ ]
183
+
184
+ }
185
+
186
+ }
187
+
188
+ // If we have one or more entitlements in transactionDictionary
189
+ // we want the response to include it in the data property
190
+ if(transactionDictionary.count > 0) {
191
+
192
+ let response = [
193
+ "responseCode": 0,
194
+ "responseMessage": "Successfully found all entitlements across all product types",
195
+ "data": transactionDictionary
196
+ ] as [String : Any]
197
+
198
+ return response;
199
+
200
+ // Otherwise - no entitlements were found
201
+ } else {
202
+ return [
203
+ "responseCode": 1,
204
+ "responseMessage": "No entitlements were found",
205
+ ]
206
+ }
207
+
208
+ }
209
+
210
+
211
+ }
212
+
213
+ @available(iOS 15.0.0, *)
214
+ @objc public func getLatestTransaction(_ productIdentifier: String) async -> PluginCallResultData {
215
+
216
+ do {
217
+ guard let product: Product = await getProduct(productIdentifier) as? Product else {
218
+ return [
219
+ "responseCode": 1,
220
+ "responseMessage": "Could not find a product matching the given productIdentifier"
221
+ ]
222
+
223
+ };
224
+
225
+ guard let transaction: Transaction = checkVerified(await product.latestTransaction) as? Transaction else {
226
+ // The user hasn't purchased this product.
227
+ return [
228
+ "responseCode": 2,
229
+ "responseMessage": "No transaction for given productIdentifier, or it could not be verified"
230
+ ]
231
+ }
232
+
233
+ print("expiration" + String(decoding: formatDate(transaction.expirationDate)!, as: UTF8.self))
234
+ print("transaction.expirationDate", transaction.expirationDate!)
235
+ print("transaction.originalID", transaction.originalID);
236
+
237
+ var receiptString = "";
238
+
239
+ if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL,
240
+ FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {
241
+
242
+
243
+ do {
244
+ let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
245
+ print("Receipt Data: ", receiptData)
246
+
247
+
248
+ receiptString = receiptData.base64EncodedString(options: [Data.Base64EncodingOptions.endLineWithCarriageReturn])
249
+ print("Receipt String: ", receiptString)
250
+
251
+
252
+ // Read receiptData.
253
+ }
254
+ catch { print("Couldn't read receipt data with error: " + error.localizedDescription) }
255
+ }
256
+
257
+
258
+ return [
259
+ "responseCode": 0,
260
+ "responseMessage": "Latest transaction found",
261
+ "data": [
262
+ "productIdentifier": transaction.productID,
263
+ "originalStartDate": transaction.originalPurchaseDate,
264
+ "originalId": transaction.originalID,
265
+ "transactionId": transaction.id,
266
+ "expiryDate": transaction.expirationDate!,
267
+ "purchaseToken": receiptString
268
+ ]
269
+ ];
270
+
271
+ }
272
+
273
+ }
274
+
275
+ @available(iOS 15.0.0, *)
276
+ @objc public func manageSubscriptions() async {
277
+
278
+ let manageTransactions: UIWindowScene
279
+ await UIApplication.shared.open(URL(string: "https://apps.apple.com/account/subscriptions")!)
280
+
281
+ }
282
+
283
+ @available(iOS 15.0.0, *)
284
+ @objc private func formatDate(_ date: Date?) -> Data? {
285
+
286
+ let df = DateFormatter();
287
+ df.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
288
+ return df.string(for: date)?.data(using: String.Encoding.utf8)!;
289
+
290
+ }
291
+
292
+ @available(iOS 15.0.0, *)
293
+ @objc private func updateTrialDate(_ bid: String, _ formattedDate: Data?) {
294
+
295
+ let keyChainUpdateParams: [String: Any] = [
296
+ kSecClass as String: kSecClassGenericPassword,
297
+ kSecAttrAccount as String: bid
298
+ ]
299
+
300
+ let keyChainUpdateValue: [String: Any] = [
301
+ kSecValueData as String: formattedDate!
302
+ ];
303
+
304
+ let updateStatusCode = SecItemUpdate(keyChainUpdateParams as CFDictionary, keyChainUpdateValue as CFDictionary);
305
+ let updateStatusMessage = SecCopyErrorMessageString(updateStatusCode, nil);
306
+
307
+ print("updateStatusCode in SecItemUpdate", updateStatusCode);
308
+ print("updateStatusMessage in SecItemUpdate", updateStatusMessage!);
309
+
310
+ }
311
+
312
+ @available(iOS 15.0.0, *)
313
+ @objc private func getProduct(_ productIdentifier: String) async -> Any? {
314
+
315
+ do {
316
+ let products = try await Product.products(for: [productIdentifier]);
317
+ if (products.count > 0) {
318
+ let product = products[0];
319
+ return product;
320
+ }
321
+ return nil
322
+ } catch {
323
+ return nil;
324
+ }
325
+
326
+ }
327
+
328
+ @available(iOS 15.0.0, *)
329
+ @objc private func checkVerified(_ vr: Any?) -> Any? {
330
+
331
+ switch vr as? VerificationResult<Transaction> {
332
+ case .verified(let safe):
333
+ return safe
334
+ case .unverified:
335
+ return nil;
336
+ default:
337
+ return nil;
338
+ }
339
+
340
+ }
341
+ }