@delopay/sdk 0.113.0 → 0.117.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/dist/internal.cjs CHANGED
@@ -35,6 +35,7 @@ __export(internal_exports, {
35
35
  CHECKBOX_CHECKED: () => CHECKBOX_CHECKED,
36
36
  CHECKBOX_UNCHECKED: () => CHECKBOX_UNCHECKED,
37
37
  CHECKOUT_EVENT_KINDS: () => CHECKOUT_EVENT_KINDS,
38
+ CHECKOUT_LOCALES: () => CHECKOUT_LOCALES,
38
39
  CUSTOM_CSS_MAX_LENGTH: () => CUSTOM_CSS_MAX_LENGTH,
39
40
  CUSTOM_FIELDS_MAX: () => CUSTOM_FIELDS_MAX,
40
41
  CUSTOM_FIELD_CONDITIONS_MAX: () => CUSTOM_FIELD_CONDITIONS_MAX,
@@ -62,6 +63,7 @@ __export(internal_exports, {
62
63
  Files: () => Files,
63
64
  Forex: () => Forex,
64
65
  Gsm: () => Gsm,
66
+ LOCALIZABLE_COPY_FIELDS: () => LOCALIZABLE_COPY_FIELDS,
65
67
  NATIVE_PANES_MAX: () => NATIVE_PANES_MAX,
66
68
  NATIVE_PANE_CATEGORY_KEYS: () => NATIVE_PANE_CATEGORY_KEYS,
67
69
  NATIVE_PANE_ICON_KEYS: () => NATIVE_PANE_ICON_KEYS,
@@ -76,6 +78,16 @@ __export(internal_exports, {
76
78
  STRIPE_FALLBACK_PANE_CATALOG: () => STRIPE_FALLBACK_PANE_CATALOG,
77
79
  STRIPE_FALLBACK_PANE_METHODS: () => STRIPE_FALLBACK_PANE_METHODS,
78
80
  STRIPE_NATIVE_PANE_METHODS: () => STRIPE_NATIVE_PANE_METHODS,
81
+ SURCHARGE_BORDER_STYLES: () => SURCHARGE_BORDER_STYLES,
82
+ SURCHARGE_BORDER_WIDTHS: () => SURCHARGE_BORDER_WIDTHS,
83
+ SURCHARGE_FIGURE_MODES: () => SURCHARGE_FIGURE_MODES,
84
+ SURCHARGE_LABEL_MODES: () => SURCHARGE_LABEL_MODES,
85
+ SURCHARGE_POSITIONS: () => SURCHARGE_POSITIONS,
86
+ SURCHARGE_SHAPES: () => SURCHARGE_SHAPES,
87
+ SURCHARGE_SIGNS: () => SURCHARGE_SIGNS,
88
+ SURCHARGE_SIZES: () => SURCHARGE_SIZES,
89
+ SURCHARGE_STYLES: () => SURCHARGE_STYLES,
90
+ SURCHARGE_WEIGHTS: () => SURCHARGE_WEIGHTS,
79
91
  Search: () => Search,
80
92
  Settlement: () => Settlement,
81
93
  Subscriptions: () => Subscriptions,
@@ -87,11 +99,13 @@ __export(internal_exports, {
87
99
  applyBrandingVariables: () => applyBrandingVariables,
88
100
  buildBrandingExport: () => buildBrandingExport,
89
101
  buttonPadValue: () => buttonPadValue,
102
+ checkoutCopy: () => checkoutCopy,
90
103
  cloneBranding: () => cloneBranding,
91
104
  cloneCustomField: () => cloneCustomField,
92
105
  cloneNativePane: () => cloneNativePane,
93
106
  clonePane: () => clonePane,
94
107
  contrastRatio: () => contrastRatio,
108
+ copyTranslationsKey: () => copyTranslationsKey,
95
109
  customFieldContextFromMetadata: () => customFieldContextFromMetadata,
96
110
  customFieldIsTextLike: () => customFieldIsTextLike,
97
111
  customFieldOperatorTakesValue: () => customFieldOperatorTakesValue,
@@ -136,9 +150,14 @@ __export(internal_exports, {
136
150
  parseImportedBranding: () => parseImportedBranding,
137
151
  programToTree: () => programToTree,
138
152
  radiusValue: () => radiusValue,
153
+ readableInkOn: () => readableInkOn,
139
154
  ruleMatchToTree: () => ruleMatchToTree,
140
155
  sanitizeCustomCss: () => sanitizeCustomCss,
141
156
  shadowFor: () => shadowFor,
157
+ surchargeFigurePlan: () => surchargeFigurePlan,
158
+ surchargeShowsLabel: () => surchargeShowsLabel,
159
+ surchargeStyleDrawsAShape: () => surchargeStyleDrawsAShape,
160
+ surchargeWordFor: () => surchargeWordFor,
142
161
  surfacePadValue: () => surfacePadValue,
143
162
  validatePanes: () => validatePanes,
144
163
  verticalGapValue: () => verticalGapValue,
@@ -680,9 +699,9 @@ var Connectors = class {
680
699
  /**
681
700
  * Update a connector account.
682
701
  *
683
- * `connector_webhook_details` **merges** into the stored block key by key
684
- * (be#992): an absent key keeps its stored secret, an explicit value is
685
- * written, and an explicit empty string clears that secret. Send only the
702
+ * `connector_webhook_details` **merges** into the stored block key by key:
703
+ * an absent key keeps its stored secret, an explicit value is written, and
704
+ * an explicit empty string clears that secret. Send only the
686
705
  * keys the operator typed — padding the other environment's keys with `''`
687
706
  * clears a live signing secret and inbound webhooks stop verifying.
688
707
  *
@@ -2536,6 +2555,19 @@ var Routing = class {
2536
2555
  async getDefaultProfile() {
2537
2556
  return this.request("GET", "/routing/default/profile");
2538
2557
  }
2558
+ /**
2559
+ * Retrieve one profile's default config. `GET /routing/default/profile/{profileId}`
2560
+ *
2561
+ * The narrow counterpart of `getDefaultProfile()`: that one returns every
2562
+ * profile of the merchant and needs merchant-level routing read, so a
2563
+ * profile-scoped (shop) role could write its own default through
2564
+ * `updateDefaultProfile()` but never read it back. This read is gated on
2565
+ * profile-level routing read and pinned to the caller's own profile — a shop
2566
+ * role asking for a sibling profile is refused.
2567
+ */
2568
+ async getDefaultForProfile(profileId) {
2569
+ return this.request("GET", `/routing/default/profile/${encodeURIComponent(profileId)}`);
2570
+ }
2539
2571
  /** Update default config for a profile. `POST /routing/default/profile/{profileId}` */
2540
2572
  async updateDefaultProfile(profileId, params) {
2541
2573
  return this.request("POST", `/routing/default/profile/${encodeURIComponent(profileId)}`, {
@@ -4299,11 +4331,12 @@ var Settlement = class {
4299
4331
  /**
4300
4332
  * Record payout progress on a statement (`unpaid` / `partial` / `paid`).
4301
4333
  *
4302
- * Subject to the caller's `settlement_payout` operation limit, which can
4303
- * only be a per-operation ceiling: an over-limit call fails with `DE_01`
4304
- * and nothing is recorded. There is no approval route out of it — four-eyes
4305
- * needs an executor that can run the operation once somebody says yes, and
4306
- * only refunds have one, so a settlement rule can only block.
4334
+ * Subject to the caller's `settlement_payout` operation limit a
4335
+ * per-operation ceiling, a windowed total, a windowed count, or any
4336
+ * combination: an over-limit call fails with `DE_01` and nothing is
4337
+ * recorded. There is no approval route out of it four-eyes needs an
4338
+ * executor that can run the operation once somebody says yes, and only
4339
+ * refunds have one, so a settlement rule can only block.
4307
4340
  *
4308
4341
  * `POST /settlement/statements/{statementId}/payout`
4309
4342
  */
@@ -5169,6 +5202,121 @@ function feeProgram() {
5169
5202
  }
5170
5203
 
5171
5204
  // src/branding.ts
5205
+ function surchargeShowsLabel(labelMode, style, position) {
5206
+ if (labelMode !== "labelled") return false;
5207
+ return !(style === "ribbon" && (position === "cornerStart" || position === "cornerEnd"));
5208
+ }
5209
+ function surchargeFigurePlan(branding, isDiscount, percentAvailable) {
5210
+ const mode = isDiscount ? branding.discountFigure : branding.surchargeFigure;
5211
+ const label = surchargeShowsLabel(
5212
+ branding.surchargeLabel,
5213
+ branding.surchargeStyle,
5214
+ branding.surchargePosition
5215
+ );
5216
+ if (!percentAvailable) return { first: "amount", second: null, label };
5217
+ const ordered = {
5218
+ amount: ["amount", null],
5219
+ percent: ["percent", null],
5220
+ amountThenPercent: ["amount", "percent"],
5221
+ percentThenAmount: ["percent", "amount"]
5222
+ };
5223
+ const [first, second] = ordered[mode];
5224
+ const cornerRibbon = branding.surchargeStyle === "ribbon" && (branding.surchargePosition === "cornerStart" || branding.surchargePosition === "cornerEnd");
5225
+ return { first, second: cornerRibbon ? null : second, label };
5226
+ }
5227
+ function readableInkOn(color) {
5228
+ const onBlack = contrastRatio(color, "#000000");
5229
+ const onWhite = contrastRatio(color, "#ffffff");
5230
+ if (onBlack === null || onWhite === null) return "#ffffff";
5231
+ return onBlack >= onWhite ? "#000000" : "#ffffff";
5232
+ }
5233
+ var SURCHARGE_FONT_SIZE = {
5234
+ sm: "0.6875rem",
5235
+ md: "0.8125rem",
5236
+ lg: "0.9375rem"
5237
+ };
5238
+ var SURCHARGE_PAD = {
5239
+ sm: "1px 6px",
5240
+ md: "2px 8px",
5241
+ lg: "3px 10px"
5242
+ };
5243
+ var SURCHARGE_RADIUS = {
5244
+ pill: "999px",
5245
+ rounded: "6px",
5246
+ square: "0px"
5247
+ };
5248
+ var SURCHARGE_BORDER_WIDTH = {
5249
+ none: "0px",
5250
+ thin: "1px",
5251
+ medium: "2px",
5252
+ thick: "3px"
5253
+ };
5254
+ var SURCHARGE_FONT_WEIGHT = {
5255
+ regular: "400",
5256
+ medium: "600",
5257
+ bold: "700"
5258
+ };
5259
+ var SURCHARGE_POSITIONS = [
5260
+ "trailing",
5261
+ "inline",
5262
+ "below",
5263
+ "above",
5264
+ "cornerStart",
5265
+ "cornerEnd"
5266
+ ];
5267
+ var SURCHARGE_STYLES = [
5268
+ "plain",
5269
+ "underline",
5270
+ "outline",
5271
+ "badge",
5272
+ "solid",
5273
+ "ribbon"
5274
+ ];
5275
+ var SURCHARGE_BORDER_WIDTHS = [
5276
+ "none",
5277
+ "thin",
5278
+ "medium",
5279
+ "thick"
5280
+ ];
5281
+ var SURCHARGE_BORDER_STYLES = [
5282
+ "solid",
5283
+ "dashed",
5284
+ "dotted"
5285
+ ];
5286
+ var SURCHARGE_SIZES = ["sm", "md", "lg"];
5287
+ function surchargeStyleDrawsAShape(style) {
5288
+ return style === "badge" || style === "outline" || style === "solid";
5289
+ }
5290
+ var SURCHARGE_SHAPES = ["pill", "rounded", "square"];
5291
+ var SURCHARGE_WEIGHTS = ["regular", "medium", "bold"];
5292
+ var SURCHARGE_SIGNS = ["always", "minusOnly", "none"];
5293
+ var SURCHARGE_LABEL_MODES = ["amount", "labelled"];
5294
+ var SURCHARGE_FIGURE_MODES = [
5295
+ "amount",
5296
+ "percent",
5297
+ "amountThenPercent",
5298
+ "percentThenAmount"
5299
+ ];
5300
+ var CHECKOUT_LOCALES = ["en", "de"];
5301
+ var LOCALIZABLE_COPY_FIELDS = [
5302
+ "headerText",
5303
+ "payButtonLabel",
5304
+ "cardTermsMessage",
5305
+ "footerText"
5306
+ ];
5307
+ function copyTranslationsKey(field) {
5308
+ return `${field}Translations`;
5309
+ }
5310
+ function checkoutCopy(branding, field, locale) {
5311
+ const translated = translationFor(branding[copyTranslationsKey(field)], locale);
5312
+ return translated ?? branding[field];
5313
+ }
5314
+ function surchargeWordFor(branding, isDiscount, locale) {
5315
+ return translationFor(
5316
+ isDiscount ? branding.discountWordTranslations : branding.surchargeWordTranslations,
5317
+ locale
5318
+ );
5319
+ }
5172
5320
  var FONT_STACKS = {
5173
5321
  inter: "'Inter Variable', 'Inter', system-ui, -apple-system, sans-serif",
5174
5322
  system: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif",
@@ -5359,6 +5507,44 @@ var DEFAULT_BRANDING_BASE = {
5359
5507
  verticalGap: "comfortable",
5360
5508
  inputSize: "md",
5361
5509
  buttonSize: "md",
5510
+ // Disclosure on by default: with provider-scoped pricing the tile is where
5511
+ // the buyer chooses between prices, and a price they cannot see is one they
5512
+ // find out about on the statement.
5513
+ showSurcharge: true,
5514
+ surchargePosition: "trailing",
5515
+ surchargeStyle: "badge",
5516
+ surchargeSize: "sm",
5517
+ surchargeShape: "pill",
5518
+ surchargeBorderWidth: "thin",
5519
+ surchargeBorderStyle: "solid",
5520
+ surchargeWeight: "medium",
5521
+ surchargeSign: "always",
5522
+ surchargeUppercase: false,
5523
+ // Named, not bare. A tile that reads "-EUR 2.50" beside a brand name is a
5524
+ // number with no subject — buyers read it as the price, not as a change to
5525
+ // it. "Discount -EUR 2.50" needs no interpreting, and the word is what makes
5526
+ // the default configuration legible without the merchant touching anything.
5527
+ surchargeLabel: "labelled",
5528
+ // The two directions default differently on purpose, which is the whole
5529
+ // reason they are two settings. A fee is something a buyer acts on in money,
5530
+ // so it leads with money and says nothing else. A saving is something worth
5531
+ // advertising, and the share is the persuasive half of it — "-5.1% (EUR
5532
+ // 2.50)" sells what "-EUR 2.50" merely states, and the amount is still right
5533
+ // there beside it.
5534
+ surchargeFigure: "amount",
5535
+ discountFigure: "percentThenAmount",
5536
+ // Empty: the checkout's own localized words are the default, in every
5537
+ // language it ships. A merchant fills these in only to say it differently.
5538
+ surchargeWordTranslations: {},
5539
+ discountWordTranslations: {},
5540
+ // amber-700 / emerald-700, not the 600s: the `plain` style renders the
5541
+ // disclosure as coloured TEXT, so it is bound by `WCAG_AA_TEXT` (4.5) rather
5542
+ // than by the 3:1 a coloured shape would be, and the 600s come to 3.19 and
5543
+ // 3.77 against the default white surface. These are 5.02 and 5.48, pinned by
5544
+ // tests. Far enough apart to read as opposite news at a glance rather than as
5545
+ // two shades of "extra".
5546
+ surchargeColor: "#b45309",
5547
+ discountColor: "#047857",
5362
5548
  layout: "split",
5363
5549
  summaryPosition: "left",
5364
5550
  showOrderSummary: true,
@@ -5367,10 +5553,17 @@ var DEFAULT_BRANDING_BASE = {
5367
5553
  totalLabel: "Total",
5368
5554
  showCurrencyCode: false,
5369
5555
  showOrderItems: true,
5556
+ // Each flat field keeps its meaning: what the merchant wrote, used in every
5557
+ // locale that carries no override. Empty maps therefore change nothing for a
5558
+ // profile saved before translations existed.
5370
5559
  headerText: "",
5560
+ headerTextTranslations: {},
5371
5561
  payButtonLabel: "",
5562
+ payButtonLabelTranslations: {},
5372
5563
  cardTermsMessage: "",
5564
+ cardTermsMessageTranslations: {},
5373
5565
  footerText: "",
5566
+ footerTextTranslations: {},
5374
5567
  supportEmail: "",
5375
5568
  paymentLayout: "tabs",
5376
5569
  labelStyle: "above",
@@ -5396,6 +5589,11 @@ var DEFAULT_BRANDING_DARK = {
5396
5589
  buttonBackground: "#1E4FEB",
5397
5590
  buttonText: "#ffffff",
5398
5591
  surfaceStyle: "flat",
5592
+ // amber-400 / emerald-400: the 700s above are far too dark to read on
5593
+ // slate-900, and this pair is the same news in the same order at the light
5594
+ // end of the ramp — 10.69 and 9.29 against the dark surface, also pinned.
5595
+ surchargeColor: "#fbbf24",
5596
+ discountColor: "#34d399",
5399
5597
  trustBadges: DEFAULT_BADGES_DARK.map((b) => ({ ...b })),
5400
5598
  customFields: []
5401
5599
  };
@@ -5406,7 +5604,16 @@ function cloneBranding(b) {
5406
5604
  return {
5407
5605
  ...b,
5408
5606
  trustBadges: b.trustBadges.map((badge) => ({ ...badge })),
5409
- customFields: b.customFields.map(cloneCustomField)
5607
+ customFields: b.customFields.map(cloneCustomField),
5608
+ // Copied, not shared. A spread alone would leave the clone pointing at the
5609
+ // original's maps, and the dashboard edits a clone precisely so the form
5610
+ // can be abandoned without touching what is saved.
5611
+ surchargeWordTranslations: { ...b.surchargeWordTranslations },
5612
+ discountWordTranslations: { ...b.discountWordTranslations },
5613
+ headerTextTranslations: { ...b.headerTextTranslations },
5614
+ payButtonLabelTranslations: { ...b.payButtonLabelTranslations },
5615
+ cardTermsMessageTranslations: { ...b.cardTermsMessageTranslations },
5616
+ footerTextTranslations: { ...b.footerTextTranslations }
5410
5617
  };
5411
5618
  }
5412
5619
  function cloneCustomField(f) {
@@ -5557,13 +5764,25 @@ function defaultCustomFieldVisibility() {
5557
5764
  return { mode: "always", match: "all", conditions: [] };
5558
5765
  }
5559
5766
  function parseTranslations(raw) {
5560
- if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
5767
+ let value = raw;
5768
+ if (typeof value === "string") {
5769
+ try {
5770
+ value = JSON.parse(value);
5771
+ } catch {
5772
+ return {};
5773
+ }
5774
+ }
5775
+ if (!value || typeof value !== "object" || Array.isArray(value)) return {};
5561
5776
  const out = {};
5562
- for (const [k, v] of Object.entries(raw)) {
5563
- if (typeof v === "string" && v.length > 0) out[k] = v;
5777
+ for (const [k, v] of Object.entries(value)) {
5778
+ if (typeof v === "string" && v.trim().length > 0) out[k] = v;
5564
5779
  }
5565
5780
  return out;
5566
5781
  }
5782
+ function encodeTranslations(map) {
5783
+ const entries = Object.entries(map).filter(([, v]) => v.trim().length > 0);
5784
+ return entries.length > 0 ? JSON.stringify(Object.fromEntries(entries)) : void 0;
5785
+ }
5567
5786
  function normalizeCondition(raw, index) {
5568
5787
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
5569
5788
  const c = raw;
@@ -5915,6 +6134,74 @@ function decodeBranding(source) {
5915
6134
  ["sm", "md", "lg"],
5916
6135
  DEFAULT_BRANDING.buttonSize
5917
6136
  ),
6137
+ showSurcharge: parseBool(extras["showSurcharge"], DEFAULT_BRANDING.showSurcharge),
6138
+ surchargePosition: pickEnum(
6139
+ extras["surchargePosition"],
6140
+ SURCHARGE_POSITIONS,
6141
+ DEFAULT_BRANDING.surchargePosition
6142
+ ),
6143
+ surchargeStyle: pickEnum(
6144
+ extras["surchargeStyle"],
6145
+ SURCHARGE_STYLES,
6146
+ DEFAULT_BRANDING.surchargeStyle
6147
+ ),
6148
+ surchargeSize: pickEnum(
6149
+ extras["surchargeSize"],
6150
+ SURCHARGE_SIZES,
6151
+ DEFAULT_BRANDING.surchargeSize
6152
+ ),
6153
+ surchargeShape: pickEnum(
6154
+ extras["surchargeShape"],
6155
+ SURCHARGE_SHAPES,
6156
+ DEFAULT_BRANDING.surchargeShape
6157
+ ),
6158
+ surchargeBorderWidth: pickEnum(
6159
+ extras["surchargeBorderWidth"],
6160
+ SURCHARGE_BORDER_WIDTHS,
6161
+ DEFAULT_BRANDING.surchargeBorderWidth
6162
+ ),
6163
+ surchargeBorderStyle: pickEnum(
6164
+ extras["surchargeBorderStyle"],
6165
+ SURCHARGE_BORDER_STYLES,
6166
+ DEFAULT_BRANDING.surchargeBorderStyle
6167
+ ),
6168
+ surchargeWeight: pickEnum(
6169
+ extras["surchargeWeight"],
6170
+ SURCHARGE_WEIGHTS,
6171
+ DEFAULT_BRANDING.surchargeWeight
6172
+ ),
6173
+ surchargeSign: pickEnum(
6174
+ extras["surchargeSign"],
6175
+ SURCHARGE_SIGNS,
6176
+ DEFAULT_BRANDING.surchargeSign
6177
+ ),
6178
+ surchargeUppercase: parseBool(
6179
+ extras["surchargeUppercase"],
6180
+ DEFAULT_BRANDING.surchargeUppercase
6181
+ ),
6182
+ surchargeLabel: pickEnum(
6183
+ extras["surchargeLabel"],
6184
+ SURCHARGE_LABEL_MODES,
6185
+ DEFAULT_BRANDING.surchargeLabel
6186
+ ),
6187
+ surchargeFigure: pickEnum(
6188
+ extras["surchargeFigure"],
6189
+ SURCHARGE_FIGURE_MODES,
6190
+ DEFAULT_BRANDING.surchargeFigure
6191
+ ),
6192
+ discountFigure: pickEnum(
6193
+ extras["discountFigure"],
6194
+ SURCHARGE_FIGURE_MODES,
6195
+ DEFAULT_BRANDING.discountFigure
6196
+ ),
6197
+ surchargeWordTranslations: parseTranslations(extras["surchargeWordTranslations"]),
6198
+ discountWordTranslations: parseTranslations(extras["discountWordTranslations"]),
6199
+ headerTextTranslations: parseTranslations(extras["headerTextTranslations"]),
6200
+ payButtonLabelTranslations: parseTranslations(extras["payButtonLabelTranslations"]),
6201
+ cardTermsMessageTranslations: parseTranslations(extras["cardTermsMessageTranslations"]),
6202
+ footerTextTranslations: parseTranslations(extras["footerTextTranslations"]),
6203
+ surchargeColor: s(extras["surchargeColor"]) || DEFAULT_BRANDING.surchargeColor,
6204
+ discountColor: s(extras["discountColor"]) || DEFAULT_BRANDING.discountColor,
5918
6205
  layout: pickEnum(extras["layout"], ["compact", "split"], DEFAULT_BRANDING.layout),
5919
6206
  summaryPosition: pickEnum(
5920
6207
  extras["summaryPosition"],
@@ -5968,6 +6255,21 @@ function encodeBranding(branding, base) {
5968
6255
  verticalGap: branding.verticalGap,
5969
6256
  inputSize: branding.inputSize,
5970
6257
  buttonSize: branding.buttonSize,
6258
+ showSurcharge: String(branding.showSurcharge),
6259
+ surchargePosition: branding.surchargePosition,
6260
+ surchargeStyle: branding.surchargeStyle,
6261
+ surchargeSize: branding.surchargeSize,
6262
+ surchargeShape: branding.surchargeShape,
6263
+ surchargeBorderWidth: branding.surchargeBorderWidth,
6264
+ surchargeBorderStyle: branding.surchargeBorderStyle,
6265
+ surchargeWeight: branding.surchargeWeight,
6266
+ surchargeSign: branding.surchargeSign,
6267
+ surchargeUppercase: String(branding.surchargeUppercase),
6268
+ surchargeLabel: branding.surchargeLabel,
6269
+ surchargeFigure: branding.surchargeFigure,
6270
+ discountFigure: branding.discountFigure,
6271
+ surchargeColor: branding.surchargeColor,
6272
+ discountColor: branding.discountColor,
5971
6273
  layout: branding.layout,
5972
6274
  summaryPosition: branding.summaryPosition,
5973
6275
  showOrderSummary: String(branding.showOrderSummary),
@@ -5985,6 +6287,17 @@ function encodeBranding(branding, base) {
5985
6287
  if (branding.customFields.length > 0) {
5986
6288
  extras["customFields"] = encodeCustomFields(branding.customFields);
5987
6289
  }
6290
+ for (const key of [
6291
+ "surchargeWordTranslations",
6292
+ "discountWordTranslations",
6293
+ "headerTextTranslations",
6294
+ "payButtonLabelTranslations",
6295
+ "cardTermsMessageTranslations",
6296
+ "footerTextTranslations"
6297
+ ]) {
6298
+ const encoded = encodeTranslations(branding[key]);
6299
+ if (encoded) extras[key] = encoded;
6300
+ }
5988
6301
  const tagline = trim(branding.tagline);
5989
6302
  if (tagline) extras["tagline"] = tagline;
5990
6303
  const footer = trim(branding.footerText);
@@ -6093,6 +6406,71 @@ function parseImportedBranding(raw) {
6093
6406
  ),
6094
6407
  inputSize: pickEnum(root["inputSize"], ["sm", "md", "lg"], dflt.inputSize),
6095
6408
  buttonSize: pickEnum(root["buttonSize"], ["sm", "md", "lg"], dflt.buttonSize),
6409
+ showSurcharge: parseBool(root["showSurcharge"], dflt.showSurcharge),
6410
+ surchargePosition: pickEnum(
6411
+ root["surchargePosition"],
6412
+ SURCHARGE_POSITIONS,
6413
+ dflt.surchargePosition
6414
+ ),
6415
+ surchargeStyle: pickEnum(
6416
+ root["surchargeStyle"],
6417
+ SURCHARGE_STYLES,
6418
+ dflt.surchargeStyle
6419
+ ),
6420
+ surchargeSize: pickEnum(
6421
+ root["surchargeSize"],
6422
+ SURCHARGE_SIZES,
6423
+ dflt.surchargeSize
6424
+ ),
6425
+ surchargeShape: pickEnum(
6426
+ root["surchargeShape"],
6427
+ SURCHARGE_SHAPES,
6428
+ dflt.surchargeShape
6429
+ ),
6430
+ surchargeBorderWidth: pickEnum(
6431
+ root["surchargeBorderWidth"],
6432
+ SURCHARGE_BORDER_WIDTHS,
6433
+ dflt.surchargeBorderWidth
6434
+ ),
6435
+ surchargeBorderStyle: pickEnum(
6436
+ root["surchargeBorderStyle"],
6437
+ SURCHARGE_BORDER_STYLES,
6438
+ dflt.surchargeBorderStyle
6439
+ ),
6440
+ surchargeWeight: pickEnum(
6441
+ root["surchargeWeight"],
6442
+ SURCHARGE_WEIGHTS,
6443
+ dflt.surchargeWeight
6444
+ ),
6445
+ surchargeSign: pickEnum(
6446
+ root["surchargeSign"],
6447
+ SURCHARGE_SIGNS,
6448
+ dflt.surchargeSign
6449
+ ),
6450
+ surchargeUppercase: parseBool(root["surchargeUppercase"], dflt.surchargeUppercase),
6451
+ surchargeLabel: pickEnum(
6452
+ root["surchargeLabel"],
6453
+ SURCHARGE_LABEL_MODES,
6454
+ dflt.surchargeLabel
6455
+ ),
6456
+ surchargeFigure: pickEnum(
6457
+ root["surchargeFigure"],
6458
+ SURCHARGE_FIGURE_MODES,
6459
+ dflt.surchargeFigure
6460
+ ),
6461
+ discountFigure: pickEnum(
6462
+ root["discountFigure"],
6463
+ SURCHARGE_FIGURE_MODES,
6464
+ dflt.discountFigure
6465
+ ),
6466
+ surchargeWordTranslations: parseTranslations(root["surchargeWordTranslations"]),
6467
+ discountWordTranslations: parseTranslations(root["discountWordTranslations"]),
6468
+ headerTextTranslations: parseTranslations(root["headerTextTranslations"]),
6469
+ payButtonLabelTranslations: parseTranslations(root["payButtonLabelTranslations"]),
6470
+ cardTermsMessageTranslations: parseTranslations(root["cardTermsMessageTranslations"]),
6471
+ footerTextTranslations: parseTranslations(root["footerTextTranslations"]),
6472
+ surchargeColor: sHex(root["surchargeColor"], dflt.surchargeColor),
6473
+ discountColor: sHex(root["discountColor"], dflt.discountColor),
6096
6474
  layout: pickEnum(root["layout"], ["compact", "split"], dflt.layout),
6097
6475
  summaryPosition: pickEnum(
6098
6476
  root["summaryPosition"],
@@ -6159,6 +6537,19 @@ function applyBrandingVariables(el, b) {
6159
6537
  set("--dp-gap-vertical", VERTICAL_GAP[b.verticalGap]);
6160
6538
  set("--dp-input-pad", INPUT_PAD[b.inputSize]);
6161
6539
  set("--dp-button-pad", BUTTON_PAD[b.buttonSize]);
6540
+ set("--dp-surcharge", b.surchargeColor);
6541
+ set("--dp-discount", b.discountColor);
6542
+ set("--dp-surcharge-ink", readableInkOn(b.surchargeColor));
6543
+ set("--dp-discount-ink", readableInkOn(b.discountColor));
6544
+ set("--dp-surcharge-size", SURCHARGE_FONT_SIZE[b.surchargeSize]);
6545
+ set("--dp-surcharge-pad", SURCHARGE_PAD[b.surchargeSize]);
6546
+ set("--dp-surcharge-radius", SURCHARGE_RADIUS[b.surchargeShape]);
6547
+ set("--dp-surcharge-weight", SURCHARGE_FONT_WEIGHT[b.surchargeWeight]);
6548
+ set(
6549
+ "--dp-surcharge-border-width",
6550
+ SURCHARGE_BORDER_WIDTH[b.surchargeStyle === "outline" && b.surchargeBorderWidth === "none" ? "thin" : b.surchargeBorderWidth]
6551
+ );
6552
+ set("--dp-surcharge-border-style", b.surchargeBorderStyle);
6162
6553
  set("--dp-shadow", shadowFor(b.surfaceStyle));
6163
6554
  set(
6164
6555
  "--dp-surface-border",
@@ -6549,9 +6940,9 @@ var STRIPE_FALLBACK_PANE_METHODS = [
6549
6940
  requiresBillingCountry: true,
6550
6941
  defaultLabel: "Klarna",
6551
6942
  // NOT the router's current "Pay later or in 3 instalments". This table is
6552
- // what a router predating the capability endpoint (delopay-backend#964)
6553
- // renders, and that copy only gained the "3" in delopay-backend#1051
6554
- // the same release that added the endpoint. Restating the new string here
6943
+ // what a router predating the capability endpoint renders, and that copy
6944
+ // only gained the "3" in the same release that added the endpoint.
6945
+ // Restating the new string here
6555
6946
  // would put copy no reachable router emits in front of a merchant, and
6556
6947
  // would change what the deprecated `nativePaneMethodInfo` has returned
6557
6948
  // since 0.106.0.
@@ -7660,6 +8051,63 @@ var PlatformBilling = class {
7660
8051
  body: params
7661
8052
  });
7662
8053
  }
8054
+ /**
8055
+ * Mark a merchant free (not billed), or put it back on the prepaid model.
8056
+ * While free, no platform fee is deducted, the payment gate never blocks on
8057
+ * billing status, top-ups are refused and auto-recharge is inert. Marking
8058
+ * free needs a `reason` and is refused (412) while an admin suspension is in
8059
+ * force — lift that first.
8060
+ *
8061
+ * Requires a router that supports the free flag; older ones answer `404`.
8062
+ *
8063
+ * @param merchantId - The merchant account ID.
8064
+ * @param params - The desired free state and, when marking free, the reason.
8065
+ * @returns The updated billing profile.
8066
+ */
8067
+ async setFree(merchantId, params) {
8068
+ return this.request("PATCH", `/billing/${encodeURIComponent(merchantId)}/admin/free`, {
8069
+ body: params
8070
+ });
8071
+ }
8072
+ /**
8073
+ * Delete a merchant's **entire** ledger. Every live entry is soft-deleted —
8074
+ * kept, so a replayed fee deduction or top-up webhook still no-ops — the
8075
+ * balance is set to zero and the status re-derived (`active` for a free
8076
+ * merchant; an active paying merchant lands in `delinquent`). Refused (412)
8077
+ * while the merchant has shop allocations. Audited.
8078
+ *
8079
+ * Requires a router that serves the ledger admin routes; older ones answer
8080
+ * `404`.
8081
+ *
8082
+ * @param merchantId - The merchant account ID.
8083
+ * @param params - The reason, required for audit.
8084
+ * @returns What was removed and the post-reset profile.
8085
+ */
8086
+ async resetLedger(merchantId, params) {
8087
+ return this.request("DELETE", `/billing/${encodeURIComponent(merchantId)}/admin/ledger`, {
8088
+ body: params
8089
+ });
8090
+ }
8091
+ /**
8092
+ * (Re)create a merchant's ledger, optionally seeded with an opening
8093
+ * balance. Ensures the billing profile exists (created without the welcome
8094
+ * promo credit) and, when `opening_balance` is set, writes one
8095
+ * `opening_balance` entry through the same atomic helper an admin credit
8096
+ * uses. Refused (412) while live entries or a non-zero balance remain —
8097
+ * reset first. Does not clear the free flag. Audited.
8098
+ *
8099
+ * Requires a router that serves the ledger admin routes; older ones answer
8100
+ * `404`.
8101
+ *
8102
+ * @param merchantId - The merchant account ID.
8103
+ * @param params - Opening balance (minor units), currency for a new profile, and the reason.
8104
+ * @returns The opening entry id (if one was written) and the profile.
8105
+ */
8106
+ async createLedger(merchantId, params) {
8107
+ return this.request("POST", `/billing/${encodeURIComponent(merchantId)}/admin/ledger`, {
8108
+ body: params
8109
+ });
8110
+ }
7663
8111
  };
7664
8112
 
7665
8113
  // src/internal/resources/platformFees.ts
@@ -7772,6 +8220,7 @@ var DelopayInternal = class extends Delopay {
7772
8220
  CHECKBOX_CHECKED,
7773
8221
  CHECKBOX_UNCHECKED,
7774
8222
  CHECKOUT_EVENT_KINDS,
8223
+ CHECKOUT_LOCALES,
7775
8224
  CUSTOM_CSS_MAX_LENGTH,
7776
8225
  CUSTOM_FIELDS_MAX,
7777
8226
  CUSTOM_FIELD_CONDITIONS_MAX,
@@ -7799,6 +8248,7 @@ var DelopayInternal = class extends Delopay {
7799
8248
  Files,
7800
8249
  Forex,
7801
8250
  Gsm,
8251
+ LOCALIZABLE_COPY_FIELDS,
7802
8252
  NATIVE_PANES_MAX,
7803
8253
  NATIVE_PANE_CATEGORY_KEYS,
7804
8254
  NATIVE_PANE_ICON_KEYS,
@@ -7813,6 +8263,16 @@ var DelopayInternal = class extends Delopay {
7813
8263
  STRIPE_FALLBACK_PANE_CATALOG,
7814
8264
  STRIPE_FALLBACK_PANE_METHODS,
7815
8265
  STRIPE_NATIVE_PANE_METHODS,
8266
+ SURCHARGE_BORDER_STYLES,
8267
+ SURCHARGE_BORDER_WIDTHS,
8268
+ SURCHARGE_FIGURE_MODES,
8269
+ SURCHARGE_LABEL_MODES,
8270
+ SURCHARGE_POSITIONS,
8271
+ SURCHARGE_SHAPES,
8272
+ SURCHARGE_SIGNS,
8273
+ SURCHARGE_SIZES,
8274
+ SURCHARGE_STYLES,
8275
+ SURCHARGE_WEIGHTS,
7816
8276
  Search,
7817
8277
  Settlement,
7818
8278
  Subscriptions,
@@ -7824,11 +8284,13 @@ var DelopayInternal = class extends Delopay {
7824
8284
  applyBrandingVariables,
7825
8285
  buildBrandingExport,
7826
8286
  buttonPadValue,
8287
+ checkoutCopy,
7827
8288
  cloneBranding,
7828
8289
  cloneCustomField,
7829
8290
  cloneNativePane,
7830
8291
  clonePane,
7831
8292
  contrastRatio,
8293
+ copyTranslationsKey,
7832
8294
  customFieldContextFromMetadata,
7833
8295
  customFieldIsTextLike,
7834
8296
  customFieldOperatorTakesValue,
@@ -7873,9 +8335,14 @@ var DelopayInternal = class extends Delopay {
7873
8335
  parseImportedBranding,
7874
8336
  programToTree,
7875
8337
  radiusValue,
8338
+ readableInkOn,
7876
8339
  ruleMatchToTree,
7877
8340
  sanitizeCustomCss,
7878
8341
  shadowFor,
8342
+ surchargeFigurePlan,
8343
+ surchargeShowsLabel,
8344
+ surchargeStyleDrawsAShape,
8345
+ surchargeWordFor,
7879
8346
  surfacePadValue,
7880
8347
  validatePanes,
7881
8348
  verticalGapValue,