@delopay/sdk 0.247.0 → 0.255.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.
@@ -963,11 +963,92 @@ var Connectors = class {
963
963
  { body: params }
964
964
  );
965
965
  }
966
+ /**
967
+ * Every webhook the connector's payment provider lists for its credentials
968
+ * in one environment: Delopay's own, other connector accounts', former
969
+ * addresses' and other integrations'.
970
+ * `GET /account/{merchantId}/connectors/webhooks/{connectorId}/provider`
971
+ *
972
+ * Available for Stripe, PayPal, Airwallex, Whop and Adyen. Destinations are
973
+ * masked; `capabilities` says which changes the provider allows and
974
+ * `editable` whether the caller may make them.
975
+ */
976
+ async listProviderWebhooks(merchantId, connectorId, environment) {
977
+ return this.request("GET", providerWebhooksPath(merchantId, connectorId), {
978
+ query: { environment }
979
+ });
980
+ }
981
+ /**
982
+ * Create a webhook at the provider for the merchant's own systems.
983
+ * `POST /account/{merchantId}/connectors/webhooks/{connectorId}/provider`
984
+ *
985
+ * The URL must be `https` and outside Delopay; Delopay's own webhook is
986
+ * registered with `registerWebhook`. A returned `signing_secret` is not kept
987
+ * by Delopay and cannot be read again.
988
+ */
989
+ async createProviderWebhook(merchantId, connectorId, params) {
990
+ return this.request("POST", providerWebhooksPath(merchantId, connectorId), { body: params });
991
+ }
992
+ /**
993
+ * Change one webhook at the provider.
994
+ * `PATCH /account/{merchantId}/connectors/webhooks/{connectorId}/provider/{webhookId}`
995
+ *
996
+ * Refused once the webhook changed since `fingerprint`, and for Delopay's
997
+ * own webhooks.
998
+ */
999
+ async updateProviderWebhook(merchantId, connectorId, webhookId, params) {
1000
+ return this.request(
1001
+ "PATCH",
1002
+ `${providerWebhooksPath(merchantId, connectorId)}/${encodeURIComponent(webhookId)}`,
1003
+ { body: params }
1004
+ );
1005
+ }
1006
+ /**
1007
+ * Delete one webhook at the provider.
1008
+ * `POST /account/{merchantId}/connectors/webhooks/{connectorId}/provider/{webhookId}/delete`
1009
+ *
1010
+ * Refused once the webhook changed since `fingerprint`. Deleting Delopay's
1011
+ * own webhook needs `confirm_managed: true`; another connector account's is
1012
+ * never deleted from here.
1013
+ */
1014
+ async deleteProviderWebhook(merchantId, connectorId, webhookId, params) {
1015
+ return this.request(
1016
+ "POST",
1017
+ `${providerWebhooksPath(merchantId, connectorId)}/${encodeURIComponent(webhookId)}/delete`,
1018
+ { body: params }
1019
+ );
1020
+ }
1021
+ /**
1022
+ * What "replace all" would delete and keep. Nothing is changed.
1023
+ * `GET /account/{merchantId}/connectors/webhooks/{connectorId}/provider/replace`
1024
+ */
1025
+ async previewProviderWebhookReplace(merchantId, connectorId, environment) {
1026
+ return this.request("GET", `${providerWebhooksPath(merchantId, connectorId)}/replace`, {
1027
+ query: { environment }
1028
+ });
1029
+ }
1030
+ /**
1031
+ * Keep only Delopay's webhook: delete exactly the confirmed webhooks of the
1032
+ * preview, after registering Delopay's own unless `sequence` is
1033
+ * `delete_first`.
1034
+ * `POST /account/{merchantId}/connectors/webhooks/{connectorId}/provider/replace`
1035
+ *
1036
+ * A list that changed since the preview answers `scope_changed` and deletes
1037
+ * nothing. A second replacement while one runs is refused as busy (`HE_00`).
1038
+ */
1039
+ async replaceProviderWebhooks(merchantId, connectorId, params) {
1040
+ return this.request("POST", `${providerWebhooksPath(merchantId, connectorId)}/replace`, {
1041
+ body: params
1042
+ });
1043
+ }
966
1044
  /** List available payment methods. `GET /account/payment-methods` */
