@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 +25 -73
- package/dist/Purchases.es.d.ts +155 -41
- package/dist/Purchases.es.js +2395 -1546
- package/dist/Purchases.umd.js +14 -14
- package/dist/style.css +1 -1
- package/package.json +4 -1
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
|
|
144
|
-
|
|
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.
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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
|
-
|
|
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
|
package/dist/Purchases.es.d.ts
CHANGED
|
@@ -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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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
|
-
|
|
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
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
|
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
|
-
|
|
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,
|
|
84
|
-
{ customerEmail, htmlTarget, }?: {
|
|
185
|
+
purchasePackage(appUserId: string, rcPackage: Package, { customerEmail, htmlTarget, }?: {
|
|
85
186
|
customerEmail?: string;
|
|
86
187
|
htmlTarget?: HTMLElement;
|
|
87
|
-
}): Promise<
|
|
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 { }
|