@revenuecat/purchases-js 0.0.11 → 0.0.12

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
@@ -55,9 +55,10 @@ By downloading the current Offerings you can easily build a Paywall page using t
55
55
  associated `rcBillingProduct` and price.
56
56
 
57
57
  ```typescript
58
+ const appUserId = "the unique id of the user in your systems";
58
59
  const purchases = new Purchases("your RC_PUBLISHABLE_API_KEY");
59
60
 
60
- purchases.getOfferings().then((offerings) => {
61
+ purchases.getOfferings(appUserId).then((offerings) => {
61
62
  // Get current offering
62
63
  console.log(offerings.current);
63
64
  // Or a dictionary of all offerings
@@ -127,6 +128,17 @@ const App = () => (
127
128
  );
128
129
  ```
129
130
 
131
+ If you need further information about the user's entitlements, you can use the `getCustomerInfo` method:
132
+
133
+ ```ts
134
+ const customerInfo = await purchases.getCustomerInfo(appUserId);
135
+ ```
136
+
137
+ ### Important note
138
+
139
+ Please be aware that the information about the entitlements can be manipulated by malicious actors, so make sure
140
+ you protect your apps against attacks that modify the entitlements by validating access through your servers.
141
+
130
142
  ## Subscribe a User to an entitlement and allow payment with Stripe
131
143
 
132
144
  RCBilling allows you to use your payment gateway for payments.
@@ -136,88 +148,28 @@ In this example we will show Stripe, more will be supported soon!
136
148
 
137
149
  You built your paywall, and your user just clicked on the offer they want to subscribe to.
138
150
 
139
- ### 1. Call the .subscribe method to initialise the process
140
-
141
151
  ```tsx
142
152
  const purchases = new Purchases("your RC_PUBLISHABLE_API_KEY");
143
- // You can retrieve this from the offerings you downloaded, as example:
144
- // offerings.current.packages[0].rcBillingProduct.identifier
145
- const rcBillingProductIndentifier =
146
- "the Product Identifier the user wants to buy";
153
+ // You can retrieve the package from the offerings through `getOfferings`:
154
+ const rcBillingPackage = offerings.current.packages[0];
147
155
  const appUserId =
148
156
  "the unique id of the user that wants to subscribe to your product";
157
+ const entitlementIdToCheck =
158
+ "the entitlementId you set up in RC for your product"; // TODO: remove once this is not needed
149
159
 
150
- purchase.subscribe(appUserId, rcBillingProductIndentifier).then((response) => {
151
- if (response.nextAction === "collect_payment_info") {
152
- // Use the clientSecret to show the StripeElements payment components
153
- showStripeElements({
154
- setupIntentClientSecret: response.data.clientSecret,
155
- });
160
+ purchase.purchasePackage(appUserId, rcBillingPackage).then((response) => {
161
+ const isEntitled =
162
+ entitlementIdToCheck in response.customerInfo.entitlements.active;
163
+ if (isEntitled == true) {
164
+ console.log(`User ${appUserID} is entitled to ${entitlementId}`);
156
165
  } else {
157
- // No need to collect payment info, just wait for the entitlement to be granted
166
+ console.log(
167
+ `User ${appUserID} is not entitled to ${entitlementId}, even after ${numberOfAttempts} attempts`,
168
+ );
158
169
  }
159
170
  });
160
171
  ```
161
172
 