967
1045
  async listPaymentMethods() {
968
1046
  return this.request("GET", "/account/payment-methods");
969
1047
  }
970
1048
  };
1049
+ function providerWebhooksPath(merchantId, connectorId) {
1050
+ return `/account/${encodeURIComponent(merchantId)}/connectors/webhooks/${encodeURIComponent(connectorId)}/provider`;
1051
+ }
971
1052
 
972
1053
  // src/resources/customers.ts
973
1054
  function toQuery(params) {
@@ -2140,6 +2221,44 @@ var PaymentMethods = class {
2140
2221
  query: params
2141
2222
  });
2142
2223
  }
2224
+ /**
2225
+ * The shop's payment buttons as the hosted checkout draws them: order,
2226
+ * labels in the shop's or caller's language, artwork, and what selecting
2227
+ * each one does. For rendering payment buttons on your own site without a
2228
+ * local table of provider names and icons.
2229
+ *
2230
+ * With a secret key, name the shop (`profile_id`) and optionally the
2231
+ * environment and a buyer context; the answer may be reused for
2232
+ * `cache.max_age_seconds` — {@link PresentationCache} does that. With a
2233
+ * publishable key, pass the payment's `client_secret` (or use
2234
+ * `CheckoutSession.paymentMethodPresentation`); that answer is never reused.
2235
+ *
2236
+ * A displayed entry is not a promise: the payment is confirmed against the
2237
+ * current configuration.
2238
+ *
2239
+ * `GET /account/payment-methods/presentation`
2240
+ *
2241
+ * @example
2242
+ * ```typescript
2243
+ * const buttons = await delopay.paymentMethods.presentation({
2244
+ * profile_id: 'pro_123',
2245
+ * country: 'DE',
2246
+ * currency: 'EUR',
2247
+ * amount: 4999,
2248
+ * locale: 'de',
2249
+ * });
2250
+ * for (const entry of buttons.entries) {
2251
+ * if (entry.kind === 'heading') renderHeading(entry.label);
2252
+ * else renderButton(entry.label, entry.sublabel, presentationIconSrc(entry));
2253
+ * }
2254
+ * ```
2255
+ */
2256
+ async presentation(params, options) {
2257
+ return this.request("GET", "/account/payment-methods/presentation", {
2258
+ query: params,
2259
+ ...options
2260
+ });
2261
+ }
2143
2262
  /**
2144
2263
  * List all saved payment methods for a customer, optionally filtered.
2145
2264
  *
@@ -6982,7 +7101,7 @@ var BuyerAccount = class {
6982
7101
  constructor(request) {
6983
7102
  this.request = request;
6984
7103
  }
6985
- /** Whether buyers can sign in by email on this platform, and how. */
7104
+ /** Whether buyers can sign in on this platform, and which methods are offered. */
6986
7105
  async availability(options) {
6987
7106
  return this.request("GET", "/buyer-account/availability", { ...options });
6988
7107
  }
@@ -12111,6 +12230,37 @@ var CheckoutSession = class {
12111
12230
  headers: this.bearerHeaders(options?.headers)
12112
12231
  });
12113
12232
  }
