palbase 0.0.0-stage → 0.1.0
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/LICENSE +27 -0
- package/README.md +2 -2
- package/dist/ai/index.js +17 -0
- package/dist/backend/engine.js +2 -0
- package/dist/backend/env.js +1 -0
- package/dist/backend/index.js +12 -0
- package/dist/backend/stack.js +1 -0
- package/dist/backend/test.js +2 -0
- package/dist/chunks/3OGEBGYZ.js +20 -0
- package/dist/chunks/3VASGTIN.js +2 -0
- package/dist/chunks/3XT4L2XV.js +2 -0
- package/dist/chunks/45J7YXRB.js +2 -0
- package/dist/chunks/6FWCNTAM.js +2 -0
- package/dist/chunks/DAOLIUNZ.js +2 -0
- package/dist/chunks/E5Q4VTW4.js +2 -0
- package/dist/chunks/HKJU2FKE.js +2 -0
- package/dist/chunks/IKVOXHEE.js +2 -0
- package/dist/chunks/JAWWIVZH.js +2 -0
- package/dist/chunks/LYEFPLJZ.js +4 -0
- package/dist/chunks/QXUMLO7O.js +13 -0
- package/dist/chunks/UAY56IQR.js +6 -0
- package/dist/cli.js +815 -0
- package/dist/refuse/ai.js +2 -0
- package/dist/refuse/backend.js +2 -0
- package/dist/refuse/server.js +2 -0
- package/dist/server/index.js +2 -0
- package/dist/server/testing.js +2 -0
- package/dist/web/index.js +2 -0
- package/dist/web/palbe.js +2 -0
- package/dist/web/vite.js +3 -0
- package/package.json +107 -4
- package/types/ai/src/ai.d.ts +178 -0
- package/types/ai/src/index.d.ts +5 -0
- package/types/ai/src/partial.d.ts +1 -0
- package/types/ai/src/schema.d.ts +47 -0
- package/types/backend/src/bootstrap.d.ts +72 -0
- package/types/backend/src/cache.d.ts +32 -0
- package/types/backend/src/container.d.ts +49 -0
- package/types/backend/src/database.d.ts +148 -0
- package/types/backend/src/db-env.d.ts +4 -0
- package/types/backend/src/decorators.d.ts +293 -0
- package/types/backend/src/engine-db.d.ts +24 -0
- package/types/backend/src/engine-exports.d.ts +3 -0
- package/types/backend/src/engine.d.ts +124 -0
- package/types/backend/src/env.d.ts +27 -0
- package/types/backend/src/errors.d.ts +70 -0
- package/types/backend/src/i18n.d.ts +21 -0
- package/types/backend/src/index.d.ts +23 -0
- package/types/backend/src/openapi.d.ts +73 -0
- package/types/backend/src/platform-calls.d.ts +41 -0
- package/types/backend/src/requests.d.ts +81 -0
- package/types/backend/src/rooms.d.ts +168 -0
- package/types/backend/src/router.d.ts +22 -0
- package/types/backend/src/runtime.d.ts +56 -0
- package/types/backend/src/services.d.ts +262 -0
- package/types/backend/src/stack.d.ts +20 -0
- package/types/backend/src/strings-files.d.ts +3 -0
- package/types/backend/src/testing/index.d.ts +3 -0
- package/types/backend/src/testing/unit.d.ts +66 -0
- package/types/backend/src/upload.d.ts +125 -0
- package/types/backend/src/webhooks.d.ts +113 -0
- package/types/internal/src/event.d.ts +9 -0
- package/types/internal/src/modules/ai.d.ts +678 -0
- package/types/internal/src/modules/analytics.d.ts +1414 -0
- package/types/internal/src/modules/auth.d.ts +5660 -0
- package/types/internal/src/modules/cache.d.ts +158 -0
- package/types/internal/src/modules/events.d.ts +19 -0
- package/types/internal/src/modules/flags.d.ts +957 -0
- package/types/internal/src/modules/index.d.ts +13 -0
- package/types/internal/src/modules/machines.d.ts +1584 -0
- package/types/internal/src/modules/notify.d.ts +1450 -0
- package/types/internal/src/modules/purchases.d.ts +2944 -0
- package/types/internal/src/modules/realtime.d.ts +326 -0
- package/types/internal/src/modules/secrets.d.ts +275 -0
- package/types/internal/src/modules/storage.d.ts +691 -0
- package/types/internal/src/modules/stores.d.ts +1516 -0
- package/types/internal/src/retry.d.ts +14 -0
- package/types/internal/src/transport.d.ts +106 -0
- package/types/server/src/auth/dpop.d.ts +47 -0
- package/types/server/src/auth/jwt.d.ts +115 -0
- package/types/server/src/index.d.ts +9 -0
- package/types/server/src/pages.d.ts +4 -0
- package/types/server/src/purchases.d.ts +51 -0
- package/types/server/src/secrets-env.d.ts +22 -0
- package/types/server/src/server.d.ts +40 -0
- package/types/server/src/testing.d.ts +91 -0
- package/types/server/src/webhooks.d.ts +72 -0
- package/types/web/src/analytics.d.ts +87 -0
- package/types/web/src/auth.d.ts +155 -0
- package/types/web/src/backend-error.d.ts +38 -0
- package/types/web/src/backend-names.d.ts +25 -0
- package/types/web/src/backends.d.ts +84 -0
- package/types/web/src/client.d.ts +51 -0
- package/types/web/src/index.d.ts +11 -0
- package/types/web/src/palbe.d.ts +2 -0
- package/types/web/src/purchases.d.ts +73 -0
- package/types/web/src/rooms.d.ts +61 -0
- package/types/web/src/session.d.ts +91 -0
- package/types/web/src/socket.d.ts +87 -0
- package/types/web/src/vite.d.ts +49 -0
|
@@ -0,0 +1,2944 @@
|
|
|
1
|
+
import { type Reply, type Transport } from '../transport.js';
|
|
2
|
+
/**
|
|
3
|
+
* What App Review needs to see of a product (the App Store's alone): without it the product is saved, but not sent to the App Store.
|
|
4
|
+
*/
|
|
5
|
+
export type AppReview = {
|
|
6
|
+
/**
|
|
7
|
+
* A note to the reviewer.
|
|
8
|
+
*/
|
|
9
|
+
note?: string;
|
|
10
|
+
/**
|
|
11
|
+
* The id of an image the project uploaded: the product in the app.
|
|
12
|
+
*/
|
|
13
|
+
screenshot?: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* The project's App Store connection as the API shows it: never the key itself.
|
|
17
|
+
*/
|
|
18
|
+
export type AppleAccount = {
|
|
19
|
+
/**
|
|
20
|
+
* What the person has to do, when Apple refuses the key or the App Store does not report here.
|
|
21
|
+
*/
|
|
22
|
+
action?: string;
|
|
23
|
+
/**
|
|
24
|
+
* The app's Apple ID, as App Store Connect names it: production purchases and notifications are taken once it is known (the stores module reads it when it binds the notification address).
|
|
25
|
+
*/
|
|
26
|
+
app_apple_id?: number;
|
|
27
|
+
/**
|
|
28
|
+
* The app the key is connected for: one of this environment's registered iOS apps.
|
|
29
|
+
*/
|
|
30
|
+
bundle_id?: string;
|
|
31
|
+
/**
|
|
32
|
+
* When Apple was last asked of the key.
|
|
33
|
+
*/
|
|
34
|
+
checked_at?: string | null;
|
|
35
|
+
/**
|
|
36
|
+
* Whether an In-App Purchase key is connected.
|
|
37
|
+
*/
|
|
38
|
+
connected: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* When the key was connected.
|
|
41
|
+
*/
|
|
42
|
+
connected_at?: string | null;
|
|
43
|
+
/**
|
|
44
|
+
* Who asked for the grant the key was connected with (the API key that asked).
|
|
45
|
+
*/
|
|
46
|
+
connected_by?: string;
|
|
47
|
+
/**
|
|
48
|
+
* The key's issuer (the Apple account's team-wide id).
|
|
49
|
+
*/
|
|
50
|
+
issuer_id?: string;
|
|
51
|
+
/**
|
|
52
|
+
* The key's id, as App Store Connect lists it: what tells it apart.
|
|
53
|
+
*/
|
|
54
|
+
key_id?: string;
|
|
55
|
+
notifications?: AppleNotifications;
|
|
56
|
+
/**
|
|
57
|
+
* What Apple last said of the key: active (it takes it), refused (it no longer does: connect a new one).
|
|
58
|
+
*/
|
|
59
|
+
status?: "active" | "refused";
|
|
60
|
+
xcode_certificate?: XcodeCertificate;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* What names the customer to the App Store without saying who they are.
|
|
64
|
+
*/
|
|
65
|
+
export type AppleAccountToken = {
|
|
66
|
+
/**
|
|
67
|
+
* A UUID, the customer's for the connected app: pass it to StoreKit's purchase (Product.PurchaseOption.appAccountToken). The App Store's notifications carry it back, and the purchase is the customer's before their app reports it.
|
|
68
|
+
*/
|
|
69
|
+
app_account_token: string;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* What the stores module answered of a plan's App Store part once it was confirmed: absent until it answers.
|
|
73
|
+
*/
|
|
74
|
+
export type AppleCatalogResult = {
|
|
75
|
+
/**
|
|
76
|
+
* The app's Apple ID.
|
|
77
|
+
*/
|
|
78
|
+
asc_app_id: number;
|
|
79
|
+
/**
|
|
80
|
+
* The app it was written for.
|
|
81
|
+
*/
|
|
82
|
+
bundle_id: string;
|
|
83
|
+
/**
|
|
84
|
+
* Why it was not, as a whole.
|
|
85
|
+
*/
|
|
86
|
+
error?: string;
|
|
87
|
+
/**
|
|
88
|
+
* Whether every step was written.
|
|
89
|
+
*/
|
|
90
|
+
ok: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* The plan.
|
|
93
|
+
*/
|
|
94
|
+
plan_id: string;
|
|
95
|
+
/**
|
|
96
|
+
* Each step, as App Store Connect holds it.
|
|
97
|
+
*/
|
|
98
|
+
steps: AppleStepResult[];
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* A one-time grant to connect an In-App Purchase key: the key goes from the person's browser (connect_url) or terminal (POST /purchases/apple/connect with the grant) straight to the module.
|
|
102
|
+
*/
|
|
103
|
+
export type AppleGrant = {
|
|
104
|
+
/**
|
|
105
|
+
* The page that takes the key from a browser. The grant rides in the URL's fragment, which a browser never sends to a server.
|
|
106
|
+
*/
|
|
107
|
+
connect_url: string;
|
|
108
|
+
/**
|
|
109
|
+
* When the grant stops working.
|
|
110
|
+
*/
|
|
111
|
+
expires_at: string;
|
|
112
|
+
/**
|
|
113
|
+
* The grant: spent by the first key Apple takes, or after 30 minutes.
|
|
114
|
+
*/
|
|
115
|
+
grant: string;
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* The App Store's notification, as Apple signs and sends it: its signedPayload is verified, and what it signs is read.
|
|
119
|
+
*/
|
|
120
|
+
export type AppleNotification = {
|
|
121
|
+
/**
|
|
122
|
+
* The notification, signed by the App Store (JWS).
|
|
123
|
+
*/
|
|
124
|
+
signedPayload: string;
|
|
125
|
+
[key: string]: unknown;
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* Where the App Store reports the app's purchases, and whether it does.
|
|
129
|
+
*/
|
|
130
|
+
export type AppleNotifications = {
|
|
131
|
+
/**
|
|
132
|
+
* Whether the stores module set it as the app's notification address in App Store Connect (both environments).
|
|
133
|
+
*/
|
|
134
|
+
bound: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* When it was bound; null until then.
|
|
137
|
+
*/
|
|
138
|
+
bound_at: string | null;
|
|
139
|
+
/**
|
|
140
|
+
* Why it is not bound, or cannot be verified, as the stores module or Apple said it.
|
|
141
|
+
*/
|
|
142
|
+
error?: string;
|
|
143
|
+
/**
|
|
144
|
+
* The address: POST /purchases/webhooks/apple of this environment, one for Apple's sandbox and production.
|
|
145
|
+
*/
|
|
146
|
+
url: string;
|
|
147
|
+
/**
|
|
148
|
+
* When the App Store's TEST notification, asked for once it was bound, arrived: the address is reached; null until then.
|
|
149
|
+
*/
|
|
150
|
+
verified_at: string | null;
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* The App Store's price point a step's price was resolved to, in the base currency's storefront.
|
|
154
|
+
*/
|
|
155
|
+
export type ApplePrice = {
|
|
156
|
+
/**
|
|
157
|
+
* Its currency.
|
|
158
|
+
*/
|
|
159
|
+
currency: string;
|
|
160
|
+
/**
|
|
161
|
+
* What the customer pays there, as App Store Connect writes it (9.99).
|
|
162
|
+
*/
|
|
163
|
+
customer_price: string;
|
|
164
|
+
/**
|
|
165
|
+
* The storefront (USA).
|
|
166
|
+
*/
|
|
167
|
+
territory: string;
|
|
168
|
+
};
|
|
169
|
+
/**
|
|
170
|
+
* Whether the environment sells in the App Store, check by check.
|
|
171
|
+
*/
|
|
172
|
+
export type AppleReadiness = {
|
|
173
|
+
/**
|
|
174
|
+
* The checks, in a fixed order.
|
|
175
|
+
*/
|
|
176
|
+
checks: ReadinessCheck[];
|
|
177
|
+
/**
|
|
178
|
+
* Every check that is not informational holds.
|
|
179
|
+
*/
|
|
180
|
+
ready: boolean;
|
|
181
|
+
};
|
|
182
|
+
/**
|
|
183
|
+
* One step of a plan's App Store part, as App Store Connect holds it now.
|
|
184
|
+
*/
|
|
185
|
+
export type AppleStepResult = {
|
|
186
|
+
/**
|
|
187
|
+
* App Store Connect's own id of what was made.
|
|
188
|
+
*/
|
|
189
|
+
apple_id?: string;
|
|
190
|
+
/**
|
|
191
|
+
* Why the step was not written, as App Store Connect said it.
|
|
192
|
+
*/
|
|
193
|
+
error?: string;
|
|
194
|
+
/**
|
|
195
|
+
* The step's op.
|
|
196
|
+
*/
|
|
197
|
+
op: string;
|
|
198
|
+
price?: ApplePrice;
|
|
199
|
+
/**
|
|
200
|
+
* Its state at App Store Connect (MISSING_METADATA, READY_TO_SUBMIT, WAITING_FOR_REVIEW, APPROVED …).
|
|
201
|
+
*/
|
|
202
|
+
state?: string;
|
|
203
|
+
/**
|
|
204
|
+
* The App Store's product id (or the subscription group's reference name).
|
|
205
|
+
*/
|
|
206
|
+
store_id: string;
|
|
207
|
+
};
|
|
208
|
+
/**
|
|
209
|
+
* What StoreKit gave the customer's app.
|
|
210
|
+
*/
|
|
211
|
+
export type AppleTransactionReport = {
|
|
212
|
+
/**
|
|
213
|
+
* The reporting device's AppStore.deviceVerificationID (its uuidString). StoreKit signs each transaction for one device: its deviceVerification is the SHA-384 of its deviceVerificationNonce and this id, both lowercase. A restore moves a purchase another customer has only when the transaction was signed for this device; without it, a restore moves none.
|
|
214
|
+
*/
|
|
215
|
+
device_verification_id?: string;
|
|
216
|
+
/**
|
|
217
|
+
* The customer asked to restore their purchases: each purchase moves to them from the customer that has it — only with a transaction StoreKit signed for this device (`device_verification_id`), never an account's by a guest's restore, and one purchase 3 times in 30 days at most; one that stays is answered (403, 409) once the rest is applied. Without it (false, the default), a purchase another customer has stays theirs.
|
|
218
|
+
*/
|
|
219
|
+
restore?: boolean;
|
|
220
|
+
/**
|
|
221
|
+
* The transactions, as StoreKit 2 signs each (Transaction.jwsRepresentation): a purchase just made, Transaction.updates, or every one of currentEntitlements on a restore.
|
|
222
|
+
*/
|
|
223
|
+
transactions: string[];
|
|
224
|
+
};
|
|
225
|
+
/**
|
|
226
|
+
* What the Stripe account holds of the catalog once a plan was written, read back from Stripe; null maps when the plan failed before reading it.
|
|
227
|
+
*/
|
|
228
|
+
export type AppliedStripe = {
|
|
229
|
+
/**
|
|
230
|
+
* The prices, by lookup key.
|
|
231
|
+
*/
|
|
232
|
+
prices: ({
|
|
233
|
+
[key: string]: StripePrice;
|
|
234
|
+
}) | null;
|
|
235
|
+
/**
|
|
236
|
+
* The products, by the catalog's product key.
|
|
237
|
+
*/
|
|
238
|
+
products: ({
|
|
239
|
+
[key: string]: StripeProduct;
|
|
240
|
+
}) | null;
|
|
241
|
+
};
|
|
242
|
+
/**
|
|
243
|
+
* The project's one definition of what it sells: each product once — its kind, plans and prices, its names in each language, the channels it is sold on and what it gives. Read strictly: a field it does not know is refused (400 `invalid_catalog`). What a store's rules allow is not part of the shape: POST /purchases/catalog/validate says it, problem by problem.
|
|
244
|
+
*/
|
|
245
|
+
export type Catalog = {
|
|
246
|
+
/**
|
|
247
|
+
* The language every product names itself in (a tag such as en or pt-BR); the others are translations. Stripe keeps one name: this one's.
|
|
248
|
+
*/
|
|
249
|
+
base_locale: string;
|
|
250
|
+
/**
|
|
251
|
+
* The kinds of credit the project counts ("tokens").
|
|
252
|
+
*/
|
|
253
|
+
credits: CatalogCredit[];
|
|
254
|
+
/**
|
|
255
|
+
* What a customer has or not ("pro").
|
|
256
|
+
*/
|
|
257
|
+
entitlements: CatalogEntitlement[];
|
|
258
|
+
/**
|
|
259
|
+
* The metered quotas ("ai_requests a month").
|
|
260
|
+
*/
|
|
261
|
+
limits: CatalogLimit[];
|
|
262
|
+
/**
|
|
263
|
+
* The products.
|
|
264
|
+
*/
|
|
265
|
+
products: Product[];
|
|
266
|
+
};
|
|
267
|
+
/**
|
|
268
|
+
* purchases.catalog.applied: a plan's Stripe part was written (applied) or failed; or the stores module answered of its App Store part.
|
|
269
|
+
*/
|
|
270
|
+
export type CatalogAppliedEvent = {
|
|
271
|
+
/**
|
|
272
|
+
* The plan.
|
|
273
|
+
*/
|
|
274
|
+
plan_id: string;
|
|
275
|
+
/**
|
|
276
|
+
* Its revision.
|
|
277
|
+
*/
|
|
278
|
+
revision: number;
|
|
279
|
+
/**
|
|
280
|
+
* How it ended.
|
|
281
|
+
*/
|
|
282
|
+
status: "applied" | "failed";
|
|
283
|
+
/**
|
|
284
|
+
* The store written.
|
|
285
|
+
*/
|
|
286
|
+
store: "stripe" | "app_store";
|
|
287
|
+
};
|
|
288
|
+
/**
|
|
289
|
+
* purchases.catalog.changed: a new revision of the catalog was saved; plans of older ones went stale.
|
|
290
|
+
*/
|
|
291
|
+
export type CatalogChangedEvent = {
|
|
292
|
+
/**
|
|
293
|
+
* The new revision.
|
|
294
|
+
*/
|
|
295
|
+
revision: number;
|
|
296
|
+
};
|
|
297
|
+
/**
|
|
298
|
+
* A kind of credit the project counts.
|
|
299
|
+
*/
|
|
300
|
+
export type CatalogCredit = {
|
|
301
|
+
/**
|
|
302
|
+
* Whether the customer's own app may spend its credits with the publishable key — for an app with no backend; off, only the secret key spends.
|
|
303
|
+
*/
|
|
304
|
+
client_spend?: boolean;
|
|
305
|
+
/**
|
|
306
|
+
* Its key: lowercase letters, digits and _, starting with a letter, at most 40.
|
|
307
|
+
*/
|
|
308
|
+
key: string;
|
|
309
|
+
/**
|
|
310
|
+
* The balance under which the project's backend hears `purchases.credits.low` (0 or absent: never).
|
|
311
|
+
*/
|
|
312
|
+
low_at?: number;
|
|
313
|
+
/**
|
|
314
|
+
* Its name, for people.
|
|
315
|
+
*/
|
|
316
|
+
name: string;
|
|
317
|
+
};
|
|
318
|
+
/**
|
|
319
|
+
* The catalog as saved: a revision.
|
|
320
|
+
*/
|
|
321
|
+
export type CatalogDoc = {
|
|
322
|
+
catalog: Catalog;
|
|
323
|
+
/**
|
|
324
|
+
* When the revision was saved; absent before the first.
|
|
325
|
+
*/
|
|
326
|
+
created_at?: string | null;
|
|
327
|
+
/**
|
|
328
|
+
* Who saved it (the API key that asked).
|
|
329
|
+
*/
|
|
330
|
+
created_by?: string;
|
|
331
|
+
/**
|
|
332
|
+
* The revision: 0 before the first save, then one more with each.
|
|
333
|
+
*/
|
|
334
|
+
revision: number;
|
|
335
|
+
};
|
|
336
|
+
/**
|
|
337
|
+
* Something a customer has or not.
|
|
338
|
+
*/
|
|
339
|
+
export type CatalogEntitlement = {
|
|
340
|
+
/**
|
|
341
|
+
* Its key: lowercase letters, digits and _, starting with a letter, at most 40.
|
|
342
|
+
*/
|
|
343
|
+
key: string;
|
|
344
|
+
/**
|
|
345
|
+
* Its name, for people.
|
|
346
|
+
*/
|
|
347
|
+
name: string;
|
|
348
|
+
};
|
|
349
|
+
/**
|
|
350
|
+
* A metered quota, counted in a window.
|
|
351
|
+
*/
|
|
352
|
+
export type CatalogLimit = {
|
|
353
|
+
/**
|
|
354
|
+
* What a customer gets with nothing that gives more.
|
|
355
|
+
*/
|
|
356
|
+
free: number;
|
|
357
|
+
/**
|
|
358
|
+
* Its key: lowercase letters, digits and _, starting with a letter, at most 40.
|
|
359
|
+
*/
|
|
360
|
+
key: string;
|
|
361
|
+
/**
|
|
362
|
+
* Its name, for people.
|
|
363
|
+
*/
|
|
364
|
+
name: string;
|
|
365
|
+
overflow?: LimitOverflow;
|
|
366
|
+
/**
|
|
367
|
+
* What it is counted in: calendar_month, calendar_day (both from midnight in the project's time zone) or billing_period (the period of the subscription that gives it; a calendar month without one).
|
|
368
|
+
*/
|
|
369
|
+
window: string;
|
|
370
|
+
};
|
|
371
|
+
/**
|
|
372
|
+
* What bringing the stores to a revision of the catalog writes, store by store, before anything is written.
|
|
373
|
+
*/
|
|
374
|
+
export type CatalogPlan = {
|
|
375
|
+
apple: StorePlan;
|
|
376
|
+
apple_result?: AppleCatalogResult;
|
|
377
|
+
/**
|
|
378
|
+
* When it was written.
|
|
379
|
+
*/
|
|
380
|
+
applied_at?: string | null;
|
|
381
|
+
/**
|
|
382
|
+
* When it was made.
|
|
383
|
+
*/
|
|
384
|
+
created_at: string;
|
|
385
|
+
/**
|
|
386
|
+
* Why it failed, as Stripe said it.
|
|
387
|
+
*/
|
|
388
|
+
error?: string;
|
|
389
|
+
google: StorePlan;
|
|
390
|
+
/**
|
|
391
|
+
* The plan's id.
|
|
392
|
+
*/
|
|
393
|
+
id: string;
|
|
394
|
+
/**
|
|
395
|
+
* What the check found of the revision (warnings: a saved revision has no other).
|
|
396
|
+
*/
|
|
397
|
+
problems: CatalogProblem[];
|
|
398
|
+
result?: AppliedStripe;
|
|
399
|
+
/**
|
|
400
|
+
* The revision it was made from.
|
|
401
|
+
*/
|
|
402
|
+
revision: number;
|
|
403
|
+
/**
|
|
404
|
+
* planned (waits on a person), stale (the catalog changed since), applying, applied, failed (`error` says why), declined.
|
|
405
|
+
*/
|
|
406
|
+
status: "planned" | "stale" | "applying" | "applied" | "failed" | "declined";
|
|
407
|
+
/**
|
|
408
|
+
* The Stripe part, against what the account held when the plan was made: the one confirmed here. Null when no Stripe account is connected.
|
|
409
|
+
*/
|
|
410
|
+
stripe: StorePlan | null;
|
|
411
|
+
};
|
|
412
|
+
/**
|
|
413
|
+
* One thing wrong with a catalog.
|
|
414
|
+
*/
|
|
415
|
+
export type CatalogProblem = {
|
|
416
|
+
/**
|
|
417
|
+
* The store whose rule it breaks: ios, android or web; absent for every channel.
|
|
418
|
+
*/
|
|
419
|
+
channel?: string;
|
|
420
|
+
/**
|
|
421
|
+
* What it is (too_long, unsupported_period, unknown_entitlement, review_missing …).
|
|
422
|
+
*/
|
|
423
|
+
code: string;
|
|
424
|
+
/**
|
|
425
|
+
* What to do about it.
|
|
426
|
+
*/
|
|
427
|
+
message: string;
|
|
428
|
+
/**
|
|
429
|
+
* Where it is (products[0].channels.ios.locales.en.name).
|
|
430
|
+
*/
|
|
431
|
+
path: string;
|
|
432
|
+
/**
|
|
433
|
+
* A warning does not stop a save: the product is sold without what the channel lacks.
|
|
434
|
+
*/
|
|
435
|
+
warning?: boolean;
|
|
436
|
+
};
|
|
437
|
+
/**
|
|
438
|
+
* What a catalog's check found.
|
|
439
|
+
*/
|
|
440
|
+
export type CatalogValidation = {
|
|
441
|
+
/**
|
|
442
|
+
* Every problem, by path.
|
|
443
|
+
*/
|
|
444
|
+
problems: CatalogProblem[];
|
|
445
|
+
/**
|
|
446
|
+
* Whether it can be saved: no problem that is not a warning.
|
|
447
|
+
*/
|
|
448
|
+
valid: boolean;
|
|
449
|
+
};
|
|
450
|
+
/**
|
|
451
|
+
* What a product is on one store beyond what it is everywhere.
|
|
452
|
+
*/
|
|
453
|
+
export type Channel = {
|
|
454
|
+
/**
|
|
455
|
+
* Shares the purchase with the buyer's family (the App Store's alone).
|
|
456
|
+
*/
|
|
457
|
+
family_shareable?: boolean;
|
|
458
|
+
/**
|
|
459
|
+
* Its own text, field by field, in each language named: where the store's limits or audience call for it (Apple's 30-character names, Google's benefits).
|
|
460
|
+
*/
|
|
461
|
+
locales?: {
|
|
462
|
+
[key: string]: Locale;
|
|
463
|
+
};
|
|
464
|
+
/**
|
|
465
|
+
* Its own price for a plan, by the plan's key: a web price without the stores' commission.
|
|
466
|
+
*/
|
|
467
|
+
prices?: {
|
|
468
|
+
[key: string]: Price;
|
|
469
|
+
};
|
|
470
|
+
review?: AppReview;
|
|
471
|
+
/**
|
|
472
|
+
* Stripe's tax code for the product (the web's alone).
|
|
473
|
+
*/
|
|
474
|
+
tax_code?: string;
|
|
475
|
+
};
|
|
476
|
+
/**
|
|
477
|
+
* A Stripe Checkout session to send the customer to.
|
|
478
|
+
*/
|
|
479
|
+
export type Checkout = {
|
|
480
|
+
/**
|
|
481
|
+
* Stripe's session id.
|
|
482
|
+
*/
|
|
483
|
+
session_id: string;
|
|
484
|
+
/**
|
|
485
|
+
* Where the customer pays.
|
|
486
|
+
*/
|
|
487
|
+
url: string;
|
|
488
|
+
};
|
|
489
|
+
/**
|
|
490
|
+
* The error envelope of a refused checkout, with where the customer already has it when that is why (`already_entitled`): buying it again would charge twice for one thing.
|
|
491
|
+
*/
|
|
492
|
+
export type CheckoutConflictError = {
|
|
493
|
+
/**
|
|
494
|
+
* Machine-readable error code (snake_case)
|
|
495
|
+
*/
|
|
496
|
+
error: string;
|
|
497
|
+
/**
|
|
498
|
+
* Human-readable explanation
|
|
499
|
+
*/
|
|
500
|
+
error_description: string;
|
|
501
|
+
/**
|
|
502
|
+
* The catalog's product they have — the same, or one of its group: with `already_entitled`, absent otherwise.
|
|
503
|
+
*/
|
|
504
|
+
product?: string;
|
|
505
|
+
/**
|
|
506
|
+
* Correlation ID for log/audit lookup
|
|
507
|
+
*/
|
|
508
|
+
request_id: string;
|
|
509
|
+
/**
|
|
510
|
+
* Seconds to wait before retrying; present on a refusal that ends with time.
|
|
511
|
+
*/
|
|
512
|
+
retry_after?: number;
|
|
513
|
+
/**
|
|
514
|
+
* HTTP status code (mirrors the response status)
|
|
515
|
+
*/
|
|
516
|
+
status: number;
|
|
517
|
+
/**
|
|
518
|
+
* Where they have it: with `already_entitled`, absent otherwise.
|
|
519
|
+
*/
|
|
520
|
+
store?: "app_store" | "play_store" | "stripe";
|
|
521
|
+
};
|
|
522
|
+
/**
|
|
523
|
+
* What the signed-in customer buys on the web.
|
|
524
|
+
*/
|
|
525
|
+
export type CheckoutRequest = {
|
|
526
|
+
/**
|
|
527
|
+
* Where Stripe sends the customer back when they do not pay; the same rule.
|
|
528
|
+
*/
|
|
529
|
+
cancel_url: string;
|
|
530
|
+
/**
|
|
531
|
+
* Its plan.
|
|
532
|
+
*/
|
|
533
|
+
plan: string;
|
|
534
|
+
/**
|
|
535
|
+
* The catalog's product (sold on the web).
|
|
536
|
+
*/
|
|
537
|
+
product: string;
|
|
538
|
+
/**
|
|
539
|
+
* Where Stripe sends the customer back once paid: a registered web app's origin, or a native app's own scheme.
|
|
540
|
+
*/
|
|
541
|
+
success_url: string;
|
|
542
|
+
};
|
|
543
|
+
/**
|
|
544
|
+
* An In-App Purchase key handed over with a grant, for one of the environment's iOS apps.
|
|
545
|
+
*/
|
|
546
|
+
export type ConnectAppleKeyRequest = {
|
|
547
|
+
/**
|
|
548
|
+
* The app the key is for: one of this environment's registered iOS apps.
|
|
549
|
+
*/
|
|
550
|
+
bundle_id: string;
|
|
551
|
+
/**
|
|
552
|
+
* The grant a connect link carries.
|
|
553
|
+
*/
|
|
554
|
+
grant: string;
|
|
555
|
+
/**
|
|
556
|
+
* The key's issuer: App Store Connect → Users and Access → Integrations → In-App Purchase.
|
|
557
|
+
*/
|
|
558
|
+
issuer_id: string;
|
|
559
|
+
/**
|
|
560
|
+
* The key's id (10 capital letters and digits).
|
|
561
|
+
*/
|
|
562
|
+
key_id: string;
|
|
563
|
+
/**
|
|
564
|
+
* The key's .p8 file as Apple let it be downloaded (SubscriptionKey_<key id>.p8: PEM, PKCS#8). An App Store Connect API key is not this key.
|
|
565
|
+
*/
|
|
566
|
+
private_key: string;
|
|
567
|
+
};
|
|
568
|
+
/**
|
|
569
|
+
* A Stripe restricted key handed over with a grant.
|
|
570
|
+
*/
|
|
571
|
+
export type ConnectStripeKeyRequest = {
|
|
572
|
+
/**
|
|
573
|
+
* The grant a connect link carries.
|
|
574
|
+
*/
|
|
575
|
+
grant: string;
|
|
576
|
+
/**
|
|
577
|
+
* A restricted key made for Palbase (rk_live_… or rk_test_…) that may read products, prices, customers, Checkout Sessions, subscriptions, invoices, payment intents and charges, and write webhook endpoints. An unrestricted secret key is refused: it can do anything on the account.
|
|
578
|
+
*/
|
|
579
|
+
key: string;
|
|
580
|
+
};
|
|
581
|
+
/**
|
|
582
|
+
* A customer's balance in one credit.
|
|
583
|
+
*/
|
|
584
|
+
export type CreditBalance = {
|
|
585
|
+
/**
|
|
586
|
+
* What a spend can take now: the balance less what open holds keep.
|
|
587
|
+
*/
|
|
588
|
+
available: number;
|
|
589
|
+
/**
|
|
590
|
+
* What the live lots hold less what the customer owes: below zero while they owe (a refund took back credits already spent).
|
|
591
|
+
*/
|
|
592
|
+
balance: number;
|
|
593
|
+
/**
|
|
594
|
+
* The credit.
|
|
595
|
+
*/
|
|
596
|
+
currency: string;
|
|
597
|
+
/**
|
|
598
|
+
* What the customer owes: the next credits pay it first.
|
|
599
|
+
*/
|
|
600
|
+
debt: number;
|
|
601
|
+
/**
|
|
602
|
+
* When credits next expire; null when none do.
|
|
603
|
+
*/
|
|
604
|
+
next_expiry: string | null;
|
|
605
|
+
/**
|
|
606
|
+
* What open holds keep.
|
|
607
|
+
*/
|
|
608
|
+
reserved: number;
|
|
609
|
+
};
|
|
610
|
+
/**
|
|
611
|
+
* What a spend took from one lot.
|
|
612
|
+
*/
|
|
613
|
+
export type CreditConsumption = {
|
|
614
|
+
/**
|
|
615
|
+
* How much.
|
|
616
|
+
*/
|
|
617
|
+
amount: number;
|
|
618
|
+
/**
|
|
619
|
+
* The lot; absent for debt.
|
|
620
|
+
*/
|
|
621
|
+
lot_id?: string;
|
|
622
|
+
/**
|
|
623
|
+
* Where the lot came from: purchase (credits bought), period (a subscription's), promotion, support; debt — what a refund in between left uncovered.
|
|
624
|
+
*/
|
|
625
|
+
source: "purchase" | "period" | "promotion" | "support" | "debt";
|
|
626
|
+
};
|
|
627
|
+
/**
|
|
628
|
+
* A page of a customer's credit movements, newest first.
|
|
629
|
+
*/
|
|
630
|
+
export type CreditEntries = {
|
|
631
|
+
/**
|
|
632
|
+
* The movements.
|
|
633
|
+
*/
|
|
634
|
+
entries: CreditEntry[];
|
|
635
|
+
/**
|
|
636
|
+
* Goes on to the next page (send it as `cursor`); absent on the last page.
|
|
637
|
+
*/
|
|
638
|
+
next_cursor?: string;
|
|
639
|
+
};
|
|
640
|
+
/**
|
|
641
|
+
* One movement of a customer's credits.
|
|
642
|
+
*/
|
|
643
|
+
export type CreditEntry = {
|
|
644
|
+
/**
|
|
645
|
+
* Who moved them: the wallet itself (`wallet`: a spend, an expiry, a merge), a store (`store`, `store:<environment>`), a key (`key:<id>`) or a user (`user:<id>`).
|
|
646
|
+
*/
|
|
647
|
+
actor: string;
|
|
648
|
+
/**
|
|
649
|
+
* When.
|
|
650
|
+
*/
|
|
651
|
+
created_at: string;
|
|
652
|
+
/**
|
|
653
|
+
* The credit.
|
|
654
|
+
*/
|
|
655
|
+
currency: string;
|
|
656
|
+
/**
|
|
657
|
+
* What it changed the debt by: above zero a refund took back credits already spent, below zero the debt was paid or forgiven.
|
|
658
|
+
*/
|
|
659
|
+
debt_delta: number;
|
|
660
|
+
/**
|
|
661
|
+
* What it changed the balance by: above zero it gave, below zero it took.
|
|
662
|
+
*/
|
|
663
|
+
delta: number;
|
|
664
|
+
/**
|
|
665
|
+
* The movement's id: newer ones are larger.
|
|
666
|
+
*/
|
|
667
|
+
id: number;
|
|
668
|
+
/**
|
|
669
|
+
* What moved them: grant (bought, a period's, a promotion, support), spend, shortfall (a refund took back more than was left: the rest is owed), revoke (a refund or chargeback took them back), unrevoke (that was reversed), expire, reversal (a spend handed back), merge (a guest's went to the account), forgive (support forgave a debt).
|
|
670
|
+
*/
|
|
671
|
+
kind: "grant" | "spend" | "shortfall" | "revoke" | "unrevoke" | "expire" | "reversal" | "merge" | "forgive";
|
|
672
|
+
/**
|
|
673
|
+
* The lot it moved, when it moved one.
|
|
674
|
+
*/
|
|
675
|
+
lot_id?: string;
|
|
676
|
+
/**
|
|
677
|
+
* Why, when a person said it (a grant's, a forgiveness's).
|
|
678
|
+
*/
|
|
679
|
+
reason?: string;
|
|
680
|
+
/**
|
|
681
|
+
* The spend it was part of, when it was one's.
|
|
682
|
+
*/
|
|
683
|
+
spend_id?: string;
|
|
684
|
+
};
|
|
685
|
+
/**
|
|
686
|
+
* A debt forgiven.
|
|
687
|
+
*/
|
|
688
|
+
export type CreditForgiveRequest = {
|
|
689
|
+
/**
|
|
690
|
+
* How much of the debt, at most all of it; absent or 0: all of it.
|
|
691
|
+
*/
|
|
692
|
+
amount?: number;
|
|
693
|
+
/**
|
|
694
|
+
* The credit (a key of the catalog's credits).
|
|
695
|
+
*/
|
|
696
|
+
credits: string;
|
|
697
|
+
/**
|
|
698
|
+
* Why: the record.
|
|
699
|
+
*/
|
|
700
|
+
reason: string;
|
|
701
|
+
};
|
|
702
|
+
/**
|
|
703
|
+
* What a forgiveness took off a debt, and the account it left.
|
|
704
|
+
*/
|
|
705
|
+
export type CreditForgiven = {
|
|
706
|
+
/**
|
|
707
|
+
* What a spend can take now.
|
|
708
|
+
*/
|
|
709
|
+
available: number;
|
|
710
|
+
/**
|
|
711
|
+
* The balance after: what the live lots hold less what is still owed.
|
|
712
|
+
*/
|
|
713
|
+
balance: number;
|
|
714
|
+
/**
|
|
715
|
+
* The credit.
|
|
716
|
+
*/
|
|
717
|
+
credits: string;
|
|
718
|
+
/**
|
|
719
|
+
* What is still owed.
|
|
720
|
+
*/
|
|
721
|
+
debt: number;
|
|
722
|
+
/**
|
|
723
|
+
* What it took off: 0 when the customer owed nothing.
|
|
724
|
+
*/
|
|
725
|
+
forgiven: number;
|
|
726
|
+
};
|
|
727
|
+
/**
|
|
728
|
+
* Credits given to a customer.
|
|
729
|
+
*/
|
|
730
|
+
export type CreditGrantRequest = {
|
|
731
|
+
/**
|
|
732
|
+
* How many.
|
|
733
|
+
*/
|
|
734
|
+
amount: number;
|
|
735
|
+
/**
|
|
736
|
+
* The credit (a key of the catalog's credits).
|
|
737
|
+
*/
|
|
738
|
+
credits: string;
|
|
739
|
+
/**
|
|
740
|
+
* When they expire, in the future; absent: never.
|
|
741
|
+
*/
|
|
742
|
+
expires_at?: string | null;
|
|
743
|
+
/**
|
|
744
|
+
* Why: the record.
|
|
745
|
+
*/
|
|
746
|
+
reason: string;
|
|
747
|
+
/**
|
|
748
|
+
* Why, in kind.
|
|
749
|
+
*/
|
|
750
|
+
source: "promotion" | "support";
|
|
751
|
+
};
|
|
752
|
+
/**
|
|
753
|
+
* A lot of credits, as granted.
|
|
754
|
+
*/
|
|
755
|
+
export type CreditLot = {
|
|
756
|
+
/**
|
|
757
|
+
* When it was given.
|
|
758
|
+
*/
|
|
759
|
+
created_at: string;
|
|
760
|
+
/**
|
|
761
|
+
* The credit.
|
|
762
|
+
*/
|
|
763
|
+
currency: string;
|
|
764
|
+
/**
|
|
765
|
+
* Its customer.
|
|
766
|
+
*/
|
|
767
|
+
customer: string;
|
|
768
|
+
/**
|
|
769
|
+
* When it expires; absent: never.
|
|
770
|
+
*/
|
|
771
|
+
expires_at?: string | null;
|
|
772
|
+
/**
|
|
773
|
+
* The lot's id.
|
|
774
|
+
*/
|
|
775
|
+
id: string;
|
|
776
|
+
/**
|
|
777
|
+
* What it gave.
|
|
778
|
+
*/
|
|
779
|
+
original: number;
|
|
780
|
+
/**
|
|
781
|
+
* What is left of it (less what paid a debt).
|
|
782
|
+
*/
|
|
783
|
+
remaining: number;
|
|
784
|
+
/**
|
|
785
|
+
* What was taken back of it.
|
|
786
|
+
*/
|
|
787
|
+
revoked: number;
|
|
788
|
+
/**
|
|
789
|
+
* Where it came from.
|
|
790
|
+
*/
|
|
791
|
+
source: "purchase" | "period" | "promotion" | "support";
|
|
792
|
+
/**
|
|
793
|
+
* What made it (a grant's: grant:<customer>:<Idempotency-Key>).
|
|
794
|
+
*/
|
|
795
|
+
source_ref: string;
|
|
796
|
+
};
|
|
797
|
+
/**
|
|
798
|
+
* A spend or a hold of credits.
|
|
799
|
+
*/
|
|
800
|
+
export type CreditSpendRequest = {
|
|
801
|
+
/**
|
|
802
|
+
* How many credits or units.
|
|
803
|
+
*/
|
|
804
|
+
amount: number;
|
|
805
|
+
/**
|
|
806
|
+
* The credit spent (a key of the catalog's credits).
|
|
807
|
+
*/
|
|
808
|
+
credits: string;
|
|
809
|
+
/**
|
|
810
|
+
* The caller's own notes, kept with the spend (a JSON object, 2048 bytes at most).
|
|
811
|
+
*/
|
|
812
|
+
metadata?: {
|
|
813
|
+
[key: string]: unknown;
|
|
814
|
+
};
|
|
815
|
+
/**
|
|
816
|
+
* A hold's life: it runs out after it (600 unless said). A spend in one step holds nothing and refuses it (400 `ttl_for_holds`).
|
|
817
|
+
*/
|
|
818
|
+
ttl_seconds?: number;
|
|
819
|
+
};
|
|
820
|
+
/**
|
|
821
|
+
* purchases.credits.depleted: a customer's balance of a credit came down to nothing (or below).
|
|
822
|
+
*/
|
|
823
|
+
export type CreditsDepletedEvent = {
|
|
824
|
+
/**
|
|
825
|
+
* What is available now.
|
|
826
|
+
*/
|
|
827
|
+
available: number;
|
|
828
|
+
/**
|
|
829
|
+
* The balance now.
|
|
830
|
+
*/
|
|
831
|
+
balance: number;
|
|
832
|
+
/**
|
|
833
|
+
* The credit.
|
|
834
|
+
*/
|
|
835
|
+
currency: string;
|
|
836
|
+
/**
|
|
837
|
+
* The customer.
|
|
838
|
+
*/
|
|
839
|
+
customer_id: string;
|
|
840
|
+
/**
|
|
841
|
+
* What the customer owes now.
|
|
842
|
+
*/
|
|
843
|
+
debt: number;
|
|
844
|
+
/**
|
|
845
|
+
* The low mark, when the same change crossed it.
|
|
846
|
+
*/
|
|
847
|
+
low_at?: number;
|
|
848
|
+
};
|
|
849
|
+
/**
|
|
850
|
+
* purchases.credits.low: a customer's balance of a credit fell under its low mark (the catalog's low_at); told once, until it is back above.
|
|
851
|
+
*/
|
|
852
|
+
export type CreditsLowEvent = {
|
|
853
|
+
/**
|
|
854
|
+
* What is available now.
|
|
855
|
+
*/
|
|
856
|
+
available: number;
|
|
857
|
+
/**
|
|
858
|
+
* The balance now.
|
|
859
|
+
*/
|
|
860
|
+
balance: number;
|
|
861
|
+
/**
|
|
862
|
+
* The credit.
|
|
863
|
+
*/
|
|
864
|
+
currency: string;
|
|
865
|
+
/**
|
|
866
|
+
* The customer.
|
|
867
|
+
*/
|
|
868
|
+
customer_id: string;
|
|
869
|
+
/**
|
|
870
|
+
* What the customer owes now.
|
|
871
|
+
*/
|
|
872
|
+
debt: number;
|
|
873
|
+
/**
|
|
874
|
+
* The low mark.
|
|
875
|
+
*/
|
|
876
|
+
low_at: number;
|
|
877
|
+
};
|
|
878
|
+
/**
|
|
879
|
+
* purchases.customer.changed: what a customer has changed — a purchase, a renewal or its end, a refund, a grant, credits or quota used, a merge — and their revision rose. Realtime carries it to the customer's apps, which read GET /purchases/me again.
|
|
880
|
+
*/
|
|
881
|
+
export type CustomerChangedEvent = {
|
|
882
|
+
/**
|
|
883
|
+
* The customer.
|
|
884
|
+
*/
|
|
885
|
+
customer_id: string;
|
|
886
|
+
/**
|
|
887
|
+
* The customer's new revision.
|
|
888
|
+
*/
|
|
889
|
+
revision: number;
|
|
890
|
+
};
|
|
891
|
+
/**
|
|
892
|
+
* purchases.customer.erased: a deleted user's purchases record was erased (and the guests merged into them); their id is never a customer again.
|
|
893
|
+
*/
|
|
894
|
+
export type CustomerErasedEvent = {
|
|
895
|
+
/**
|
|
896
|
+
* The customer.
|
|
897
|
+
*/
|
|
898
|
+
customer_id: string;
|
|
899
|
+
};
|
|
900
|
+
/**
|
|
901
|
+
* Everything a customer has: the one answer every app of the project reads, whatever store a purchase was made in.
|
|
902
|
+
*/
|
|
903
|
+
export type CustomerInfo = {
|
|
904
|
+
/**
|
|
905
|
+
* Their balance in every credit they have one in.
|
|
906
|
+
*/
|
|
907
|
+
credits: CreditBalance[];
|
|
908
|
+
/**
|
|
909
|
+
* The customer: the user's id.
|
|
910
|
+
*/
|
|
911
|
+
customer_id: string;
|
|
912
|
+
/**
|
|
913
|
+
* Every entitlement the customer has or had, by key.
|
|
914
|
+
*/
|
|
915
|
+
entitlements: {
|
|
916
|
+
[key: string]: EntitlementInfo;
|
|
917
|
+
};
|
|
918
|
+
/**
|
|
919
|
+
* Whether the user is a guest (anonymous): what a guest buys moves to the account it signs in to.
|
|
920
|
+
*/
|
|
921
|
+
guest: boolean;
|
|
922
|
+
/**
|
|
923
|
+
* Their use of every limit of the catalog.
|
|
924
|
+
*/
|
|
925
|
+
limits: LimitUse[];
|
|
926
|
+
/**
|
|
927
|
+
* Their one-time purchases, oldest first.
|
|
928
|
+
*/
|
|
929
|
+
purchases: PurchaseInfo[];
|
|
930
|
+
/**
|
|
931
|
+
* The time it was computed at: what was active is as of then.
|
|
932
|
+
*/
|
|
933
|
+
requested_at: string;
|
|
934
|
+
/**
|
|
935
|
+
* Rises with every change of what the customer has (0: nothing yet). The customer's apps join the realtime channel `purchases:<project ref>:<user id>` — theirs alone, read-only — whose state and `changed` broadcast carry `{"revision": N}`: a revision above the one read means reading GET /purchases/me again. `purchases.customer.changed` carries it to the project's webhooks.
|
|
936
|
+
*/
|
|
937
|
+
revision: number;
|
|
938
|
+
/**
|
|
939
|
+
* Their subscriptions and non-renewing periods, oldest first.
|
|
940
|
+
*/
|
|
941
|
+
subscriptions: SubscriptionInfo[];
|
|
942
|
+
};
|
|
943
|
+
/**
|
|
944
|
+
* purchases.customer.merged: a guest's purchases, grants, credits and quota use went to the account it signed in to; the guest's id points to the account from then on.
|
|
945
|
+
*/
|
|
946
|
+
export type CustomerMergedEvent = {
|
|
947
|
+
/**
|
|
948
|
+
* The guest.
|
|
949
|
+
*/
|
|
950
|
+
from: string;
|
|
951
|
+
/**
|
|
952
|
+
* The account.
|
|
953
|
+
*/
|
|
954
|
+
into: string;
|
|
955
|
+
};
|
|
956
|
+
/**
|
|
957
|
+
* purchases.entitlement.changed: an entitlement of a customer turned on or off.
|
|
958
|
+
*/
|
|
959
|
+
export type EntitlementChangedEvent = {
|
|
960
|
+
/**
|
|
961
|
+
* Whether the customer has it now.
|
|
962
|
+
*/
|
|
963
|
+
active: boolean;
|
|
964
|
+
/**
|
|
965
|
+
* The customer.
|
|
966
|
+
*/
|
|
967
|
+
customer_id: string;
|
|
968
|
+
/**
|
|
969
|
+
* The entitlement.
|
|
970
|
+
*/
|
|
971
|
+
entitlement: string;
|
|
972
|
+
/**
|
|
973
|
+
* When it ends; null for life (or off).
|
|
974
|
+
*/
|
|
975
|
+
expires_at: string | null;
|
|
976
|
+
/**
|
|
977
|
+
* Whether a store's test purchase gives it.
|
|
978
|
+
*/
|
|
979
|
+
is_sandbox: boolean;
|
|
980
|
+
/**
|
|
981
|
+
* The catalog's product that gives it; empty for a grant, or once nothing gives it.
|
|
982
|
+
*/
|
|
983
|
+
product: string;
|
|
984
|
+
/**
|
|
985
|
+
* Where it comes from now: app_store, play_store, stripe, promotional; empty once nothing gives it.
|
|
986
|
+
*/
|
|
987
|
+
store: string;
|
|
988
|
+
};
|
|
989
|
+
/**
|
|
990
|
+
* An entitlement as the customer has it: from the source that gives it longest (one for life wins; a real purchase over a test one).
|
|
991
|
+
*/
|
|
992
|
+
export type EntitlementInfo = {
|
|
993
|
+
/**
|
|
994
|
+
* Whether the customer has it now.
|
|
995
|
+
*/
|
|
996
|
+
active: boolean;
|
|
997
|
+
/**
|
|
998
|
+
* The store could not charge the renewal: the customer keeps access in its grace period.
|
|
999
|
+
*/
|
|
1000
|
+
billing_issue: boolean;
|
|
1001
|
+
/**
|
|
1002
|
+
* When it ends; null for life.
|
|
1003
|
+
*/
|
|
1004
|
+
expires_at: string | null;
|
|
1005
|
+
/**
|
|
1006
|
+
* Whether it is a store's test purchase.
|
|
1007
|
+
*/
|
|
1008
|
+
is_sandbox: boolean;
|
|
1009
|
+
manage?: Management;
|
|
1010
|
+
/**
|
|
1011
|
+
* How the customer has it.
|
|
1012
|
+
*/
|
|
1013
|
+
ownership: "purchased";
|
|
1014
|
+
/**
|
|
1015
|
+
* normal, trial (a free trial), or promotional (a grant).
|
|
1016
|
+
*/
|
|
1017
|
+
period_type: "normal" | "trial" | "promotional";
|
|
1018
|
+
/**
|
|
1019
|
+
* Its plan.
|
|
1020
|
+
*/
|
|
1021
|
+
plan?: string;
|
|
1022
|
+
/**
|
|
1023
|
+
* The catalog's product that gives it.
|
|
1024
|
+
*/
|
|
1025
|
+
product?: string;
|
|
1026
|
+
/**
|
|
1027
|
+
* Everything that gives it, active ones first.
|
|
1028
|
+
*/
|
|
1029
|
+
sources: EntitlementSource[];
|
|
1030
|
+
/**
|
|
1031
|
+
* Where it comes from.
|
|
1032
|
+
*/
|
|
1033
|
+
store: "app_store" | "play_store" | "stripe" | "promotional";
|
|
1034
|
+
/**
|
|
1035
|
+
* Whether it renews.
|
|
1036
|
+
*/
|
|
1037
|
+
will_renew: boolean;
|
|
1038
|
+
};
|
|
1039
|
+
/**
|
|
1040
|
+
* One thing that gives an entitlement.
|
|
1041
|
+
*/
|
|
1042
|
+
export type EntitlementSource = {
|
|
1043
|
+
/**
|
|
1044
|
+
* Whether it gives the entitlement now.
|
|
1045
|
+
*/
|
|
1046
|
+
active: boolean;
|
|
1047
|
+
/**
|
|
1048
|
+
* When it ends; null for life.
|
|
1049
|
+
*/
|
|
1050
|
+
expires_at: string | null;
|
|
1051
|
+
/**
|
|
1052
|
+
* Whether it is a store's test purchase.
|
|
1053
|
+
*/
|
|
1054
|
+
is_sandbox: boolean;
|
|
1055
|
+
/**
|
|
1056
|
+
* The catalog's product.
|
|
1057
|
+
*/
|
|
1058
|
+
product?: string;
|
|
1059
|
+
/**
|
|
1060
|
+
* Where it comes from: a store, or promotional (a grant).
|
|
1061
|
+
*/
|
|
1062
|
+
store: "app_store" | "play_store" | "stripe" | "promotional";
|
|
1063
|
+
/**
|
|
1064
|
+
* Whether it renews.
|
|
1065
|
+
*/
|
|
1066
|
+
will_renew: boolean;
|
|
1067
|
+
};
|
|
1068
|
+
export type ErrorResponse = {
|
|
1069
|
+
/**
|
|
1070
|
+
* Machine-readable error code (snake_case)
|
|
1071
|
+
*/
|
|
1072
|
+
error: string;
|
|
1073
|
+
/**
|
|
1074
|
+
* Human-readable explanation
|
|
1075
|
+
*/
|
|
1076
|
+
error_description: string;
|
|
1077
|
+
/**
|
|
1078
|
+
* Correlation ID for log/audit lookup
|
|
1079
|
+
*/
|
|
1080
|
+
request_id: string;
|
|
1081
|
+
/**
|
|
1082
|
+
* Seconds to wait before retrying; present on a refusal that ends with time.
|
|
1083
|
+
*/
|
|
1084
|
+
retry_after?: number;
|
|
1085
|
+
/**
|
|
1086
|
+
* HTTP status code (mirrors the response status)
|
|
1087
|
+
*/
|
|
1088
|
+
status: number;
|
|
1089
|
+
};
|
|
1090
|
+
/**
|
|
1091
|
+
* A granted (promotional) entitlement.
|
|
1092
|
+
*/
|
|
1093
|
+
export type GrantInfo = {
|
|
1094
|
+
/**
|
|
1095
|
+
* Its customer.
|
|
1096
|
+
*/
|
|
1097
|
+
customer_id: string;
|
|
1098
|
+
/**
|
|
1099
|
+
* The entitlement.
|
|
1100
|
+
*/
|
|
1101
|
+
entitlement: string;
|
|
1102
|
+
/**
|
|
1103
|
+
* When it ends; null for life.
|
|
1104
|
+
*/
|
|
1105
|
+
expires_at: string | null;
|
|
1106
|
+
/**
|
|
1107
|
+
* Who gave it (the API key).
|
|
1108
|
+
*/
|
|
1109
|
+
granted_by: string;
|
|
1110
|
+
/**
|
|
1111
|
+
* The grant's id.
|
|
1112
|
+
*/
|
|
1113
|
+
id: string;
|
|
1114
|
+
/**
|
|
1115
|
+
* Why.
|
|
1116
|
+
*/
|
|
1117
|
+
reason: string;
|
|
1118
|
+
/**
|
|
1119
|
+
* When it was revoked.
|
|
1120
|
+
*/
|
|
1121
|
+
revoked_at: string | null;
|
|
1122
|
+
/**
|
|
1123
|
+
* When it started.
|
|
1124
|
+
*/
|
|
1125
|
+
starts_at: string;
|
|
1126
|
+
};
|
|
1127
|
+
/**
|
|
1128
|
+
* An entitlement given to a customer.
|
|
1129
|
+
*/
|
|
1130
|
+
export type GrantRequest = {
|
|
1131
|
+
/**
|
|
1132
|
+
* The catalog's entitlement.
|
|
1133
|
+
*/
|
|
1134
|
+
entitlement: string;
|
|
1135
|
+
/**
|
|
1136
|
+
* When it ends, in the future; absent or null for life.
|
|
1137
|
+
*/
|
|
1138
|
+
expires_at?: string | null;
|
|
1139
|
+
/**
|
|
1140
|
+
* Why: the record.
|
|
1141
|
+
*/
|
|
1142
|
+
reason: string;
|
|
1143
|
+
};
|
|
1144
|
+
/**
|
|
1145
|
+
* A subscription plan's introductory offer: once per customer, across every channel.
|
|
1146
|
+
*/
|
|
1147
|
+
export type IntroOffer = {
|
|
1148
|
+
/**
|
|
1149
|
+
* How long it lasts, an ISO 8601 duration (the App Store's free trials: P3D, P1W, P2W, P1M, P2M, P3M, P6M, P1Y).
|
|
1150
|
+
*/
|
|
1151
|
+
duration: string;
|
|
1152
|
+
/**
|
|
1153
|
+
* free_trial, pay_as_you_go (a price for a number of periods) or pay_up_front (one price for the whole offer; not on the web).
|
|
1154
|
+
*/
|
|
1155
|
+
mode: string;
|
|
1156
|
+
/**
|
|
1157
|
+
* How many periods pay_as_you_go lasts.
|
|
1158
|
+
*/
|
|
1159
|
+
periods?: number;
|
|
1160
|
+
/**
|
|
1161
|
+
* A paid offer's price, in the plan's currency's minor units; a free trial has none.
|
|
1162
|
+
*/
|
|
1163
|
+
price?: number | null;
|
|
1164
|
+
};
|
|
1165
|
+
/**
|
|
1166
|
+
* More of a limit, in the window it is in now.
|
|
1167
|
+
*/
|
|
1168
|
+
export type LimitGrantRequest = {
|
|
1169
|
+
/**
|
|
1170
|
+
* How many units more.
|
|
1171
|
+
*/
|
|
1172
|
+
amount: number;
|
|
1173
|
+
/**
|
|
1174
|
+
* Why: the record.
|
|
1175
|
+
*/
|
|
1176
|
+
reason: string;
|
|
1177
|
+
/**
|
|
1178
|
+
* Why, in kind.
|
|
1179
|
+
*/
|
|
1180
|
+
source: "promotion" | "support";
|
|
1181
|
+
};
|
|
1182
|
+
/**
|
|
1183
|
+
* Past the limit, a unit is spent in credits instead of refused.
|
|
1184
|
+
*/
|
|
1185
|
+
export type LimitOverflow = {
|
|
1186
|
+
/**
|
|
1187
|
+
* The credit spent (a key of the catalog's credits).
|
|
1188
|
+
*/
|
|
1189
|
+
currency: string;
|
|
1190
|
+
/**
|
|
1191
|
+
* How many credits a unit costs.
|
|
1192
|
+
*/
|
|
1193
|
+
per_unit: number;
|
|
1194
|
+
};
|
|
1195
|
+
/**
|
|
1196
|
+
* A customer's own limit: what each window allows them, in place of what their products give.
|
|
1197
|
+
*/
|
|
1198
|
+
export type LimitOverrideRequest = {
|
|
1199
|
+
/**
|
|
1200
|
+
* When it ends, in the future; absent: until it is cleared.
|
|
1201
|
+
*/
|
|
1202
|
+
expires_at?: string | null;
|
|
1203
|
+
/**
|
|
1204
|
+
* What a window allows them.
|
|
1205
|
+
*/
|
|
1206
|
+
max: number;
|
|
1207
|
+
/**
|
|
1208
|
+
* Why: the record.
|
|
1209
|
+
*/
|
|
1210
|
+
reason: string;
|
|
1211
|
+
};
|
|
1212
|
+
/**
|
|
1213
|
+
* A customer's use of a limit in its current window.
|
|
1214
|
+
*/
|
|
1215
|
+
export type LimitUse = {
|
|
1216
|
+
/**
|
|
1217
|
+
* The limit.
|
|
1218
|
+
*/
|
|
1219
|
+
limit: string;
|
|
1220
|
+
/**
|
|
1221
|
+
* What the window allows them: the largest any product they hold gives, or the free tier — their own limit instead when the project set one — and what was granted them in the window on top.
|
|
1222
|
+
*/
|
|
1223
|
+
max: number;
|
|
1224
|
+
/**
|
|
1225
|
+
* What is left.
|
|
1226
|
+
*/
|
|
1227
|
+
remaining: number;
|
|
1228
|
+
/**
|
|
1229
|
+
* What open holds keep.
|
|
1230
|
+
*/
|
|
1231
|
+
reserved: number;
|
|
1232
|
+
/**
|
|
1233
|
+
* When the window ends.
|
|
1234
|
+
*/
|
|
1235
|
+
resets_at: string;
|
|
1236
|
+
/**
|
|
1237
|
+
* What they used.
|
|
1238
|
+
*/
|
|
1239
|
+
used: number;
|
|
1240
|
+
};
|
|
1241
|
+
/**
|
|
1242
|
+
* A product's text in one language.
|
|
1243
|
+
*/
|
|
1244
|
+
export type Locale = {
|
|
1245
|
+
/**
|
|
1246
|
+
* What it gives, line by line (Google Play lists 4, of 40 characters at most).
|
|
1247
|
+
*/
|
|
1248
|
+
benefits?: string[];
|
|
1249
|
+
/**
|
|
1250
|
+
* Its description (the App Store shows 45 characters at most, Google Play 200).
|
|
1251
|
+
*/
|
|
1252
|
+
description?: string;
|
|
1253
|
+
/**
|
|
1254
|
+
* Its name (the App Store shows 2 to 30 characters, Google Play 55 at most).
|
|
1255
|
+
*/
|
|
1256
|
+
name?: string;
|
|
1257
|
+
};
|
|
1258
|
+
/**
|
|
1259
|
+
* Where a subscription is managed: where it was bought.
|
|
1260
|
+
*/
|
|
1261
|
+
export type Management = {
|
|
1262
|
+
/**
|
|
1263
|
+
* The store.
|
|
1264
|
+
*/
|
|
1265
|
+
store: "app_store" | "play_store" | "stripe";
|
|
1266
|
+
/**
|
|
1267
|
+
* The store's page for it; absent for Stripe, whose portal is opened on request (POST /purchases/stripe/portal).
|
|
1268
|
+
*/
|
|
1269
|
+
url?: string;
|
|
1270
|
+
};
|
|
1271
|
+
/**
|
|
1272
|
+
* A guest's proof that it may hand its purchases over.
|
|
1273
|
+
*/
|
|
1274
|
+
export type MergeGrant = {
|
|
1275
|
+
/**
|
|
1276
|
+
* When it stops working: 5 minutes, a sign-in.
|
|
1277
|
+
*/
|
|
1278
|
+
expires_at: string;
|
|
1279
|
+
/**
|
|
1280
|
+
* The proof: spent with the account's session.
|
|
1281
|
+
*/
|
|
1282
|
+
grant: string;
|
|
1283
|
+
};
|
|
1284
|
+
/**
|
|
1285
|
+
* A guest's proof, spent with the account's session.
|
|
1286
|
+
*/
|
|
1287
|
+
export type MergeRequest = {
|
|
1288
|
+
/**
|
|
1289
|
+
* The proof the guest asked for.
|
|
1290
|
+
*/
|
|
1291
|
+
grant: string;
|
|
1292
|
+
};
|
|
1293
|
+
/**
|
|
1294
|
+
* A product on sale.
|
|
1295
|
+
*/
|
|
1296
|
+
export type Offering = {
|
|
1297
|
+
channels: OfferingChannels;
|
|
1298
|
+
/**
|
|
1299
|
+
* What it gives.
|
|
1300
|
+
*/
|
|
1301
|
+
entitlements: string[];
|
|
1302
|
+
/**
|
|
1303
|
+
* A subscription's group.
|
|
1304
|
+
*/
|
|
1305
|
+
group?: string;
|
|
1306
|
+
/**
|
|
1307
|
+
* The catalog's product key.
|
|
1308
|
+
*/
|
|
1309
|
+
key: string;
|
|
1310
|
+
/**
|
|
1311
|
+
* A subscription's level in its group.
|
|
1312
|
+
*/
|
|
1313
|
+
tier?: number;
|
|
1314
|
+
/**
|
|
1315
|
+
* Its kind.
|
|
1316
|
+
*/
|
|
1317
|
+
type: "subscription" | "non_consumable" | "consumable" | "non_renewing";
|
|
1318
|
+
};
|
|
1319
|
+
/**
|
|
1320
|
+
* A product as one channel sells it.
|
|
1321
|
+
*/
|
|
1322
|
+
export type OfferingChannel = {
|
|
1323
|
+
/**
|
|
1324
|
+
* Its text in every language it has, as the channel shows it.
|
|
1325
|
+
*/
|
|
1326
|
+
locales: {
|
|
1327
|
+
[key: string]: Locale;
|
|
1328
|
+
};
|
|
1329
|
+
/**
|
|
1330
|
+
* Its plans, with the channel's price.
|
|
1331
|
+
*/
|
|
1332
|
+
plans: OfferingPlan[];
|
|
1333
|
+
};
|
|
1334
|
+
/**
|
|
1335
|
+
* The channels a product is sold on: only those.
|
|
1336
|
+
*/
|
|
1337
|
+
export type OfferingChannels = {
|
|
1338
|
+
android?: OfferingChannel;
|
|
1339
|
+
ios?: OfferingChannel;
|
|
1340
|
+
web?: OfferingChannel;
|
|
1341
|
+
};
|
|
1342
|
+
/**
|
|
1343
|
+
* A plan with the id the channel's store sells it by.
|
|
1344
|
+
*/
|
|
1345
|
+
export type OfferingPlan = {
|
|
1346
|
+
/**
|
|
1347
|
+
* Google Play's base plan, for a subscription.
|
|
1348
|
+
*/
|
|
1349
|
+
base_plan_id?: string;
|
|
1350
|
+
/**
|
|
1351
|
+
* A non-renewing product's duration.
|
|
1352
|
+
*/
|
|
1353
|
+
duration?: string;
|
|
1354
|
+
intro?: IntroOffer;
|
|
1355
|
+
/**
|
|
1356
|
+
* The catalog's plan key.
|
|
1357
|
+
*/
|
|
1358
|
+
key: string;
|
|
1359
|
+
/**
|
|
1360
|
+
* A subscription's period.
|
|
1361
|
+
*/
|
|
1362
|
+
period?: string;
|
|
1363
|
+
price: Price;
|
|
1364
|
+
/**
|
|
1365
|
+
* What the store sells it by: the App Store's product id, Google Play's product id, Stripe's price lookup key.
|
|
1366
|
+
*/
|
|
1367
|
+
store_id: string;
|
|
1368
|
+
};
|
|
1369
|
+
/**
|
|
1370
|
+
* The paywall's catalog: the products on sale.
|
|
1371
|
+
*/
|
|
1372
|
+
export type Offerings = {
|
|
1373
|
+
/**
|
|
1374
|
+
* The products, each on the channels it is sold on.
|
|
1375
|
+
*/
|
|
1376
|
+
products: Offering[];
|
|
1377
|
+
/**
|
|
1378
|
+
* The catalog's revision.
|
|
1379
|
+
*/
|
|
1380
|
+
revision: number;
|
|
1381
|
+
};
|
|
1382
|
+
/**
|
|
1383
|
+
* What a quota spend took in credits past its limit.
|
|
1384
|
+
*/
|
|
1385
|
+
export type OverflowReceipt = {
|
|
1386
|
+
/**
|
|
1387
|
+
* What is available of it after.
|
|
1388
|
+
*/
|
|
1389
|
+
available_after: number;
|
|
1390
|
+
/**
|
|
1391
|
+
* The credit's balance after.
|
|
1392
|
+
*/
|
|
1393
|
+
balance_after: number;
|
|
1394
|
+
/**
|
|
1395
|
+
* Credits taken.
|
|
1396
|
+
*/
|
|
1397
|
+
committed: number;
|
|
1398
|
+
/**
|
|
1399
|
+
* What it took, lot by lot.
|
|
1400
|
+
*/
|
|
1401
|
+
consumed: CreditConsumption[];
|
|
1402
|
+
/**
|
|
1403
|
+
* The credit.
|
|
1404
|
+
*/
|
|
1405
|
+
currency: string;
|
|
1406
|
+
/**
|
|
1407
|
+
* Credits held.
|
|
1408
|
+
*/
|
|
1409
|
+
held: number;
|
|
1410
|
+
/**
|
|
1411
|
+
* What a unit cost.
|
|
1412
|
+
*/
|
|
1413
|
+
per_unit: number;
|
|
1414
|
+
/**
|
|
1415
|
+
* Credits handed back.
|
|
1416
|
+
*/
|
|
1417
|
+
reversed: number;
|
|
1418
|
+
/**
|
|
1419
|
+
* How many units went past the limit.
|
|
1420
|
+
*/
|
|
1421
|
+
units: number;
|
|
1422
|
+
};
|
|
1423
|
+
/**
|
|
1424
|
+
* purchases.ownership.transferred: a purchase moved from one customer to another: the second restored the App Store purchases of the Apple ID it was made with.
|
|
1425
|
+
*/
|
|
1426
|
+
export type OwnershipTransferredEvent = {
|
|
1427
|
+
/**
|
|
1428
|
+
* The purchase's id in the ledger.
|
|
1429
|
+
*/
|
|
1430
|
+
chain_id: string;
|
|
1431
|
+
/**
|
|
1432
|
+
* Who had it.
|
|
1433
|
+
*/
|
|
1434
|
+
from_customer_id: string;
|
|
1435
|
+
/**
|
|
1436
|
+
* The catalog's product; empty when unmapped.
|
|
1437
|
+
*/
|
|
1438
|
+
product: string;
|
|
1439
|
+
/**
|
|
1440
|
+
* Where it was bought.
|
|
1441
|
+
*/
|
|
1442
|
+
store: "app_store" | "play_store" | "stripe";
|
|
1443
|
+
/**
|
|
1444
|
+
* Who has it now.
|
|
1445
|
+
*/
|
|
1446
|
+
to_customer_id: string;
|
|
1447
|
+
/**
|
|
1448
|
+
* How.
|
|
1449
|
+
*/
|
|
1450
|
+
via: "restore";
|
|
1451
|
+
};
|
|
1452
|
+
/**
|
|
1453
|
+
* How a product is paid for.
|
|
1454
|
+
*/
|
|
1455
|
+
export type Plan = {
|
|
1456
|
+
/**
|
|
1457
|
+
* A non-renewing product's duration, an ISO 8601 duration such as P1M.
|
|
1458
|
+
*/
|
|
1459
|
+
duration?: string;
|
|
1460
|
+
intro?: IntroOffer;
|
|
1461
|
+
/**
|
|
1462
|
+
* Its key: lowercase letters, digits and _, starting with a letter.
|
|
1463
|
+
*/
|
|
1464
|
+
key: string;
|
|
1465
|
+
/**
|
|
1466
|
+
* A subscription's billing period, an ISO 8601 duration: the App Store sells by P1W, P1M, P2M, P3M, P6M, P1Y; Google Play adds P4W, P4M, P8M; Stripe bills at most once a year.
|
|
1467
|
+
*/
|
|
1468
|
+
period?: string;
|
|
1469
|
+
price: Price;
|
|
1470
|
+
};
|
|
1471
|
+
/**
|
|
1472
|
+
* A confirmation, with the hash of the plan shown.
|
|
1473
|
+
*/
|
|
1474
|
+
export type PlanConfirmation = {
|
|
1475
|
+
/**
|
|
1476
|
+
* The Stripe part's hash; with no Stripe account connected, the App Store part's.
|
|
1477
|
+
*/
|
|
1478
|
+
hash: string;
|
|
1479
|
+
};
|
|
1480
|
+
/**
|
|
1481
|
+
* One write a store will get to come to the catalog.
|
|
1482
|
+
*/
|
|
1483
|
+
export type PlanStep = {
|
|
1484
|
+
/**
|
|
1485
|
+
* What it writes, as the store names it.
|
|
1486
|
+
*/
|
|
1487
|
+
fields?: {
|
|
1488
|
+
[key: string]: unknown;
|
|
1489
|
+
};
|
|
1490
|
+
/**
|
|
1491
|
+
* Whether it makes something the store never lets go of: a product id at Apple or Google stays taken even once deleted.
|
|
1492
|
+
*/
|
|
1493
|
+
irreversible: boolean;
|
|
1494
|
+
/**
|
|
1495
|
+
* What the person should know of it: how a price is resolved, why it waits.
|
|
1496
|
+
*/
|
|
1497
|
+
note?: string;
|
|
1498
|
+
/**
|
|
1499
|
+
* What it does: create_product, update_product, create_price (Stripe); create_subscription_group, create_subscription, create_in_app_purchase (the App Store); create_subscription, create_onetime_product (Google Play).
|
|
1500
|
+
*/
|
|
1501
|
+
op: string;
|
|
1502
|
+
/**
|
|
1503
|
+
* The catalog's plan.
|
|
1504
|
+
*/
|
|
1505
|
+
plan?: string;
|
|
1506
|
+
/**
|
|
1507
|
+
* The catalog's product.
|
|
1508
|
+
*/
|
|
1509
|
+
product: string;
|
|
1510
|
+
/**
|
|
1511
|
+
* The store's id of what it writes.
|
|
1512
|
+
*/
|
|
1513
|
+
store_id?: string;
|
|
1514
|
+
};
|
|
1515
|
+
/**
|
|
1516
|
+
* Where Stripe's portal sends the customer back.
|
|
1517
|
+
*/
|
|
1518
|
+
export type PortalRequest = {
|
|
1519
|
+
/**
|
|
1520
|
+
* A registered web app's origin, or a native app's own scheme.
|
|
1521
|
+
*/
|
|
1522
|
+
return_url: string;
|
|
1523
|
+
};
|
|
1524
|
+
/**
|
|
1525
|
+
* Stripe's customer portal, opened for the customer.
|
|
1526
|
+
*/
|
|
1527
|
+
export type PortalSession = {
|
|
1528
|
+
/**
|
|
1529
|
+
* Where to send the customer.
|
|
1530
|
+
*/
|
|
1531
|
+
url: string;
|
|
1532
|
+
};
|
|
1533
|
+
/**
|
|
1534
|
+
* The one price entered: each store prices the other currencies its own way (Apple's price points, Google's conversion, Stripe's), except those set by hand.
|
|
1535
|
+
*/
|
|
1536
|
+
export type Price = {
|
|
1537
|
+
/**
|
|
1538
|
+
* The amount in the currency's minor units (999 is 9.99).
|
|
1539
|
+
*/
|
|
1540
|
+
amount: number;
|
|
1541
|
+
/**
|
|
1542
|
+
* Its ISO 4217 currency (USD).
|
|
1543
|
+
*/
|
|
1544
|
+
currency: string;
|
|
1545
|
+
/**
|
|
1546
|
+
* Amounts set by hand in other currencies, in their minor units.
|
|
1547
|
+
*/
|
|
1548
|
+
overrides?: {
|
|
1549
|
+
[key: string]: number;
|
|
1550
|
+
};
|
|
1551
|
+
};
|
|
1552
|
+
/**
|
|
1553
|
+
* One thing sold, on every channel it names.
|
|
1554
|
+
*/
|
|
1555
|
+
export type Product = {
|
|
1556
|
+
/**
|
|
1557
|
+
* Where it is sold — ios (the App Store), android (Google Play), web (Stripe) — each with what is its own there; {} when it is sold there as it is.
|
|
1558
|
+
*/
|
|
1559
|
+
channels: {
|
|
1560
|
+
[key: string]: Channel;
|
|
1561
|
+
};
|
|
1562
|
+
credits?: ProductCredits;
|
|
1563
|
+
/**
|
|
1564
|
+
* The entitlements it gives (a consumable gives none).
|
|
1565
|
+
*/
|
|
1566
|
+
entitlements?: string[];
|
|
1567
|
+
/**
|
|
1568
|
+
* A subscription's group: the subscriptions a customer can move between (Apple's subscription group, the plans a Stripe customer can switch to). The App Store sells every subscription in one.
|
|
1569
|
+
*/
|
|
1570
|
+
group?: string;
|
|
1571
|
+
/**
|
|
1572
|
+
* Its key: lowercase letters, digits and _, starting with a letter, at most 40. The stores know a plan of it as <product>.<plan> (40 characters at most).
|
|
1573
|
+
*/
|
|
1574
|
+
key: string;
|
|
1575
|
+
/**
|
|
1576
|
+
* Its text by language: the base locale's at least.
|
|
1577
|
+
*/
|
|
1578
|
+
locales: {
|
|
1579
|
+
[key: string]: Locale;
|
|
1580
|
+
};
|
|
1581
|
+
/**
|
|
1582
|
+
* How it is paid for: a subscription's periods and prices; one price for anything else.
|
|
1583
|
+
*/
|
|
1584
|
+
plans: Plan[];
|
|
1585
|
+
/**
|
|
1586
|
+
* How much of each limit it gives.
|
|
1587
|
+
*/
|
|
1588
|
+
quota?: QuotaAllowance[];
|
|
1589
|
+
/**
|
|
1590
|
+
* A subscription's level in its group, 1 or more: higher is more.
|
|
1591
|
+
*/
|
|
1592
|
+
tier?: number;
|
|
1593
|
+
/**
|
|
1594
|
+
* Its kind: subscription (renews until canceled), non_consumable (bought once, kept), consumable (bought again and again: credits), non_renewing (a period bought once).
|
|
1595
|
+
*/
|
|
1596
|
+
type: string;
|
|
1597
|
+
};
|
|
1598
|
+
/**
|
|
1599
|
+
* The credits a product gives: per purchase for a consumable, per period for a subscription.
|
|
1600
|
+
*/
|
|
1601
|
+
export type ProductCredits = {
|
|
1602
|
+
/**
|
|
1603
|
+
* How many.
|
|
1604
|
+
*/
|
|
1605
|
+
amount: number;
|
|
1606
|
+
/**
|
|
1607
|
+
* The credit (a key of the catalog's credits).
|
|
1608
|
+
*/
|
|
1609
|
+
currency: string;
|
|
1610
|
+
/**
|
|
1611
|
+
* A subscription's: none (a period's credits end with the period) or all (they stay). Credits bought never end.
|
|
1612
|
+
*/
|
|
1613
|
+
rollover?: string;
|
|
1614
|
+
};
|
|
1615
|
+
/**
|
|
1616
|
+
* purchases.purchase.completed: a purchase new to the ledger: a subscription's start or a one-time product, in any store.
|
|
1617
|
+
*/
|
|
1618
|
+
export type PurchaseCompletedEvent = {
|
|
1619
|
+
/**
|
|
1620
|
+
* The purchase's id in the ledger.
|
|
1621
|
+
*/
|
|
1622
|
+
chain_id: string;
|
|
1623
|
+
/**
|
|
1624
|
+
* The customer.
|
|
1625
|
+
*/
|
|
1626
|
+
customer_id: string;
|
|
1627
|
+
/**
|
|
1628
|
+
* Whether it is a store's test purchase.
|
|
1629
|
+
*/
|
|
1630
|
+
is_sandbox: boolean;
|
|
1631
|
+
/**
|
|
1632
|
+
* Its plan; empty when unmapped.
|
|
1633
|
+
*/
|
|
1634
|
+
plan: string;
|
|
1635
|
+
/**
|
|
1636
|
+
* The catalog's product; empty when unmapped.
|
|
1637
|
+
*/
|
|
1638
|
+
product: string;
|
|
1639
|
+
/**
|
|
1640
|
+
* Where it was bought.
|
|
1641
|
+
*/
|
|
1642
|
+
store: "app_store" | "play_store" | "stripe";
|
|
1643
|
+
};
|
|
1644
|
+
/**
|
|
1645
|
+
* A one-time purchase the customer owns.
|
|
1646
|
+
*/
|
|
1647
|
+
export type PurchaseInfo = {
|
|
1648
|
+
/**
|
|
1649
|
+
* Its id in the ledger.
|
|
1650
|
+
*/
|
|
1651
|
+
id: string;
|
|
1652
|
+
/**
|
|
1653
|
+
* Whether it is a store's test purchase.
|
|
1654
|
+
*/
|
|
1655
|
+
is_sandbox: boolean;
|
|
1656
|
+
/**
|
|
1657
|
+
* The catalog's product; absent when the catalog does not map what the store sold.
|
|
1658
|
+
*/
|
|
1659
|
+
product?: string;
|
|
1660
|
+
/**
|
|
1661
|
+
* When it was bought.
|
|
1662
|
+
*/
|
|
1663
|
+
purchased_at: string;
|
|
1664
|
+
/**
|
|
1665
|
+
* Where it is: active, or revoked once refunded.
|
|
1666
|
+
*/
|
|
1667
|
+
state: "pending" | "trial" | "active" | "grace" | "billing_retry" | "paused" | "expired" | "revoked" | "replaced";
|
|
1668
|
+
/**
|
|
1669
|
+
* Where it was bought.
|
|
1670
|
+
*/
|
|
1671
|
+
store: "app_store" | "play_store" | "stripe";
|
|
1672
|
+
};
|
|
1673
|
+
/**
|
|
1674
|
+
* How much of a limit a product gives: the largest a customer holds counts.
|
|
1675
|
+
*/
|
|
1676
|
+
export type QuotaAllowance = {
|
|
1677
|
+
/**
|
|
1678
|
+
* The limit (a key of the catalog's limits).
|
|
1679
|
+
*/
|
|
1680
|
+
limit: string;
|
|
1681
|
+
/**
|
|
1682
|
+
* How much, in each window.
|
|
1683
|
+
*/
|
|
1684
|
+
max: number;
|
|
1685
|
+
};
|
|
1686
|
+
/**
|
|
1687
|
+
* purchases.quota.exhausted: a customer used all of a limit's window; told once a window.
|
|
1688
|
+
*/
|
|
1689
|
+
export type QuotaExhaustedEvent = {
|
|
1690
|
+
/**
|
|
1691
|
+
* The customer.
|
|
1692
|
+
*/
|
|
1693
|
+
customer_id: string;
|
|
1694
|
+
/**
|
|
1695
|
+
* The limit.
|
|
1696
|
+
*/
|
|
1697
|
+
limit: string;
|
|
1698
|
+
/**
|
|
1699
|
+
* What it allows them.
|
|
1700
|
+
*/
|
|
1701
|
+
max: number;
|
|
1702
|
+
/**
|
|
1703
|
+
* How much of it is used (at most 100).
|
|
1704
|
+
*/
|
|
1705
|
+
percent: number;
|
|
1706
|
+
/**
|
|
1707
|
+
* When the window ends.
|
|
1708
|
+
*/
|
|
1709
|
+
resets_at: string;
|
|
1710
|
+
/**
|
|
1711
|
+
* What the customer used in it.
|
|
1712
|
+
*/
|
|
1713
|
+
used: number;
|
|
1714
|
+
/**
|
|
1715
|
+
* The window.
|
|
1716
|
+
*/
|
|
1717
|
+
window_id: string;
|
|
1718
|
+
};
|
|
1719
|
+
/**
|
|
1720
|
+
* A spend or a hold of a quota.
|
|
1721
|
+
*/
|
|
1722
|
+
export type QuotaSpendRequest = {
|
|
1723
|
+
/**
|
|
1724
|
+
* How many credits or units.
|
|
1725
|
+
*/
|
|
1726
|
+
amount: number;
|
|
1727
|
+
/**
|
|
1728
|
+
* The limit spent (a key of the catalog's limits).
|
|
1729
|
+
*/
|
|
1730
|
+
limit: string;
|
|
1731
|
+
/**
|
|
1732
|
+
* The caller's own notes, kept with the spend (a JSON object, 2048 bytes at most).
|
|
1733
|
+
*/
|
|
1734
|
+
metadata?: {
|
|
1735
|
+
[key: string]: unknown;
|
|
1736
|
+
};
|
|
1737
|
+
/**
|
|
1738
|
+
* A hold's life: it runs out after it (600 unless said). A spend in one step holds nothing and refuses it (400 `ttl_for_holds`).
|
|
1739
|
+
*/
|
|
1740
|
+
ttl_seconds?: number;
|
|
1741
|
+
};
|
|
1742
|
+
/**
|
|
1743
|
+
* purchases.quota.threshold: a customer used 80% of a limit's window; told once a window.
|
|
1744
|
+
*/
|
|
1745
|
+
export type QuotaThresholdEvent = {
|
|
1746
|
+
/**
|
|
1747
|
+
* The customer.
|
|
1748
|
+
*/
|
|
1749
|
+
customer_id: string;
|
|
1750
|
+
/**
|
|
1751
|
+
* The limit.
|
|
1752
|
+
*/
|
|
1753
|
+
limit: string;
|
|
1754
|
+
/**
|
|
1755
|
+
* What it allows them.
|
|
1756
|
+
*/
|
|
1757
|
+
max: number;
|
|
1758
|
+
/**
|
|
1759
|
+
* How much of it is used (at most 100).
|
|
1760
|
+
*/
|
|
1761
|
+
percent: number;
|
|
1762
|
+
/**
|
|
1763
|
+
* When the window ends.
|
|
1764
|
+
*/
|
|
1765
|
+
resets_at: string;
|
|
1766
|
+
/**
|
|
1767
|
+
* What the customer used in it.
|
|
1768
|
+
*/
|
|
1769
|
+
used: number;
|
|
1770
|
+
/**
|
|
1771
|
+
* The window.
|
|
1772
|
+
*/
|
|
1773
|
+
window_id: string;
|
|
1774
|
+
};
|
|
1775
|
+
/**
|
|
1776
|
+
* The window a quota spend counts in.
|
|
1777
|
+
*/
|
|
1778
|
+
export type QuotaWindow = {
|
|
1779
|
+
/**
|
|
1780
|
+
* The window's id.
|
|
1781
|
+
*/
|
|
1782
|
+
id: string;
|
|
1783
|
+
/**
|
|
1784
|
+
* What it allows the customer, when the limit is known.
|
|
1785
|
+
*/
|
|
1786
|
+
max?: number | null;
|
|
1787
|
+
/**
|
|
1788
|
+
* What open holds keep of it.
|
|
1789
|
+
*/
|
|
1790
|
+
reserved: number;
|
|
1791
|
+
/**
|
|
1792
|
+
* When it ends.
|
|
1793
|
+
*/
|
|
1794
|
+
resets_at: string;
|
|
1795
|
+
/**
|
|
1796
|
+
* When it began.
|
|
1797
|
+
*/
|
|
1798
|
+
starts_at: string;
|
|
1799
|
+
/**
|
|
1800
|
+
* What the customer used in it.
|
|
1801
|
+
*/
|
|
1802
|
+
used: number;
|
|
1803
|
+
};
|
|
1804
|
+
/**
|
|
1805
|
+
* One check of the environment's readiness to sell in the App Store.
|
|
1806
|
+
*/
|
|
1807
|
+
export type ReadinessCheck = {
|
|
1808
|
+
/**
|
|
1809
|
+
* The palbase command (or Studio's place) that fixes it; empty when nothing is the developer's to do.
|
|
1810
|
+
*/
|
|
1811
|
+
fix: string;
|
|
1812
|
+
/**
|
|
1813
|
+
* What it checks; never changes: apple_key (an In-App Purchase key connected, and Apple takes it — asked now), apple_notifications_bound (the App Store reports to this environment), apple_test_notification (Apple's TEST notification arrived), catalog_confirmed (the newest revision of the catalog was confirmed for the stores), catalog_applied (App Store Connect took its App Store part), sandbox_access (what test purchases open; informational), xcode_certificate (whether Xcode's StoreKit Testing purchases are taken; informational — taken where the App Store's production notifications come, it says so, with the command that removes the certificate: the module cannot tell a production environment from a test one).
|
|
1814
|
+
*/
|
|
1815
|
+
id: "apple_key" | "apple_notifications_bound" | "apple_test_notification" | "catalog_confirmed" | "catalog_applied" | "sandbox_access" | "xcode_certificate";
|
|
1816
|
+
/**
|
|
1817
|
+
* What was found, in one sentence a developer understands.
|
|
1818
|
+
*/
|
|
1819
|
+
message: string;
|
|
1820
|
+
/**
|
|
1821
|
+
* Whether it holds. An informational check always does.
|
|
1822
|
+
*/
|
|
1823
|
+
ok: boolean;
|
|
1824
|
+
};
|
|
1825
|
+
/**
|
|
1826
|
+
* purchases.refund.changed: a store took a payment back (a refund, a chargeback, family sharing ended), or reversed that; the credits it gave are taken back, or given back.
|
|
1827
|
+
*/
|
|
1828
|
+
export type RefundChangedEvent = {
|
|
1829
|
+
/**
|
|
1830
|
+
* The purchase's id in the ledger.
|
|
1831
|
+
*/
|
|
1832
|
+
chain_id: string;
|
|
1833
|
+
/**
|
|
1834
|
+
* The customer.
|
|
1835
|
+
*/
|
|
1836
|
+
customer_id: string;
|
|
1837
|
+
/**
|
|
1838
|
+
* Why.
|
|
1839
|
+
*/
|
|
1840
|
+
kind: "refund" | "family" | "chargeback" | "other";
|
|
1841
|
+
/**
|
|
1842
|
+
* The taking back was reversed (a dispute won).
|
|
1843
|
+
*/
|
|
1844
|
+
reversed: boolean;
|
|
1845
|
+
/**
|
|
1846
|
+
* How much of the payment was taken back, in thousandths (1000: all of it).
|
|
1847
|
+
*/
|
|
1848
|
+
share_milli: number;
|
|
1849
|
+
/**
|
|
1850
|
+
* The payment taken back.
|
|
1851
|
+
*/
|
|
1852
|
+
transaction_id: string;
|
|
1853
|
+
};
|
|
1854
|
+
/**
|
|
1855
|
+
* The error envelope of a refused save, with every problem when the catalog breaks a rule (`invalid_catalog`).
|
|
1856
|
+
*/
|
|
1857
|
+
export type SaveCatalogError = {
|
|
1858
|
+
/**
|
|
1859
|
+
* Machine-readable error code (snake_case)
|
|
1860
|
+
*/
|
|
1861
|
+
error: string;
|
|
1862
|
+
/**
|
|
1863
|
+
* Human-readable explanation
|
|
1864
|
+
*/
|
|
1865
|
+
error_description: string;
|
|
1866
|
+
/**
|
|
1867
|
+
* Every problem, by path: with `invalid_catalog`, absent otherwise.
|
|
1868
|
+
*/
|
|
1869
|
+
problems?: CatalogProblem[];
|
|
1870
|
+
/**
|
|
1871
|
+
* Correlation ID for log/audit lookup
|
|
1872
|
+
*/
|
|
1873
|
+
request_id: string;
|
|
1874
|
+
/**
|
|
1875
|
+
* Seconds to wait before retrying; present on a refusal that ends with time.
|
|
1876
|
+
*/
|
|
1877
|
+
retry_after?: number;
|
|
1878
|
+
/**
|
|
1879
|
+
* HTTP status code (mirrors the response status)
|
|
1880
|
+
*/
|
|
1881
|
+
status: number;
|
|
1882
|
+
};
|
|
1883
|
+
/**
|
|
1884
|
+
* The project's choices for its customers' purchases; the defaults (everyone, cancel on delete, UTC) until it makes its own.
|
|
1885
|
+
*/
|
|
1886
|
+
export type Settings = {
|
|
1887
|
+
/**
|
|
1888
|
+
* Whether a deleted user's renewing web (Stripe) subscriptions stop renewing; they keep the period they paid. Only the customer can cancel what they bought in the App Store or Google Play.
|
|
1889
|
+
*/
|
|
1890
|
+
cancel_on_delete: boolean;
|
|
1891
|
+
/**
|
|
1892
|
+
* Whether a store's test purchases — Apple's sandbox (where App Review and TestFlight buy), Google Play's license testers, Stripe's test mode — open entitlements here: everyone, only the customers on sandbox_allowlist, or nobody.
|
|
1893
|
+
*/
|
|
1894
|
+
sandbox_access: "everyone" | "allowlist" | "nobody";
|
|
1895
|
+
/**
|
|
1896
|
+
* The customers whose test purchases open entitlements when sandbox_access is allowlist.
|
|
1897
|
+
*/
|
|
1898
|
+
sandbox_allowlist: string[];
|
|
1899
|
+
/**
|
|
1900
|
+
* Where the quotas' calendar windows (a day, a month) begin: an IANA name such as Europe/Istanbul.
|
|
1901
|
+
*/
|
|
1902
|
+
time_zone: string;
|
|
1903
|
+
/**
|
|
1904
|
+
* When the settings were last changed; absent while they are the defaults.
|
|
1905
|
+
*/
|
|
1906
|
+
updated_at?: string | null;
|
|
1907
|
+
};
|
|
1908
|
+
/**
|
|
1909
|
+
* A change of the settings: the fields given change, the others stay.
|
|
1910
|
+
*/
|
|
1911
|
+
export type SettingsUpdate = {
|
|
1912
|
+
/**
|
|
1913
|
+
* Whether a deleted user's renewing web (Stripe) subscriptions stop renewing; they keep the period they paid. Only the customer can cancel what they bought in the App Store or Google Play.
|
|
1914
|
+
*/
|
|
1915
|
+
cancel_on_delete?: boolean;
|
|
1916
|
+
/**
|
|
1917
|
+
* Whether a store's test purchases — Apple's sandbox (where App Review and TestFlight buy), Google Play's license testers, Stripe's test mode — open entitlements here: everyone, only the customers on sandbox_allowlist, or nobody.
|
|
1918
|
+
*/
|
|
1919
|
+
sandbox_access?: "everyone" | "allowlist" | "nobody";
|
|
1920
|
+
/**
|
|
1921
|
+
* The customers whose test purchases open entitlements when sandbox_access is allowlist.
|
|
1922
|
+
*/
|
|
1923
|
+
sandbox_allowlist?: string[];
|
|
1924
|
+
/**
|
|
1925
|
+
* Where the quotas' calendar windows (a day, a month) begin: an IANA name such as Europe/Istanbul.
|
|
1926
|
+
*/
|
|
1927
|
+
time_zone?: string;
|
|
1928
|
+
};
|
|
1929
|
+
/**
|
|
1930
|
+
* What a commit, an extension or a reversal takes; a release takes nothing.
|
|
1931
|
+
*/
|
|
1932
|
+
export type SpendAction = {
|
|
1933
|
+
/**
|
|
1934
|
+
* commit: how much of the hold is taken, at most what it holds — absent, all of it; 0, nothing (the hold is released). reverse: how much of what the spend took is handed back in all — absent or 0, everything.
|
|
1935
|
+
*/
|
|
1936
|
+
amount?: number;
|
|
1937
|
+
/**
|
|
1938
|
+
* extend: the hold runs out this long from now (600 unless said).
|
|
1939
|
+
*/
|
|
1940
|
+
ttl_seconds?: number;
|
|
1941
|
+
};
|
|
1942
|
+
/**
|
|
1943
|
+
* A spend or a hold, as it stands.
|
|
1944
|
+
*/
|
|
1945
|
+
export type SpendReceipt = {
|
|
1946
|
+
/**
|
|
1947
|
+
* A credit spend's: what is available after. A quota spend's: what of the window no hold keeps.
|
|
1948
|
+
*/
|
|
1949
|
+
available_after?: number | null;
|
|
1950
|
+
/**
|
|
1951
|
+
* A credit spend's: the balance after. A quota spend's: what is left of the window.
|
|
1952
|
+
*/
|
|
1953
|
+
balance_after?: number | null;
|
|
1954
|
+
/**
|
|
1955
|
+
* What it took.
|
|
1956
|
+
*/
|
|
1957
|
+
committed: number;
|
|
1958
|
+
/**
|
|
1959
|
+
* What a credit spend took, lot by lot.
|
|
1960
|
+
*/
|
|
1961
|
+
consumed: CreditConsumption[];
|
|
1962
|
+
/**
|
|
1963
|
+
* When it was made.
|
|
1964
|
+
*/
|
|
1965
|
+
created_at: string;
|
|
1966
|
+
/**
|
|
1967
|
+
* Its customer (the account, for a guest merged into one).
|
|
1968
|
+
*/
|
|
1969
|
+
customer: string;
|
|
1970
|
+
/**
|
|
1971
|
+
* When a hold runs out; absent once it is not held.
|
|
1972
|
+
*/
|
|
1973
|
+
expires_at?: string | null;
|
|
1974
|
+
/**
|
|
1975
|
+
* What it holds.
|
|
1976
|
+
*/
|
|
1977
|
+
held: number;
|
|
1978
|
+
/**
|
|
1979
|
+
* The spend's id.
|
|
1980
|
+
*/
|
|
1981
|
+
id: string;
|
|
1982
|
+
/**
|
|
1983
|
+
* The Idempotency-Key that named it.
|
|
1984
|
+
*/
|
|
1985
|
+
idempotency_key: string;
|
|
1986
|
+
/**
|
|
1987
|
+
* The credit or the limit.
|
|
1988
|
+
*/
|
|
1989
|
+
key: string;
|
|
1990
|
+
/**
|
|
1991
|
+
* Of credits or of a quota.
|
|
1992
|
+
*/
|
|
1993
|
+
kind: "credit" | "quota";
|
|
1994
|
+
/**
|
|
1995
|
+
* The caller's own notes, kept with the spend (a JSON object, 2048 bytes at most).
|
|
1996
|
+
*/
|
|
1997
|
+
metadata?: {
|
|
1998
|
+
[key: string]: unknown;
|
|
1999
|
+
};
|
|
2000
|
+
overflow?: OverflowReceipt;
|
|
2001
|
+
/**
|
|
2002
|
+
* What was handed back of it.
|
|
2003
|
+
*/
|
|
2004
|
+
reversed: number;
|
|
2005
|
+
/**
|
|
2006
|
+
* held (a hold, until committed, released or run out), committed, released, expired.
|
|
2007
|
+
*/
|
|
2008
|
+
status: "held" | "committed" | "released" | "expired";
|
|
2009
|
+
window?: QuotaWindow;
|
|
2010
|
+
};
|
|
2011
|
+
/**
|
|
2012
|
+
* A spend or a hold: of credits (`credits`) or of a quota (`limit`), exactly one of them (400 `credits_or_limit` otherwise).
|
|
2013
|
+
*/
|
|
2014
|
+
export type SpendRequest = CreditSpendRequest | QuotaSpendRequest;
|
|
2015
|
+
/**
|
|
2016
|
+
* purchases.store.changed: the project's Stripe account or In-App Purchase key was connected, disconnected, or (Stripe) checked and Stripe's answer changed (active, refused). Never the key.
|
|
2017
|
+
*/
|
|
2018
|
+
export type StoreChangedEvent = {
|
|
2019
|
+
/**
|
|
2020
|
+
* The Stripe account (Stripe's).
|
|
2021
|
+
*/
|
|
2022
|
+
account_id?: string;
|
|
2023
|
+
/**
|
|
2024
|
+
* The app the key is connected for (the App Store's).
|
|
2025
|
+
*/
|
|
2026
|
+
bundle_id?: string;
|
|
2027
|
+
/**
|
|
2028
|
+
* What happened.
|
|
2029
|
+
*/
|
|
2030
|
+
change: "connected" | "active" | "refused" | "disconnected";
|
|
2031
|
+
/**
|
|
2032
|
+
* Whether the key is a live one (Stripe's, connected).
|
|
2033
|
+
*/
|
|
2034
|
+
livemode?: boolean;
|
|
2035
|
+
/**
|
|
2036
|
+
* The store.
|
|
2037
|
+
*/
|
|
2038
|
+
store: "stripe" | "app_store";
|
|
2039
|
+
};
|
|
2040
|
+
/**
|
|
2041
|
+
* One store's part of a plan.
|
|
2042
|
+
*/
|
|
2043
|
+
export type StorePlan = {
|
|
2044
|
+
/**
|
|
2045
|
+
* The part's hash: a confirmation names the Stripe part's, or — with no Stripe account connected — the App Store part's.
|
|
2046
|
+
*/
|
|
2047
|
+
hash?: string;
|
|
2048
|
+
/**
|
|
2049
|
+
* What waits on what: the App Store and Google Play parts are written by the stores module once their accounts are connected.
|
|
2050
|
+
*/
|
|
2051
|
+
note?: string;
|
|
2052
|
+
/**
|
|
2053
|
+
* What it writes, in order.
|
|
2054
|
+
*/
|
|
2055
|
+
steps: PlanStep[];
|
|
2056
|
+
/**
|
|
2057
|
+
* The Stripe account's mode the part is for.
|
|
2058
|
+
*/
|
|
2059
|
+
store_env?: "sandbox" | "production";
|
|
2060
|
+
};
|
|
2061
|
+
/**
|
|
2062
|
+
* The project's Stripe account as the API shows it: never the key itself.
|
|
2063
|
+
*/
|
|
2064
|
+
export type StripeAccount = {
|
|
2065
|
+
/**
|
|
2066
|
+
* The Stripe account's id (acct_…).
|
|
2067
|
+
*/
|
|
2068
|
+
account_id?: string;
|
|
2069
|
+
/**
|
|
2070
|
+
* What the person has to do, when Stripe waits on them.
|
|
2071
|
+
*/
|
|
2072
|
+
action?: string;
|
|
2073
|
+
/**
|
|
2074
|
+
* When Stripe was last asked.
|
|
2075
|
+
*/
|
|
2076
|
+
checked_at?: string | null;
|
|
2077
|
+
/**
|
|
2078
|
+
* Whether the project has a Stripe account connected.
|
|
2079
|
+
*/
|
|
2080
|
+
connected: boolean;
|
|
2081
|
+
/**
|
|
2082
|
+
* When the key was connected.
|
|
2083
|
+
*/
|
|
2084
|
+
connected_at?: string | null;
|
|
2085
|
+
/**
|
|
2086
|
+
* Who asked for the grant the key was connected with (the API key that asked).
|
|
2087
|
+
*/
|
|
2088
|
+
connected_by?: string;
|
|
2089
|
+
/**
|
|
2090
|
+
* The key's last characters, to tell it apart.
|
|
2091
|
+
*/
|
|
2092
|
+
key_hint?: string;
|
|
2093
|
+
/**
|
|
2094
|
+
* Whether the key is a live one (rk_live_…): live payments, not Stripe's test mode.
|
|
2095
|
+
*/
|
|
2096
|
+
livemode: boolean;
|
|
2097
|
+
/**
|
|
2098
|
+
* What the key may read, as Stripe answered when it was last checked.
|
|
2099
|
+
*/
|
|
2100
|
+
permissions?: string[];
|
|
2101
|
+
/**
|
|
2102
|
+
* What Stripe last said of the key: active (accepts it), refused (no longer does: connect a new key).
|
|
2103
|
+
*/
|
|
2104
|
+
status?: "active" | "refused";
|
|
2105
|
+
/**
|
|
2106
|
+
* Where Stripe reports changes on the account: the endpoint the module made there (POST /purchases/webhooks/stripe).
|
|
2107
|
+
*/
|
|
2108
|
+
webhook_url?: string;
|
|
2109
|
+
};
|
|
2110
|
+
/**
|
|
2111
|
+
* A Stripe event, as Stripe signs and sends it: only its id, type and the id of the object it names are read; the object is read again from Stripe.
|
|
2112
|
+
*/
|
|
2113
|
+
export type StripeEvent = {
|
|
2114
|
+
[key: string]: unknown;
|
|
2115
|
+
};
|
|
2116
|
+
/**
|
|
2117
|
+
* A one-time grant to connect a Stripe key: the key goes from the person's browser (connect_url) or terminal (POST /purchases/connect with the grant) straight to the module.
|
|
2118
|
+
*/
|
|
2119
|
+
export type StripeGrant = {
|
|
2120
|
+
/**
|
|
2121
|
+
* The page that takes the key from a browser. The grant rides in the URL's fragment, which a browser never sends to a server.
|
|
2122
|
+
*/
|
|
2123
|
+
connect_url: string;
|
|
2124
|
+
/**
|
|
2125
|
+
* When the grant stops working.
|
|
2126
|
+
*/
|
|
2127
|
+
expires_at: string;
|
|
2128
|
+
/**
|
|
2129
|
+
* The grant: spent by the first key Stripe accepts, or after 30 minutes.
|
|
2130
|
+
*/
|
|
2131
|
+
grant: string;
|
|
2132
|
+
};
|
|
2133
|
+
/**
|
|
2134
|
+
* A price on the project's Stripe account.
|
|
2135
|
+
*/
|
|
2136
|
+
export type StripePrice = {
|
|
2137
|
+
/**
|
|
2138
|
+
* Whether it is on sale.
|
|
2139
|
+
*/
|
|
2140
|
+
active: boolean;
|
|
2141
|
+
/**
|
|
2142
|
+
* Its currency (lowercase, as Stripe writes it).
|
|
2143
|
+
*/
|
|
2144
|
+
currency: string;
|
|
2145
|
+
/**
|
|
2146
|
+
* Its amounts in other currencies.
|
|
2147
|
+
*/
|
|
2148
|
+
currency_options?: {
|
|
2149
|
+
[key: string]: number;
|
|
2150
|
+
};
|
|
2151
|
+
/**
|
|
2152
|
+
* Stripe's id.
|
|
2153
|
+
*/
|
|
2154
|
+
id: string;
|
|
2155
|
+
/**
|
|
2156
|
+
* A subscription's: day, week, month or year.
|
|
2157
|
+
*/
|
|
2158
|
+
interval?: string;
|
|
2159
|
+
/**
|
|
2160
|
+
* How many intervals a period is.
|
|
2161
|
+
*/
|
|
2162
|
+
interval_count?: number;
|
|
2163
|
+
/**
|
|
2164
|
+
* Its lookup key: palbase:<ref>:<product>.<plan>.
|
|
2165
|
+
*/
|
|
2166
|
+
lookup_key: string;
|
|
2167
|
+
/**
|
|
2168
|
+
* Its Stripe product.
|
|
2169
|
+
*/
|
|
2170
|
+
product: string;
|
|
2171
|
+
/**
|
|
2172
|
+
* Its amount, in minor units.
|
|
2173
|
+
*/
|
|
2174
|
+
unit_amount: number;
|
|
2175
|
+
};
|
|
2176
|
+
/**
|
|
2177
|
+
* A product on the project's Stripe account.
|
|
2178
|
+
*/
|
|
2179
|
+
export type StripeProduct = {
|
|
2180
|
+
/**
|
|
2181
|
+
* Whether it is on sale.
|
|
2182
|
+
*/
|
|
2183
|
+
active: boolean;
|
|
2184
|
+
/**
|
|
2185
|
+
* Its description.
|
|
2186
|
+
*/
|
|
2187
|
+
description: string;
|
|
2188
|
+
/**
|
|
2189
|
+
* Stripe's id.
|
|
2190
|
+
*/
|
|
2191
|
+
id: string;
|
|
2192
|
+
/**
|
|
2193
|
+
* Its name.
|
|
2194
|
+
*/
|
|
2195
|
+
name: string;
|
|
2196
|
+
};
|
|
2197
|
+
/**
|
|
2198
|
+
* purchases.subscription.changed: a customer's subscription started, renewed, stopped renewing (canceled) or renews again (uncanceled), could not be charged (billing_issue) or was again (recovered), ended (expired), or moved to another product (product_changed).
|
|
2199
|
+
*/
|
|
2200
|
+
export type SubscriptionChangedEvent = {
|
|
2201
|
+
/**
|
|
2202
|
+
* The subscription's id in the ledger.
|
|
2203
|
+
*/
|
|
2204
|
+
chain_id: string;
|
|
2205
|
+
/**
|
|
2206
|
+
* What happened.
|
|
2207
|
+
*/
|
|
2208
|
+
change: "started" | "renewed" | "canceled" | "uncanceled" | "billing_issue" | "recovered" | "expired" | "product_changed";
|
|
2209
|
+
/**
|
|
2210
|
+
* The customer.
|
|
2211
|
+
*/
|
|
2212
|
+
customer_id: string;
|
|
2213
|
+
/**
|
|
2214
|
+
* When access ends.
|
|
2215
|
+
*/
|
|
2216
|
+
expires_at: string | null;
|
|
2217
|
+
/**
|
|
2218
|
+
* Whether it is a store's test purchase.
|
|
2219
|
+
*/
|
|
2220
|
+
is_sandbox: boolean;
|
|
2221
|
+
/**
|
|
2222
|
+
* Its plan; empty when unmapped.
|
|
2223
|
+
*/
|
|
2224
|
+
plan: string;
|
|
2225
|
+
/**
|
|
2226
|
+
* The catalog's product; empty when unmapped.
|
|
2227
|
+
*/
|
|
2228
|
+
product: string;
|
|
2229
|
+
/**
|
|
2230
|
+
* Where it is now.
|
|
2231
|
+
*/
|
|
2232
|
+
state: "pending" | "trial" | "active" | "grace" | "billing_retry" | "paused" | "expired" | "revoked" | "replaced";
|
|
2233
|
+
/**
|
|
2234
|
+
* Where it was bought.
|
|
2235
|
+
*/
|
|
2236
|
+
store: "app_store" | "play_store" | "stripe";
|
|
2237
|
+
/**
|
|
2238
|
+
* Whether it renews.
|
|
2239
|
+
*/
|
|
2240
|
+
will_renew: boolean;
|
|
2241
|
+
};
|
|
2242
|
+
/**
|
|
2243
|
+
* A subscription (or a non-renewing period) the customer owns.
|
|
2244
|
+
*/
|
|
2245
|
+
export type SubscriptionInfo = {
|
|
2246
|
+
/**
|
|
2247
|
+
* Whether it gives access now.
|
|
2248
|
+
*/
|
|
2249
|
+
active: boolean;
|
|
2250
|
+
/**
|
|
2251
|
+
* When access ends.
|
|
2252
|
+
*/
|
|
2253
|
+
expires_at: string | null;
|
|
2254
|
+
/**
|
|
2255
|
+
* Its id in the ledger.
|
|
2256
|
+
*/
|
|
2257
|
+
id: string;
|
|
2258
|
+
/**
|
|
2259
|
+
* Whether it is a store's test purchase.
|
|
2260
|
+
*/
|
|
2261
|
+
is_sandbox: boolean;
|
|
2262
|
+
manage?: Management;
|
|
2263
|
+
/**
|
|
2264
|
+
* Its plan.
|
|
2265
|
+
*/
|
|
2266
|
+
plan?: string;
|
|
2267
|
+
/**
|
|
2268
|
+
* The catalog's product; absent when the catalog does not map what the store sold.
|
|
2269
|
+
*/
|
|
2270
|
+
product?: string;
|
|
2271
|
+
/**
|
|
2272
|
+
* Where it is: trial, active and grace give access; billing_retry, paused, expired, revoked (refunded) and replaced (another purchase took it over) do not.
|
|
2273
|
+
*/
|
|
2274
|
+
state: "pending" | "trial" | "active" | "grace" | "billing_retry" | "paused" | "expired" | "revoked" | "replaced";
|
|
2275
|
+
/**
|
|
2276
|
+
* Where it was bought.
|
|
2277
|
+
*/
|
|
2278
|
+
store: "app_store" | "play_store" | "stripe";
|
|
2279
|
+
/**
|
|
2280
|
+
* Whether it renews (false once canceled: it runs to expires_at).
|
|
2281
|
+
*/
|
|
2282
|
+
will_renew: boolean;
|
|
2283
|
+
};
|
|
2284
|
+
/**
|
|
2285
|
+
* The certificate the environment takes Xcode's StoreKit Testing purchases signed with: test purchases made on a developer's Mac with no App Store at all, the sandbox's. It is public: Xcode saves it for whoever asks (Editor › Save Public Certificate).
|
|
2286
|
+
*/
|
|
2287
|
+
export type XcodeCertificate = {
|
|
2288
|
+
/**
|
|
2289
|
+
* The SHA-256 of its DER, hex: what it is pinned by.
|
|
2290
|
+
*/
|
|
2291
|
+
fingerprint: string;
|
|
2292
|
+
/**
|
|
2293
|
+
* When it expires: Xcode makes a new one, to be set again.
|
|
2294
|
+
*/
|
|
2295
|
+
not_after: string;
|
|
2296
|
+
/**
|
|
2297
|
+
* When it was set.
|
|
2298
|
+
*/
|
|
2299
|
+
set_at: string;
|
|
2300
|
+
/**
|
|
2301
|
+
* Who set it (the API key that asked).
|
|
2302
|
+
*/
|
|
2303
|
+
set_by: string;
|
|
2304
|
+
/**
|
|
2305
|
+
* Its subject, as Xcode names it.
|
|
2306
|
+
*/
|
|
2307
|
+
subject: string;
|
|
2308
|
+
};
|
|
2309
|
+
/**
|
|
2310
|
+
* The certificate Xcode signs StoreKit Testing purchases with, as Editor › Save Public Certificate saves it.
|
|
2311
|
+
*/
|
|
2312
|
+
export type XcodeCertificateRequest = {
|
|
2313
|
+
/**
|
|
2314
|
+
* The saved .cer: PEM, or the base64 of its DER. A P-256 certificate that signed itself, not expired.
|
|
2315
|
+
*/
|
|
2316
|
+
certificate: string;
|
|
2317
|
+
};
|
|
2318
|
+
/** The events this module sends the project's webhooks (x-palbase-events), by type: each one's payload, the event's data. */
|
|
2319
|
+
export interface Events {
|
|
2320
|
+
/**
|
|
2321
|
+
* purchases.catalog.applied: a plan's Stripe part was written (applied) or failed; or the stores module answered of its App Store part.
|
|
2322
|
+
*/
|
|
2323
|
+
"purchases.catalog.applied": CatalogAppliedEvent;
|
|
2324
|
+
/**
|
|
2325
|
+
* purchases.catalog.changed: a new revision of the catalog was saved; plans of older ones went stale.
|
|
2326
|
+
*/
|
|
2327
|
+
"purchases.catalog.changed": CatalogChangedEvent;
|
|
2328
|
+
/**
|
|
2329
|
+
* purchases.credits.depleted: a customer's balance of a credit came down to nothing (or below).
|
|
2330
|
+
*/
|
|
2331
|
+
"purchases.credits.depleted": CreditsDepletedEvent;
|
|
2332
|
+
/**
|
|
2333
|
+
* purchases.credits.low: a customer's balance of a credit fell under its low mark (the catalog's low_at); told once, until it is back above.
|
|
2334
|
+
*/
|
|
2335
|
+
"purchases.credits.low": CreditsLowEvent;
|
|
2336
|
+
/**
|
|
2337
|
+
* purchases.customer.changed: what a customer has changed — a purchase, a renewal or its end, a refund, a grant, credits or quota used, a merge — and their revision rose. Realtime carries it to the customer's apps, which read GET /purchases/me again.
|
|
2338
|
+
*/
|
|
2339
|
+
"purchases.customer.changed": CustomerChangedEvent;
|
|
2340
|
+
/**
|
|
2341
|
+
* purchases.customer.erased: a deleted user's purchases record was erased (and the guests merged into them); their id is never a customer again.
|
|
2342
|
+
*/
|
|
2343
|
+
"purchases.customer.erased": CustomerErasedEvent;
|
|
2344
|
+
/**
|
|
2345
|
+
* purchases.customer.merged: a guest's purchases, grants, credits and quota use went to the account it signed in to; the guest's id points to the account from then on.
|
|
2346
|
+
*/
|
|
2347
|
+
"purchases.customer.merged": CustomerMergedEvent;
|
|
2348
|
+
/**
|
|
2349
|
+
* purchases.entitlement.changed: an entitlement of a customer turned on or off.
|
|
2350
|
+
*/
|
|
2351
|
+
"purchases.entitlement.changed": EntitlementChangedEvent;
|
|
2352
|
+
/**
|
|
2353
|
+
* purchases.ownership.transferred: a purchase moved from one customer to another: the second restored the App Store purchases of the Apple ID it was made with.
|
|
2354
|
+
*/
|
|
2355
|
+
"purchases.ownership.transferred": OwnershipTransferredEvent;
|
|
2356
|
+
/**
|
|
2357
|
+
* purchases.purchase.completed: a purchase new to the ledger: a subscription's start or a one-time product, in any store.
|
|
2358
|
+
*/
|
|
2359
|
+
"purchases.purchase.completed": PurchaseCompletedEvent;
|
|
2360
|
+
/**
|
|
2361
|
+
* purchases.quota.exhausted: a customer used all of a limit's window; told once a window.
|
|
2362
|
+
*/
|
|
2363
|
+
"purchases.quota.exhausted": QuotaExhaustedEvent;
|
|
2364
|
+
/**
|
|
2365
|
+
* purchases.quota.threshold: a customer used 80% of a limit's window; told once a window.
|
|
2366
|
+
*/
|
|
2367
|
+
"purchases.quota.threshold": QuotaThresholdEvent;
|
|
2368
|
+
/**
|
|
2369
|
+
* purchases.refund.changed: a store took a payment back (a refund, a chargeback, family sharing ended), or reversed that; the credits it gave are taken back, or given back.
|
|
2370
|
+
*/
|
|
2371
|
+
"purchases.refund.changed": RefundChangedEvent;
|
|
2372
|
+
/**
|
|
2373
|
+
* purchases.store.changed: the project's Stripe account or In-App Purchase key was connected, disconnected, or (Stripe) checked and Stripe's answer changed (active, refused). Never the key.
|
|
2374
|
+
*/
|
|
2375
|
+
"purchases.store.changed": StoreChangedEvent;
|
|
2376
|
+
/**
|
|
2377
|
+
* purchases.subscription.changed: a customer's subscription started, renewed, stopped renewing (canceled) or renews again (uncanceled), could not be charged (billing_issue) or was again (recovered), ended (expired), or moved to another product (product_changed).
|
|
2378
|
+
*/
|
|
2379
|
+
"purchases.subscription.changed": SubscriptionChangedEvent;
|
|
2380
|
+
}
|
|
2381
|
+
/** Palbase Purchases */
|
|
2382
|
+
export declare function client(t: Transport): {
|
|
2383
|
+
/**
|
|
2384
|
+
* Read the App Store connection
|
|
2385
|
+
*
|
|
2386
|
+
* The project's App Store connection: the app the In-App Purchase key is connected for, the key's ids, the app's Apple ID once known, and where the App Store reports — bound by the stores module, verified by Apple's TEST notification — never the key.
|
|
2387
|
+
*/
|
|
2388
|
+
getAppleAccount(input?: {
|
|
2389
|
+
signal?: AbortSignal;
|
|
2390
|
+
}): Promise<Reply<200, AppleAccount>>;
|
|
2391
|
+
/**
|
|
2392
|
+
* Disconnect the In-App Purchase key
|
|
2393
|
+
*
|
|
2394
|
+
* Forgets the key for good. Purchases already made stay in the ledger; the App Store's notifications and the apps' reports are refused from then on. With nothing connected, nothing changes. Emits `purchases.store.changed` (disconnected).
|
|
2395
|
+
*/
|
|
2396
|
+
disconnectApple(input?: {
|
|
2397
|
+
headers?: {
|
|
2398
|
+
"Idempotency-Key"?: string;
|
|
2399
|
+
}; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2400
|
+
signal?: AbortSignal;
|
|
2401
|
+
}): Promise<Reply<204, undefined>>;
|
|
2402
|
+
/**
|
|
2403
|
+
* The customer's App Store token
|
|
2404
|
+
*
|
|
2405
|
+
* The signed-in customer's appAccountToken for the connected app — with no key connected and an Xcode certificate set, for Xcode's StoreKit Testing — a guest's too: a random UUID made the first time it is asked for, the same afterwards. The app passes it to StoreKit's purchase; the App Store's notifications carry it back, so a purchase is the customer's before the app reports it, and nothing personal goes to Apple. A guest's goes with it when it merges into an account.
|
|
2406
|
+
*/
|
|
2407
|
+
getAppleAccountToken(input?: {
|
|
2408
|
+
signal?: AbortSignal;
|
|
2409
|
+
}): Promise<Reply<200, AppleAccountToken>>;
|
|
2410
|
+
/**
|
|
2411
|
+
* The In-App Purchase key's connect page
|
|
2412
|
+
*
|
|
2413
|
+
* The page an App Store connect link opens: it names the project the key goes to, lists the environment's iOS apps to connect it for, reads the grant from the link's fragment and posts the key with it. No credential: the grant is the authorization.
|
|
2414
|
+
*/
|
|
2415
|
+
getAppleConnectPage(input?: {
|
|
2416
|
+
signal?: AbortSignal;
|
|
2417
|
+
}): Promise<Reply<200, Response>>;
|
|
2418
|
+
/**
|
|
2419
|
+
* Hand over an In-App Purchase key with a grant
|
|
2420
|
+
*
|
|
2421
|
+
* Takes an In-App Purchase key with a grant, for one of the environment's registered iOS apps. Apple is asked, with a call that changes nothing (the app's notification history of the last hour, in the sandbox), whether it takes the key for the app; the key is kept sealed with the project's own key, the grant is spent, and the stores module is asked to set this environment's address (POST /purchases/webhooks/apple) as the app's notification address in App Store Connect. Each key tried counts against the grant — 10 at most. A key connected again replaces the one before. Emits `purchases.store.changed` (connected).
|
|
2422
|
+
*/
|
|
2423
|
+
connectAppleKey(input: {
|
|
2424
|
+
body: ConnectAppleKeyRequest; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2425
|
+
signal?: AbortSignal;
|
|
2426
|
+
}): Promise<Reply<200, AppleAccount>>;
|
|
2427
|
+
/**
|
|
2428
|
+
* Grant an In-App Purchase key's connection
|
|
2429
|
+
*
|
|
2430
|
+
* A one-time grant, good for 30 minutes, to hand the project an In-App Purchase key for one of its iOS apps. Whoever asks for it never holds the key: the person opens `connect_url` in a browser, or a terminal posts the key to POST /purchases/apple/connect with the grant. A project holds 10 open grants at most, Stripe's and the App Store's together (429 `too_many_grants`).
|
|
2431
|
+
*/
|
|
2432
|
+
createAppleGrant(input?: {
|
|
2433
|
+
headers?: {
|
|
2434
|
+
"Idempotency-Key"?: string;
|
|
2435
|
+
}; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2436
|
+
signal?: AbortSignal;
|
|
2437
|
+
}): Promise<Reply<201, AppleGrant>>;
|
|
2438
|
+
/**
|
|
2439
|
+
* Check readiness to sell in the App Store
|
|
2440
|
+
*
|
|
2441
|
+
* Whether the environment sells in the App Store, check by check, each with what was found in one sentence and the palbase command that fixes it: the In-App Purchase key (Apple is asked now whether it takes it — a call that changes nothing), the notification address bound and Apple's TEST notification arrived, the newest revision of the catalog confirmed and App Store Connect's answer of it (with each failing step's error), what test purchases open, and whether Xcode's StoreKit Testing purchases are taken. The checks' ids never change.
|
|
2442
|
+
*/
|
|
2443
|
+
getAppleReadiness(input?: {
|
|
2444
|
+
signal?: AbortSignal;
|
|
2445
|
+
}): Promise<Reply<200, AppleReadiness>>;
|
|
2446
|
+
/**
|
|
2447
|
+
* Report what StoreKit gave the app
|
|
2448
|
+
*
|
|
2449
|
+
* The signed-in customer's app — a guest's too: a guest buys in the app — reports the transactions StoreKit gave it: a purchase just made, Transaction.updates, or on a restore every one of currentEntitlements. Each is verified as the App Store signed it for the connected app, of the sandbox or production; with an Xcode certificate set, one Xcode signed with it on the developer's Mac (StoreKit Testing, environment Xcode, for one of the environment's iOS apps) is taken too — a test purchase, the sandbox's, gated by `sandbox_access` as the sandbox's are, of which nothing is asked of Apple — key connected or not. One that is neither refuses the report, naming it. A subscription's state is not taken from the device: it is read from Apple with the project's own key (Get All Subscription Statuses). Whose a purchase is: one nobody has becomes the customer's its appAccountToken names, or the reporter's; one another customer has stays theirs — unless `restore` from the device StoreKit signed its transaction for (`device_verification_id`), which moves it to the reporter (an account's is never taken by a guest's restore, and one purchase moves 3 times in 30 days at most). A restore that leaves a purchase where it was answers why once the rest of the report is applied (403 `restore_not_this_device`, 403 `restore_account_owned`, 409 `restore_limit`). Apple is asked of a subscription once however many copies of it the report holds. A guest that signed in to an account reports for the account: what StoreKit gave it is the account's, and the answer is the account's. Sent again, a report applies nothing twice. Answers what the customer has now, as GET /purchases/me. Emits what a purchase changed — `purchases.purchase.completed`, `purchases.subscription.changed`, `purchases.entitlement.changed`, `purchases.ownership.transferred` on a move, credits' events — and `purchases.customer.changed`.
|
|
2450
|
+
*/
|
|
2451
|
+
reportAppleTransactions(input: {
|
|
2452
|
+
body: AppleTransactionReport; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2453
|
+
signal?: AbortSignal;
|
|
2454
|
+
}): Promise<Reply<200, CustomerInfo>>;
|
|
2455
|
+
/**
|
|
2456
|
+
* Take Xcode's StoreKit Testing purchases
|
|
2457
|
+
*
|
|
2458
|
+
* Sets the certificate Xcode signs a developer's StoreKit Testing purchases with (Editor › Save Public Certificate): from then on, what the app reports signed with it — environment Xcode alone, for one of the environment's iOS apps — is taken as a test purchase, the sandbox's, gated by `sandbox_access`, with or without an In-App Purchase key connected; nothing of it is asked of Apple. It never speaks for the App Store's sandbox or production. Set it on a development environment: Studio and the CLI refuse to on production. Set again, it replaces the one before.
|
|
2459
|
+
*/
|
|
2460
|
+
setXcodeCertificate(input: {
|
|
2461
|
+
headers?: {
|
|
2462
|
+
"Idempotency-Key"?: string;
|
|
2463
|
+
};
|
|
2464
|
+
body: XcodeCertificateRequest; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2465
|
+
signal?: AbortSignal;
|
|
2466
|
+
}): Promise<Reply<200, XcodeCertificate>>;
|
|
2467
|
+
/**
|
|
2468
|
+
* Stop taking Xcode's purchases
|
|
2469
|
+
*
|
|
2470
|
+
* Forgets the Xcode certificate: what Xcode signs is refused from then on. Test purchases already taken stay in the ledger. With none set, nothing changes.
|
|
2471
|
+
*/
|
|
2472
|
+
clearXcodeCertificate(input?: {
|
|
2473
|
+
headers?: {
|
|
2474
|
+
"Idempotency-Key"?: string;
|
|
2475
|
+
}; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2476
|
+
signal?: AbortSignal;
|
|
2477
|
+
}): Promise<Reply<204, undefined>>;
|
|
2478
|
+
/**
|
|
2479
|
+
* Read the catalog
|
|
2480
|
+
*
|
|
2481
|
+
* The project's catalog: its newest revision (revision 0, empty, before the first save). The ETag is the revision: send it back as If-Match to save an edit.
|
|
2482
|
+
*/
|
|
2483
|
+
getCatalog(input?: {
|
|
2484
|
+
signal?: AbortSignal;
|
|
2485
|
+
}): Promise<Reply<200, CatalogDoc>>;
|
|
2486
|
+
/**
|
|
2487
|
+
* Save the catalog
|
|
2488
|
+
*
|
|
2489
|
+
* Saves a new revision of the whole catalog. It is checked first: a problem that is not a warning refuses it, with every problem listed (422 `invalid_catalog`); a warning (a channel's feature the product goes without) does not. If-Match names the revision it was edited from (0 for the first): of two people editing at once, the second is told (412 `catalog_changed`), not overwritten. Nothing is written to a store: a plan made from an older revision goes stale, and a new one is made (POST /purchases/catalog/plans). Emits `purchases.catalog.changed`.
|
|
2490
|
+
*/
|
|
2491
|
+
saveCatalog(input: {
|
|
2492
|
+
headers: {
|
|
2493
|
+
"If-Match": string; /** Makes the write safe to send again (at most 255 characters). A retry with the same key and the same request gets the first answer back, marked `Idempotent-Replayed: true`, and changes nothing; the same key with a different request is refused with 422, and while the first request still runs a retry gets 409 with Retry-After. Answers are kept for 24 hours. */
|
|
2494
|
+
"Idempotency-Key"?: string;
|
|
2495
|
+
};
|
|
2496
|
+
body: Catalog; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2497
|
+
signal?: AbortSignal;
|
|
2498
|
+
}): Promise<Reply<200, CatalogDoc>>;
|
|
2499
|
+
/**
|
|
2500
|
+
* Plan bringing the stores to the catalog
|
|
2501
|
+
*
|
|
2502
|
+
* Computes what writing the newest revision to the stores takes, store by store, before anything is written. The Stripe part is against what the project's Stripe account holds now: a product for each web product, a price for each plan — a price never changes at Stripe: a new amount is a new price, which takes the old one's lookup key, and customers on the old one keep paying it. The App Store and Google Play parts are as the stores module writes them once their accounts are connected; each creation there is permanent. A plan is confirmed with the Stripe part's hash (POST /purchases/catalog/plans/{plan_id}/confirm) — the Stripe part is null with no Stripe account connected, and the App Store part's hash confirms it then.
|
|
2503
|
+
*/
|
|
2504
|
+
planCatalog(input?: {
|
|
2505
|
+
headers?: {
|
|
2506
|
+
"Idempotency-Key"?: string;
|
|
2507
|
+
}; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2508
|
+
signal?: AbortSignal;
|
|
2509
|
+
}): Promise<Reply<201, CatalogPlan>>;
|
|
2510
|
+
/**
|
|
2511
|
+
* Read a plan
|
|
2512
|
+
*
|
|
2513
|
+
* A plan and where it is — planned, stale once the catalog changed, applying, applied, failed, declined — and, once written, what the Stripe account holds of the catalog (`result`) and what App Store Connect holds of its App Store part, step by step (`apple_result`, once the stores module answered).
|
|
2514
|
+
*/
|
|
2515
|
+
getCatalogPlan(input: {
|
|
2516
|
+
path: {
|
|
2517
|
+
plan_id: string;
|
|
2518
|
+
}; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2519
|
+
signal?: AbortSignal;
|
|
2520
|
+
}): Promise<Reply<200, CatalogPlan>>;
|
|
2521
|
+
/**
|
|
2522
|
+
* Confirm a plan
|
|
2523
|
+
*
|
|
2524
|
+
* Writes the plan: only with the hash of the plan shown (the Stripe part's; with no Stripe account connected, the App Store part's), and only while it is planned — a plan the catalog moved past is refused, not written as something nobody saw. The Stripe part is written now, each write with an idempotency key of its own at Stripe: answers the plan applied, with what the account holds now, or failed, with what Stripe said; a new plan picks up where a failed one stopped. The App Store part goes to the stores module, which writes it to App Store Connect with the project's Apple account and answers later (`apple_result`; a plan with no Stripe part stays applying until then); from the confirmation on, a purchase of what it sells maps to the catalog's product and plan. Emits `purchases.catalog.applied`.
|
|
2525
|
+
*/
|
|
2526
|
+
confirmCatalogPlan(input: {
|
|
2527
|
+
path: {
|
|
2528
|
+
plan_id: string;
|
|
2529
|
+
};
|
|
2530
|
+
headers?: {
|
|
2531
|
+
"Idempotency-Key"?: string;
|
|
2532
|
+
};
|
|
2533
|
+
body: PlanConfirmation; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2534
|
+
signal?: AbortSignal;
|
|
2535
|
+
}): Promise<Reply<200, CatalogPlan>>;
|
|
2536
|
+
/**
|
|
2537
|
+
* Decline a plan
|
|
2538
|
+
*
|
|
2539
|
+
* Declines a planned plan: nothing of it is written.
|
|
2540
|
+
*/
|
|
2541
|
+
declineCatalogPlan(input: {
|
|
2542
|
+
path: {
|
|
2543
|
+
plan_id: string;
|
|
2544
|
+
};
|
|
2545
|
+
headers?: {
|
|
2546
|
+
"Idempotency-Key"?: string;
|
|
2547
|
+
}; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2548
|
+
signal?: AbortSignal;
|
|
2549
|
+
}): Promise<Reply<200, CatalogPlan>>;
|
|
2550
|
+
/**
|
|
2551
|
+
* Check a catalog
|
|
2552
|
+
*
|
|
2553
|
+
* Checks a catalog without saving it: every problem, with its path and the store whose rule it breaks — Apple's 30-character names and six subscription periods, Google Play's limits, Stripe's yearly longest period, keys, prices, what a product gives. `valid` says whether it can be saved.
|
|
2554
|
+
*/
|
|
2555
|
+
validateCatalog(input: {
|
|
2556
|
+
headers?: {
|
|
2557
|
+
"Idempotency-Key"?: string;
|
|
2558
|
+
};
|
|
2559
|
+
body: Catalog; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2560
|
+
signal?: AbortSignal;
|
|
2561
|
+
}): Promise<Reply<200, CatalogValidation>>;
|
|
2562
|
+
/**
|
|
2563
|
+
* The connect page
|
|
2564
|
+
*
|
|
2565
|
+
* The page a connect link opens: it names the project the key goes to, reads the grant from the link's fragment and posts the restricted key with it. No credential: the grant is the authorization.
|
|
2566
|
+
*/
|
|
2567
|
+
getStripeConnectPage(input?: {
|
|
2568
|
+
signal?: AbortSignal;
|
|
2569
|
+
}): Promise<Reply<200, Response>>;
|
|
2570
|
+
/**
|
|
2571
|
+
* Hand over a Stripe key with a grant
|
|
2572
|
+
*
|
|
2573
|
+
* Takes a Stripe restricted key with a grant. Stripe is asked whose account it is and what the key may read; the module makes its webhook endpoint on the account at this environment's address, keeps the key and the endpoint's secret sealed with the project's own key, and spends the grant. Each key tried counts against the grant — 10 at most — and one Stripe refuses leaves the grant for the right one. A key connected again (rolled, or another of the same account) replaces the one before, and its endpoint. Emits `purchases.store.changed` (connected).
|
|
2574
|
+
*/
|
|
2575
|
+
connectStripeKey(input: {
|
|
2576
|
+
body: ConnectStripeKeyRequest; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2577
|
+
signal?: AbortSignal;
|
|
2578
|
+
}): Promise<Reply<200, StripeAccount>>;
|
|
2579
|
+
/**
|
|
2580
|
+
* Read a customer
|
|
2581
|
+
*
|
|
2582
|
+
* What a customer has, as GET /purchases/me answers it to them, for the project's backend. A guest merged into an account answers the account's. A user never seen here has nothing yet but the free tier of every quota; the read writes nothing — they become a customer when something is theirs.
|
|
2583
|
+
*/
|
|
2584
|
+
getCustomer(input: {
|
|
2585
|
+
path: {
|
|
2586
|
+
customer_id: string;
|
|
2587
|
+
}; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2588
|
+
signal?: AbortSignal;
|
|
2589
|
+
}): Promise<Reply<200, CustomerInfo>>;
|
|
2590
|
+
/**
|
|
2591
|
+
* Grant credits
|
|
2592
|
+
*
|
|
2593
|
+
* Gives a customer credits as a promotion or by support, saying why; they may expire. They pay what the customer owes first (a refund can leave a debt). The Idempotency-Key names the grant for good: sent again it answers the same lot and gives nothing more. A customer not seen before is made; a guest merged into an account gives the account. Emits the credits' events it crosses and `purchases.customer.changed`.
|
|
2594
|
+
*/
|
|
2595
|
+
grantCredits(input: {
|
|
2596
|
+
path: {
|
|
2597
|
+
customer_id: string;
|
|
2598
|
+
};
|
|
2599
|
+
headers: {
|
|
2600
|
+
"Idempotency-Key": string;
|
|
2601
|
+
};
|
|
2602
|
+
body: CreditGrantRequest; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2603
|
+
signal?: AbortSignal;
|
|
2604
|
+
}): Promise<Reply<201, CreditLot>>;
|
|
2605
|
+
/**
|
|
2606
|
+
* List credit movements
|
|
2607
|
+
*
|
|
2608
|
+
* A customer's credit movements, newest first, a page at a time: what they were given and by whom, what each spend took, what expired, what a refund took back and what they owe — support's answer to "where did my credits go". `credits` reads one credit; `cursor` goes on from a page's `next_cursor`. A user never seen here has none.
|
|
2609
|
+
*/
|
|
2610
|
+
listCreditEntries(input: {
|
|
2611
|
+
path: {
|
|
2612
|
+
customer_id: string;
|
|
2613
|
+
};
|
|
2614
|
+
query?: {
|
|
2615
|
+
credits?: string; /** The `next_cursor` of the page before. */
|
|
2616
|
+
cursor?: string; /** How many movements a page holds (50 unless said). */
|
|
2617
|
+
limit?: number;
|
|
2618
|
+
}; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2619
|
+
signal?: AbortSignal;
|
|
2620
|
+
}): Promise<Reply<200, CreditEntries>>;
|
|
2621
|
+
/**
|
|
2622
|
+
* Forgive a debt
|
|
2623
|
+
*
|
|
2624
|
+
* Takes what a customer owes in a credit off their debt — all of it, or `amount` of it — saying why: a refund took back credits they had already spent, and support lets it go. The next credits they get then count in full. Answers what it took off and the account it left; a customer who owes nothing is forgiven 0. A credit the catalog no longer defines can still be forgiven while the customer has an account in it. Emits the credits' events it crosses and `purchases.customer.changed`.
|
|
2625
|
+
*/
|
|
2626
|
+
forgiveCredits(input: {
|
|
2627
|
+
path: {
|
|
2628
|
+
customer_id: string;
|
|
2629
|
+
};
|
|
2630
|
+
headers: {
|
|
2631
|
+
"Idempotency-Key": string;
|
|
2632
|
+
};
|
|
2633
|
+
body: CreditForgiveRequest; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2634
|
+
signal?: AbortSignal;
|
|
2635
|
+
}): Promise<Reply<200, CreditForgiven>>;
|
|
2636
|
+
/**
|
|
2637
|
+
* Grant an entitlement
|
|
2638
|
+
*
|
|
2639
|
+
* Gives a customer one of the catalog's entitlements, for a while or for life — a promotion, a support case, a tester — saying why: the reason is the record. A customer not seen before is made; a guest merged into an account gives the account. Emits `purchases.entitlement.changed` when the entitlement turns on, and `purchases.customer.changed`.
|
|
2640
|
+
*/
|
|
2641
|
+
grantEntitlement(input: {
|
|
2642
|
+
path: {
|
|
2643
|
+
customer_id: string;
|
|
2644
|
+
};
|
|
2645
|
+
headers?: {
|
|
2646
|
+
"Idempotency-Key"?: string;
|
|
2647
|
+
};
|
|
2648
|
+
body: GrantRequest; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2649
|
+
signal?: AbortSignal;
|
|
2650
|
+
}): Promise<Reply<201, GrantInfo>>;
|
|
2651
|
+
/**
|
|
2652
|
+
* Revoke a granted entitlement
|
|
2653
|
+
*
|
|
2654
|
+
* Ends a grant now. What the customer bought is not touched: the entitlement stays on while another source gives it. Emits `purchases.entitlement.changed` when it turns off, and `purchases.customer.changed`.
|
|
2655
|
+
*/
|
|
2656
|
+
revokeGrant(input: {
|
|
2657
|
+
path: {
|
|
2658
|
+
customer_id: string; /** The grant's id. */
|
|
2659
|
+
grant_id: string;
|
|
2660
|
+
};
|
|
2661
|
+
headers?: {
|
|
2662
|
+
"Idempotency-Key"?: string;
|
|
2663
|
+
}; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2664
|
+
signal?: AbortSignal;
|
|
2665
|
+
}): Promise<Reply<204, undefined>>;
|
|
2666
|
+
/**
|
|
2667
|
+
* Hold credits or a quota for a job
|
|
2668
|
+
*
|
|
2669
|
+
* Keeps a customer's credits or quota units for a job that has yet to run: they stay the customer's, but no other spend can take them, until the hold is committed (the job ran), released (it did not) or runs out (`ttl_seconds`: 10 minutes unless said, 24 hours at most). A quota hold counts in the window it was made in, even when committed after it ends. Named for good by its Idempotency-Key, as a spend is.
|
|
2670
|
+
*/
|
|
2671
|
+
holdSpend(input: {
|
|
2672
|
+
path: {
|
|
2673
|
+
customer_id: string;
|
|
2674
|
+
};
|
|
2675
|
+
headers: {
|
|
2676
|
+
"Idempotency-Key": string;
|
|
2677
|
+
};
|
|
2678
|
+
body: SpendRequest; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2679
|
+
signal?: AbortSignal;
|
|
2680
|
+
}): Promise<Reply<200, SpendReceipt> | Reply<201, SpendReceipt>>;
|
|
2681
|
+
/**
|
|
2682
|
+
* Set a customer's own limit
|
|
2683
|
+
*
|
|
2684
|
+
* Sets what each window of a limit allows one customer — more for a customer support looks after, less for one who abuses it — in place of what their products give, until `expires_at` or until cleared, saying why. Use already counted in the window stays counted. A customer not seen before is made; a guest merged into an account sets the account's. Answers the limit as it stands for them now. Emits `purchases.customer.changed`.
|
|
2685
|
+
*/
|
|
2686
|
+
setCustomerLimit(input: {
|
|
2687
|
+
path: {
|
|
2688
|
+
customer_id: string; /** The limit (a key of the catalog's limits). */
|
|
2689
|
+
limit_key: string;
|
|
2690
|
+
};
|
|
2691
|
+
headers?: {
|
|
2692
|
+
"Idempotency-Key"?: string;
|
|
2693
|
+
};
|
|
2694
|
+
body: LimitOverrideRequest; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2695
|
+
signal?: AbortSignal;
|
|
2696
|
+
}): Promise<Reply<200, LimitUse>>;
|
|
2697
|
+
/**
|
|
2698
|
+
* Clear a customer's own limit
|
|
2699
|
+
*
|
|
2700
|
+
* Ends a customer's own limit: their products give it again. Clearing one that is not set changes nothing and emits nothing. Answers the limit as it stands for them now. Emits `purchases.customer.changed` when one was set.
|
|
2701
|
+
*/
|
|
2702
|
+
clearCustomerLimit(input: {
|
|
2703
|
+
path: {
|
|
2704
|
+
customer_id: string; /** The limit (a key of the catalog's limits). */
|
|
2705
|
+
limit_key: string;
|
|
2706
|
+
};
|
|
2707
|
+
headers?: {
|
|
2708
|
+
"Idempotency-Key"?: string;
|
|
2709
|
+
}; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2710
|
+
signal?: AbortSignal;
|
|
2711
|
+
}): Promise<Reply<200, LimitUse>>;
|
|
2712
|
+
/**
|
|
2713
|
+
* Grant more of a limit
|
|
2714
|
+
*
|
|
2715
|
+
* Gives a customer more units of a limit in the window it is in now — a promotion, a support case — saying why; the next window starts from what their products give again. The Idempotency-Key names the grant in the project for good: sent again — a minute or a month later — it gives nothing more (200, `Idempotent-Replayed`); with another customer, limit, amount or source it is refused (422 `idempotency_key_reused`). A customer not seen before is made; a guest merged into an account gives the account. Answers the limit as it stands for them now. Emits `purchases.customer.changed` when it gave.
|
|
2716
|
+
*/
|
|
2717
|
+
grantLimit(input: {
|
|
2718
|
+
path: {
|
|
2719
|
+
customer_id: string; /** The limit (a key of the catalog's limits). */
|
|
2720
|
+
limit_key: string;
|
|
2721
|
+
};
|
|
2722
|
+
headers: {
|
|
2723
|
+
"Idempotency-Key": string;
|
|
2724
|
+
};
|
|
2725
|
+
body: LimitGrantRequest; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2726
|
+
signal?: AbortSignal;
|
|
2727
|
+
}): Promise<Reply<200, LimitUse> | Reply<201, LimitUse>>;
|
|
2728
|
+
/**
|
|
2729
|
+
* Spend credits or a quota
|
|
2730
|
+
*
|
|
2731
|
+
* Takes a customer's credits (`credits`, a credit of the catalog) or units of a quota (`limit`) in one step. Credits go from the lots that expire first, bought ones last. A quota counts in its current window, up to the most any product the customer holds gives (the limit's free tier otherwise); past it, a limit with overflow takes credits instead, and one without is refused (409 `limit_reached`). The Idempotency-Key names the spend for good: sent again — a minute or a month later — it is the same spend (200, `Idempotent-Replayed`), never a second. A customer not seen before is made. Emits the credits' and quota's events when a balance crosses its low mark or runs out and when a window reaches 80% or 100%, and `purchases.customer.changed`.
|
|
2732
|
+
*/
|
|
2733
|
+
spend(input: {
|
|
2734
|
+
path: {
|
|
2735
|
+
customer_id: string;
|
|
2736
|
+
};
|
|
2737
|
+
headers: {
|
|
2738
|
+
"Idempotency-Key": string;
|
|
2739
|
+
};
|
|
2740
|
+
body: SpendRequest; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2741
|
+
signal?: AbortSignal;
|
|
2742
|
+
}): Promise<Reply<200, SpendReceipt> | Reply<201, SpendReceipt>>;
|
|
2743
|
+
/**
|
|
2744
|
+
* Commit a hold
|
|
2745
|
+
*
|
|
2746
|
+
* Takes `amount` of what a hold keeps — all of it when no amount is given — and frees the rest; an `amount` of 0 takes nothing and releases the hold. Committed again with the same amount, it answers the same. A hold that ran out is refused (409 `hold_expired`): what it kept is free again. Emits the credits' and quota's events it crosses, and `purchases.customer.changed`.
|
|
2747
|
+
*/
|
|
2748
|
+
commitSpend(input: {
|
|
2749
|
+
path: {
|
|
2750
|
+
customer_id: string; /** The spend's id. */
|
|
2751
|
+
spend_id: string;
|
|
2752
|
+
};
|
|
2753
|
+
headers?: {
|
|
2754
|
+
"Idempotency-Key"?: string;
|
|
2755
|
+
};
|
|
2756
|
+
body?: SpendAction; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2757
|
+
signal?: AbortSignal;
|
|
2758
|
+
}): Promise<Reply<200, SpendReceipt>>;
|
|
2759
|
+
/**
|
|
2760
|
+
* Give a hold more time
|
|
2761
|
+
*
|
|
2762
|
+
* The hold runs out `ttl_seconds` from now: 10 minutes unless said, 24 hours at most.
|
|
2763
|
+
*/
|
|
2764
|
+
extendHold(input: {
|
|
2765
|
+
path: {
|
|
2766
|
+
customer_id: string; /** The spend's id. */
|
|
2767
|
+
spend_id: string;
|
|
2768
|
+
};
|
|
2769
|
+
headers?: {
|
|
2770
|
+
"Idempotency-Key"?: string;
|
|
2771
|
+
};
|
|
2772
|
+
body?: SpendAction; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2773
|
+
signal?: AbortSignal;
|
|
2774
|
+
}): Promise<Reply<200, SpendReceipt>>;
|
|
2775
|
+
/**
|
|
2776
|
+
* Release a hold
|
|
2777
|
+
*
|
|
2778
|
+
* Frees all a hold keeps: the job did not run. A hold that ran out answers itself, expired.
|
|
2779
|
+
*/
|
|
2780
|
+
releaseSpend(input: {
|
|
2781
|
+
path: {
|
|
2782
|
+
customer_id: string; /** The spend's id. */
|
|
2783
|
+
spend_id: string;
|
|
2784
|
+
};
|
|
2785
|
+
headers?: {
|
|
2786
|
+
"Idempotency-Key"?: string;
|
|
2787
|
+
};
|
|
2788
|
+
body?: SpendAction; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2789
|
+
signal?: AbortSignal;
|
|
2790
|
+
}): Promise<Reply<200, SpendReceipt>>;
|
|
2791
|
+
/**
|
|
2792
|
+
* Reverse a spend
|
|
2793
|
+
*
|
|
2794
|
+
* Hands back what a committed spend took — the job failed. `amount` is how much is handed back in all (absent or 0: everything), so asked again it is the same reversal. Credits go back to the lots they came from (what fell on a lot that expired since is gone with it, what fell on one refunded since pays the debt); a quota's units go back to the window while it is open; credits a quota spend took past its limit come back first. Emits `purchases.customer.changed`.
|
|
2795
|
+
*/
|
|
2796
|
+
reverseSpend(input: {
|
|
2797
|
+
path: {
|
|
2798
|
+
customer_id: string; /** The spend's id. */
|
|
2799
|
+
spend_id: string;
|
|
2800
|
+
};
|
|
2801
|
+
headers?: {
|
|
2802
|
+
"Idempotency-Key"?: string;
|
|
2803
|
+
};
|
|
2804
|
+
body?: SpendAction; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2805
|
+
signal?: AbortSignal;
|
|
2806
|
+
}): Promise<Reply<200, SpendReceipt>>;
|
|
2807
|
+
/**
|
|
2808
|
+
* Read what the customer has
|
|
2809
|
+
*
|
|
2810
|
+
* Everything the signed-in customer has, whatever store they bought in: each entitlement (whether it is on, until when, whether it renews, which store gives it, every source), their subscriptions and one-time purchases, credit balances and quota use. The first read makes the user a customer. A store's test purchases open entitlements as the project's sandbox setting says. The ETag is the customer's revision. The customer's apps join the realtime channel `purchases:<project ref>:<user id>` — theirs alone, read-only — whose state and `changed` broadcast carry `{"revision": N}`: a revision above the one read means reading GET /purchases/me again.
|
|
2811
|
+
*/
|
|
2812
|
+
getMyCustomerInfo(input?: {
|
|
2813
|
+
signal?: AbortSignal;
|
|
2814
|
+
}): Promise<Reply<200, CustomerInfo>>;
|
|
2815
|
+
/**
|
|
2816
|
+
* Move a guest's purchases to the account
|
|
2817
|
+
*
|
|
2818
|
+
* With the account's session and the guest's proof: everything the guest bought — subscriptions and purchases, grants, credits and quota use — goes to the account in one step, and the guest's id points to the account from then on (its session reads 409 `customer_merged`). It cannot be undone; asked again, it is the same merge. Answers what the account has now. Emits `purchases.customer.merged`, the credits' events and `purchases.customer.changed` for both.
|
|
2819
|
+
*/
|
|
2820
|
+
mergeGuest(input: {
|
|
2821
|
+
body: MergeRequest; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2822
|
+
signal?: AbortSignal;
|
|
2823
|
+
}): Promise<Reply<200, CustomerInfo>>;
|
|
2824
|
+
/**
|
|
2825
|
+
* Prove a guest's purchases
|
|
2826
|
+
*
|
|
2827
|
+
* Asked with a guest's session before it signs in to an existing account: a proof, good for 5 minutes, that whoever signs in held the guest. Spent with the account's session (POST /purchases/me/merge), it moves what the guest bought to the account. A guest that signs up instead keeps its id, and its purchases with it: nothing to merge.
|
|
2828
|
+
*/
|
|
2829
|
+
createMergeGrant(input?: {
|
|
2830
|
+
signal?: AbortSignal;
|
|
2831
|
+
}): Promise<Reply<201, MergeGrant>>;
|
|
2832
|
+
/**
|
|
2833
|
+
* Read the offerings
|
|
2834
|
+
*
|
|
2835
|
+
* The catalog's products as an app shows them on a paywall: each channel's own text in every language and its price, and the id the channel's store sells each plan by — the App Store's product id, Google Play's product id (and base plan, for a subscription), Stripe's price lookup key. Nobody's purchases: any of the project's keys reads it, the publishable one included.
|
|
2836
|
+
*/
|
|
2837
|
+
getOfferings(input?: {
|
|
2838
|
+
query?: {
|
|
2839
|
+
channel?: "ios" | "android" | "web";
|
|
2840
|
+
}; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2841
|
+
signal?: AbortSignal;
|
|
2842
|
+
}): Promise<Reply<200, Offerings>>;
|
|
2843
|
+
/**
|
|
2844
|
+
* Read the settings
|
|
2845
|
+
*
|
|
2846
|
+
* The project's choices for its customers' purchases; the defaults until it makes its own.
|
|
2847
|
+
*/
|
|
2848
|
+
getSettings(input?: {
|
|
2849
|
+
signal?: AbortSignal;
|
|
2850
|
+
}): Promise<Reply<200, Settings>>;
|
|
2851
|
+
/**
|
|
2852
|
+
* Change the settings
|
|
2853
|
+
*
|
|
2854
|
+
* Changes the settings given — whether a store's test purchases open entitlements, ending a deleted user's renewing web subscriptions, where the quotas' calendar windows begin — and leaves the others as they are.
|
|
2855
|
+
*/
|
|
2856
|
+
updateSettings(input: {
|
|
2857
|
+
headers?: {
|
|
2858
|
+
"Idempotency-Key"?: string;
|
|
2859
|
+
};
|
|
2860
|
+
body: SettingsUpdate; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2861
|
+
signal?: AbortSignal;
|
|
2862
|
+
}): Promise<Reply<200, Settings>>;
|
|
2863
|
+
/**
|
|
2864
|
+
* Read the Stripe account
|
|
2865
|
+
*
|
|
2866
|
+
* The project's Stripe account as connected — its id, its mode, the key's last characters, what Stripe last said of the key and what it may read, the webhook endpoint's address — never the key.
|
|
2867
|
+
*/
|
|
2868
|
+
getStripeAccount(input?: {
|
|
2869
|
+
signal?: AbortSignal;
|
|
2870
|
+
}): Promise<Reply<200, StripeAccount>>;
|
|
2871
|
+
/**
|
|
2872
|
+
* Disconnect the Stripe account
|
|
2873
|
+
*
|
|
2874
|
+
* Forgets the key for good and removes the webhook endpoint the module made on the account. Purchases already made stay in the ledger; nothing new is sold on the web. With nothing connected, nothing changes. Emits `purchases.store.changed` (disconnected).
|
|
2875
|
+
*/
|
|
2876
|
+
disconnectStripe(input?: {
|
|
2877
|
+
headers?: {
|
|
2878
|
+
"Idempotency-Key"?: string;
|
|
2879
|
+
}; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2880
|
+
signal?: AbortSignal;
|
|
2881
|
+
}): Promise<Reply<204, undefined>>;
|
|
2882
|
+
/**
|
|
2883
|
+
* Check the Stripe account again
|
|
2884
|
+
*
|
|
2885
|
+
* Asks Stripe again what the connected key may read: after its permissions were edited, or once Stripe stopped accepting it (status `refused`: connect a new key). Emits `purchases.store.changed` when the status changed.
|
|
2886
|
+
*/
|
|
2887
|
+
checkStripeAccount(input?: {
|
|
2888
|
+
headers?: {
|
|
2889
|
+
"Idempotency-Key"?: string;
|
|
2890
|
+
}; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2891
|
+
signal?: AbortSignal;
|
|
2892
|
+
}): Promise<Reply<200, StripeAccount>>;
|
|
2893
|
+
/**
|
|
2894
|
+
* Buy on the web
|
|
2895
|
+
*
|
|
2896
|
+
* Opens a Stripe Checkout session for the signed-in customer to buy one of the catalog's products sold on the web, at the plan's price on the project's Stripe account: send the customer to `url`. Stripe sends them back to `success_url` or `cancel_url`, which go back to one of the project's registered apps — a web app's origin, or a native app's own scheme — and nowhere else. What is bought on the web is the account's on every device: a guest is refused. A customer who already has the product, or a subscription of its group, from any store is refused (409 `already_entitled`, naming the store to manage it in): nothing is charged twice. Credits can always be bought again. A free trial is given once per customer, across every channel. The purchase is the customer's once Stripe reports it (POST /purchases/webhooks/stripe).
|
|
2897
|
+
*/
|
|
2898
|
+
createCheckout(input: {
|
|
2899
|
+
body: CheckoutRequest; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2900
|
+
signal?: AbortSignal;
|
|
2901
|
+
}): Promise<Reply<201, Checkout>>;
|
|
2902
|
+
/**
|
|
2903
|
+
* Grant a key's connection
|
|
2904
|
+
*
|
|
2905
|
+
* A one-time grant, good for 30 minutes, to hand the project a Stripe restricted key. Whoever asks for it never holds the key: the person opens `connect_url` in a browser, or a terminal posts the key to POST /purchases/connect with the grant. A project holds 10 open grants at most (429 `too_many_grants`).
|
|
2906
|
+
*/
|
|
2907
|
+
createStripeGrant(input?: {
|
|
2908
|
+
headers?: {
|
|
2909
|
+
"Idempotency-Key"?: string;
|
|
2910
|
+
}; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2911
|
+
signal?: AbortSignal;
|
|
2912
|
+
}): Promise<Reply<201, StripeGrant>>;
|
|
2913
|
+
/**
|
|
2914
|
+
* Manage what was bought on the web
|
|
2915
|
+
*
|
|
2916
|
+
* Opens Stripe's customer portal for the signed-in customer, where they change, cancel or renew what they bought on the web and how they pay: send them to `url`. `return_url` goes back to one of the project's registered apps.
|
|
2917
|
+
*/
|
|
2918
|
+
createPortalSession(input: {
|
|
2919
|
+
body: PortalRequest; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2920
|
+
signal?: AbortSignal;
|
|
2921
|
+
}): Promise<Reply<201, PortalSession>>;
|
|
2922
|
+
/**
|
|
2923
|
+
* Take the App Store's notification
|
|
2924
|
+
*
|
|
2925
|
+
* Where the App Store reports the connected app's purchases (App Store Server Notifications V2), sandbox's and production's alike — no key. The signed payload is verified: Apple's root, the app's bundle, the sandbox or production (production naming the app's Apple ID); a developer's machine's (Xcode, LocalTesting) is refused. Each notification is kept once, sealed, by its notificationUUID: one sent again is answered and not applied twice. A TEST notification proves the address (`notifications.verified_at`). One about a purchase applies what Apple signed of it — the transaction, the renewal info, the subscription's status — to the ledger: the newest by Apple's time is the state, an older one is recorded and not applied. A purchase new to the ledger is the customer's its appAccountToken names, else nobody's until the app reports it. Apple hears 200 once that is written; anything else, and it sends the notification again.
|
|
2926
|
+
*/
|
|
2927
|
+
receiveAppleNotification(input: {
|
|
2928
|
+
body: AppleNotification; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2929
|
+
signal?: AbortSignal;
|
|
2930
|
+
}): Promise<Reply<200, undefined>>;
|
|
2931
|
+
/**
|
|
2932
|
+
* Take Stripe's notification
|
|
2933
|
+
*
|
|
2934
|
+
* Where Stripe reports a change on the project's account: the endpoint the module made there when the key was connected, with the endpoint's signature (Stripe-Signature) — no key. What a delivery says is not believed: the object it names is read again from Stripe and what Stripe holds now is applied to the ledger — a Checkout completed, a subscription started, renewed, canceled or ended, a one-time payment, a refund or a dispute. Each delivery is kept once, sealed, by its event id: one sent again is answered and not applied twice. An event of the account's other mode, or of an object another integration made, is answered and ignored. Stripe hears 2xx only once the change is written; any other answer makes it send the delivery again. Emits what changed: `purchases.purchase.completed`, `purchases.subscription.changed`, `purchases.refund.changed`, `purchases.entitlement.changed`, the credits' events and `purchases.customer.changed`.
|
|
2935
|
+
*/
|
|
2936
|
+
receiveStripeEvent(input: {
|
|
2937
|
+
headers: {
|
|
2938
|
+
"Stripe-Signature": string;
|
|
2939
|
+
};
|
|
2940
|
+
body: StripeEvent; /** Stops the call: the request in flight, a wait before a retry, a proof-of-work being solved. */
|
|
2941
|
+
signal?: AbortSignal;
|
|
2942
|
+
}): Promise<Reply<200, undefined>>;
|
|
2943
|
+
};
|
|
2944
|
+
export type Client = ReturnType<typeof client>;
|