@delopay/sdk 0.146.0 → 0.149.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/index.cjs CHANGED
@@ -1348,7 +1348,7 @@ var Events = class {
1348
1348
  }
1349
1349
  /**
1350
1350
  * Fire an outgoing webhook event by hand for one object.
1351
- * `POST /events/{merchant_id}/trigger` (be#318)
1351
+ * `POST /events/{merchant_id}/trigger`
1352
1352
  *
1353
1353
  * Not a replay — see {@link EventManualTriggerRequest}. Needs the
1354
1354
  * `WebhookEventTrigger` permission, which is separate from the one that
@@ -1371,7 +1371,7 @@ var Events = class {
1371
1371
  }
1372
1372
  /**
1373
1373
  * Fire an outgoing webhook event by hand (profile-scoped).
1374
- * `POST /events/profile/trigger` (be#318)
1374
+ * `POST /events/profile/trigger`
1375
1375
  *
1376
1376
  * The shop-user twin of {@link trigger}; the shop is taken from the auth
1377
1377
  * context, so `profile_id` on the body is ignored.
@@ -2063,6 +2063,61 @@ var Payments = class {
2063
2063
  options
2064
2064
  );
2065
2065
  }
2066
+ /**
2067
+ * Open a playback of the payment's stored checkout recording: the audited
2068
+ * act of watching. Answers the manifest — which slices exist, how long the
2069
+ * recording runs, whether a pause in it is expected — and the
2070
+ * `playback_id` every {@link Payments.replaySlice} call carries.
2071
+ *
2072
+ * A payment that was never recorded answers `200` with `slices: []` and
2073
+ * `session_id: null` — the ordinary case for every payment made before the
2074
+ * checkout started recording — not a `404`. `404` means the payment does not
2075
+ * exist. Fetch the slices in `sequence` order; a number missing from the
2076
+ * list is a gap, not the end.
2077
+ *
2078
+ * A `POST`, because it writes one audit row: the SDK retries `GET` on its
2079
+ * own, and a lost response must not open three playbacks. Calling this
2080
+ * again deliberately opens another playback.
2081
+ *
2082
+ * Requires the `PaymentReplay` permission on a dashboard session in addition
2083
+ * to payment read access.
2084
+ *
2085
+ * `POST /payments/{paymentId}/replay/playback`
2086
+ *
2087
+ * @param paymentId - The payment intent ID.
2088
+ * @param options - Optional per-call extras: extra `headers`, a `timeout`
2089
+ * override, and an `AbortSignal`.
2090
+ */
2091
+ async openReplayPlayback(paymentId, options) {
2092
+ return this.request(
2093
+ "POST",
2094
+ `/payments/${encodeURIComponent(paymentId)}/replay/playback`,
2095
+ options
2096
+ );
2097
+ }
2098
+ /**
2099
+ * One slice of the payment's stored checkout recording, read against an
2100
+ * open playback: the rrweb events the checkout recorded under that number.
2101
+ * `playbackId` and the numbers come from {@link Payments.openReplayPlayback};
2102
+ * a `playbackId` that names no playback of this payment opened by this
2103
+ * caller, and a number the manifest does not list, both answer `404`.
2104
+ * Not audited per slice — the playback was.
2105
+ *
2106
+ * `GET /payments/{paymentId}/replay/playback/{playbackId}/slices/{sequence}`
2107
+ *
2108
+ * @param paymentId - The payment intent ID.
2109
+ * @param playbackId - The playback, from `openReplayPlayback`.
2110
+ * @param sequence - The slice number, from the playback's manifest.
2111
+ * @param options - Optional per-call extras: extra `headers`, a `timeout`
2112
+ * override, and an `AbortSignal`.
2113
+ */
2114
+ async replaySlice(paymentId, playbackId, sequence, options) {
2115
+ return this.request(
2116
+ "GET",
2117
+ `/payments/${encodeURIComponent(paymentId)}/replay/playback/${encodeURIComponent(playbackId)}/slices/${encodeURIComponent(String(sequence))}`,
2118
+ options
2119
+ );
2120
+ }
2066
2121
  /**
2067
2122
  * Soft-delete a payment. Only payments whose status is in the merchant's
2068
2123
  * delete policy (see {@link Payments.getDeletePolicy}) can be deleted;
@@ -4620,6 +4675,15 @@ var Audit = class {
4620
4675
  };
4621
4676
 
4622
4677
  // src/resources/settlement.ts
4678
+ function exportHeaders(options, accept) {
4679
+ const headers = new Headers(options?.headers);
4680
+ headers.set("Accept", accept);
4681
+ const output = {};
4682
+ headers.forEach((value, key) => {
4683
+ output[key] = value;
4684
+ });
4685
+ return output;
4686
+ }
4623
4687
  var Settlement = class {
4624
4688
  constructor(request) {
4625
4689
  this.request = request;
@@ -4772,6 +4836,45 @@ var Settlement = class {
4772
4836
  { body: params, ...options }
4773
4837
  );
4774
4838
  }
4839
+ /** Append one external transfer record. Send a stable idempotency_key for safe retries. */
4840
+ async recordStatementPayout(statementId, params, options) {
4841
+ return this.request(
4842
+ "POST",
4843
+ `/settlement/statements/${encodeURIComponent(statementId)}/payout`,
4844
+ {
4845
+ body: params,
4846
+ ...options,
4847
+ bodyIdempotencyKey: params.idempotency_key ?? null
4848
+ }
4849
+ );
4850
+ }
4851
+ /** Read individual transfer records, their signed total, and any overpayment. */
4852
+ async listStatementPayouts(statementId, options) {
4853
+ return this.request(
4854
+ "GET",
4855
+ `/settlement/statements/${encodeURIComponent(statementId)}/payouts`,
4856
+ options
4857
+ );
4858
+ }
4859
+ /** Record a transfer against a shop's month before its statement exists. */
4860
+ async recordAdvance(params, options) {
4861
+ return this.request("POST", "/settlement/advances", {
4862
+ body: params,
4863
+ ...options,
4864
+ bodyIdempotencyKey: params.idempotency_key ?? null
4865
+ });
4866
+ }
4867
+ async listAdvances(params, options) {
4868
+ return this.request("GET", "/settlement/advances", {
4869
+ query: {
4870
+ profile_id: params.profile_id,
4871
+ year: params.year,
4872
+ month: params.month,
4873
+ test_mode: params.test_mode
4874
+ },
4875
+ ...options
4876
+ });
4877
+ }
4775
4878
  /**
4776
4879
  * Export a statement as PDF. Returns the raw PDF bytes as a `Blob`, with
4777
4880
  * the same auth, retries and error handling as every other call — persist
@@ -4889,6 +4992,109 @@ var Settlement = class {
4889
4992
  options
4890
4993
  );
4891
4994
  }
4995
+ /**
4996
+ * Calculate a period in its transaction currency. Requires a host-level
4997
+ * dashboard JWT and settlement read permission. Profile users and roles
4998
+ * restricted to selected connector accounts cannot read this aggregate.
4999
+ * Rates apply once to the period total. Unknown or estimated fees keep
5000
+ * dependent amounts provisional. Native money values remain integer strings.
5001
+ */
5002
+ async previewNative(params, options) {
5003
+ return this.request("POST", "/settlement/native/preview", { body: params, ...options });
5004
+ }
5005
+ /**
5006
+ * Recalculate and freeze an immutable report version. Requires settlement
5007
+ * edit permission. Explicitly allow provisional figures when source fees
5008
+ * are incomplete. A report records a calculation and sends no money.
5009
+ * Reuse the same idempotency key when retrying the same request.
5010
+ */
5011
+ async createNativeReport(params, options) {
5012
+ return this.request("POST", "/settlement/native/reports", {
5013
+ body: params,
5014
+ ...options,
5015
+ bodyIdempotencyKey: params.idempotency_key
5016
+ });
5017
+ }
5018
+ async retrieveNativeReport(reportId, options) {
5019
+ return this.request(
5020
+ "GET",
5021
+ `/settlement/native/reports/${encodeURIComponent(reportId)}`,
5022
+ options
5023
+ );
5024
+ }
5025
+ /** List report summaries without fetching every source row in each saved snapshot. */
5026
+ async listNativeReports(params, options) {
5027
+ return this.request("GET", "/settlement/native/reports", {
5028
+ query: {
5029
+ profile_id: params.profile_id,
5030
+ currency: params.currency,
5031
+ test_mode: params.test_mode,
5032
+ limit: params.limit,
5033
+ offset: params.offset
5034
+ },
5035
+ ...options
5036
+ });
5037
+ }
5038
+ /**
5039
+ * Record a transfer already made, under settlement write permission and
5040
+ * the caller's payout limits. This method never sends money. Native minor
5041
+ * units remain strings; negative records must name a same-scope reversal.
5042
+ * These records belong to the native ledger, separate from monthly USD
5043
+ * statement payouts and advances.
5044
+ */
5045
+ async recordNativePayout(params, options) {
5046
+ return this.request("POST", "/settlement/native/payouts", {
5047
+ body: params,
5048
+ ...options,
5049
+ bodyIdempotencyKey: params.idempotency_key
5050
+ });
5051
+ }
5052
+ async listNativePayouts(params, options) {
5053
+ return this.request("GET", "/settlement/native/payouts", {
5054
+ query: {
5055
+ profile_id: params.profile_id,
5056
+ currency: params.currency,
5057
+ test_mode: params.test_mode,
5058
+ limit: params.limit,
5059
+ offset: params.offset
5060
+ },
5061
+ ...options
5062
+ });
5063
+ }
5064
+ /** Refresh a bounded page of provider fee evidence. Follow next_offset while has_more is true. */
5065
+ async refreshNativeFees(params, options) {
5066
+ return this.request("POST", "/settlement/native/fees/refresh", { body: params, ...options });
5067
+ }
5068
+ async downloadNativeReportPdf(reportId, params, options) {
5069
+ return this.request("GET", `/settlement/native/reports/${encodeURIComponent(reportId)}/pdf`, {
5070
+ query: { include_transactions: params?.include_transactions },
5071
+ responseType: "blob",
5072
+ ...options
5073
+ });
5074
+ }
5075
+ /** Download the frozen source rows and calculation as CSV. */
5076
+ async downloadNativeReportCsv(reportId, options) {
5077
+ return this.request(
5078
+ "GET",
5079
+ `/settlement/native/reports/${encodeURIComponent(reportId)}/export`,
5080
+ {
5081
+ ...options,
5082
+ headers: exportHeaders(options, "text/csv"),
5083
+ responseType: "blob"
5084
+ }
5085
+ );
5086
+ }
5087
+ /** Export the frozen report as JSON, excluding host account-level costs. */
5088
+ async exportNativeReportJson(reportId, options) {
5089
+ return this.request(
5090
+ "GET",
5091
+ `/settlement/native/reports/${encodeURIComponent(reportId)}/export`,
5092
+ {
5093
+ ...options,
5094
+ headers: exportHeaders(options, "application/json")
5095
+ }
5096
+ );
5097
+ }
4892
5098
  };
