@genesis-tech/genesispay-seller 0.8.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.
Files changed (60) hide show
  1. package/CHANGELOG.md +330 -0
  2. package/LICENSE +21 -0
  3. package/README.md +429 -0
  4. package/dist/client.d.ts +275 -0
  5. package/dist/client.d.ts.map +1 -0
  6. package/dist/client.js +541 -0
  7. package/dist/client.js.map +1 -0
  8. package/dist/customers.d.ts +41 -0
  9. package/dist/customers.d.ts.map +1 -0
  10. package/dist/customers.js +76 -0
  11. package/dist/customers.js.map +1 -0
  12. package/dist/errors.d.ts +63 -0
  13. package/dist/errors.d.ts.map +1 -0
  14. package/dist/errors.js +162 -0
  15. package/dist/errors.js.map +1 -0
  16. package/dist/index.d.ts +13 -0
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/index.js +13 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/invoices.d.ts +80 -0
  21. package/dist/invoices.d.ts.map +1 -0
  22. package/dist/invoices.js +133 -0
  23. package/dist/invoices.js.map +1 -0
  24. package/dist/mandate-gate.d.ts +49 -0
  25. package/dist/mandate-gate.d.ts.map +1 -0
  26. package/dist/mandate-gate.js +109 -0
  27. package/dist/mandate-gate.js.map +1 -0
  28. package/dist/mandates.d.ts +172 -0
  29. package/dist/mandates.d.ts.map +1 -0
  30. package/dist/mandates.js +213 -0
  31. package/dist/mandates.js.map +1 -0
  32. package/dist/networks.d.ts +10 -0
  33. package/dist/networks.d.ts.map +1 -0
  34. package/dist/networks.js +22 -0
  35. package/dist/networks.js.map +1 -0
  36. package/dist/payment-gate.d.ts +67 -0
  37. package/dist/payment-gate.d.ts.map +1 -0
  38. package/dist/payment-gate.js +106 -0
  39. package/dist/payment-gate.js.map +1 -0
  40. package/dist/peerpay-settlement.d.ts +27 -0
  41. package/dist/peerpay-settlement.d.ts.map +1 -0
  42. package/dist/peerpay-settlement.js +100 -0
  43. package/dist/peerpay-settlement.js.map +1 -0
  44. package/dist/plans.d.ts +68 -0
  45. package/dist/plans.d.ts.map +1 -0
  46. package/dist/plans.js +127 -0
  47. package/dist/plans.js.map +1 -0
  48. package/dist/resource.d.ts +47 -0
  49. package/dist/resource.d.ts.map +1 -0
  50. package/dist/resource.js +71 -0
  51. package/dist/resource.js.map +1 -0
  52. package/dist/usdc-amount.d.ts +7 -0
  53. package/dist/usdc-amount.d.ts.map +1 -0
  54. package/dist/usdc-amount.js +21 -0
  55. package/dist/usdc-amount.js.map +1 -0
  56. package/dist/webhooks.d.ts +277 -0
  57. package/dist/webhooks.d.ts.map +1 -0
  58. package/dist/webhooks.js +223 -0
  59. package/dist/webhooks.js.map +1 -0
  60. package/package.json +58 -0
