@delopay/sdk 0.164.0 → 0.166.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
@@ -71,6 +71,7 @@ __export(internal_exports, {
71
71
  DEFAULT_BADGES_DARK: () => DEFAULT_BADGES_DARK,
72
72
  DEFAULT_BRANDING: () => DEFAULT_BRANDING,
73
73
  DEFAULT_BRANDING_DARK: () => DEFAULT_BRANDING_DARK,
74
+ DEFAULT_NOTICES: () => DEFAULT_NOTICES,
74
75
  Delopay: () => Delopay,
75
76
  DelopayAuthenticationError: () => DelopayAuthenticationError,
76
77
  DelopayError: () => DelopayError,
@@ -95,6 +96,12 @@ __export(internal_exports, {
95
96
  NATIVE_PANE_CATEGORY_KEYS: () => NATIVE_PANE_CATEGORY_KEYS,
96
97
  NATIVE_PANE_ICON_KEYS: () => NATIVE_PANE_ICON_KEYS,
97
98
  NOMUPAY_FORM_STYLES: () => NOMUPAY_FORM_STYLES,
99
+ NOTICES_PER_SECTION: () => NOTICES_PER_SECTION,
100
+ NOTICE_ICONS: () => NOTICE_ICONS,
101
+ NOTICE_ICON_FALLBACK: () => NOTICE_ICON_FALLBACK,
102
+ NOTICE_ICON_PATHS: () => NOTICE_ICON_PATHS,
103
+ NOTICE_LABEL_MAX_LENGTH: () => NOTICE_LABEL_MAX_LENGTH,
104
+ NOTICE_SECTIONS: () => NOTICE_SECTIONS,
98
105
  OperationLimits: () => OperationLimits,
99
106
  PANES_MAX: () => PANES_MAX,
100
107
  PANE_CATEGORY_KEYS: () => PANE_CATEGORY_KEYS,
@@ -154,6 +161,7 @@ __export(internal_exports, {
154
161
  cloneBranding: () => cloneBranding,
155
162
  cloneCustomField: () => cloneCustomField,
156
163
  cloneNativePane: () => cloneNativePane,
164
+ cloneNotice: () => cloneNotice,
157
165
  clonePane: () => clonePane,
158
166
  compareSections: () => compareSections,
159
167
  contrastRatio: () => contrastRatio,
@@ -169,11 +177,13 @@ __export(internal_exports, {
169
177
  decodeMethodSectionLabels: () => decodeMethodSectionLabels,
170
178
  decodeMethodSectionOrder: () => decodeMethodSectionOrder,
171
179
  decodeNativePanes: () => decodeNativePanes,
180
+ decodeNotices: () => decodeNotices,
172
181
  decodePanes: () => decodePanes,
173
182
  defaultBranding: () => defaultBranding,
174
183
  defaultCustomFieldVisibility: () => defaultCustomFieldVisibility,
175
184
  defaultMethodSectionOrder: () => defaultMethodSectionOrder,
176
185
  defaultNativePane: () => defaultNativePane,
186
+ defaultNotices: () => defaultNotices,
177
187
  defaultOperatorForSource: () => defaultOperatorForSource,
178
188
  defaultPane: () => defaultPane,
179
189
  emptyPaneCatalog: () => emptyPaneCatalog,
@@ -183,6 +193,7 @@ __export(internal_exports, {
183
193
  encodeMethodSectionLabels: () => encodeMethodSectionLabels,
184
194
  encodeMethodSectionOrder: () => encodeMethodSectionOrder,
185
195
  encodeNativePanes: () => encodeNativePanes,
196
+ encodeNotices: () => encodeNotices,
186
197
  encodePanes: () => encodePanes,
187
198
  evaluateCustomFieldCondition: () => evaluateCustomFieldCondition,
188
199
  evaluateCustomFieldVisibility: () => evaluateCustomFieldVisibility,
@@ -193,13 +204,17 @@ __export(internal_exports, {
193
204
  inputPadValue: () => inputPadValue,
194
205
  isCheckboxChecked: () => isCheckboxChecked,
195
206
  isDarkSurface: () => isDarkSurface,
207
+ isDefaultBadgeSet: () => isDefaultBadgeSet,
196
208
  isHexColor: () => isHexColor,
209
+ isNoticeIcon: () => isNoticeIcon,
197
210
  isSubscriptionDisputeWebhook: () => isSubscriptionDisputeWebhook,
198
211
  isSubscriptionLifecycleWebhook: () => isSubscriptionLifecycleWebhook,
199
212
  knownSectionLabelKey: () => knownSectionLabelKey,
200
213
  leaf: () => leaf,
201
214
  logoDimensions: () => logoDimensions,
202
215
  nativePaneMethodInfo: () => nativePaneMethodInfo,
216
+ noticeText: () => noticeText,
217
+ noticesIn: () => noticesIn,
203
218
  offerablePaneMethods: () => offerablePaneMethods,
204
219
  paneCatalogFor: () => paneCatalogFor,
205
220
  paneDisplayDefaults: () => paneDisplayDefaults,
@@ -208,6 +223,7 @@ __export(internal_exports, {
208
223
  paneViewVisibility: () => paneViewVisibility,
209
224
  parseCustomFieldsLoose: () => parseCustomFieldsLoose,
210
225
  parseImportedBranding: () => parseImportedBranding,
226
+ parseNoticesLoose: () => parseNoticesLoose,
211
227
  programToTree: () => programToTree,
212
228
  radiusValue: () => radiusValue,
213
229
  readableInkOn: () => readableInkOn,
@@ -215,12 +231,14 @@ __export(internal_exports, {
215
231
  resolveAirwallexLabelStyle: () => resolveAirwallexLabelStyle,
216
232
  resolveApplePayButtonStyle: () => resolveApplePayButtonStyle,
217
233
  resolveGooglePayButtonColor: () => resolveGooglePayButtonColor,
234
+ resolveNoticesAndBadges: () => resolveNoticesAndBadges,
218
235
  resolveStripeTheme: () => resolveStripeTheme,
219
236
  ruleMatchToTree: () => ruleMatchToTree,
220
237
  sanitizeCustomCss: () => sanitizeCustomCss,
221
238
  sectionLabel: () => sectionLabel,
222
239
  sectionOrderOf: () => sectionOrderOf,
223
240
  shadowFor: () => shadowFor,
241
+ shownNotices: () => shownNotices,
224
242
  stripeSpacingValues: () => stripeSpacingValues,
225
243
  surchargeFigurePlan: () => surchargeFigurePlan,
226
244
  surchargeShowsLabel: () => surchargeShowsLabel,
@@ -1174,6 +1192,289 @@ var Customers = class {
1174
1192
  }
1175
1193
  };
1176
1194
 
1195
+ // src/recordCounter.ts
1196
+ var LF = 10;
1197
+ var CR = 13;
1198
+ var QUOTE = 34;
1199
+ var BACKSLASH = 92;
1200
+ var OPEN_BRACE = 123;
1201
+ var CLOSE_BRACE = 125;
1202
+ var OPEN_BRACKET = 91;
1203
+ var CLOSE_BRACKET = 93;
1204
+ var CsvRecordCounter = class {
1205
+ constructor() {
1206
+ this.inQuotes = false;
1207
+ this.newlines = 0;
1208
+ /** Whether anything but a line break has arrived since the last newline. */
1209
+ this.lineHasContent = false;
1210
+ }
1211
+ push(chunk) {
1212
+ let inQuotes = this.inQuotes;
1213
+ let newlines = this.newlines;
1214
+ let lineHasContent = this.lineHasContent;
1215
+ for (const byte of chunk) {
1216
+ if (byte === QUOTE) {
1217
+ inQuotes = !inQuotes;
1218
+ lineHasContent = true;
1219
+ } else if (inQuotes) {
1220
+ lineHasContent = true;
1221
+ } else if (byte === LF) {
1222
+ newlines++;
1223
+ lineHasContent = false;
1224
+ } else if (byte !== CR) {
1225
+ lineHasContent = true;
1226
+ }
1227
+ }
1228
+ this.inQuotes = inQuotes;
1229
+ this.newlines = newlines;
1230
+ this.lineHasContent = lineHasContent;
1231
+ }
1232
+ get records() {
1233
+ return Math.max(0, this.newlines - 1);
1234
+ }
1235
+ /**
1236
+ * The export writer ends every line — the header and each record — with a
1237
+ * newline, so a whole body ends on one, outside quotes. RFC 4180 lets a
1238
+ * final line break be omitted, but these bodies never omit it, and without
1239
+ * that rule a file cut part-way through its last unquoted field
1240
+ * (`pay_1,12` of `pay_1,123`) would count as one more whole record and
1241
+ * match the figure it was announced with.
1242
+ */
1243
+ get complete() {
1244
+ return this.newlines >= 1 && !this.inQuotes && !this.lineHasContent;
1245
+ }
1246
+ /**
1247
+ * The records that ended. An unterminated tail is not one of them — see
1248
+ * {@link complete}.
1249
+ */
1250
+ finish() {
1251
+ return this.records;
1252
+ }
1253
+ };
1254
+ var SEEKING = 0;
1255
+ var COUNTING = 1;
1256
+ var CLOSED = 2;
1257
+ var JsonArrayRecordCounter = class {
1258
+ constructor() {
1259
+ this.depth = 0;
1260
+ this.inString = false;
1261
+ this.escaped = false;
1262
+ this.topIsObject = false;
1263
+ this.state = SEEKING;
1264
+ this.count = 0;
1265
+ }
1266
+ push(chunk) {
1267
+ if (this.state === CLOSED) return;
1268
+ let { depth, inString, escaped, topIsObject, count } = this;
1269
+ let state = this.state;
1270
+ for (const byte of chunk) {
1271
+ if (inString) {
1272
+ if (escaped) escaped = false;
1273
+ else if (byte === BACKSLASH) escaped = true;
1274
+ else if (byte === QUOTE) inString = false;
1275
+ continue;
1276
+ }
1277
+ if (byte === QUOTE) {
1278
+ inString = true;
1279
+ } else if (byte === OPEN_BRACE || byte === OPEN_BRACKET) {
1280
+ if (depth === 0 && byte === OPEN_BRACE) topIsObject = true;
1281
+ if (byte === OPEN_BRACKET && depth === 1 && topIsObject && state === SEEKING) {
1282
+ state = COUNTING;
1283
+ }
1284
+ depth++;
1285
+ } else if (byte === CLOSE_BRACE || byte === CLOSE_BRACKET) {
1286
+ depth--;
1287
+ if (state === COUNTING) {
1288
+ if (depth === 2) count++;
1289
+ else if (depth === 1) {
1290
+ state = CLOSED;
1291
+ break;
1292
+ }
1293
+ }
1294
+ }
1295
+ }
1296
+ this.depth = depth;
1297
+ this.inString = inString;
1298
+ this.escaped = escaped;
1299
+ this.topIsObject = topIsObject;
1300
+ this.state = state;
1301
+ this.count = count;
1302
+ }
1303
+ get records() {
1304
+ return this.count;
1305
+ }
1306
+ /**
1307
+ * Whether the rows array has closed. What follows it is checked by parsing
1308
+ * the whole document, which a cut-off body fails.
1309
+ */
1310
+ get complete() {
1311
+ return this.state === CLOSED;
1312
+ }
1313
+ finish() {
1314
+ return this.count;
1315
+ }
1316
+ };
1317
+
1318
+ // src/exportDownload.ts
1319
+ var RECORD_COUNT_HEADER = "x-delopay-record-count";
1320
+ var LIST_ENVELOPE = { rows: "records", count: "record_count" };
1321
+ var WORKSPACE_ENVELOPE = { rows: "data", count: "total_count" };
1322
+ function parseRecordCount(header) {
1323
+ if (header === null) return null;
1324
+ const trimmed = header.trim();
1325
+ if (!/^\d+$/.test(trimmed)) return null;
1326
+ const value = Number(trimmed);
1327
+ return Number.isSafeInteger(value) ? value : null;
1328
+ }
1329
+ function counterFor(format) {
1330
+ if (format === "csv") return new CsvRecordCounter();
1331
+ if (format === "json") return new JsonArrayRecordCounter();
1332
+ return null;
1333
+ }
1334
+ function isRecord(value) {
1335
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1336
+ }
1337
+ function announced(expected) {
1338
+ return expected === null ? "" : ` of the ${expected} announced`;
1339
+ }
1340
+ function incomplete(message, expected, received, requestId) {
1341
+ return new DelopayError(message, {
1342
+ status: 0,
1343
+ code: "EXPORT_INCOMPLETE",
1344
+ type: "export_incomplete",
1345
+ ...requestId !== void 0 ? { requestId } : {},
1346
+ data: { expected_records: expected, received_records: received }
1347
+ });
1348
+ }
1349
+ async function downloadExport(request, call, options) {
1350
+ const { format } = call;
1351
+ const envelope = call.envelope ?? LIST_ENVELOPE;
1352
+ const onProgress = options?.onProgress;
1353
+ let latest = {
1354
+ phase: "preparing",
1355
+ receivedBytes: 0,
1356
+ totalBytes: null,
1357
+ receivedRecords: 0,
1358
+ expectedRecords: null
1359
+ };
1360
+ const seen = { attempt: -1, counter: null, expected: null, requestId: void 0, listenerError: null };
1361
+ const report = (progress) => {
1362
+ latest = progress;
1363
+ if (!onProgress) return;
1364
+ try {
1365
+ onProgress({ ...progress });
1366
+ } catch (error) {
1367
+ seen.listenerError = { error };
1368
+ throw error;
1369
+ }
1370
+ };
1371
+ report(latest);
1372
+ const onDownloadProgress = (event) => {
1373
+ if (event.attempt !== seen.attempt) {
1374
+ seen.attempt = event.attempt;
1375
+ seen.counter = counterFor(format);
1376
+ seen.expected = format === "pdf" ? null : parseRecordCount(event.headers.get(RECORD_COUNT_HEADER));
1377
+ seen.requestId = event.headers.get("x-request-id") ?? event.headers.get("x-trace-id") ?? void 0;
1378
+ }
1379
+ if (event.chunk.byteLength > 0) seen.counter?.push(event.chunk);
1380
+ report({
1381
+ phase: "receiving",
1382
+ receivedBytes: event.loaded,
1383
+ totalBytes: event.total,
1384
+ receivedRecords: seen.counter?.records ?? 0,
1385
+ expectedRecords: seen.expected
1386
+ });
1387
+ };
1388
+ let result;
1389
+ try {
1390
+ result = await request(call.method, call.path, {
1391
+ ...call.request,
1392
+ ...options?.signal !== void 0 ? { signal: options.signal } : {},
1393
+ ...options?.timeout !== void 0 ? { timeout: options.timeout } : {},
1394
+ onDownloadProgress
1395
+ });
1396
+ } catch (err) {
1397
+ if (seen.listenerError !== null && err === seen.listenerError.error) throw err;
1398
+ if (format === "json" && seen.attempt >= 0 && err instanceof SyntaxError) {
1399
+ const received2 = seen.counter?.records ?? 0;
1400
+ throw incomplete(
1401
+ seen.expected === null ? `Export incomplete: the body ended part-way through the JSON document, after ${received2} records` : `Export incomplete: the server announced ${seen.expected} records, and the body ended part-way through the JSON document after ${received2}`,
1402
+ seen.expected,
1403
+ received2,
1404
+ seen.requestId
1405
+ );
1406
+ }
1407
+ throw err;
1408
+ }
1409
+ const { expected, requestId } = seen;
1410
+ let received = 0;
1411
+ if (format === "json") {
1412
+ const rows = isRecord(result) ? result[envelope.rows] : void 0;
1413
+ if (!Array.isArray(rows)) {
1414
+ throw incomplete(
1415
+ `Export incomplete: the body is not an export envelope with a "${envelope.rows}" array, so it carries 0 records${announced(expected)}`,
1416
+ expected,
1417
+ 0,
1418
+ requestId
1419
+ );
1420
+ }
1421
+ received = rows.length;
1422
+ const declared = isRecord(result) ? result[envelope.count] : void 0;
1423
+ if (typeof declared === "number" && declared !== rows.length) {
1424
+ throw incomplete(
1425
+ `Export incomplete: the file's ${envelope.count} is ${declared}, but it carries ${rows.length} records`,
1426
+ declared,
1427
+ rows.length,
1428
+ requestId
1429
+ );
1430
+ }
1431
+ } else if (format === "csv") {
1432
+ const counter = seen.counter;
1433
+ received = counter?.finish() ?? 0;
1434
+ if (!counter?.complete) {
1435
+ throw incomplete(
1436
+ `Export incomplete: the CSV body ended part-way through a line, after ${received} complete records${announced(expected)}`,
1437
+ expected,
1438
+ received,
1439
+ requestId
1440
+ );
1441
+ }
1442
+ }
1443
+ if (expected !== null && received !== expected) {
1444
+ throw incomplete(
1445
+ `Export incomplete: the server announced ${expected} records, and the body carried ${received}`,
1446
+ expected,
1447
+ received,
1448
+ requestId
1449
+ );
1450
+ }
1451
+ report({
1452
+ phase: "done",
1453
+ receivedBytes: latest.receivedBytes,
1454
+ totalBytes: latest.totalBytes,
1455
+ receivedRecords: received,
1456
+ expectedRecords: expected
1457
+ });
1458
+ return result;
1459
+ }
1460
+ var ACCEPT = {
1461
+ csv: "text/csv",
1462
+ json: "application/json",
1463
+ pdf: "application/pdf"
1464
+ };
1465
+ function negotiated(options, format) {
1466
+ const headers = { ...options.headers, Accept: ACCEPT[format] };
1467
+ return format === "json" ? { ...options, headers } : { ...options, headers, responseType: "blob" };
1468
+ }
1469
+ function runExport(request, method, path, base, options) {
1470
+ const format = options?.format ?? "json";
1471
+ return downloadExport(
1472
+ request,
1473
+ { method, path, request: negotiated(base, format), format },
1474
+ options
1475
+ );
1476
+ }
1477
+
1177
1478
  // src/resources/disputes.ts
1178
1479
  function workspaceQuery(params) {
1179
1480
  if (!params) return void 0;
@@ -1202,9 +1503,28 @@ var Disputes = class {
1202
1503
  async workspaceAggregate(params) {
1203
1504
  return this.request("GET", "/disputes/workspace/aggregate", { query: workspaceQuery(params) });
1204
1505
  }
1205
- /** Export the complete filtered set, or throw on the server's explicit export-limit refusal. */
1206
- async workspaceExport(params) {
1207
- return this.request("GET", "/disputes/workspace/export", { query: workspaceQuery(params) });
1506
+ /**
1507
+ * Export the complete filtered set, or throw on the server's explicit
1508
+ * export-limit refusal. `GET /disputes/workspace/export`
1509
+ *
1510
+ * The body is streamed, and held to the `X-Delopay-Record-Count` the server
1511
+ * announces and to its own `total_count`: a set that arrives short rejects
1512
+ * with `EXPORT_INCOMPLETE` rather than resolving. `options` reports the
1513
+ * download's progress and takes a signal and an idle timeout — see
1514
+ * {@link ExportTransferOptions}.
1515
+ */
1516
+ async workspaceExport(params, options) {
1517
+ return downloadExport(
1518
+ this.request,
1519
+ {
1520
+ method: "GET",
1521
+ path: "/disputes/workspace/export",
1522
+ request: { query: workspaceQuery(params) },
1523
+ format: "json",
1524
+ envelope: WORKSPACE_ENVELOPE
1525
+ },
1526
+ options
1527
+ );
1208
1528
  }
1209
1529
  /**
1210
1530
  * Retrieve a dispute by its ID.
@@ -4361,77 +4681,68 @@ var Export = class {
4361
4681
  this.request = request;
4362
4682
  }
4363
4683
  async transactions(params, options) {
4364
- return this.request(
4365
- "POST",
4366
- "/export/transactions",
4367
- transactionBody(params, options)
4368
- );
4684
+ return runExport(this.request, "POST", "/export/transactions", { body: params ?? {} }, options);
4369
4685
  }
4370
4686
  async transactionsForProfile(params, options) {
4371
- return this.request(
4687
+ return runExport(
4688
+ this.request,
4372
4689
  "POST",
4373
4690
  "/export/profile/transactions",
4374
- transactionBody(params, options)
4691
+ { body: params ?? {} },
4692
+ options
4375
4693
  );
4376
4694
  }
4377
4695
  async refunds(params, options) {
4378
- return this.request("POST", "/refunds/list/export", bodied(params ?? {}, options));
4696
+ return runExport(this.request, "POST", "/refunds/list/export", { body: params ?? {} }, options);
4379
4697
  }
4380
4698
  async refundsForProfile(params, options) {
4381
- return this.request(
4699
+ return runExport(
4700
+ this.request,
4382
4701
  "POST",
4383
4702
  "/refunds/profile/list/export",
4384
- bodied(params ?? {}, options)
4703
+ { body: params ?? {} },
4704
+ options
4385
4705
  );
4386
4706
  }
4387
4707
  async disputes(params, options) {
4388
- return this.request("GET", "/disputes/list/export", queried(params, options));
4708
+ return runExport(this.request, "GET", "/disputes/list/export", queried(params), options);
4389
4709
  }
4390
4710
  async disputesForProfile(params, options) {
4391
- return this.request(
4711
+ return runExport(
4712
+ this.request,
4392
4713
  "GET",
4393
4714
  "/disputes/profile/list/export",
4394
- queried(params, options)
4715
+ queried(params),
4716
+ options
4395
4717
  );
4396
4718
  }
4397
4719
  async payouts(params, options) {
4398
- return this.request("POST", "/payouts/list/export", bodied(params, options));
4720
+ return runExport(this.request, "POST", "/payouts/list/export", { body: params }, options);
4399
4721
  }
4400
4722
  async payoutsForProfile(params, options) {
4401
- return this.request("POST", "/payouts/profile/list/export", bodied(params, options));
4723
+ return runExport(
4724
+ this.request,
4725
+ "POST",
4726
+ "/payouts/profile/list/export",
4727
+ { body: params },
4728
+ options
4729
+ );
4402
4730
  }
4403
4731
  async subscriptions(profileId, params, options) {
4404
- return this.request(
4732
+ return runExport(
4733
+ this.request,
4405
4734
  "GET",
4406
4735
  "/subscriptions/list/export",
4407
- queried(params, options, { "X-Profile-Id": profileId })
4736
+ queried(params, { "X-Profile-Id": profileId }),
4737
+ options
4408
4738
  );
4409
4739
  }
4410
4740
  async auditLog(params, options) {
4411
- return this.request("GET", "/audit/export", queried(params, options));
4741
+ return runExport(this.request, "GET", "/audit/export", queried(params), options);
4412
4742
  }
4413
4743
  };
4414
- var ACCEPT = {
4415
- csv: "text/csv",
4416
- json: "application/json",
4417
- pdf: "application/pdf"
4418
- };
4419
- function negotiated(options, format) {
4420
- const headers = { ...options.headers, Accept: ACCEPT[format] };
4421
- return format === "json" ? { ...options, headers } : { ...options, headers, responseType: "blob" };
4422
- }
4423
- function transactionBody(params, options) {
4424
- const format = options?.format ?? "json";
4425
- return negotiated({ body: { ...params, format } }, format);
4426
- }
4427
- function bodied(body, options) {
4428
- return negotiated({ body }, options?.format ?? "json");
4429
- }
4430
- function queried(params, options, headers) {
4431
- return negotiated(
4432
- { query: params ?? {}, ...headers ? { headers } : {} },
4433
- options?.format ?? "json"
4434
- );
4744
+ function queried(params, headers) {
4745
+ return { query: params ?? {}, ...headers ? { headers } : {} };
4435
4746
  }
4436
4747
 
4437
4748
  // src/resources/featureMatrix.ts
@@ -5804,6 +6115,112 @@ function findIdempotencyKey(headers) {
5804
6115
  }
5805
6116
  function noop() {
5806
6117
  }
6118
+ var ListenerFailure = class {
6119
+ constructor(cause) {
6120
+ this.cause = cause;
6121
+ }
6122
+ };
6123
+ var BodyStreamFailure = class {
6124
+ constructor(cause) {
6125
+ this.cause = cause;
6126
+ }
6127
+ };
6128
+ function abortError() {
6129
+ const error = new Error("The operation was aborted");
6130
+ error.name = "AbortError";
6131
+ return error;
6132
+ }
6133
+ function parseContentLength(header) {
6134
+ if (header === null || !/^\s*\d+\s*$/.test(header)) return null;
6135
+ const value = Number(header);
6136
+ return Number.isSafeInteger(value) ? value : null;
6137
+ }
6138
+ function readChunk(reader, signal) {
6139
+ if (signal.aborted) return Promise.reject(abortError());
6140
+ return new Promise((resolve, reject) => {
6141
+ const onAbort = () => reject(abortError());
6142
+ signal.addEventListener("abort", onAbort, { once: true });
6143
+ reader.read().then(
6144
+ (result) => {
6145
+ signal.removeEventListener("abort", onAbort);
6146
+ resolve(result);
6147
+ },
6148
+ (cause) => {
6149
+ signal.removeEventListener("abort", onAbort);
6150
+ reject(signal.aborted ? abortError() : new BodyStreamFailure(cause));
6151
+ }
6152
+ );
6153
+ });
6154
+ }
6155
+ function concatChunks(chunks, length) {
6156
+ const out = new Uint8Array(length);
6157
+ let offset = 0;
6158
+ for (const chunk of chunks) {
6159
+ out.set(chunk, offset);
6160
+ offset += chunk.byteLength;
6161
+ }
6162
+ return out.buffer;
6163
+ }
6164
+ async function receiveWithProgress(response, responseType, listener, attempt, signal, onActivity) {
6165
+ const headers = response.headers ?? new Headers();
6166
+ const total = parseContentLength(headers.get("content-length"));
6167
+ let loaded = 0;
6168
+ const notify = (chunk) => {
6169
+ try {
6170
+ listener({ loaded, total, chunk: chunk.slice(), headers, attempt });
6171
+ } catch (cause) {
6172
+ throw new ListenerFailure(cause);
6173
+ }
6174
+ };
6175
+ onActivity();
6176
+ notify(new Uint8Array(0));
6177
+ const body = response.body;
6178
+ if (!body || typeof body.getReader !== "function") {
6179
+ if (responseType === "blob") {
6180
+ const blob = await response.blob();
6181
+ const bytes3 = new Uint8Array(await blob.arrayBuffer());
6182
+ loaded = bytes3.byteLength;
6183
+ if (loaded > 0) notify(bytes3);
6184
+ return blob;
6185
+ }
6186
+ if (responseType === "arraybuffer") {
6187
+ const buffer = await response.arrayBuffer();
6188
+ loaded = buffer.byteLength;
6189
+ if (loaded > 0) notify(new Uint8Array(buffer));
6190
+ return buffer;
6191
+ }
6192
+ const text2 = await response.text();
6193
+ const bytes2 = new TextEncoder().encode(text2);
6194
+ loaded = bytes2.byteLength;
6195
+ if (loaded > 0) notify(bytes2);
6196
+ return text2 ? JSON.parse(text2) : void 0;
6197
+ }
6198
+ const reader = body.getReader();
6199
+ const chunks = [];
6200
+ try {
6201
+ for (; ; ) {
6202
+ const { done, value } = await readChunk(reader, signal);
6203
+ if (done) break;
6204
+ if (!value || value.byteLength === 0) continue;
6205
+ chunks.push(value);
6206
+ loaded += value.byteLength;
6207
+ onActivity();
6208
+ notify(value);
6209
+ }
6210
+ } catch (err) {
6211
+ reader.cancel().catch(noop);
6212
+ throw err;
6213
+ }
6214
+ const bytes = concatChunks(chunks, loaded);
6215
+ if (responseType === "blob") {
6216
+ return new Blob([bytes], { type: headers.get("content-type") ?? "" });
6217
+ }
6218
+ if (responseType === "arraybuffer") {
6219
+ return bytes;
6220
+ }
6221
+ const text = new TextDecoder().decode(bytes);
6222
+ return text ? JSON.parse(text) : void 0;
6223
+ }
5807
6224
  function combineSignals(signals) {
5808
6225
  const controller = new AbortController();
5809
6226
  const listeners = [];
@@ -6085,7 +6502,12 @@ var Delopay = class {
6085
6502
  emit("retry", { attempt, maxRetries: this.maxRetries, method, path });
6086
6503
  }
6087
6504
  const timeoutCtrl = new AbortController();
6088
- const timeoutId = setTimeout(() => timeoutCtrl.abort(), timeoutMs);
6505
+ let timeoutId = setTimeout(() => timeoutCtrl.abort(), timeoutMs);
6506
+ const restartIdleTimer = () => {
6507
+ if (timeoutCtrl.signal.aborted) return;
6508
+ clearTimeout(timeoutId);
6509
+ timeoutId = setTimeout(() => timeoutCtrl.abort(), timeoutMs);
6510
+ };
6089
6511
  const combined = combineSignals(
6090
6512
  callerSignal ? [timeoutCtrl.signal, callerSignal] : [timeoutCtrl.signal]
6091
6513
  );
@@ -6143,6 +6565,16 @@ var Delopay = class {
6143
6565
  }
6144
6566
  throw error;
6145
6567
  }
6568
+ if (options?.onDownloadProgress) {
6569
+ return await receiveWithProgress(
6570
+ response,
6571
+ options.responseType,
6572
+ options.onDownloadProgress,
6573
+ attempt,
6574
+ combined.signal,
6575
+ restartIdleTimer
6576
+ );
6577
+ }
6146
6578
  if (options?.responseType === "blob") {
6147
6579
  return await response.blob();
6148
6580
  }
@@ -6155,6 +6587,20 @@ var Delopay = class {
6155
6587
  if (err instanceof DelopayError || err instanceof DelopayAuthenticationError) {
6156
6588
  throw err;
6157
6589
  }
6590
+ if (err instanceof ListenerFailure) {
6591
+ throw err.cause;
6592
+ }
6593
+ if (err instanceof BodyStreamFailure) {
6594
+ const cause = err.cause;
6595
+ const detail = cause instanceof Error ? cause.message : String(cause ?? "body stream failed");
6596
+ lastError = new DelopayError(`Network error: ${detail}`, {
6597
+ status: 0,
6598
+ code: "NETWORK",
6599
+ type: "network_error"
6600
+ });
6601
+ if (isRetryable && attempt < this.maxRetries) continue;
6602
+ throw lastError;
6603
+ }
6158
6604
  if (err instanceof Error && err.name === "AbortError") {
6159
6605
  if (callerSignal?.aborted) {
6160
6606
  throw new DelopayError("Request aborted", {
@@ -6732,6 +7178,66 @@ function surchargeWordFor(branding, isDiscount, locale) {
6732
7178
  locale
6733
7179
  );
6734
7180
  }
7181
+ var NOTICE_SECTIONS = ["summary", "payment"];
7182
+ var NOTICES_PER_SECTION = 3;
7183
+ var NOTICE_LABEL_MAX_LENGTH = 80;
7184
+ var NOTICE_ICONS = [
7185
+ "lock",
7186
+ "shield",
7187
+ "check",
7188
+ "truck",
7189
+ "package",
7190
+ "refresh",
7191
+ "star",
7192
+ "support",
7193
+ "globe",
7194
+ "tag",
7195
+ "heart",
7196
+ "leaf",
7197
+ "clock",
7198
+ "bank"
7199
+ ];
7200
+ var NOTICE_ICON_FALLBACK = "check";
7201
+ var NOTICE_ICON_PATHS = {
7202
+ lock: [
7203
+ "M6 10h12a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2z",
7204
+ "M8 10V7a4 4 0 0 1 8 0v3"
7205
+ ],
7206
+ shield: ["M12 3l7 3v6c0 4.2-2.9 7.6-7 9-4.1-1.4-7-4.8-7-9V6z", "M9 12l2.5 2.5 4-4.5"],
7207
+ check: ["M21 12a9 9 0 1 1-18 0a9 9 0 1 1 18 0z", "M8 12.5l3 3 5-6"],
7208
+ truck: [
7209
+ "M3 7.5h10v9H3z",
7210
+ "M13 11h4l3 3v2.5h-7z",
7211
+ "M8.8 18a1.8 1.8 0 1 1-3.6 0a1.8 1.8 0 1 1 3.6 0z",
7212
+ "M18.8 18a1.8 1.8 0 1 1-3.6 0a1.8 1.8 0 1 1 3.6 0z"
7213
+ ],
7214
+ package: [
7215
+ "M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z",
7216
+ "M12 22V12",
7217
+ "M3.29 7L12 12l8.71-5"
7218
+ ],
7219
+ refresh: ["M20 12a8 8 0 1 1-2.5-5.8", "M20 4v5h-5"],
7220
+ star: ["m12 3.6 2.6 5.3 5.9.9-4.3 4.1 1 5.8-5.2-2.7-5.2 2.7 1-5.8-4.3-4.1 5.9-.9z"],
7221
+ support: [
7222
+ "M5 13v-1a7 7 0 0 1 14 0v1",
7223
+ "M3.5 14.5a1.8 1.8 0 0 1 1.8-1.8H7v5H5.3a1.8 1.8 0 0 1-1.8-1.8z",
7224
+ "M20.5 14.5a1.8 1.8 0 0 0-1.8-1.8H17v5h1.7a1.8 1.8 0 0 0 1.8-1.8z",
7225
+ "M19 17.7v.8a2.5 2.5 0 0 1-2.5 2.5H13"
7226
+ ],
7227
+ globe: [
7228
+ "M21 12a9 9 0 1 1-18 0a9 9 0 1 1 18 0z",
7229
+ "M3 12h18",
7230
+ "M12 3a14 14 0 0 1 0 18a14 14 0 0 1 0-18z"
7231
+ ],
7232
+ tag: ["M11 3H4v7l10 10 7-7z", "M9.1 7a1.3 1.3 0 1 1-2.6 0a1.3 1.3 0 1 1 2.6 0z"],
7233
+ heart: ["M12 20s-7-4.4-7-9.3A3.9 3.9 0 0 1 12 8a3.9 3.9 0 0 1 7 2.7c0 4.9-7 9.3-7 9.3z"],
7234
+ leaf: ["M20 4c0 9-5.4 13-9.5 13A4.5 4.5 0 0 1 6 12.5C6 7 12 4 20 4z", "M4 20c2-4.5 5-7.5 9-9.5"],
7235
+ clock: ["M21 12a9 9 0 1 1-18 0a9 9 0 1 1 18 0z", "M12 7v5l3 2"],
7236
+ bank: ["M3 9.5 12 4l9 5.5", "M5 10v8M9.5 10v8M14.5 10v8M19 10v8", "M3 20h18"]
7237
+ };
7238
+ function isNoticeIcon(value) {
7239
+ return typeof value === "string" && NOTICE_ICONS.includes(value);
7240
+ }
6735
7241
  var FONT_STACKS = {
6736
7242
  inter: "'Inter Variable', 'Inter', system-ui, -apple-system, sans-serif",
6737
7243
  system: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif",
@@ -6901,6 +7407,96 @@ var DEFAULT_BADGES_DARK = [
6901
7407
  borderColor: "#1e40af"
6902
7408
  }
6903
7409
  ];
7410
+ var DEFAULT_NOTICES = [
7411
+ {
7412
+ id: "secure",
7413
+ section: "summary",
7414
+ icon: "shield",
7415
+ label: "Secure payment",
7416
+ labelTranslations: {
7417
+ de: "Sichere Zahlung",
7418
+ fr: "Paiement s\xE9curis\xE9",
7419
+ es: "Pago seguro",
7420
+ it: "Pagamento sicuro",
7421
+ nl: "Veilig betalen",
7422
+ zh: "\u5B89\u5168\u652F\u4ED8",
7423
+ "zh-Hant": "\u5B89\u5168\u4ED8\u6B3E",
7424
+ hi: "\u0938\u0941\u0930\u0915\u094D\u0937\u093F\u0924 \u092D\u0941\u0917\u0924\u093E\u0928",
7425
+ ar: "\u062F\u0641\u0639 \u0622\u0645\u0646"
7426
+ }
7427
+ },
7428
+ {
7429
+ id: "ssl",
7430
+ section: "summary",
7431
+ icon: "lock",
7432
+ label: "Encrypted \xB7 256-bit SSL",
7433
+ labelTranslations: {
7434
+ de: "Verschl\xFCsselt \xB7 256-Bit-SSL",
7435
+ fr: "Chiffr\xE9 \xB7 SSL 256 bits",
7436
+ es: "Cifrado \xB7 SSL de 256 bits",
7437
+ it: "Crittografato \xB7 SSL a 256 bit",
7438
+ nl: "Versleuteld \xB7 256-bit SSL",
7439
+ zh: "\u52A0\u5BC6 \xB7 256 \u4F4D SSL",
7440
+ "zh-Hant": "\u52A0\u5BC6 \xB7 256 \u4F4D\u5143 SSL",
7441
+ hi: "\u090F\u0928\u094D\u0915\u094D\u0930\u093F\u092A\u094D\u091F\u0947\u0921 \xB7 256-\u092C\u093F\u091F SSL",
7442
+ ar: "\u0645\u0634\u0641\u0651\u0631 \xB7 SSL \u0628\u0637\u0648\u0644 256 \u0628\u062A"
7443
+ }
7444
+ }
7445
+ ];
7446
+ function defaultNotices() {
7447
+ return DEFAULT_NOTICES.map(cloneNotice);
7448
+ }
7449
+ function cloneNotice(notice) {
7450
+ return { ...notice, labelTranslations: { ...notice.labelTranslations } };
7451
+ }
7452
+ function hexChannels(hex) {
7453
+ const raw = /^#([0-9a-f]{6})$/i.exec(hex.trim())?.[1];
7454
+ if (!raw) return null;
7455
+ return [
7456
+ parseInt(raw.slice(0, 2), 16),
7457
+ parseInt(raw.slice(2, 4), 16),
7458
+ parseInt(raw.slice(4, 6), 16)
7459
+ ];
7460
+ }
7461
+ function isThemeTintedBadgeColouring(textColor, fill, border) {
7462
+ const primary = hexChannels(textColor);
7463
+ const bg = hexChannels(fill);
7464
+ const line = hexChannels(border);
7465
+ if (!primary || !bg || !line) return false;
7466
+ const mixed = (surface, to, share) => Math.round(surface + (to - surface) * share);
7467
+ return primary.every((p, i) => {
7468
+ for (let surface = 0; surface <= 255; surface += 1) {
7469
+ if (mixed(surface, p, 0.08) === bg[i] && mixed(surface, p, 0.3) === line[i]) return true;
7470
+ }
7471
+ return false;
7472
+ });
7473
+ }
7474
+ function isDefaultBadgeSet(badges) {
7475
+ if (badges.length !== DEFAULT_BADGES.length) return false;
7476
+ const sameContent = badges.every(
7477
+ (badge, i) => badge.id === DEFAULT_BADGES[i]?.id && badge.label === DEFAULT_BADGES[i]?.label
7478
+ );
7479
+ if (!sameContent) return false;
7480
+ const colouring = (set) => set.map((b) => [b.textColor, b.backgroundColor, b.borderColor ?? ""].join("|").toLowerCase()).join("/");
7481
+ const mine = colouring(badges);
7482
+ if (mine === colouring(DEFAULT_BADGES) || mine === colouring(DEFAULT_BADGES_DARK)) return true;
7483
+ const [first] = badges;
7484
+ const border = first?.borderColor;
7485
+ if (!first || !border) return false;
7486
+ const same = (a, b) => (a ?? "").toLowerCase() === b.toLowerCase();
7487
+ return badges.every(
7488
+ (b) => same(b.textColor, first.textColor) && same(b.backgroundColor, first.backgroundColor) && same(b.borderColor, border)
7489
+ ) && isThemeTintedBadgeColouring(first.textColor, first.backgroundColor, border);
7490
+ }
7491
+ function resolveNoticesAndBadges(savedBadges, savedNotices) {
7492
+ if (savedNotices !== null) {
7493
+ return { trustBadges: savedBadges ?? [], notices: savedNotices };
7494
+ }
7495
+ if (savedBadges === null || isDefaultBadgeSet(savedBadges)) {
7496
+ return { trustBadges: [], notices: defaultNotices() };
7497
+ }
7498
+ return { trustBadges: savedBadges, notices: [] };
7499
+ }
6904
7500
  var METHOD_SECTION_ORDER_KEY = "methodSectionOrder";
6905
7501
  var METHOD_SECTION_LABELS_KEY = "methodSectionLabels";
6906
7502
  var MIN_SECTION_ORDER = 1;
@@ -7187,7 +7783,11 @@ var DEFAULT_BRANDING_BASE = {
7187
7783
  var DEFAULT_BRANDING = {
7188
7784
  ...DEFAULT_BRANDING_BASE,
7189
7785
  ...LIGHT_PALETTE,
7190
- trustBadges: DEFAULT_BADGES.map((b) => ({ ...b })),
7786
+ // No badges by default since todos#218 — notices took their place.
7787
+ // `DEFAULT_BADGES` stays exported because `isDefaultBadgeSet` still has to
7788
+ // recognise the pair on shops saved before.
7789
+ trustBadges: [],
7790
+ notices: defaultNotices(),
7191
7791
  customFields: [],
7192
7792
  methodSectionOrder: defaultMethodSectionOrder(),
7193
7793
  methodSectionLabels: {}
@@ -7210,7 +7810,8 @@ var DEFAULT_BRANDING_DARK = {
7210
7810
  // end of the ramp — 10.69 and 9.29 against the dark surface, also pinned.
7211
7811
  surchargeColor: "#fbbf24",
7212
7812
  discountColor: "#34d399",
7213
- trustBadges: DEFAULT_BADGES_DARK.map((b) => ({ ...b })),
7813
+ trustBadges: [],
7814
+ notices: defaultNotices(),
7214
7815
  customFields: [],
7215
7816
  methodSectionOrder: defaultMethodSectionOrder(),
7216
7817
  methodSectionLabels: {}
@@ -7222,6 +7823,7 @@ function cloneBranding(b) {
7222
7823
  return {
7223
7824
  ...b,
7224
7825
  trustBadges: b.trustBadges.map((badge) => ({ ...badge })),
7826
+ notices: b.notices.map(cloneNotice),
7225
7827
  customFields: b.customFields.map(cloneCustomField),
7226
7828
  methodSectionOrder: { ...b.methodSectionOrder },
7227
7829
  methodSectionLabels: Object.fromEntries(
@@ -7331,6 +7933,80 @@ function encodeBadges(badges) {
7331
7933
  }))
7332
7934
  );
7333
7935
  }
7936
+ var NOTICE_ID_MAX_LENGTH = 40;
7937
+ function capNoticeText(value) {
7938
+ return Array.from(value).slice(0, NOTICE_LABEL_MAX_LENGTH).join("");
7939
+ }
7940
+ function normalizeNotices(list) {
7941
+ const seen = /* @__PURE__ */ new Set();
7942
+ const perSection = /* @__PURE__ */ new Map();
7943
+ const out = [];
7944
+ list.forEach((raw, index) => {
7945
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return;
7946
+ const src = raw;
7947
+ const label = typeof src["label"] === "string" ? capNoticeText(src["label"]) : "";
7948
+ const labelTranslations = {};
7949
+ for (const [locale, text] of Object.entries(parseTranslations(src["labelTranslations"]))) {
7950
+ labelTranslations[locale] = capNoticeText(text);
7951
+ }
7952
+ if (label.trim().length === 0 && Object.keys(labelTranslations).length === 0) return;
7953
+ const section = pickEnum(src["section"], NOTICE_SECTIONS, "summary");
7954
+ const used = perSection.get(section) ?? 0;
7955
+ if (used >= NOTICES_PER_SECTION) return;
7956
+ perSection.set(section, used + 1);
7957
+ let id = typeof src["id"] === "string" ? src["id"].replace(/[^A-Za-z0-9_-]/g, "").slice(0, NOTICE_ID_MAX_LENGTH) : "";
7958
+ if (!id || seen.has(id)) id = `notice-${index + 1}`;
7959
+ while (seen.has(id)) id = `${id}x`;
7960
+ seen.add(id);
7961
+ out.push({
7962
+ id,
7963
+ section,
7964
+ icon: isNoticeIcon(src["icon"]) ? src["icon"] : NOTICE_ICON_FALLBACK,
7965
+ label,
7966
+ labelTranslations
7967
+ });
7968
+ });
7969
+ return out;
7970
+ }
7971
+ function decodeNotices(raw) {
7972
+ if (raw === void 0) return null;
7973
+ let parsed;
7974
+ try {
7975
+ parsed = JSON.parse(raw);
7976
+ } catch {
7977
+ return null;
7978
+ }
7979
+ return Array.isArray(parsed) ? normalizeNotices(parsed) : null;
7980
+ }
7981
+ function parseNoticesLoose(raw) {
7982
+ if (typeof raw === "string") return decodeNotices(raw);
7983
+ return Array.isArray(raw) ? normalizeNotices(raw) : null;
7984
+ }
7985
+ function encodeNotices(notices) {
7986
+ return JSON.stringify(
7987
+ notices.map((n) => {
7988
+ const translations = Object.entries(n.labelTranslations).filter(
7989
+ ([, text]) => text.trim().length > 0
7990
+ );
7991
+ return {
7992
+ id: n.id,
7993
+ section: n.section,
7994
+ icon: n.icon,
7995
+ label: n.label,
7996
+ ...translations.length > 0 ? { labelTranslations: Object.fromEntries(translations) } : {}
7997
+ };
7998
+ })
7999
+ );
8000
+ }
8001
+ function noticeText(notice, locale) {
8002
+ return translationFor(notice.labelTranslations, locale) ?? notice.label;
8003
+ }
8004
+ function noticesIn(notices, section) {
8005
+ return notices.filter((n) => n.section === section).slice(0, NOTICES_PER_SECTION);
8006
+ }
8007
+ function shownNotices(notices, section, locale) {
8008
+ return noticesIn(notices, section).map((notice) => ({ notice, text: noticeText(notice, locale).trim() })).filter((entry) => entry.text.length > 0);
8009
+ }
7334
8010
  var CUSTOM_FIELDS_MAX = 20;
7335
8011
  var CUSTOM_FIELD_KEY_PATTERN = /^[A-Za-z][A-Za-z0-9_-]{0,39}$/;
7336
8012
  var ALL_CUSTOM_FIELD_TYPES = [
@@ -7674,7 +8350,10 @@ function customFieldOptionLabel(option, locale) {
7674
8350
  function decodeBranding(source) {
7675
8351
  if (!source) return cloneBranding(DEFAULT_BRANDING);
7676
8352
  const extras = source.sdk_ui_rules?.[BRANDING_GROUP_KEY] ?? {};
7677
- const decodedBadges = decodeBadges(extras["trustBadges"]);
8353
+ const trustRow = resolveNoticesAndBadges(
8354
+ decodeBadges(extras["trustBadges"]),
8355
+ decodeNotices(extras["notices"])
8356
+ );
7678
8357
  const decodedCustomFields = decodeCustomFields(extras["customFields"]);
7679
8358
  const displayName = s(source.merchant_name) || s(source.seller_name);
7680
8359
  const logoUrl = s(source.merchant_logo) || s(source.logo);
@@ -7853,7 +8532,8 @@ function decodeBranding(source) {
7853
8532
  totalLabel: s(extras["totalLabel"]) || DEFAULT_BRANDING.totalLabel,
7854
8533
  showCurrencyCode: parseBool(extras["showCurrencyCode"], DEFAULT_BRANDING.showCurrencyCode),
7855
8534
  showOrderItems: parseBool(extras["showOrderItems"], DEFAULT_BRANDING.showOrderItems),
7856
- trustBadges: decodedBadges ?? DEFAULT_BRANDING.trustBadges.map((b) => ({ ...b })),
8535
+ trustBadges: trustRow.trustBadges,
8536
+ notices: trustRow.notices,
7857
8537
  customFields: decodedCustomFields ?? [],
7858
8538
  methodSectionOrder: decodeMethodSectionOrder(extras[METHOD_SECTION_ORDER_KEY]),
7859
8539
  methodSectionLabels: decodeMethodSectionLabels(extras[METHOD_SECTION_LABELS_KEY]),
@@ -8137,9 +8817,14 @@ function encodeBranding(branding, base) {
8137
8817
  nomupayApplePayButtonType: branding.nomupayApplePayButtonType,
8138
8818
  nomupayGooglePayButtonColor: branding.nomupayGooglePayButtonColor,
8139
8819
  nomupayGooglePayButtonType: branding.nomupayGooglePayButtonType,
8140
- trustBadges: encodeBadges(branding.trustBadges),
8820
+ // Always written, `[]` included — its presence is what stops a later
8821
+ // decode from migrating the shop again (`resolveNoticesAndBadges`).
8822
+ notices: encodeNotices(branding.notices),
8141
8823
  [METHOD_SECTION_ORDER_KEY]: encodeMethodSectionOrder(branding.methodSectionOrder)
8142
8824
  };
8825
+ if (branding.trustBadges.length > 0) {
8826
+ extras["trustBadges"] = encodeBadges(branding.trustBadges);
8827
+ }
8143
8828
  const sectionLabels = encodeMethodSectionLabels(branding.methodSectionLabels);
8144
8829
  if (sectionLabels) extras[METHOD_SECTION_LABELS_KEY] = sectionLabels;
8145
8830
  if (branding.customFields.length > 0) {
@@ -8205,7 +8890,10 @@ function parseImportedBranding(raw) {
8205
8890
  const dflt = DEFAULT_BRANDING;
8206
8891
  const sStr = (v, fallback) => typeof v === "string" ? v : fallback;
8207
8892
  const sHex = (v, fallback) => typeof v === "string" && isHexColor(v) ? v : fallback;
8208
- const trustBadges = parseTrustBadgesLoose(root["trustBadges"]) ?? dflt.trustBadges.map((b) => ({ ...b }));
8893
+ const { trustBadges, notices } = resolveNoticesAndBadges(
8894
+ parseTrustBadgesLoose(root["trustBadges"]),
8895
+ parseNoticesLoose(root["notices"])
8896
+ );
8209
8897
  const customFields = parseCustomFieldsLoose(root["customFields"]) ?? [];
8210
8898
  const labelStyle = (() => {
8211
8899
  const v = root["labelStyle"];
@@ -8348,6 +9036,7 @@ function parseImportedBranding(raw) {
8348
9036
  showCurrencyCode: parseBool(root["showCurrencyCode"], dflt.showCurrencyCode),
8349
9037
  showOrderItems: parseBool(root["showOrderItems"], dflt.showOrderItems),
8350
9038
  trustBadges,
9039
+ notices,
8351
9040
  customFields,
8352
9041
  // An export writes the decoded maps; a hand-written file may carry the
8353
9042
  // JSON strings the bag uses. Both are accepted, and neither is required.
@@ -9559,6 +10248,15 @@ var AdminPortal = class {
9559
10248
  query
9560
10249
  });
9561
10250
  }
10251
+ async exportTransactions(params, options) {
10252
+ return runExport(
10253
+ this.request,
10254
+ "GET",
10255
+ "/admin-portal/transactions/export",
10256
+ { query: transactionListQuery(params) },
10257
+ options
10258
+ );
10259
+ }
9562
10260
  /**
9563
10261
  * Full detail for a single transaction of ANY merchant — the same
9564
10262
  * `PaymentResponse` the merchant `payments.retrieve` returns. Admin-scoped:
@@ -10157,11 +10855,13 @@ var AdminPortal = class {
10157
10855
  }
10158
10856
  /**
10159
10857
  * Export a settlement statement as PDF. Returns the raw bytes as a `Blob`
10160
- * with the same auth and error handling as every other call.
10858
+ * with the same auth and error handling as every other call. `options`
10859
+ * takes a signal, a timeout and an `onDownloadProgress` listener for the
10860
+ * download's bytes (the PDF carries a `Content-Length`, so `total` is set).
10161
10861
  *
10162
10862
  * `GET /admin-portal/accounts/{merchantId}/settlement/statements/{statementId}/pdf`
10163
10863
  */
10164
- async downloadSettlementStatementPdf(merchantId, statementId, params) {
10864
+ async downloadSettlementStatementPdf(merchantId, statementId, params, options) {
10165
10865
  return this.request(
10166
10866
  "GET",
10167
10867
  `/admin-portal/accounts/${encodeURIComponent(merchantId)}/settlement/statements/${encodeURIComponent(statementId)}/pdf`,
@@ -10170,7 +10870,8 @@ var AdminPortal = class {
10170
10870
  currency: params?.currency,
10171
10871
  include_transactions: params?.include_transactions
10172
10872
  },
10173
- responseType: "blob"
10873
+ responseType: "blob",
10874
+ ...options
10174
10875
  }
10175
10876
  );
10176
10877
  }
@@ -10275,17 +10976,16 @@ var AuditLogs = class {
10275
10976
  return this.request("GET", `/admin-portal/audit/${encodeURIComponent(logId)}`);
10276
10977
  }
10277
10978
  async export(params, options) {
10278
- const format = options?.format ?? "json";
10279
- const accept = format === "csv" ? "text/csv" : format === "pdf" ? "application/pdf" : "application/json";
10280
- const request = {
10281
- query: params,
10979
+ return runExport(
10980
+ this.request,
10981
+ "GET",
10982
+ "/admin-portal/audit/export",
10282
10983
  // The format is negotiated by `Accept`, never a query field: the query
10283
10984
  // here is the list's own filter model, and adding a key to it would fork
10284
10985
  // the filter vocabulary the export exists to reuse.
10285
- headers: { Accept: accept }
10286
- };
10287
- if (format !== "json") request.responseType = "blob";
10288
- return this.request("GET", "/admin-portal/audit/export", request);
10986
+ { query: params },
10987
+ options
10988
+ );
10289
10989
  }
10290
10990
  };
10291
10991
 
@@ -10956,6 +11656,7 @@ var DelopayInternal = class extends Delopay {
10956
11656
  DEFAULT_BADGES_DARK,
10957
11657
  DEFAULT_BRANDING,
10958
11658
  DEFAULT_BRANDING_DARK,
11659
+ DEFAULT_NOTICES,
10959
11660
  Delopay,
10960
11661
  DelopayAuthenticationError,
10961
11662
  DelopayError,
@@ -10980,6 +11681,12 @@ var DelopayInternal = class extends Delopay {
10980
11681
  NATIVE_PANE_CATEGORY_KEYS,
10981
11682
  NATIVE_PANE_ICON_KEYS,
10982
11683
  NOMUPAY_FORM_STYLES,
11684
+ NOTICES_PER_SECTION,
11685
+ NOTICE_ICONS,
11686
+ NOTICE_ICON_FALLBACK,
11687
+ NOTICE_ICON_PATHS,
11688
+ NOTICE_LABEL_MAX_LENGTH,
11689
+ NOTICE_SECTIONS,
10983
11690
  OperationLimits,
10984
11691
  PANES_MAX,
10985
11692
  PANE_CATEGORY_KEYS,
@@ -11039,6 +11746,7 @@ var DelopayInternal = class extends Delopay {
11039
11746
  cloneBranding,
11040
11747
  cloneCustomField,
11041
11748
  cloneNativePane,
11749
+ cloneNotice,
11042
11750
  clonePane,
11043
11751
  compareSections,
11044
11752
  contrastRatio,
@@ -11054,11 +11762,13 @@ var DelopayInternal = class extends Delopay {
11054
11762
  decodeMethodSectionLabels,
11055
11763
  decodeMethodSectionOrder,
11056
11764
  decodeNativePanes,
11765
+ decodeNotices,
11057
11766
  decodePanes,
11058
11767
  defaultBranding,
11059
11768
  defaultCustomFieldVisibility,
11060
11769
  defaultMethodSectionOrder,
11061
11770
  defaultNativePane,
11771
+ defaultNotices,
11062
11772
  defaultOperatorForSource,
11063
11773
  defaultPane,
11064
11774
  emptyPaneCatalog,
@@ -11068,6 +11778,7 @@ var DelopayInternal = class extends Delopay {
11068
11778
  encodeMethodSectionLabels,
11069
11779
  encodeMethodSectionOrder,
11070
11780
  encodeNativePanes,
11781
+ encodeNotices,
11071
11782
  encodePanes,
11072
11783
  evaluateCustomFieldCondition,
11073
11784
  evaluateCustomFieldVisibility,
@@ -11078,13 +11789,17 @@ var DelopayInternal = class extends Delopay {
11078
11789
  inputPadValue,
11079
11790
  isCheckboxChecked,
11080
11791
  isDarkSurface,
11792
+ isDefaultBadgeSet,
11081
11793
  isHexColor,
11794
+ isNoticeIcon,
11082
11795
  isSubscriptionDisputeWebhook,
11083
11796
  isSubscriptionLifecycleWebhook,
11084
11797
  knownSectionLabelKey,
11085
11798
  leaf,
11086
11799
  logoDimensions,
11087
11800
  nativePaneMethodInfo,
11801
+ noticeText,
11802
+ noticesIn,
11088
11803
  offerablePaneMethods,
11089
11804
  paneCatalogFor,
11090
11805
  paneDisplayDefaults,
@@ -11093,6 +11808,7 @@ var DelopayInternal = class extends Delopay {
11093
11808
  paneViewVisibility,
11094
11809
  parseCustomFieldsLoose,
11095
11810
  parseImportedBranding,
11811
+ parseNoticesLoose,
11096
11812
  programToTree,
11097
11813
  radiusValue,
11098
11814
  readableInkOn,
@@ -11100,12 +11816,14 @@ var DelopayInternal = class extends Delopay {
11100
11816
  resolveAirwallexLabelStyle,
11101
11817
  resolveApplePayButtonStyle,
11102
11818
  resolveGooglePayButtonColor,
11819
+ resolveNoticesAndBadges,
11103
11820
  resolveStripeTheme,
11104
11821
  ruleMatchToTree,
11105
11822
  sanitizeCustomCss,
11106
11823
  sectionLabel,
11107
11824
  sectionOrderOf,
11108
11825
  shadowFor,
11826
+ shownNotices,
11109
11827
  stripeSpacingValues,
11110
11828
  surchargeFigurePlan,
11111
11829
  surchargeShowsLabel,