162
- ### 2. [If nextAction === 'collect_payment_info'] Show the Stripe Elements to collect payment
163
-
164
- ```tsx
165
- // Set up stripe as shown in their docs
166
- const stripePromise = loadStripe(
167
- import.meta.env.VITE_RC_STRIPE_PK_KEY as string,
168
- { stripeAccount: import.meta.env.VITE_RC_STRIPE_ACCOUNT_ID as string },
169
- );
170
-
171
- // Use the clientSecret obtained in the step 1. Call the .subscribe method to initialise the process
172
- const PaymentForm = ({ clientSecret }) => {
173
- const handleSubmit = async (e: SyntheticEvent) => {
174
- e.preventDefault();
175
- stripe
176
- .confirmSetup({
177
- elements,
178
- clientSecret,
179
- confirmParams: {
180
- return_url: `${window.location.origin}/success`,
181
- },
182
- redirect: "if_required",
183
- })
184
- .then((response) => {
185
- // All is done you can now wait for the entitlement to be granted.
186
- });
187
- };
188
-
189
- return (
190
- <form id="payment-form" onSubmit={handleSubmit}>
191
- <PaymentElement id="payment-element" options={paymentElementOptions} />
192
- </form>
193
- );
194
- };
195
- ```
196
-
197
- ### 3. Wait for the entitlement to be granted
198
-
199
- You can use the `.waitForEntitlement` method.
200
-
201
- ```tsx
202
- const appUserId = "the unique id of the user in your systems";
203
- const entitlementId = "the entitlementId you set up in RC";
204
-
205
- const purchases = new Purchases("your RC_PUBLISHABLE_API_KEY");
206
- const numberOfAttempts = 10;
207
-
208
- purchases
209
- .waitForEntitlement(appUserId, entitlementId, numberOfAttempts)
210
- .then((isEntitled) => {
211
- if (isEntitled == true) {
212
- console.log(`User ${appUserID} is entitled to ${entitlementId}`);
213
- } else {
214
- console.log(
215
- `User ${appUserID} is not entitled to ${entitlementId}, even after ${numberOfAttempts} attempts`,
216
- );
217
- }
218
- });
219
- ```
220
-
221
173
  # Development
222
174
 
223
175
  ## Install the library in a local project
@@ -1,93 +1,207 @@
1
+ declare enum BackendErrorCode {
2
+ BackendInvalidPlatform = 7000,
3
+ BackendStoreProblem = 7101,
4
+ BackendCannotTransferPurchase = 7102,
5
+ BackendInvalidReceiptToken = 7103,
6
+ BackendInvalidAppStoreSharedSecret = 7104,
7
+ BackendInvalidPaymentModeOrIntroPriceNotProvided = 7105,
8
+ BackendProductIdForGoogleReceiptNotProvided = 7106,
9
+ BackendInvalidPlayStoreCredentials = 7107,
10
+ BackendInternalServerError = 7110,
11
+ BackendEmptyAppUserId = 7220,
12
+ BackendInvalidAuthToken = 7224,
13
+ BackendInvalidAPIKey = 7225,
14
+ BackendBadRequest = 7226,
15
+ BackendPlayStoreQuotaExceeded = 7229,
16
+ BackendPlayStoreInvalidPackageName = 7230,
17
+ BackendPlayStoreGenericError = 7231,
18
+ BackendUserIneligibleForPromoOffer = 7232,
19
+ BackendInvalidAppleSubscriptionKey = 7234,
20
+ BackendInvalidSubscriberAttributes = 7263,
21
+ BackendInvalidSubscriberAttributesBody = 7264,
22
+ BackendProductIDsMalformed = 7662
23
+ }
24
+
1
25
  export declare type CustomerInfo = CustomerInfo_2;
2
26
 
3
27
  declare interface CustomerInfo_2 {
4
- entitlements: EntitlementInfos;
5
- managementURL: string | null;
6
- requestDate: Date;
7
- firstSeenDate: Date;
8
- originalPurchaseDate: Date | null;
28
+ readonly entitlements: EntitlementInfos;
29
+ readonly allExpirationDatesByProduct: {
30
+ [productIdentifier: string]: Date | null;
31
+ };
32
+ readonly allPurchaseDatesByProduct: {
33
+ [productIdentifier: string]: Date;
34
+ };
35
+ readonly activeSubscriptions: Set<string>;
36
+ readonly managementURL: string | null;
37
+ readonly requestDate: Date;
38
+ readonly firstSeenDate: Date;
39
+ readonly originalPurchaseDate: Date | null;
40
+ readonly originalAppUserId: string;
9
41
  }
10
42
 
