iap-apple 2.0.5 โ†’ 3.0.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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  | Statements | Branches | Functions | Lines |
2
2
  | --------------------------- | ----------------------- | ------------------------- | ----------------- |
3
- | ![Statements](https://img.shields.io/badge/statements-76.97%25-red.svg?style=flat) | ![Branches](https://img.shields.io/badge/branches-47.96%25-red.svg?style=flat) | ![Functions](https://img.shields.io/badge/functions-75%25-red.svg?style=flat) | ![Lines](https://img.shields.io/badge/lines-75%25-red.svg?style=flat) |
3
+ | ![Statements](https://img.shields.io/badge/statements-93.54%25-brightgreen.svg?style=flat) | ![Branches](https://img.shields.io/badge/branches-82.92%25-yellow.svg?style=flat) | ![Functions](https://img.shields.io/badge/functions-93.75%25-brightgreen.svg?style=flat) | ![Lines](https://img.shields.io/badge/lines-93.16%25-brightgreen.svg?style=flat) |
4
4
 
5
5
  # iap-apple
6
6
 
@@ -8,173 +8,183 @@
8
8
  ![https://img.shields.io/github/issues-raw/ssbarbee/iap-apple](https://img.shields.io/github/issues-raw/ssbarbee/iap-apple)
9
9
  ![https://img.shields.io/npm/dw/iap-apple](https://img.shields.io/npm/dw/iap-apple)
10
10
 
11
- ๐Ÿ“ฆ๐Ÿš€ Integration of Apples ๏ฃฟ **validation service** for App Store Receipts, written in Typescript, available for NodeJS environments.
11
+ Integration of Apple's **validation service** for App Store Receipts, written in TypeScript, available for Node.js environments.
12
12
 
13
- A NodeJS module for in-app purchase (in-app billing) and subscription for Apple.
13
+ A Node.js module for in-app purchase (in-app billing) and subscription validation for Apple.
14
14
 
15
- ## Overview ๐Ÿง
15
+ ## Requirements
16
16
 
17
- Create a Typescript package for validation of [App Store Receipts](https://developer.apple.com/documentation/appstorereceipts).
18
- This package is meant to be used server side to validate receipts from the App Store by talking to Apples servers.
17
+ - **Node.js 22+** (uses native `fetch`, zero runtime dependencies)
19
18
 
20
- ## Installation ๐Ÿ“ฆ
19
+ ## Overview
20
+
21
+ Server-side validation of [App Store Receipts](https://developer.apple.com/documentation/appstorereceipts) by communicating with Apple's verifyReceipt endpoints.
22
+
23
+ ## Installation
24
+
25
+ ### pnpm
26
+
27
+ ```bash
28
+ pnpm add iap-apple
29
+ ```
21
30
 
22
31
  ### npm
23
32
 
24
- ```npm install iap-apple```
33
+ ```bash
34
+ npm install iap-apple
35
+ ```
25
36
 
26
37
  ### yarn
27
38
 
28
- ```yarn add iap-apple```
39
+ ```bash
40
+ yarn add iap-apple
41
+ ```
29
42
 
30
- ## API documentation ๐Ÿ“š
43
+ ## API Documentation
31
44
 
32
- ### verify ๐Ÿงช
45
+ ### verify
33
46
 
34
- API used to verify receipt data received during an App Store purchase.
35
- Requires **appSharedSecret** to be passed as part of the configuration.
36
- See example for more details.
47
+ Validates a receipt against Apple's verifyReceipt endpoint. Attempts production first, falls back to sandbox if needed.
37
48
 
38
49
  ```typescript
39
-
40
50
  import { verify, IAPAppleError, IVerifyReceiptResponseBody } from 'iap-apple';
41
51
 
42
52
  async function verifyAppleReceipt(receipt: string) {
43
- try {
44
- const verifyReceiptResponse = await verify(receipt, {
45
- /*
46
- Your app's shared secret, which is a hexadecimal string. For more information about the shared secret.
47
- https://help.apple.com/app-store-connect/#/devf341c0f01
48
- */
49
- appSharedSecret,
50
- /*
51
- To exclude old transaction, set this to true.
52
- Default is false.
53
- */
54
- excludeOldTransactions: false,
55
- /*
56
- Force validation against Apple Sandbox only.
57
- In effect this means that the validation against Apple Production endpoint won't be used.
58
- Default is false.
59
- */
60
- test: false,
61
- /*
62
- Optional can be omitted, pass logger object if you want to debug.
63
- Default is null object.
64
- */
65
- logger: console,
66
- });
67
- console.log('verifyReceiptResponse', verifyReceiptResponse);
68
- } catch(error) {
69
- const iapAppleError = error as IAPAppleError;
70
- const rejectionMessage: string = error.rejectionMessage;
71
- const errorData: IVerifyReceiptResponseBody | null = error.data;
72
- console.error('Error happened', rejectionMessage);
73
- console.error('Details', errorData);
74
- }
53
+ try {
54
+ const verifyReceiptResponse = await verify(receipt, {
55
+ // Required: Your app's shared secret (hexadecimal string)
56
+ // https://help.apple.com/app-store-connect/#/devf341c0f01
57
+ appSharedSecret: 'your-shared-secret',
58
+
59
+ // Optional: Exclude old transactions (default: false)
60
+ appleExcludeOldTransactions: false,
61
+
62
+ // Optional: Force sandbox-only validation (default: false)
63
+ test: false,
64
+
65
+ // Optional: Logger for debugging (default: null)
66
+ logger: console,
67
+ });
68
+ console.log('verifyReceiptResponse', verifyReceiptResponse);
69
+ } catch (error) {
70
+ const iapAppleError = error as IAPAppleError;
71
+ console.error('Error:', iapAppleError.rejectionMessage);
72
+ console.error('Details:', iapAppleError.data);
73
+ }
75
74
  }
76
75
  ```
77
76
 
78
- ### isVerifiedReceipt ๐Ÿงช
77
+ ### isVerifiedReceipt
79
78
 
80
- API used to verify if response returned by `verify` is verified.
81
- Requires the output of `verify` to be passed.
82
- See example for more details.
79
+ Checks if the response from `verify` indicates a successful validation.
83
80
 
84
81
  ```typescript
85
-
86
82
  import { verify, isVerifiedReceipt, IIAPAppleConfig } from 'iap-apple';
87
83
 
88
- async function isVerifiedAppleReceipt(receipt: string, config: IIAPAppleConfig) {
89
- try {
90
- const verifyReceiptResponse = await verify(receipt, config);
91
- const isVerifiedReceipt = isVerifiedReceipt(verifyReceiptResponse);
92
- } catch(error) {
93
- const iapAppleError = error as IAPAppleError;
94
- const rejectionMessage: string = error.rejectionMessage;
95
- const errorData: IVerifyReceiptResponseBody | null = error.data;
96
- console.error('Error happened', rejectionMessage);
97
- console.error('Details', errorData);
84
+ async function checkReceipt(receipt: string, config: IIAPAppleConfig) {
85
+ try {
86
+ const response = await verify(receipt, config);
87
+ if (isVerifiedReceipt(response)) {
88
+ console.log('Receipt is valid');
98
89
  }
90
+ } catch (error) {
91
+ console.error('Validation failed:', (error as IAPAppleError).rejectionMessage);
92
+ }
99
93
  }
100
94
  ```
101
95
 
102
- ### getPurchasedItems ๐Ÿงช
96
+ ### getPurchasedItems
103
97
 
104
- API used to get an array of PurchasedItem objects from the Apple App Store response,
105
- sort by their purchase date descending.
106
- Usually what we are interested in is the first item of the purchase.
107
- Requires the output of `verify` to be passed.
108
- See example for more details.
98
+ Extracts purchased items from the validated receipt, sorted by purchase date (newest first), deduplicated by `original_transaction_id`.
109
99
 
110
100
  ```typescript
111
-
112
101
  import { verify, getPurchasedItems, IIAPAppleConfig } from 'iap-apple';
113
102
 
114
- async function isVerifiedAppleReceipt(receipt: string, config: IIAPAppleConfig) {
115
- try {
116
- const verifyReceiptResponse = await verify(receipt, config);
117
- const purchasedItems = getPurchasedItems(verifyReceiptResponse);
118
- const latestPurchase = purchasedItems[0];
119
- } catch(error) {
120
- const iapAppleError = error as IAPAppleError;
121
- const rejectionMessage: string = error.rejectionMessage;
122
- const errorData: IVerifyReceiptResponseBody | null = error.data;
123
- console.error('Error happened', rejectionMessage);
124
- console.error('Details', errorData);
125
- }
103
+ async function getLatestPurchase(receipt: string, config: IIAPAppleConfig) {
104
+ try {
105
+ const response = await verify(receipt, config);
106
+ const purchasedItems = getPurchasedItems(response);
107
+ const latestPurchase = purchasedItems[0];
108
+ console.log('Latest purchase:', latestPurchase);
109
+ } catch (error) {
110
+ console.error('Error:', (error as IAPAppleError).rejectionMessage);
111
+ }
126
112
  }
127
113
  ```
128
114
 
129
- ### isPurchasedItemCanceled ๐Ÿงช
115
+ ### isPurchasedItemCanceled
130
116
 
131
- API used to check if a purchased item is canceled.
132
- Requires the output of `getPurchasedItems` to be passed.
133
- See example for more details.
117
+ Checks if a purchased item has been canceled.
134
118
 
135
119
  ```typescript
136
-
137
120
  import { verify, getPurchasedItems, isPurchasedItemCanceled, IIAPAppleConfig } from 'iap-apple';
138
121
 
139
- async function isVerifiedAppleReceipt(receipt: string, config: IIAPAppleConfig) {
140
- try {
141
- const verifyReceiptResponse = await verify(receipt, config);
142
- const purchasedItems = getPurchasedItems(verifyReceiptResponse);
143
- const latestPurchase = purchasedItems[0];
144
- const isCanceled = isPurchasedItemCanceled(latestPurchase);
145
- } catch(error) {
146
- const iapAppleError = error as IAPAppleError;
147
- const rejectionMessage: string = error.rejectionMessage;
148
- const errorData: IVerifyReceiptResponseBody | null = error.data;
149
- console.error('Error happened', rejectionMessage);
150
- console.error('Details', errorData);
122
+ async function checkCancellation(receipt: string, config: IIAPAppleConfig) {
123
+ try {
124
+ const response = await verify(receipt, config);
125
+ const purchasedItems = getPurchasedItems(response);
126
+ const latestPurchase = purchasedItems[0];
127
+ if (isPurchasedItemCanceled(latestPurchase)) {
128
+ console.log('Purchase was canceled');
151
129
  }
130
+ } catch (error) {
131
+ console.error('Error:', (error as IAPAppleError).rejectionMessage);
132
+ }
152
133
  }
153
134
  ```
154
135
 
136
+ ### isPurchasedItemExpired
155
137
 
156
- ### isPurchasedItemExpired ๐Ÿงช
157
-
158
- API used to check if a purchased item is expired.
159
- Requires the output of `getPurchasedItems` to be passed.
160
- See example for more details.
138
+ Checks if a purchased item has expired (canceled or past expiration date).
161
139
 
162
140
  ```typescript
163
-
164
141
  import { verify, getPurchasedItems, isPurchasedItemExpired, IIAPAppleConfig } from 'iap-apple';
165
142
 
166
- async function isVerifiedAppleReceipt(receipt: string, config: IIAPAppleConfig) {
167
- try {
168
- const verifyReceiptResponse = await verify(receipt, config);
169
- const purchasedItems = getPurchasedItems(verifyReceiptResponse);
170
- const latestPurchase = purchasedItems[0];
171
- const isExpired = isPurchasedItemExpired(latestPurchase);
172
- } catch(error) {
173
- const iapAppleError = error as IAPAppleError;
174
- const rejectionMessage: string = error.rejectionMessage;
175
- const errorData: IVerifyReceiptResponseBody | null = error.data;
176
- console.error('Error happened', rejectionMessage);
177
- console.error('Details', errorData);
143
+ async function checkExpiration(receipt: string, config: IIAPAppleConfig) {
144
+ try {
145
+ const response = await verify(receipt, config);
146
+ const purchasedItems = getPurchasedItems(response);
147
+ const latestPurchase = purchasedItems[0];
148
+ if (isPurchasedItemExpired(latestPurchase)) {
149
+ console.log('Purchase has expired');
178
150
  }
151
+ } catch (error) {
152
+ console.error('Error:', (error as IAPAppleError).rejectionMessage);
153
+ }
179
154
  }
180
- ```
155
+ ```
156
+
157
+ ## Types
158
+
159
+ ### PurchasedItem
160
+
161
+ ```typescript
162
+ interface PurchasedItem {
163
+ bundleId: string;
164
+ appItemId: string;
165
+ originalTransactionId?: string;
166
+ transactionId: string;
167
+ productId: string;
168
+ originalPurchaseDateMS?: number;
169
+ expirationDateMS?: number;
170
+ purchaseDateMS: number;
171
+ isTrialPeriod: boolean;
172
+ cancellationDateMS?: number;
173
+ quantity: number;
174
+ }
175
+ ```
176
+
177
+ ### IIAPAppleConfig
178
+
179
+ ```typescript
180
+ interface IIAPAppleConfig {
181
+ appSharedSecret: string;
182
+ appleExcludeOldTransactions?: boolean;
183
+ test?: boolean;
184
+ logger?: ILogger | null;
185
+ }
186
+ ```
187
+
188
+ ## License
189
+
190
+ ISC
@@ -0,0 +1,146 @@
1
+ declare enum RECEIPT_STATUS_ENUM {
2
+ SUCCESS = 0,
3
+ VALID_NO_PURCHASE = 2,
4
+ CANNOT_READ_JSON = 21000,
5
+ DATA_MALFORMED = 21002,
6
+ RECEIPT_NOT_AUTHENTICATED = 21003,
7
+ SHARED_SECRET_DOESNT_MATCH = 21004,
8
+ SERVER_NOT_AVAILABLE = 21005,
9
+ SUBSCRIPTION_EXPIRED = 21006,
10
+ TEST_ENV_RECEIPT_DETECTED = 21007,
11
+ PRODUCTION_ENV_RECEIPT_DETECTED = 21008,
12
+ INTERNAL_DATA_ACCESS_ERROR = 21009,
13
+ USER_ACCOUNT_DELETED = 21010
14
+ }
15
+
16
+ interface IPendingRenewalInfo {
17
+ auto_renew_product_id: string;
18
+ auto_renew_status: '0' | '1';
19
+ original_transaction_id: string;
20
+ product_id: string;
21
+ expiration_intent?: '1' | '2' | '3' | '4' | '5';
22
+ grace_period_expires_date_ms?: string;
23
+ is_in_billing_retry_period?: '0' | '1';
24
+ offer_code_ref_name?: string;
25
+ price_consent_status?: '0' | '1';
26
+ promotional_offer_id?: string;
27
+ }
28
+ interface IReceiptInAppItem {
29
+ quantity: string;
30
+ product_id: string;
31
+ transaction_id: string;
32
+ original_transaction_id: string;
33
+ purchase_date: string;
34
+ purchase_date_ms: string;
35
+ original_purchase_date: string;
36
+ original_purchase_date_ms: string;
37
+ expires_date?: string;
38
+ expires_date_ms?: string;
39
+ expiration_intent?: '1' | '2' | '3' | '4' | '5';
40
+ is_trial_period: string;
41
+ cancellation_date?: string;
42
+ cancellation_date_ms?: string;
43
+ cancellation_reason?: '0' | '1';
44
+ app_item_id: string;
45
+ web_order_line_item_id?: string;
46
+ is_in_intro_offer_period?: string;
47
+ promotional_offer_id?: string;
48
+ offer_code_ref_name?: string;
49
+ in_app_ownership_type?: 'FAMILY_SHARED' | 'PURCHASED';
50
+ }
51
+
52
+ interface ILogger {
53
+ log: (message: string) => void;
54
+ warn: (message: string) => void;
55
+ error: (message: string) => void;
56
+ }
57
+ interface IIAPAppleConfig {
58
+ appleExcludeOldTransactions?: boolean;
59
+ appSharedSecret: string;
60
+ test?: boolean | undefined;
61
+ logger?: ILogger | null;
62
+ }
63
+ interface PurchasedItem {
64
+ bundleId: string;
65
+ appItemId: string;
66
+ originalTransactionId?: string;
67
+ transactionId: string;
68
+ productId: string;
69
+ originalPurchaseDateMS?: number;
70
+ expirationDateMS?: number;
71
+ purchaseDateMS: number;
72
+ isTrialPeriod: boolean;
73
+ cancellationDateMS?: number;
74
+ quantity: number;
75
+ }
76
+ interface IAPAppleError {
77
+ rejectionMessage: string;
78
+ data?: IVerifyReceiptResponseBody | null;
79
+ }
80
+ interface IVerifyReceiptResponseBody {
81
+ status: RECEIPT_STATUS_ENUM;
82
+ environment: 'Sandbox' | 'Production';
83
+ receipt: IReceipt;
84
+ latest_receipt: string;
85
+ latest_receipt_info: IReceiptInAppItem[];
86
+ 'is-retryable'?: boolean;
87
+ pending_renewal_info?: IPendingRenewalInfo[];
88
+ }
89
+ interface IReceipt {
90
+ bundle_id: string;
91
+ application_version: string;
92
+ in_app: IReceiptInAppItem[];
93
+ latest_receipt_info: IReceiptInAppItem[];
94
+ original_application_version: string;
95
+ receipt_creation_date_ms: string;
96
+ expiration_date_ms: string;
97
+ original_purchase_date: string;
98
+ app_item_id: string;
99
+ version_external_identifier: string;
100
+ expires_date_ms?: string;
101
+ }
102
+
103
+ /**
104
+ * Validates an Apple App Store receipt against Apple's verifyReceipt endpoint.
105
+ * Attempts production endpoint first, falls back to sandbox if needed.
106
+ *
107
+ * @param receipt - Base64-encoded receipt data from the App Store
108
+ * @param config - Configuration including shared secret and optional settings
109
+ * @returns Validated receipt response from Apple
110
+ * @throws {IAPAppleError} When validation fails or receipt is invalid
111
+ */
112
+ declare function verify(receipt: string, config: IIAPAppleConfig): Promise<IVerifyReceiptResponseBody>;
113
+ /**
114
+ * Checks whether the receipt validation was successful.
115
+ *
116
+ * @param verifyReceiptResponse - Response from Apple's verifyReceipt endpoint
117
+ * @returns True if the receipt status indicates success
118
+ */
119
+ declare const isVerifiedReceipt: (verifyReceiptResponse: IVerifyReceiptResponseBody | null) => boolean;
120
+ /**
121
+ * Determines if a purchased item has expired (cancelled or past expiration date).
122
+ *
123
+ * @param purchasedItem - The purchased item to check
124
+ * @returns True if the item has been cancelled or its expiration date has passed
125
+ * @throws {Error} If purchasedItem is invalid or missing transactionId
126
+ */
127
+ declare const isPurchasedItemExpired: (purchasedItem: PurchasedItem | null) => boolean;
128
+ /**
129
+ * Checks if a purchased item has been cancelled.
130
+ *
131
+ * @param purchasedItem - The purchased item to check
132
+ * @returns True if the item has a cancellation date
133
+ * @throws {Error} If purchasedItem is invalid or missing transactionId
134
+ */
135
+ declare const isPurchasedItemCanceled: (purchasedItem: PurchasedItem) => boolean;
136
+ /**
137
+ * Extracts purchased items from a validated receipt response.
138
+ * Combines in_app and latest_receipt_info, deduplicates by original_transaction_id,
139
+ * and returns items sorted by purchase date (newest first).
140
+ *
141
+ * @param verifyReceiptResponse - Response from Apple's verifyReceipt endpoint
142
+ * @returns Array of purchased items, deduplicated and sorted by purchase date descending
143
+ */
144
+ declare const getPurchasedItems: (verifyReceiptResponse: IVerifyReceiptResponseBody | null) => PurchasedItem[];
145
+
146
+ export { type IAPAppleError, type IIAPAppleConfig, type ILogger, type IPendingRenewalInfo, type IReceiptInAppItem, type IVerifyReceiptResponseBody, type PurchasedItem, RECEIPT_STATUS_ENUM, getPurchasedItems, isPurchasedItemCanceled, isPurchasedItemExpired, isVerifiedReceipt, verify };
@@ -0,0 +1,146 @@
1
+ declare enum RECEIPT_STATUS_ENUM {
2
+ SUCCESS = 0,
3
+ VALID_NO_PURCHASE = 2,
4
+ CANNOT_READ_JSON = 21000,
5
+ DATA_MALFORMED = 21002,
6
+ RECEIPT_NOT_AUTHENTICATED = 21003,
7
+ SHARED_SECRET_DOESNT_MATCH = 21004,
8
+ SERVER_NOT_AVAILABLE = 21005,
9
+ SUBSCRIPTION_EXPIRED = 21006,
10
+ TEST_ENV_RECEIPT_DETECTED = 21007,
11
+ PRODUCTION_ENV_RECEIPT_DETECTED = 21008,
12
+ INTERNAL_DATA_ACCESS_ERROR = 21009,
13
+ USER_ACCOUNT_DELETED = 21010
14
+ }
15
+
16
+ interface IPendingRenewalInfo {
17
+ auto_renew_product_id: string;
18
+ auto_renew_status: '0' | '1';
19
+ original_transaction_id: string;
20
+ product_id: string;
21
+ expiration_intent?: '1' | '2' | '3' | '4' | '5';
22
+ grace_period_expires_date_ms?: string;
23
+ is_in_billing_retry_period?: '0' | '1';
24
+ offer_code_ref_name?: string;
25
+ price_consent_status?: '0' | '1';
26
+ promotional_offer_id?: string;
27
+ }
28
+ interface IReceiptInAppItem {
29
+ quantity: string;
30
+ product_id: string;
31
+ transaction_id: string;
32
+ original_transaction_id: string;
33
+ purchase_date: string;
34
+ purchase_date_ms: string;
35
+ original_purchase_date: string;
36
+ original_purchase_date_ms: string;
37
+ expires_date?: string;
38
+ expires_date_ms?: string;
39
+ expiration_intent?: '1' | '2' | '3' | '4' | '5';
40
+ is_trial_period: string;
41
+ cancellation_date?: string;
42
+ cancellation_date_ms?: string;
43
+ cancellation_reason?: '0' | '1';
44
+ app_item_id: string;
45
+ web_order_line_item_id?: string;
46
+ is_in_intro_offer_period?: string;
47
+ promotional_offer_id?: string;
48
+ offer_code_ref_name?: string;
49
+ in_app_ownership_type?: 'FAMILY_SHARED' | 'PURCHASED';
50
+ }
51
+
52
+ interface ILogger {
53
+ log: (message: string) => void;
54
+ warn: (message: string) => void;
55
+ error: (message: string) => void;
56
+ }
57
+ interface IIAPAppleConfig {
58
+ appleExcludeOldTransactions?: boolean;
59
+ appSharedSecret: string;
60
+ test?: boolean | undefined;
61
+ logger?: ILogger | null;
62
+ }
63
+ interface PurchasedItem {
64
+ bundleId: string;
65
+ appItemId: string;
66
+ originalTransactionId?: string;
67
+ transactionId: string;
68
+ productId: string;
69
+ originalPurchaseDateMS?: number;
70
+ expirationDateMS?: number;
71
+ purchaseDateMS: number;
72
+ isTrialPeriod: boolean;
73
+ cancellationDateMS?: number;
74
+ quantity: number;
75
+ }
76
+ interface IAPAppleError {
77
+ rejectionMessage: string;
78
+ data?: IVerifyReceiptResponseBody | null;
79
+ }
80
+ interface IVerifyReceiptResponseBody {
81
+ status: RECEIPT_STATUS_ENUM;
82
+ environment: 'Sandbox' | 'Production';
83
+ receipt: IReceipt;
84
+ latest_receipt: string;
85
+ latest_receipt_info: IReceiptInAppItem[];
86
+ 'is-retryable'?: boolean;
87
+ pending_renewal_info?: IPendingRenewalInfo[];
88
+ }
89
+ interface IReceipt {
90
+ bundle_id: string;
91
+ application_version: string;
92
+ in_app: IReceiptInAppItem[];
93
+ latest_receipt_info: IReceiptInAppItem[];
94
+ original_application_version: string;
95
+ receipt_creation_date_ms: string;
96
+ expiration_date_ms: string;
97
+ original_purchase_date: string;
98
+ app_item_id: string;
99
+ version_external_identifier: string;
100
+ expires_date_ms?: string;
101
+ }
102
+
103
+ /**
104
+ * Validates an Apple App Store receipt against Apple's verifyReceipt endpoint.
105
+ * Attempts production endpoint first, falls back to sandbox if needed.
106
+ *
107
+ * @param receipt - Base64-encoded receipt data from the App Store
108
+ * @param config - Configuration including shared secret and optional settings
109
+ * @returns Validated receipt response from Apple
110
+ * @throws {IAPAppleError} When validation fails or receipt is invalid
111
+ */
112
+ declare function verify(receipt: string, config: IIAPAppleConfig): Promise<IVerifyReceiptResponseBody>;
113
+ /**
114
+ * Checks whether the receipt validation was successful.
115
+ *
116
+ * @param verifyReceiptResponse - Response from Apple's verifyReceipt endpoint
117
+ * @returns True if the receipt status indicates success
118
+ */
119
+ declare const isVerifiedReceipt: (verifyReceiptResponse: IVerifyReceiptResponseBody | null) => boolean;
120
+ /**
121
+ * Determines if a purchased item has expired (cancelled or past expiration date).
122
+ *
123
+ * @param purchasedItem - The purchased item to check
124
+ * @returns True if the item has been cancelled or its expiration date has passed
125
+ * @throws {Error} If purchasedItem is invalid or missing transactionId
126
+ */
127
+ declare const isPurchasedItemExpired: (purchasedItem: PurchasedItem | null) => boolean;
128
+ /**
129
+ * Checks if a purchased item has been cancelled.
130
+ *
131
+ * @param purchasedItem - The purchased item to check
132
+ * @returns True if the item has a cancellation date
133
+ * @throws {Error} If purchasedItem is invalid or missing transactionId
134
+ */
135
+ declare const isPurchasedItemCanceled: (purchasedItem: PurchasedItem) => boolean;
136
+ /**
137
+ * Extracts purchased items from a validated receipt response.
138
+ * Combines in_app and latest_receipt_info, deduplicates by original_transaction_id,
139
+ * and returns items sorted by purchase date (newest first).
140
+ *
141
+ * @param verifyReceiptResponse - Response from Apple's verifyReceipt endpoint
142
+ * @returns Array of purchased items, deduplicated and sorted by purchase date descending
143
+ */
144
+ declare const getPurchasedItems: (verifyReceiptResponse: IVerifyReceiptResponseBody | null) => PurchasedItem[];
145
+
146
+ export { type IAPAppleError, type IIAPAppleConfig, type ILogger, type IPendingRenewalInfo, type IReceiptInAppItem, type IVerifyReceiptResponseBody, type PurchasedItem, RECEIPT_STATUS_ENUM, getPurchasedItems, isPurchasedItemCanceled, isPurchasedItemExpired, isVerifiedReceipt, verify };