4893
5099
 
4894
5100
  // src/resources/operationLimits.ts
@@ -5246,7 +5452,7 @@ var Delopay = class {
5246
5452
  url += `?${qs}`;
5247
5453
  }
5248
5454
  }
5249
- const headers = {
5455
+ let headers = {
5250
5456
  ...this.jwtToken ? { Authorization: `Bearer ${this.jwtToken}` } : this.apiKey ? { "api-key": this.apiKey } : {},
5251
5457
  ...options?.headers
5252
5458
  };
@@ -5254,14 +5460,40 @@ var Delopay = class {
5254
5460
  if (options?.body && !isRawBody) {
5255
5461
  headers["Content-Type"] = "application/json";
5256
5462
  }
5257
- const idempotencyKey = findIdempotencyKey(headers)?.trim();
5258
- const isRetryable = method === "GET" || method === "DELETE" || idempotencyKey !== void 0 && idempotencyKey !== "";
5259
5463
  let serializedBody;
5260
5464
  if (isRawBody) {
5261
5465
  serializedBody = options?.body;
5262
5466
  } else if (options?.body) {
5263
5467
  serializedBody = JSON.stringify(options.body);
5264
5468
  }
5469
+ let idempotencyKey = findIdempotencyKey(headers)?.trim();
5470
+ if (options && Object.prototype.hasOwnProperty.call(options, "bodyIdempotencyKey")) {
5471
+ const bodyKey = options?.bodyIdempotencyKey;
5472
+ const serialized = !isRawBody && typeof serializedBody === "string" ? JSON.parse(serializedBody) : null;
5473
+ const actualKey = serialized && typeof serialized === "object" && !Array.isArray(serialized) ? serialized.idempotency_key ?? null : null;
5474
+ const suppliedHeaders = Object.keys(headers).filter(
5475
+ (name) => name.toLowerCase() === "idempotency-key"
5476
+ );
5477
+ if (bodyKey !== null && typeof bodyKey !== "string" || actualKey !== bodyKey || suppliedHeaders.some(
5478
+ (name) => headers[name] !== bodyKey || headers[name]?.trim() !== headers[name]
5479
+ )) {
5480
+ throw new DelopayError("Request retry keys must match the JSON body key", {
5481
+ status: 0,
5482
+ code: "IDEMPOTENCY_KEY_MISMATCH",
5483
+ type: "invalid_request"
5484
+ });
5485
+ }
5486
+ idempotencyKey = bodyKey?.trim();
5487
+ if (suppliedHeaders.length > 0) {
5488
+ headers = {
5489
+ ...Object.fromEntries(
5490
+ Object.entries(headers).filter(([name]) => name.toLowerCase() !== "idempotency-key")
5491
+ ),
5492
+ "Idempotency-Key": idempotencyKey ?? ""
5493
+ };
5494
+ }
5495
+ }
5496
+ const isRetryable = method === "GET" || method === "DELETE" || idempotencyKey !== void 0 && idempotencyKey !== "";
5265
5497
  const callerSignal = options?.signal;
5266
5498
  if (callerSignal?.aborted) {
5267
5499
  throw new DelopayError("Request aborted", {
@@ -7601,6 +7833,41 @@ var CheckoutSession = class {
7601
7833
  } catch {
7602
7834
  }
7603
7835
  }
7836
+ /**
7837
+ * Store one slice of the buyer's checkout recording on our own side.
7838
+ * Called by the hosted checkout as the buyer works through the page; the
7839
+ * client secret is attached automatically.
7840
+ *
7841
+ * **Not telemetry semantics, on purpose.** Unlike
7842
+ * {@link CheckoutSession.recordEvent}, this rejects with a `DelopayError`
7843
+ * like every other payment call, because the recorder has to tell the
7844
+ * answers apart: a `400` with code `IR_16` means the backend will not take
7845
+ * this recording (recording is off on that deployment, the recording is
7846
+ * full, the payment is already recording a different session, or this
7847
+ * number is stored with different content) and the recorder must stop; any
7848
+ * other `400` is the slice itself being refused; a transport failure may be
7849
+ * retried with the **same** bytes under the **same** number, which the
7850
+ * backend answers with `duplicate: true`.
7851
+ *
7852
+ * Pass `keepalive: true` for the last slice of a page that is navigating
7853
+ * away (a redirect rail); browsers refuse keepalive bodies over ~64 KiB, so
7854
+ * only a small final slice should carry it.
7855
+ *
7856
+ * `POST /payments/{paymentId}/replay/slice` (publishable key)
7857
+ */
7858
+ async storeReplaySlice(params, options) {
7859
+ const { keepalive, ...extras } = options ?? {};
7860
+ return this.client.request(
7861
+ "POST",
7862
+ `/payments/${encodeURIComponent(this.paymentId)}/replay/slice`,
7863
+ {
7864
+ body: { ...params, client_secret: this.requireClientSecret() },
7865
+ ...keepalive !== void 0 ? { keepalive } : {},
7866
+ ...extras,
7867
+ headers: this.pkHeaders(extras.headers)
7868
+ }
7869
+ );
7870
+ }
7604
7871
  /**
7605
7872
  * Confirm a subscription (PayPal approval rail). The client secret is
7606
7873
  * attached automatically; the shop's profile id travels as the
@@ -7625,20 +7892,6 @@ var CheckoutSession = class {
7625
7892
  }
7626
7893
  );
7627
7894
  }
7628
- /**
7629
- * The Paysepro rail catalog for the buyer's country.
7630
- *
7631
- * `GET /payment-link/{merchantId}/{paymentId}/paysepro/methods`
7632
- *
7633
- * @param country - Lowercase ISO 3166-1 alpha-2 country code.
7634
- */
7635
- async payseproMethods(country, options) {
7636
- return this.client.request("GET", `${this.linkBase}/paysepro/methods`, {
7637
- query: { cc: country },
7638
- ...options,
7639
- headers: this.bearerHeaders(options?.headers)
7640
- });
7641
- }
7642
7895
  /**
7643
7896
  * The e-Payouts rail catalog for the buyer's country, plus the set of
7644
7897
  * countries that have at least one vendor.