package/dist/client.js ADDED
@@ -0,0 +1,541 @@
1
+ import { PeerPayConfigError, PeerPayNetworkSafetyError, PeerPayValidationError, throwForErrorResponse, } from "./errors.js";
2
+ import { createMandatesResource } from "./mandates.js";
3
+ import { createCustomersResource } from "./customers.js";
4
+ import { createInvoicesResource } from "./invoices.js";
5
+ import { createPaymentGate } from "./payment-gate.js";
6
+ import { DEFAULT_FACILITATOR_BASE_URL, peerPaySettlement } from "./peerpay-settlement.js";
7
+ import { createPlansResource } from "./plans.js";
8
+ import { resolvePaymentGateNetwork } from "./networks.js";
9
+ import { parseUsdcAmountToMinorUnits } from "./usdc-amount.js";
10
+ import { asRecord, oneOf, optionalMetadata, optionalString, requiredString, toCount, } from "./resource.js";
11
+ import { constructEvent } from "./webhooks.js";
12
+ // The error classes live in ./errors.js (shared with every future resource:
13
+ // plans, mandates, …) and are re-exported here so existing imports from
14
+ // "./client.js" keep working.
15
+ export { PeerPayConfigError, PeerPayNetworkSafetyError, PeerPayNotFoundError, PeerPayRateLimitError, PeerPayValidationError, } from "./errors.js";
16
+ /**
17
+ * Production GenesisPay facilitator — the `peerpay-app` Railway production
18
+ * environment (see docs/runbooks/DEPLOY_RAILWAY.md). Hardcoded so a live key always
19
+ * resolves to our facilitator with zero config, mirroring the test default.
20
+ * Update this if/when GenesisPay moves to a custom production domain (D4).
21
+ */
22
+ const PRODUCTION_FACILITATOR_BASE_URL = "https://peerpay-app-production.up.railway.app";
23
+ // Both facilitator URLs are hardcoded so the key mode alone routes to the right
24
+ // GenesisPay facilitator; an explicit `baseUrl` still overrides for self-host/staging.
25
+ const MODE_BASE_URLS = {
26
+ test: DEFAULT_FACILITATOR_BASE_URL,
27
+ live: PRODUCTION_FACILITATOR_BASE_URL,
28
+ };
29
+ /**
30
+ * Appended to the error when simulate-payment answers 403. The server sends its
31
+ * own explanation in the body, but a proxy or a future rewording must not be
32
+ * able to leave the caller without the one fact that matters: the endpoint is
33
+ * gated on the *key mode*, and a live key can never mint a payment.
34
+ */
35
+ const SIMULATE_PAYMENT_LIVE_KEY_HINT = "simulate-payment only works with a test-mode key (pp_sk_test_…); this client " +
36
+ "is using a live key, and live keys can only record real, on-chain payments.";
37
+ /** Which networks each key mode may legitimately resolve to (fail-closed guard). */
38
+ const MODE_NETWORKS = {
39
+ test: ["base-sepolia"],
40
+ live: ["base"],
41
+ };
42
+ function parseKeyMode(apiKey) {
43
+ if (apiKey.startsWith("pp_sk_live_"))
44
+ return "live";
45
+ if (apiKey.startsWith("pp_sk_"))
46
+ return "test"; // pp_sk_test_… and legacy pp_sk_<32>
47
+ throw new PeerPayConfigError("apiKey must be a GenesisPay seller key (pp_sk_test_… or pp_sk_live_…).");
48
+ }
49
+ function normalizeBaseUrl(url) {
50
+ const trimmed = url.trim().replace(/\/+$/, "");
51
+ const isHttps = /^https:\/\//i.test(trimmed);
52
+ const isLocalHttp = /^http:\/\/(localhost|127\.0\.0\.1)(:\d+)?(\/|$)/i.test(trimmed);
53
+ if (!isHttps && !isLocalHttp) {
54
+ throw new PeerPayConfigError(`baseUrl must be https (got "${trimmed}").`);
55
+ }
56
+ return trimmed;
57
+ }
58
+ function describeError(error) {
59
+ return error instanceof Error ? error.message : "unknown error";
60
+ }
61
+ function toCheckoutLink(raw) {
62
+ // A backend older than 0.6.0 reports the amount only as `amountUsdc`; both
63
+ // names carry the same decimal string, so either one populates both fields.
64
+ // The check is on "is a string" rather than "is present", so a backend that
65
+ // sends a non-string `amount` still falls back instead of yielding "".
66
+ const amount = requiredString(typeof raw.amount === "string" ? raw.amount : raw.amountUsdc);
67
+ return {
68
+ publicId: requiredString(raw.publicId),
69
+ payUrl: requiredString(raw.payUrl),
70
+ amount,
71
+ amountUsdc: amount,
72
+ asset: oneOf(raw.asset, ["USDC", "EURC"], "USDC"),
73
+ title: requiredString(raw.title),
74
+ metadata: optionalMetadata(raw.metadata),
75
+ clientReferenceId: optionalString(raw.clientReferenceId),
76
+ returnUrl: optionalString(raw.returnUrl),
77
+ cancelUrl: optionalString(raw.cancelUrl),
78
+ };
79
+ }
80
+ /**
81
+ * Maps the server's attempt views tolerantly: a non-array (or missing) field
82
+ * yields `[]`, an entry without a usable `id` is skipped, and every optional
83
+ * field degrades to `null` — an older backend must never crash a poll loop.
84
+ */
85
+ function toCheckoutAttempts(value) {
86
+ if (!Array.isArray(value))
87
+ return [];
88
+ const attempts = [];
89
+ for (const entry of value) {
90
+ if (!entry || typeof entry !== "object" || Array.isArray(entry))
91
+ continue;
92
+ const raw = entry;
93
+ const id = optionalString(raw.id);
94
+ if (!id)
95
+ continue;
96
+ attempts.push({
97
+ id,
98
+ status: oneOf(raw.status, ["pending", "submitted", "confirmed", "failed", "expired"], "pending"),
99
+ txHash: optionalString(raw.txHash),
100
+ payerWallet: optionalString(raw.payerWallet),
101
+ createdAt: requiredString(raw.createdAt),
102
+ confirmedAt: optionalString(raw.confirmedAt),
103
+ failureReason: optionalString(raw.failureReason),
104
+ // Only an explicit `true` counts: an older backend omits the field, and
105
+ // treating anything truthy as simulated would misreport real payments.
106
+ simulated: raw.simulated === true,
107
+ });
108
+ }
109
+ return attempts;
110
+ }
111
+ function toCheckoutSession(raw) {
112
+ const confirmedPaymentCount = toCount(raw.confirmedPaymentCount);
113
+ return {
114
+ ...toCheckoutLink(raw),
115
+ description: optionalString(raw.description),
116
+ linkType: oneOf(raw.linkType, ["single", "reusable"], "single"),
117
+ status: oneOf(raw.status, ["active", "paid", "archived"], "active"),
118
+ destinationWallet: requiredString(raw.destinationWallet),
119
+ chainId: toCount(raw.chainId),
120
+ // Derived, not sent by the server: one confirmed payment is what "paid" means
121
+ // for a reusable link too, so this is the single value worth polling on.
122
+ paid: confirmedPaymentCount > 0,
123
+ confirmedPaymentCount,
124
+ createdAt: requiredString(raw.createdAt),
125
+ attempts: toCheckoutAttempts(raw.attempts),
126
+ };
127
+ }
128
+ /**
129
+ * Folds the `{ attempt, link }` that `simulate-payment` answers with into one
130
+ * `CheckoutSession`, so the method returns the same shape `checkout.retrieve`
131
+ * does and a test can go straight from simulating to asserting on `paid`.
132
+ *
133
+ * The merge is necessary rather than cosmetic: the simulate route's `link` is a
134
+ * plain link view with no `confirmedPaymentCount` and no `attempts`, so mapping
135
+ * it alone would report `paid: false` immediately after minting a confirmed
136
+ * payment. The confirmed attempt from the same response supplies both.
137
+ *
138
+ * The one thing this cannot know is how many payments a *reusable* link already
139
+ * had — `confirmedPaymentCount` is therefore "at least this one". Call
140
+ * `checkout.retrieve()` when the exact total matters.
141
+ */
142
+ function toSimulatedCheckoutSession(rawLink, attempt) {
143
+ const session = toCheckoutSession(rawLink);
144
+ const confirmedPaymentCount = session.confirmedPaymentCount + (attempt.status === "confirmed" ? 1 : 0);
145
+ return {
146
+ ...session,
147
+ attempts: [attempt, ...session.attempts],
148
+ confirmedPaymentCount,
149
+ paid: confirmedPaymentCount > 0,
150
+ };
151
+ }
152
+ /**
153
+ * True when two amount strings mean different money. `"5.0"` and `"5.00"` are
154
+ * the same amount, so the comparison is on parsed minor units rather than on
155
+ * the strings; a value the parser cannot read at all is left to the server,
156
+ * which owns amount validation, and only counts as a disagreement if the other
157
+ * string differs from it.
158
+ */
159
+ function amountsDisagree(a, b) {
160
+ if (a.trim() === b.trim())
161
+ return false;
162
+ const minorUnits = (value) => {
163
+ try {
164
+ return parseUsdcAmountToMinorUnits(value);
165
+ }
166
+ catch {
167
+ return null;
168
+ }
169
+ };
170
+ const [minorA, minorB] = [minorUnits(a), minorUnits(b)];
171
+ if (minorA === null || minorB === null)
172
+ return true;
173
+ return minorA !== minorB;
174
+ }
175
+ /**
176
+ * Resolves `amount` and the deprecated `amountUsdc` down to the single value
177
+ * the request carries.
178
+ *
179
+ * The disagreement case is stopped here rather than on the server because a
180
+ * create call that names two different prices has no correct interpretation —
181
+ * picking either one would create a link for money the caller did not mean.
182
+ */
183
+ function resolveCheckoutAmount(input) {
184
+ const { amount, amountUsdc } = input;
185
+ if (amount === undefined && amountUsdc === undefined) {
186
+ throw new PeerPayValidationError('checkout.create requires `amount` — a decimal string in the link\'s asset, e.g. "5.00".', [{ path: "amount", message: "amount is required." }]);
187
+ }
188
+ if (amount !== undefined && amountUsdc !== undefined && amountsDisagree(amount, amountUsdc)) {
189
+ throw new PeerPayValidationError(`checkout.create got amount "${amount}" and the deprecated amountUsdc "${amountUsdc}", ` +
190
+ "which are different amounts. Set `amount` on its own.", [{ path: "amount", message: "amount and amountUsdc disagree." }]);
191
+ }
192
+ return (amount ?? amountUsdc);
193
+ }
194
+ function paymentNotConfiguredResponse() {
195
+ return Response.json({
196
+ error: "payment_not_configured",
197
+ message: "This seller has no receiving wallet configured yet.",
198
+ }, { status: 402 });
199
+ }
200
+ function paymentUnavailableResponse(error) {
201
+ return Response.json({
202
+ error: "payment_unavailable",
203
+ message: `Payment is temporarily unavailable: ${describeError(error)}`,
204
+ }, { status: 503 });
205
+ }
206
+ export class PeerPay {
207
+ mode;
208
+ baseUrl;
209
+ checkout;
210
+ /** Subscription plans and their hosted `checkoutUrl` — see ./plans.ts. */
211
+ plans;
212
+ /** Reusable billing contacts for one-off invoices. */
213
+ customers;
214
+ /** Draft, finalize, deliver, and collect one-off invoices. */
215
+ invoices;
216
+ /**
217
+ * Payment mandates: bounded, revocable spending approvals a payer signs once.
218
+ *
219
+ * There is no `mandates.activate` on purpose — activation carries the
220
+ * *payer's* signature, is authorized by their wallet rather than by this API
221
+ * key, and therefore belongs in the payer-facing frontend. See the module
222
+ * comment in ./mandates.ts.
223
+ */
224
+ mandates;
225
+ /**
226
+ * Webhook signature verification. Also exported as the free function
227
+ * `constructEvent` — a webhook route rarely has a client instance in scope,
228
+ * and verification needs the endpoint secret rather than the API key.
229
+ */
230
+ webhooks;
231
+ apiKey;
232
+ fetchFn;
233
+ configTtlMs;
234
+ expectedPayTo;
235
+ cache;
236
+ inflight;
237
+ /**
238
+ * The single authenticated-JSON seam every resource goes through. Bound as a
239
+ * field so it can be handed to `./plans.ts` / `./mandates.ts` without leaking
240
+ * the key, the base URL or `fetch` into them.
241
+ */
242
+ request = (options) => this.performRequest(options);
243
+ constructor(options) {
244
+ const apiKey = options.apiKey?.trim();
245
+ if (!apiKey) {
246
+ throw new PeerPayConfigError("apiKey (pp_sk_test_… / pp_sk_live_…) is required.");
247
+ }
248
+ this.apiKey = apiKey;
249
+ this.mode = parseKeyMode(apiKey);
250
+ const chosen = options.baseUrl?.trim() || MODE_BASE_URLS[this.mode];
251
+ if (!chosen) {
252
+ throw new PeerPayConfigError(`GenesisPay ${this.mode} base URL is not configured yet; pass baseUrl explicitly.`);
253
+ }
254
+ this.baseUrl = normalizeBaseUrl(chosen);
255
+ this.fetchFn = options.fetchFn ?? fetch;
256
+ this.configTtlMs = options.configTtlMs ?? 300_000;
257
+ this.expectedPayTo = options.expectedPayTo?.trim().toLowerCase() || undefined;
258
+ this.checkout = {
259
+ create: (input) => this.createCheckout(input),
260
+ retrieve: (publicId) => this.retrieveCheckout(publicId),
261
+ simulatePayment: (publicId, opts) => this.simulateCheckoutPayment(publicId, opts),
262
+ };
263
+ // Both resources get the same bound request seam, so their errors go
264
+ // through the one shared mapper in ./errors.ts like checkout's do.
265
+ this.plans = createPlansResource(this.request, (wallet, what) => this.assertPinnedDestination(wallet, what));
266
+ this.mandates = createMandatesResource(this.request);
267
+ this.customers = createCustomersResource(this.request);
268
+ this.invoices = createInvoicesResource(this.request);
269
+ // Stateless pass-through: verification depends only on the endpoint secret,
270
+ // never on this client's key, mode or base URL.
271
+ this.webhooks = {
272
+ constructEvent: (rawBody, signatureHeader, secret, opts) => constructEvent(rawBody, signatureHeader, secret, opts),
273
+ };
274
+ }
275
+ /**
276
+ * Resolve (and cache) the seller config from the key. Single-flight so a
277
+ * cold-start burst shares one request; failures are never cached (the memo is
278
+ * cleared on rejection so the next call retries).
279
+ */
280
+ async retrieveSeller(opts) {
281
+ const now = Date.now();
282
+ if (!opts?.forceRefresh && this.cache && now - this.cache.fetchedAt < this.configTtlMs) {
283
+ return this.cache.config;
284
+ }
285
+ if (!this.inflight) {
286
+ this.inflight = this.fetchSeller()
287
+ .then((config) => {
288
+ this.cache = { config, fetchedAt: Date.now() };
289
+ return config;
290
+ })
291
+ .finally(() => {
292
+ this.inflight = undefined;
293
+ });
294
+ }
295
+ return this.inflight;
296
+ }
297
+ gate(config) {
298
+ const innerGates = new Map();
299
+ const defaultSettle = peerPaySettlement({
300
+ facilitatorBaseUrl: this.baseUrl,
301
+ apiKey: this.apiKey,
302
+ fetchFn: this.fetchFn,
303
+ });
304
+ const buildInner = (seller) => {
305
+ // Key by (payTo, chainId): a wallet rotation after TTL builds a fresh gate,
306
+ // while any single gate stays internally consistent across challenge/replay.
307
+ const cacheKey = `${seller.payTo}:${seller.network.chainId}`;
308
+ let inner = innerGates.get(cacheKey);
309
+ if (!inner) {
310
+ inner = createPaymentGate({
311
+ amountUsdc: config.amountUsdc,
312
+ payTo: seller.payTo,
313
+ network: seller.network.networkName,
314
+ description: config.description,
315
+ resource: config.resource,
316
+ mimeType: config.mimeType,
317
+ maxTimeoutSeconds: config.maxTimeoutSeconds,
318
+ });
319
+ innerGates.set(cacheKey, inner);
320
+ }
321
+ return inner;
322
+ };
323
+ const resolveSeller = () => this.retrieveSeller();
324
+ return {
325
+ prime: async () => {
326
+ await resolveSeller();
327
+ },
328
+ wrap: (handler, opts) => {
329
+ const verifySettlement = opts?.verifySettlement ?? defaultSettle;
330
+ return async (request, ...args) => {
331
+ let seller;
332
+ try {
333
+ seller = await resolveSeller();
334
+ }
335
+ catch (error) {
336
+ // Fail closed: never run the paid handler when config can't be resolved.
337
+ return paymentUnavailableResponse(error);
338
+ }
339
+ if (!seller.hasPayTo || !seller.payTo) {
340
+ return paymentNotConfiguredResponse();
341
+ }
342
+ return buildInner(seller).wrap(handler, { verifySettlement })(request, ...args);
343
+ };
344
+ },
345
+ };
346
+ }
347
+ async fetchSeller() {
348
+ let response;
349
+ try {
350
+ response = await this.fetchFn(`${this.baseUrl}/api/v1/seller`, {
351
+ headers: { authorization: `Bearer ${this.apiKey}` },
352
+ });
353
+ }
354
+ catch (error) {
355
+ throw new PeerPayConfigError(`Failed to reach GenesisPay to resolve the seller: ${describeError(error)}`);
356
+ }
357
+ if (!response.ok) {
358
+ // 401/403/500 land on PeerPayConfigError with the key/base-URL hint; a
359
+ // 429 on the seller lookup is a rate limit like any other, not a broken key.
360
+ await throwForErrorResponse(response, {
361
+ operation: "GET /api/v1/seller",
362
+ hint: "Could not resolve the seller — check the API key and base URL.",
363
+ });
364
+ }
365
+ const config = (await response.json());
366
+ this.assertSafe(config);
367
+ return config;
368
+ }
369
+ assertSafe(config) {
370
+ const net = config.network;
371
+ // (1) Mode consistency: the mode encoded in the key prefix and the mode the
372
+ // server resolved from its stored column must agree. For keys minted by this
373
+ // system they always do (both come from the deployment network at creation);
374
+ // a disagreement means key/DB corruption or a spoofed response — fail closed.
375
+ if (config.mode !== this.mode) {
376
+ throw new PeerPayNetworkSafetyError(`Key mode "${this.mode}" does not match the server-resolved mode "${config.mode}".`);
377
+ }
378
+ // (2) Mode↔network: a live key must never resolve to a testnet, and vice
379
+ // versa. Checked before the asset table so an unknown/foreign network name
380
+ // surfaces as a typed safety error instead of a generic lookup throw.
381
+ if (!MODE_NETWORKS[this.mode].includes(net.networkName)) {
382
+ throw new PeerPayNetworkSafetyError(`A ${this.mode} key must not resolve to network "${net.networkName}".`);
383
+ }
384
+ // (3) Asset integrity: the backend-reported USDC/chainId must match the
385
+ // SDK's own native-USDC table for that (now-known) network.
386
+ const known = resolvePaymentGateNetwork(net.networkName);
387
+ if (known.chainId !== net.chainId ||
388
+ known.usdcAddress.toLowerCase() !== String(net.usdcAddress).toLowerCase()) {
389
+ throw new PeerPayNetworkSafetyError(`Backend network is inconsistent for "${net.networkName}" (chainId ${net.chainId}, usdc ${net.usdcAddress}).`);
390
+ }
391
+ // (4) Optional local pin on the payout wallet.
392
+ if (this.expectedPayTo && config.payTo && config.payTo.toLowerCase() !== this.expectedPayTo) {
393
+ throw new PeerPayNetworkSafetyError(`Resolved payTo does not match expectedPayTo.`);
394
+ }
395
+ }
396
+ /**
397
+ * Applies the `expectedPayTo` pin to a destination the server just froze onto
398
+ * a newly created object.
399
+ *
400
+ * Checking it in `assertSafe` alone was not enough: that only covers the
401
+ * `/api/v1/seller` config lookup, while a checkout link and a subscription
402
+ * plan each record their own `destinationWallet` at creation. Those are the
403
+ * addresses money actually moves to — a pin that does not cover them is not
404
+ * the guarantee the option advertises.
405
+ */
406
+ assertPinnedDestination(wallet, what) {
407
+ if (!this.expectedPayTo)
408
+ return;
409
+ if (typeof wallet !== "string" || !wallet)
410
+ return;
411
+ if (wallet.toLowerCase() !== this.expectedPayTo) {
412
+ throw new PeerPayNetworkSafetyError(`The ${what} was created with a destinationWallet that does not match expectedPayTo.`);
413
+ }
414
+ }
415
+ /**
416
+ * One authenticated JSON round-trip, with the error mapping every method
417
+ * shares. A transport failure (no response at all) is the only case handled
418
+ * here rather than in `throwForErrorResponse`, because there is no status to
419
+ * map — it is always a config/connectivity problem.
420
+ */
421
+ async performRequest(options) {
422
+ const hasBody = options.body !== undefined;
423
+ let response;
424
+ try {
425
+ response = await this.fetchFn(`${this.baseUrl}${options.path}`, {
426
+ method: options.method ?? "GET",
427
+ headers: {
428
+ authorization: `Bearer ${this.apiKey}`,
429
+ ...(hasBody ? { "content-type": "application/json" } : {}),
430
+ ...options.headers,
431
+ },
432
+ ...(hasBody ? { body: JSON.stringify(options.body) } : {}),
433
+ });
434
+ }
435
+ catch (error) {
436
+ throw new PeerPayConfigError(`Failed to reach GenesisPay to ${options.action}: ${describeError(error)}`);
437
+ }
438
+ if (!response.ok) {
439
+ // Shared mapping: 422 → PeerPayValidationError (with the field issues),
440
+ // 429 → PeerPayRateLimitError (with Retry-After), 404 → NotFound, rest → Config.
441
+ await throwForErrorResponse(response, {
442
+ operation: options.operation,
443
+ notFoundMessage: options.notFoundMessage,
444
+ hint: typeof options.hint === "function" ? options.hint(response.status) : options.hint,
445
+ });
446
+ }
447
+ // An OK response with an unparseable body yields null; each caller decides
448
+ // what a missing object means, and says so in its own error message.
449
+ return (await response.json().catch(() => null));
450
+ }
451
+ async createCheckout(input) {
452
+ const amount = resolveCheckoutAmount(input);
453
+ const body = await this.request({
454
+ method: "POST",
455
+ path: "/api/v1/links",
456
+ operation: "POST /api/v1/links",
457
+ action: "create a checkout link",
458
+ body: {
459
+ title: input.title,
460
+ description: input.description,
461
+ amount,
462
+ // Both names, one value: a backend older than 0.6.0 only knows
463
+ // `amountUsdc`, and a newer one accepts the pair precisely because they
464
+ // agree. Nothing here can disagree — it is the same string twice.
465
+ amountUsdc: amount,
466
+ linkType: input.linkType ?? "single",
467
+ ...(input.destinationWallet ? { destinationWallet: input.destinationWallet } : {}),
468
+ ...(input.asset ? { asset: input.asset } : {}),
469
+ ...(input.metadata ? { metadata: input.metadata } : {}),
470
+ ...(input.clientReferenceId ? { clientReferenceId: input.clientReferenceId } : {}),
471
+ ...(input.returnUrl ? { returnUrl: input.returnUrl } : {}),
472
+ ...(input.cancelUrl ? { cancelUrl: input.cancelUrl } : {}),
473
+ },
474
+ });
475
+ const link = asRecord(body)?.link;
476
+ if (!link || typeof link.payUrl !== "string" || !link.payUrl) {
477
+ throw new PeerPayConfigError(`GenesisPay link created but no payUrl in response: ${JSON.stringify(body)}`);
478
+ }
479
+ this.assertPinnedDestination(link.destinationWallet, "checkout link");
480
+ return toCheckoutLink(link);
481
+ }
482
+ /**
483
+ * Fetch the current state of a checkout link. `paid` is the field to poll on;
484
+ * an unknown publicId raises `PeerPayNotFoundError`, never a config error.
485
+ */
486
+ async retrieveCheckout(publicId) {
487
+ const id = publicId?.trim();
488
+ if (!id) {
489
+ throw new PeerPayConfigError("checkout.retrieve(publicId) requires the publicId returned by checkout.create().");
490
+ }
491
+ const body = await this.request({
492
+ path: `/api/v1/links/${encodeURIComponent(id)}`,
493
+ operation: `GET /api/v1/links/${id}`,
494
+ action: `retrieve checkout "${id}"`,
495
+ notFoundMessage: `No GenesisPay checkout with publicId "${id}". Check the id and that it belongs to the account this API key authenticates.`,
496
+ });
497
+ const link = asRecord(body)?.link;
498
+ if (!link || typeof link.publicId !== "string" || !link.publicId) {
499
+ throw new PeerPayConfigError(`GenesisPay returned no link for publicId "${id}": ${JSON.stringify(body)}`);
500
+ }
501
+ return toCheckoutSession(link);
502
+ }
503
+ /** Test-mode only — see the doc on `checkout.simulatePayment`. */
504
+ async simulateCheckoutPayment(publicId, opts) {
505
+ const id = publicId?.trim();
506
+ if (!id) {
507
+ throw new PeerPayConfigError("checkout.simulatePayment(publicId) requires the publicId returned by checkout.create().");
508
+ }
509
+ const body = await this.request({
510
+ method: "POST",
511
+ path: `/api/v1/links/${encodeURIComponent(id)}/simulate-payment`,
512
+ operation: `POST /api/v1/links/${id}/simulate-payment`,
513
+ action: `simulate a payment on checkout "${id}"`,
514
+ body: opts?.payerWallet ? { payerWallet: opts.payerWallet } : {},
515
+ // A 404 here has two very different causes and the server cannot tell you
516
+ // which — by design, since a mainnet deployment must not even confirm the
517
+ // endpoint exists. Naming both stops the "the id is definitely right, why
518
+ // is it 404" hunt at the wrong end.
519
+ notFoundMessage: `GenesisPay simulate-payment returned 404 for checkout "${id}". Either no such ` +
520
+ `checkout exists for the account this API key authenticates, or this GenesisPay ` +
521
+ `deployment runs on mainnet, where the endpoint does not exist at all. ` +
522
+ `Check the publicId first, then the deployment's network.`,
523
+ hint: (status) => status === 403 ? SIMULATE_PAYMENT_LIVE_KEY_HINT : undefined,
524
+ });
525
+ const record = asRecord(body);
526
+ const link = record?.link;
527
+ if (!link || typeof link.publicId !== "string" || !link.publicId) {
528
+ throw new PeerPayConfigError(`GenesisPay simulated a payment on "${id}" but returned no link: ${JSON.stringify(body)}`);
529
+ }
530
+ // The attempt is not an optional detail here the way an unknown field would
531
+ // be: without it the merged session would report `paid: false` right after
532
+ // a payment was minted. A 201 that omits it is a broken contract, not an
533
+ // older backend — the endpoint and the field shipped together.
534
+ const [attempt] = toCheckoutAttempts([record?.attempt]);
535
+ if (!attempt) {
536
+ throw new PeerPayConfigError(`GenesisPay simulated a payment on "${id}" but returned no attempt: ${JSON.stringify(body)}`);
537
+ }
538
+ return toSimulatedCheckoutSession(link, attempt);
539
+ }
540
+ }
541
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import { type PeerPayRequest } from "./resource.js";
2
+ export type Customer = {
3
+ id: string;
4
+ publicId: string;
5
+ name: string;
6
+ email: string;
7
+ companyName: string | null;
8
+ addressLine1: string | null;
9
+ addressLine2: string | null;
10
+ city: string | null;
11
+ postalCode: string | null;
12
+ countryCode: string | null;
13
+ taxId: string | null;
14
+ metadata: Record<string, string> | null;
15
+ createdAt: string;
16
+ updatedAt: string;
17
+ archivedAt: string | null;
18
+ };
19
+ export type CustomerCreateInput = {
20
+ name: string;
21
+ email: string;
22
+ companyName?: string;
23
+ addressLine1?: string;
24
+ addressLine2?: string;
25
+ city?: string;
26
+ postalCode?: string;
27
+ countryCode?: string;
28
+ taxId?: string;
29
+ metadata?: Record<string, string>;
30
+ };
31
+ export type CustomerUpdateInput = Partial<CustomerCreateInput>;
32
+ export interface CustomersResource {
33
+ create(input: CustomerCreateInput): Promise<Customer>;
34
+ list(): Promise<Customer[]>;
35
+ retrieve(publicId: string): Promise<Customer>;
36
+ update(publicId: string, input: CustomerUpdateInput): Promise<Customer>;
37
+ archive(publicId: string): Promise<Customer>;
38
+ }
39
+ export declare function createCustomersResource(request: PeerPayRequest): CustomersResource;
40
+ export declare function toCustomer(raw: Record<string, unknown>): Customer;
41
+ //# sourceMappingURL=customers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"customers.d.ts","sourceRoot":"","sources":["../src/customers.ts"],"names":[],"mappings":"AAGA,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,eAAe,CAAC;AAEvB,MAAM,MAAM,QAAQ,GAAG;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAE/D,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACtD,IAAI,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACxE,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC9C;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,cAAc,GAAG,iBAAiB,CAoDlF;AAmCD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,QAAQ,CAkBjE"}