12233
+ /**
12234
+ * Remove one of the buyer's saved cards, named by its `payment_token` from
12235
+ * {@link vaultSavedCards}: from the customer's saved cards and from the
12236
+ * shop's vault, with every saved copy of the same card. Only a card of the
12237
+ * payment's own customer that the shop's vault holds can be removed, and
12238
+ * only within the payment's session.
12239
+ *
12240
+ * Refusals throw a `DelopayError`:
12241
+ *
12242
+ * - `400` with code `IR_16` and `data.reason` set to a
12243
+ * {@link VaultSavedCardRemovalRefusal}: the card stays listed.
12244
+ * `saved_card_in_use` means a subscription or agreement still charges it,
12245
+ * `saved_card_payment_in_progress` a payment with it is in flight, and
12246
+ * `saved_card_removal_unavailable` that the shop cannot remove cards here.
12247
+ * - `404`: the card is not one this buyer can remove, for example because it
12248
+ * is already gone.
12249
+ * - `422` with code `IR_29`: the token is no longer held. Read
12250
+ * {@link vaultSavedCards} again and remove the card by its new token.
12251
+ *
12252
+ * `DELETE /payment-link/{merchantId}/{paymentId}/vault/saved-cards/{paymentToken}`
12253
+ */
12254
+ async vaultRemoveSavedCard(paymentToken, options) {
12255
+ await this.client.request(
12256
+ "DELETE",
12257
+ `${this.linkBase}/vault/saved-cards/${encodeURIComponent(paymentToken)}`,
12258
+ {
12259
+ ...options,
12260
+ headers: this.bearerHeaders(options?.headers)
12261
+ }
12262
+ );
12263
+ }
12114
12264
  /**
12115
12265
  * Mint the security-code form for a saved card, on a shop whose vault keeps
12116
12266
  * the code itself (Enigma Vault). The buyer re-enters the code into the
@@ -12339,7 +12489,195 @@ var CheckoutSession = class {
12339
12489
  headers: this.pkHeaders(options?.headers)
12340
12490
  });
12341
12491
  }
12492
+ /**
12493
+ * This payment's checkout buttons, as the hosted checkout draws them: order,
12494
+ * labels, artwork, and what selecting each one does. The shop, environment,
12495
+ * currency and amount are the payment's. Ask again when the cart changes;
12496
+ * an answer is never reused for another payment.
12497
+ *
12498
+ * `GET /account/payment-methods/presentation` (publishable key + client secret)
12499
+ *
12500
+ * @param params - `country` outranks the billing address and IP
12501
+ * geolocation; `locale` names the language of the labels.
12502
+ */
12503
+ async paymentMethodPresentation(params, options) {
12504
+ return this.client.request("GET", "/account/payment-methods/presentation", {
12505
+ query: {
12506
+ client_secret: this.requireClientSecret(),
12507
+ country: params?.country,
12508
+ locale: params?.locale,
12509
+ contract_version: params?.contract_version
12510
+ },
12511
+ ...options,
12512
+ headers: this.pkHeaders(options?.headers)
12513
+ });
12514
+ }
12515
+ };
12516
+
12517
+ // src/paymentPresentation.ts
12518
+ var PRESENTATION_CONTRACT_VERSION = 1;
12519
+ var BUILTIN_PAYMENT_ICON_KEYS = [
12520
+ "wallet",
12521
+ "card",
12522
+ "bank",
12523
+ "apple",
12524
+ "google",
12525
+ "bnpl",
12526
+ "cash",
12527
+ "paypal",
12528
+ "klarna",
12529
+ "crypto"
12530
+ ];
12531
+ var SVG_OPEN = '<svg xmlns="http://www.w3.org/2000/svg"';
12532
+ function glyph(key, color) {
12533
+ const line = (body) => `${SVG_OPEN} viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">${body}</svg>`;
12534
+ switch (key) {
12535
+ case "card":
12536
+ return line('<rect x="2" y="5" width="20" height="14" rx="2"/><path d="M2 10h20"/>');
12537
+ case "bank":
12538
+ return line(
12539
+ '<path d="M3 10h18"/><path d="m12 3 9 5H3l9-5Z"/><path d="M6 10v7M10 10v7M14 10v7M18 10v7"/><path d="M3 20h18"/>'
12540
+ );
12541
+ case "bnpl":
12542
+ return line(
12543
+ '<rect x="2" y="6" width="20" height="12" rx="2"/><path d="M6 12h4"/><path d="M14 10v4"/><path d="M18 10v4"/>'
12544
+ );
12545
+ case "cash":
12546
+ return line(
12547
+ '<rect x="2" y="6" width="20" height="12" rx="2"/><circle cx="12" cy="12" r="2.5"/><path d="M6 12h.01M18 12h.01"/>'
12548
+ );
12549
+ case "apple":
12550
+ return `${SVG_OPEN} viewBox="0 0 384 512" fill="${color}"><path d="M318.7 268.7c-.2-36.7 16.4-64.4 50-84.8-18.8-26.9-47.2-41.7-84.7-44.6-35.5-2.8-74.3 20.7-88.5 20.7-15 0-49.4-19.7-76.4-19.7C63.3 141.2 4 184.8 4 273.5q0 39.3 14.4 81.2c12.8 36.7 59 126.7 107.2 125.2 25.2-.6 43-17.9 75.8-17.9 31.8 0 48.3 17.9 76.4 17.9 48.6-.7 90.4-82.5 102.6-119.3-65.2-30.7-61.7-90-61.7-91.9zm-56.6-164.2c27.3-32.4 24.8-61.9 24-72.5-24.1 1.4-52 16.4-67.9 34.9-17.5 19.8-27.8 44.3-25.6 71.9 26.1 2 49.9-11.4 69.5-34.3z"/></svg>`;
12551
+ case "google":
12552
+ return `${SVG_OPEN} viewBox="0 0 48 48"><path fill="#4285F4" d="M45.12 24.5c0-1.56-.14-3.06-.4-4.5H24v8.51h11.84c-.51 2.75-2.06 5.08-4.39 6.64v5.52h7.11c4.16-3.83 6.56-9.47 6.56-16.17z"/><path fill="#34A853" d="M24 46c5.94 0 10.92-1.97 14.56-5.33l-7.11-5.52c-1.97 1.32-4.49 2.1-7.45 2.1-5.73 0-10.58-3.87-12.31-9.07H4.34v5.7C7.96 41.07 15.4 46 24 46z"/><path fill="#FBBC05" d="M11.69 28.18C11.25 26.86 11 25.45 11 24s.25-2.86.69-4.18v-5.7H4.34C2.85 17.09 2 20.45 2 24s.85 6.91 2.34 9.88l7.35-5.7z"/><path fill="#EA4335" d="M24 10.75c3.23 0 6.13 1.11 8.41 3.29l6.31-6.31C34.91 4.18 29.93 2 24 2 15.4 2 7.96 6.93 4.34 14.12l7.35 5.7c1.73-5.2 6.58-9.07 12.31-9.07z"/></svg>`;
12553
+ case "paypal":
12554
+ return `${SVG_OPEN} viewBox="0 0 32 32"><path d="M9 4h7.2c3.4 0 6 2.4 5.6 5.8-.4 3.6-3.5 6-7.1 6h-3.2L10.4 23H6.7L9 4z" fill="#003087"/><path d="M13 8.5h7.2c3.4 0 6 2.4 5.6 5.8-.4 3.6-3.5 6-7.1 6h-3.2L14.4 27.5H10.7L13 8.5z" fill="#009cde"/></svg>`;
12555
+ case "klarna":
12556
+ return `${SVG_OPEN} viewBox="0 0 24 24"><rect width="24" height="24" rx="6" fill="#FFA8CD"/><path fill="#0B051D" d="M8 6h2.7v12H8V6zm6.5 0h2.5c-.4 2.7-1.5 5-3 6.6 1.6 1.6 2.7 3.6 3.2 5.4h-2.7c-.5-1.6-1.4-3-2.7-4.2v4.2H10V12c2.1-1 3.8-3.2 4.5-6z"/></svg>`;
12557
+ case "crypto":
12558
+ return `${SVG_OPEN} viewBox="0 0 64 64"><path fill="#F7931A" d="m63.033,39.744c-4.274,17.143-21.637,27.576-38.782,23.301-17.138-4.274-27.571-21.638-23.295-38.78,4.272-17.145,21.635-27.579,38.775-23.305,17.144,4.274,27.576,21.64,23.302,38.784z"/><path fill="#FFF" d="m46.103,27.444c0.637-4.258-2.605-6.547-7.038-8.074l1.438-5.768-3.511-0.875-1.4,5.616c-0.923-0.23-1.871-0.447-2.813-0.662l1.41-5.653-3.509-0.875-1.439,5.766c-0.764-0.174-1.514-0.346-2.242-0.527l0.004-0.018-4.842-1.209-0.934,3.75s2.605,0.597,2.55,0.634c1.422,0.355,1.679,1.296,1.636,2.042l-1.638,6.571c0.098,0.025,0.225,0.061,0.365,0.117-0.117-0.029-0.242-0.061-0.371-0.092l-2.296,9.205c-0.174,0.432-0.615,1.08-1.609,0.834,0.035,0.051-2.552-0.637-2.552-0.637l-1.743,4.019,4.569,1.139c0.85,0.213,1.683,0.436,2.503,0.646l-1.453,5.834,3.507,0.875,1.439-5.772c0.958,0.26,1.888,0.5,2.798,0.726l-1.434,5.745,3.511,0.875,1.453-5.823c5.987,1.133,10.489,0.676,12.384-4.739,1.527-4.36-0.076-6.875-3.226-8.515,2.294-0.529,4.022-2.038,4.483-5.155zm-8.022,11.249c-1.085,4.36-8.426,2.003-10.806,1.412l1.928-7.729c2.38,0.594,10.012,1.77,8.878,6.317zm1.086-11.312c-0.99,3.966-7.1,1.951-9.082,1.457l1.748-7.01c1.982,0.494,8.365,1.416,7.334,5.553z"/></svg>`;
12559
+ case "wallet":
12560
+ return line(
12561
+ '<path d="M3 7a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2"/><rect x="3" y="7" width="18" height="12" rx="2"/><path d="M16 13h3"/>'
12562
+ );
12563
+ }
12564
+ }
12565
+ function isBuiltinKey(key) {
12566
+ return BUILTIN_PAYMENT_ICON_KEYS.includes(key);
12567
+ }
12568
+ function builtinPaymentIconSvg(key, color = "#1f2937") {
12569
+ return glyph(isBuiltinKey(key) ? key : "wallet", color);
12570
+ }
12571
+ function builtinPaymentIconDataUri(key, color) {
12572
+ return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(builtinPaymentIconSvg(key, color))}`;
12573
+ }
12574
+ function presentationIconDataUri(icon, color) {
12575
+ return icon.type === "svg" ? icon.data_uri : builtinPaymentIconDataUri(icon.key, color);
12576
+ }
12577
+ function presentationIconSrc(entry, color) {
12578
+ if (entry.icon) return presentationIconDataUri(entry.icon, color);
12579
+ if (entry.fallback_icon) return builtinPaymentIconDataUri(entry.fallback_icon, color);
12580
+ return null;
12581
+ }
12582
+ function isSupportedPresentation(response) {
12583
+ return response.contract_version === PRESENTATION_CONTRACT_VERSION;
12584
+ }
12585
+ function presentationTiers(response) {
12586
+ const out = { express: [], normal: [], alternative: [] };
12587
+ for (const entry of response.entries) {
12588
+ if (entry.tier === "express") {
12589
+ const row = entry.row ?? 0;
12590
+ while (out.express.length <= row) out.express.push([]);
12591
+ out.express[row]?.push(entry);
12592
+ } else {
12593
+ out[entry.tier].push(entry);
12594
+ }
12595
+ }
12596
+ out.express = out.express.filter((row) => row.length > 0);
12597
+ return out;
12598
+ }
12599
+ function selectableEntries(response) {
12600
+ return response.entries.filter((entry) => entry.action !== void 0);
12601
+ }
12602
+ var PresentationCache = class _PresentationCache {
12603
+ constructor(options) {
12604
+ this.slots = /* @__PURE__ */ new Map();
12605
+ this.load = options.load;
12606
+ this.now = options.now ?? Date.now;
12607
+ this.maxEntries = options.maxEntries ?? 500;
12608
+ }
12609
+ /** The key two requests share exactly when DeloPay would answer them alike. */
12610
+ static keyOf(params) {
12611
+ return JSON.stringify([
12612
+ params.profile_id ?? null,
12613
+ params.environment ?? "live",
12614
+ params.locale?.toLowerCase() ?? null,
12615
+ params.country?.toUpperCase() ?? null,
12616
+ params.currency ?? null,
12617
+ params.amount ?? null,
12618
+ params.contract_version ?? PRESENTATION_CONTRACT_VERSION
12619
+ ]);
12620
+ }
12621
+ async get(params) {
12622
+ const request = {
12623
+ ...params,
12624
+ contract_version: params.contract_version ?? PRESENTATION_CONTRACT_VERSION
12625
+ };
12626
+ if (request.client_secret) {
12627
+ return { response: await this.load(request, {}), stale: false };
12628
+ }
12629
+ const key = _PresentationCache.keyOf(request);
12630
+ const slot = this.slots.get(key);
12631
+ const now = this.now();
12632
+ if (slot && now - slot.fetchedAt < slot.response.cache.max_age_seconds * 1e3) {
12633
+ return { response: slot.response, stale: false };
12634
+ }
12635
+ try {
12636
+ const response = await this.load(
12637
+ request,
12638
+ slot ? { headers: { "If-None-Match": `"${slot.response.revision}"` } } : {}
12639
+ );
12640
+ this.store(key, response, now);
12641
+ return { response, stale: false };
12642
+ } catch (error) {
12643
+ if (slot && error instanceof DelopayError && error.status === 304) {
12644
+ this.store(key, slot.response, now);
12645
+ return { response: slot.response, stale: false };
12646
+ }
12647
+ const policy = slot?.response.cache;
12648
+ const usableUntil = slot ? slot.fetchedAt + ((policy?.max_age_seconds ?? 0) + (policy?.stale_if_error_seconds ?? 0)) * 1e3 : 0;
12649
+ if (slot && isUnavailable(error) && now < usableUntil) {
12650
+ return { response: slot.response, stale: true };
12651
+ }
12652
+ if (slot && isRefusal(error)) this.slots.delete(key);
12653
+ throw error;
12654
+ }
12655
+ }
12656
+ /** Forget every answer, e.g. after the merchant changes the checkout editor. */
12657
+ clear() {
12658
+ this.slots.clear();
12659
+ }
12660
+ store(key, response, now) {
12661
+ if (response.cache.max_age_seconds <= 0) {
12662
+ this.slots.delete(key);
12663
+ return;
12664
+ }
12665
+ this.slots.delete(key);
12666
+ this.slots.set(key, { response, fetchedAt: now });
12667
+ while (this.slots.size > this.maxEntries) {
12668
+ const oldest = this.slots.keys().next().value;
12669
+ if (oldest === void 0) break;
12670
+ this.slots.delete(oldest);
12671
+ }
12672
+ }
12342
12673
  };
12674
+ function isRefusal(error) {
12675
+ return error instanceof DelopayError && error.status >= 400 && error.status < 500 && error.status !== 429;
12676
+ }
12677
+ function isUnavailable(error) {
12678
+ if (!(error instanceof DelopayError)) return false;
12679
+ return error.status === 0 || error.status === 429 || error.status >= 500;
12680
+ }
12343
12681
 
12344
12682
  // src/panes.ts
12345
12683
  var PANE_VISIBILITIES = ["always", "embedded_only", "external_only"];
@@ -12960,6 +13298,16 @@ export {
12960
13298
  applyBrandingVariables,
12961
13299
  shadowFor,
12962
13300
  CheckoutSession,
13301
+ PRESENTATION_CONTRACT_VERSION,
13302
+ BUILTIN_PAYMENT_ICON_KEYS,
13303
+ builtinPaymentIconSvg,
13304
+ builtinPaymentIconDataUri,
13305
+ presentationIconDataUri,
13306
+ presentationIconSrc,
13307
+ isSupportedPresentation,
13308
+ presentationTiers,
13309
+ selectableEntries,
13310
+ PresentationCache,
12963
13311
  paneViewVisibility,
12964
13312
  STRIPE_FALLBACK_PANE_METHODS,
12965
13313
  STRIPE_FALLBACK_PANE_CATALOG,
@@ -12989,4 +13337,4 @@ export {
12989
13337
  decodeNativePanes,
12990
13338
  encodeNativePanes
12991
13339
  };
12992
- //# sourceMappingURL=chunk-FU6W6ULM.js.map
13340
+ //# sourceMappingURL=chunk-U3KDAIWB.js.map