11
43
  export declare interface EntitlementInfo {
12
- identifier: string;
13
- isActive: boolean;
14
- originalPurchaseDate: Date;
15
- expirationDate: Date;
16
- productIdentifier: string;
44
+ readonly identifier: string;
45
+ readonly isActive: boolean;
46
+ readonly willRenew: boolean;
47
+ readonly store: Store;
48
+ readonly originalPurchaseDate: Date;
49
+ readonly expirationDate: Date | null;
50
+ readonly productIdentifier: string;
51
+ readonly unsubscribeDetectedAt: Date | null;
52
+ readonly billingIssueDetectedAt: Date | null;
53
+ readonly isSandbox: boolean;
54
+ readonly periodType: PeriodType;
17
55
  }
18
56
 
19
57
  export declare interface EntitlementInfos {
20
- all: {
58
+ readonly all: {
21
59
  [entitlementId: string]: EntitlementInfo;
22
60
  };
23
- active: {
61
+ readonly active: {
24
62
  [entitlementId: string]: EntitlementInfo;
25
63
  };
26
64
  }
27
65
 
66
+ export declare enum ErrorCode {
67
+ UnknownError = 0,
68
+ UserCancelledError = 1,
69
+ StoreProblemError = 2,
70
+ PurchaseNotAllowedError = 3,
71
+ PurchaseInvalidError = 4,
72
+ ProductNotAvailableForPurchaseError = 5,
73
+ ProductAlreadyPurchasedError = 6,
74
+ ReceiptAlreadyInUseError = 7,
75
+ InvalidReceiptError = 8,
76
+ MissingReceiptFileError = 9,
77
+ NetworkError = 10,
78
+ InvalidCredentialsError = 11,
79
+ UnexpectedBackendResponseError = 12,
80
+ InvalidAppUserIdError = 14,
81
+ OperationAlreadyInProgressError = 15,
82
+ UnknownBackendError = 16,
83
+ InvalidAppleSubscriptionKeyError = 17,
84
+ IneligibleError = 18,
85
+ InsufficientPermissionsError = 19,
86
+ PaymentPendingError = 20,
87
+ InvalidSubscriberAttributesError = 21,
88
+ LogOutWithAnonymousUserError = 22,
89
+ ConfigurationError = 23,
90
+ UnsupportedError = 24,
91
+ EmptySubscriberAttributesError = 25,
92
+ CustomerInfoError = 28,
93
+ SignatureVerificationError = 36
94
+ }
95
+
28
96
  export declare type Offering = Offering_2;
29
97
 
30
98
  declare interface Offering_2 {
31
- id: string;
32
- identifier: string;
33
- displayName: string;
34
- packages: Package_2[];
99
+ readonly id: string;
100
+ readonly identifier: string;
101
+ readonly displayName: string;
102
+ readonly metadata: {
103
+ [key: string]: unknown;
104
+ } | null;
105
+ readonly packages: {
106
+ [key: string]: Package_2;
107
+ };
108
+ readonly lifetimePackage: Package_2 | null;
109
+ readonly annualPackage: Package_2 | null;
110
+ readonly sixMonthPackage: Package_2 | null;
111
+ readonly threeMonthPackage: Package_2 | null;
112
+ readonly twoMonthPackage: Package_2 | null;
113
+ readonly monthlyPackage: Package_2 | null;
114
+ readonly weeklyPackage: Package_2 | null;
35
115
  }
36
116
 
37
117
  export declare type Offerings = Offerings_2;
38
118
 
39
119
  declare interface Offerings_2 {
40
- all: {
120
+ readonly all: {
41
121
  [offeringId: string]: Offering_2;
42
122
  };
43
- current: Offering_2 | null;
123
+ readonly current: Offering_2 | null;
44
124
  }
45
125
 
46
126
  export declare type Package = Package_2;
47
127
 
48
128
  declare interface Package_2 {
49
- id: string;
50
- identifier: string;
51
- rcBillingProduct: Product;
129
+ readonly id: string;
130
+ readonly identifier: string;
131
+ readonly rcBillingProduct: Product;
132
+ readonly packageType: PackageType;
52
133
  }
53
134
 
54
- declare type PaymentProvider = "stripe";
55
-
56
- declare type PaymentProviderConfigModels = {
57
- stripe?: {
58
- publishableKey: string;
59
- accountId: string;
60
- };
61
- };
135
+ declare enum PackageType {
136
+ Unknown = "unknown",
137
+ Custom = "custom",
138
+ Lifetime = "$rc_lifetime",
139
+ Annual = "$rc_annual",
140
+ SixMonth = "$rc_six_month",
141
+ ThreeMonth = "$rc_three_month",
142
+ TwoMonth = "$rc_two_month",
143
+ Monthly = "$rc_monthly",
144
+ Weekly = "$rc_weekly"
145
+ }
62
146
 
63
- declare type PaymentProviderSettings = Record<PaymentProvider, PaymentProviderConfigModels[PaymentProvider]>;
147
+ export declare type PeriodType = "normal" | "intro" | "trial";
64
148
 
65
149
  declare interface Price {
66
- amount: number;
67
- currency: string;
150
+ readonly amount: number;
151
+ readonly currency: string;
68
152
  }
69
153
 
70
154
  declare interface Product {
71
- id: string;
72
- displayName: string;
73
- identifier: string;
74
- currentPrice: Price | null;
75
- normalPeriodDuration: string | null;
155
+ readonly id: string;
156
+ readonly displayName: string;
157
+ readonly identifier: string;
158
+ readonly currentPrice: Price | null;
159
+ readonly normalPeriodDuration: string | null;
160
+ readonly presentedOfferingIdentifier: string;
161
+ }
162
+
163
+ declare class PurchaseFlowError extends Error {
164
+ readonly errorCode: PurchaseFlowErrorCode;
165
+ readonly underlyingErrorMessage?: string | null | undefined;
166
+ constructor(errorCode: PurchaseFlowErrorCode, message?: string, underlyingErrorMessage?: string | null | undefined);
167
+ }
168
+
169
+ declare enum PurchaseFlowErrorCode {
170
+ ErrorSettingUpPurchase = 0,
171
+ ErrorChargingPayment = 1,
172
+ UnknownError = 2,
173
+ NetworkError = 3,
174
+ StripeError = 4,
175
+ MissingEmailError = 5
76
176
  }
77
177
 
78
178
  export declare class Purchases {
79
- constructor(apiKey: string, paymentProviderSettings: PaymentProviderSettings);
179
+ private readonly backend;
180
+ private readonly purchaseOperationHelper;
181
+ constructor(apiKey: string);
80
182
  private toOfferings;
81
183
  getOfferings(appUserId: string): Promise<Offerings>;
82
184
  isEntitledTo(appUserId: string, entitlementIdentifier: string): Promise<boolean>;
83
- purchasePackage(appUserId: string, rcPackage: Package, entitlementId: string, // TODO: Remove this parameter once we don't have to poll for entitlements
84
- { customerEmail, htmlTarget, }?: {
185
+ purchasePackage(appUserId: string, rcPackage: Package, { customerEmail, htmlTarget, }?: {
85
186
  customerEmail?: string;
86
187
  htmlTarget?: HTMLElement;
87
- }): Promise<boolean>;
188
+ }): Promise<{
189
+ customerInfo: CustomerInfo;
190
+ }>;
88
191
  getCustomerInfo(appUserId: string): Promise<CustomerInfo>;
89
192
  private logMissingProductIds;
90
193
  isSandbox(): boolean;
91
194
  }
92
195
 
196
+ export declare class PurchasesError extends Error {
197
+ readonly errorCode: ErrorCode;
198
+ readonly underlyingErrorMessage?: string | null | undefined;
199
+ static getForBackendError(backendErrorCode: BackendErrorCode, backendErrorMessage: string | null): PurchasesError;
200
+ static getForPurchasesFlowError(purchasesFlowError: PurchaseFlowError): PurchasesError;
201
+ constructor(errorCode: ErrorCode, message?: string, underlyingErrorMessage?: string | null | undefined);
202
+ toString: () => string;
203
+ }
204
+
205
+ export declare type Store = "app_store" | "mac_app_store" | "play_store" | "amazon" | "stripe" | "rc_billing" | "promotional" | "unknown";
206
+
93
207
  export { }