@delopay/sdk 0.9.0 → 0.11.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/README.md +8 -6
- package/dist/{chunk-WTVISXEY.js → chunk-VQPHGGNQ.js} +106 -55
- package/dist/chunk-VQPHGGNQ.js.map +1 -0
- package/dist/index.cjs +105 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +113 -38
- package/dist/index.d.ts +113 -38
- package/dist/index.js +1 -1
- package/dist/internal.cjs +105 -54
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/internal.js +1 -1
- package/package.json +16 -16
- package/dist/chunk-WTVISXEY.js.map +0 -1
package/dist/internal.cjs
CHANGED
|
@@ -393,14 +393,20 @@ var Connectors = class {
|
|
|
393
393
|
async verify(params) {
|
|
394
394
|
return this.request("POST", "/account/connectors/verify", { body: params });
|
|
395
395
|
}
|
|
396
|
-
/**
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
396
|
+
/**
|
|
397
|
+
* Register a webhook for a connector.
|
|
398
|
+
* `POST /account/{merchantId}/connectors/webhooks/{connectorId}`
|
|
399
|
+
*
|
|
400
|
+
* @param params - Optional event scope. Defaults to `{ event_type: 'all_events' }`
|
|
401
|
+
* on the backend when omitted; pass `{ event_type: { specific_event: '…' } }`
|
|
402
|
+
* to scope to a single event.
|
|
403
|
+
*/
|
|
404
|
+
async registerWebhook(merchantId, connectorId, params) {
|
|
405
|
+
const path = `/account/${encodeURIComponent(merchantId)}/connectors/webhooks/${encodeURIComponent(connectorId)}`;
|
|
406
|
+
if (params === void 0) return this.request("POST", path);
|
|
407
|
+
return this.request("POST", path, { body: params });
|
|
402
408
|
}
|
|
403
|
-
/** Get
|
|
409
|
+
/** Get registered webhooks for a connector. `GET /account/{merchantId}/connectors/webhooks/{connectorId}` */
|
|
404
410
|
async getWebhook(merchantId, connectorId) {
|
|
405
411
|
return this.request(
|
|
406
412
|
"GET",
|
|
@@ -989,15 +995,34 @@ var Payments = class {
|
|
|
989
995
|
* Retrieve a payment by its ID.
|
|
990
996
|
*
|
|
991
997
|
* @param paymentId - The unique payment intent ID.
|
|
998
|
+
* @param options - Optional query flags. `force_sync` asks the backend to
|
|
999
|
+
* reconcile state with the connector before returning (used to recover a
|
|
1000
|
+
* stuck intent when a webhook was lost). `all_keys_required` lifts the
|
|
1001
|
+
* backend's `should_call_connector` gate so a `requires_payment_method`
|
|
1002
|
+
* intent can still trigger a sync — without it the backend short-circuits
|
|
1003
|
+
* and returns the local snapshot. Both flags are JWT-authenticated dashboard
|
|
1004
|
+
* helpers; API-key callers can use them too where the backend allows.
|
|
992
1005
|
* @returns The payment intent.
|
|
993
1006
|
*
|
|
994
1007
|
* @example
|
|
995
1008
|
* ```typescript
|
|
996
1009
|
* const payment = await delopay.payments.retrieve('pay_abc123');
|
|
1010
|
+
* const synced = await delopay.payments.retrieve('pay_abc123', {
|
|
1011
|
+
* force_sync: true,
|
|
1012
|
+
* all_keys_required: true,
|
|
1013
|
+
* });
|
|
997
1014
|
* ```
|
|
998
1015
|
*/
|
|
999
|
-
async retrieve(paymentId) {
|
|
1000
|
-
|
|
1016
|
+
async retrieve(paymentId, options) {
|
|
1017
|
+
const path = `/payments/${encodeURIComponent(paymentId)}`;
|
|
1018
|
+
if (options === void 0) return this.request("GET", path);
|
|
1019
|
+
const query = {};
|
|
1020
|
+
if (options.force_sync !== void 0) query["force_sync"] = options.force_sync;
|
|
1021
|
+
if (options.all_keys_required !== void 0) {
|
|
1022
|
+
query["all_keys_required"] = options.all_keys_required;
|
|
1023
|
+
}
|
|
1024
|
+
if (Object.keys(query).length === 0) return this.request("GET", path);
|
|
1025
|
+
return this.request("GET", path, { query });
|
|
1001
1026
|
}
|
|
1002
1027
|
/**
|
|
1003
1028
|
* Update an existing payment intent before it is confirmed.
|
|
@@ -1398,29 +1423,41 @@ var Projects = class {
|
|
|
1398
1423
|
* Retrieve a project by its ID.
|
|
1399
1424
|
*
|
|
1400
1425
|
* @param projectId - The unique project ID.
|
|
1426
|
+
* @param merchantId - Optional merchant scope. When provided, sent as
|
|
1427
|
+
* `?merchant_id=…` — required by dashboards that authenticate with a JWT
|
|
1428
|
+
* spanning multiple merchants and need to disambiguate which one this
|
|
1429
|
+
* call applies to. API-key callers can omit it.
|
|
1401
1430
|
* @returns The project.
|
|
1402
1431
|
*/
|
|
1403
|
-
async retrieve(projectId) {
|
|
1404
|
-
|
|
1432
|
+
async retrieve(projectId, merchantId) {
|
|
1433
|
+
const path = `/projects/${encodeURIComponent(projectId)}`;
|
|
1434
|
+
if (merchantId === void 0) return this.request("GET", path);
|
|
1435
|
+
return this.request("GET", path, { query: { merchant_id: merchantId } });
|
|
1405
1436
|
}
|
|
1406
1437
|
/**
|
|
1407
1438
|
* Update a project's details.
|
|
1408
1439
|
*
|
|
1409
1440
|
* @param projectId - The project ID to update.
|
|
1410
1441
|
* @param params - Fields to update.
|
|
1442
|
+
* @param merchantId - Optional merchant scope. See {@link Projects.retrieve}.
|
|
1411
1443
|
* @returns The updated project.
|
|
1412
1444
|
*/
|
|
1413
|
-
async update(projectId, params) {
|
|
1414
|
-
|
|
1445
|
+
async update(projectId, params, merchantId) {
|
|
1446
|
+
const path = `/projects/${encodeURIComponent(projectId)}`;
|
|
1447
|
+
if (merchantId === void 0) return this.request("PUT", path, { body: params });
|
|
1448
|
+
return this.request("PUT", path, { body: params, query: { merchant_id: merchantId } });
|
|
1415
1449
|
}
|
|
1416
1450
|
/**
|
|
1417
1451
|
* Delete a project.
|
|
1418
1452
|
*
|
|
1419
1453
|
* @param projectId - The project ID to delete.
|
|
1454
|
+
* @param merchantId - Optional merchant scope. See {@link Projects.retrieve}.
|
|
1420
1455
|
* @returns The deleted project object.
|
|
1421
1456
|
*/
|
|
1422
|
-
async delete(projectId) {
|
|
1423
|
-
|
|
1457
|
+
async delete(projectId, merchantId) {
|
|
1458
|
+
const path = `/projects/${encodeURIComponent(projectId)}`;
|
|
1459
|
+
if (merchantId === void 0) return this.request("DELETE", path);
|
|
1460
|
+
return this.request("DELETE", path, { query: { merchant_id: merchantId } });
|
|
1424
1461
|
}
|
|
1425
1462
|
/**
|
|
1426
1463
|
* List all projects for a merchant.
|
|
@@ -2099,9 +2136,20 @@ var Users = class {
|
|
|
2099
2136
|
async listRolesV2() {
|
|
2100
2137
|
return this.request("GET", "/user/role/v2/list");
|
|
2101
2138
|
}
|
|
2102
|
-
/**
|
|
2103
|
-
|
|
2104
|
-
|
|
2139
|
+
/**
|
|
2140
|
+
* List invitable roles. `GET /user/role/list/invite`
|
|
2141
|
+
*
|
|
2142
|
+
* @param params - Optional query. `entity_type` scopes the role list to a
|
|
2143
|
+
* particular entity (e.g. `'merchant'` to list only merchant-scoped roles
|
|
2144
|
+
* when inviting employees from the merchant dashboard).
|
|
2145
|
+
*/
|
|
2146
|
+
async listInvitableRoles(params) {
|
|
2147
|
+
if (params === void 0 || params.entity_type === void 0) {
|
|
2148
|
+
return this.request("GET", "/user/role/list/invite");
|
|
2149
|
+
}
|
|
2150
|
+
return this.request("GET", "/user/role/list/invite", {
|
|
2151
|
+
query: { entity_type: params.entity_type }
|
|
2152
|
+
});
|
|
2105
2153
|
}
|
|
2106
2154
|
/** List updatable roles. `GET /user/role/list/update` */
|
|
2107
2155
|
async listUpdatableRoles() {
|
|
@@ -2165,72 +2213,75 @@ var Webhooks = {
|
|
|
2165
2213
|
/**
|
|
2166
2214
|
* Verify the signature of an incoming Delopay webhook and return the parsed event.
|
|
2167
2215
|
*
|
|
2216
|
+
* Delopay signs each outgoing webhook with HMAC-SHA512 over the raw request body,
|
|
2217
|
+
* using your shop's webhook secret (the *payment response hash key* configured on
|
|
2218
|
+
* the shop). The hex-encoded digest is delivered in the `X-Webhook-Signature-512`
|
|
2219
|
+
* HTTP header.
|
|
2220
|
+
*
|
|
2168
2221
|
* Uses the Web Crypto API (`globalThis.crypto.subtle`), so it runs unchanged in
|
|
2169
2222
|
* Node 18+, modern browsers, Deno, Bun, and edge runtimes (Cloudflare Workers, Vercel Edge).
|
|
2170
2223
|
*
|
|
2171
|
-
*
|
|
2224
|
+
* Available as a static property on the `Delopay` class
|
|
2172
2225
|
* (`Delopay.webhooks.verify`) and does not require a client instance.
|
|
2173
2226
|
*
|
|
2174
|
-
* @param rawBody - The raw request body
|
|
2175
|
-
*
|
|
2176
|
-
*
|
|
2177
|
-
* @param
|
|
2227
|
+
* @param rawBody - The raw request body. Pass the original bytes (`Uint8Array` /
|
|
2228
|
+
* `Buffer`) when possible; if you pass a string, it must be the unmodified UTF-8
|
|
2229
|
+
* text of the request body. Do **not** parse it before passing.
|
|
2230
|
+
* @param signatureHeader - The value of the `X-Webhook-Signature-512` HTTP header.
|
|
2231
|
+
* @param secret - Your shop's webhook signing secret.
|
|
2178
2232
|
* @returns Promise that resolves to the parsed webhook event.
|
|
2179
|
-
* @throws {Error} When the signature
|
|
2233
|
+
* @throws {Error} When the signature header is malformed or does not match the body.
|
|
2180
2234
|
*
|
|
2181
2235
|
* @example
|
|
2182
2236
|
* ```typescript
|
|
2183
2237
|
* // Express example
|
|
2184
2238
|
* app.post('/webhook', express.raw({ type: 'application/json' }), async (req, res) => {
|
|
2185
|
-
*
|
|
2186
|
-
*
|
|
2187
|
-
*
|
|
2188
|
-
*
|
|
2189
|
-
*
|
|
2190
|
-
*
|
|
2191
|
-
*
|
|
2239
|
+
* try {
|
|
2240
|
+
* const event = await Delopay.webhooks.verify(
|
|
2241
|
+
* req.body, // Buffer from express.raw()
|
|
2242
|
+
* req.header('x-webhook-signature-512') ?? '',
|
|
2243
|
+
* process.env.DELOPAY_WEBHOOK_SECRET!,
|
|
2244
|
+
* );
|
|
2245
|
+
* console.log(event.type, event.data);
|
|
2246
|
+
* res.sendStatus(200);
|
|
2247
|
+
* } catch {
|
|
2248
|
+
* res.status(400).send('Invalid signature');
|
|
2249
|
+
* }
|
|
2192
2250
|
* });
|
|
2193
2251
|
* ```
|
|
2194
2252
|
*/
|
|
2195
|
-
async verify(rawBody, signatureHeader, secret
|
|
2196
|
-
const tolerance = options?.tolerance ?? 300;
|
|
2197
|
-
const parts = signatureHeader.split(",");
|
|
2198
|
-
const timestampPart = parts.find((p) => p.startsWith("t="));
|
|
2199
|
-
const signaturePart = parts.find((p) => p.startsWith("v1="));
|
|
2200
|
-
if (!timestampPart || !signaturePart) {
|
|
2201
|
-
throw new Error("Invalid webhook signature format");
|
|
2202
|
-
}
|
|
2203
|
-
const timestamp = Number.parseInt(timestampPart.slice(2), 10);
|
|
2204
|
-
if (!Number.isFinite(timestamp)) {
|
|
2205
|
-
throw new Error("Invalid webhook timestamp");
|
|
2206
|
-
}
|
|
2207
|
-
const signatureHex = signaturePart.slice(3);
|
|
2208
|
-
const signatureBytes = hexToBytes(signatureHex);
|
|
2253
|
+
async verify(rawBody, signatureHeader, secret) {
|
|
2209
2254
|
const subtle = globalThis.crypto?.subtle;
|
|
2210
2255
|
if (!subtle) {
|
|
2211
2256
|
throw new Error(
|
|
2212
2257
|
"Web Crypto unavailable: Delopay.webhooks.verify requires globalThis.crypto.subtle (Node 18+, modern browsers, Workers, Deno)"
|
|
2213
2258
|
);
|
|
2214
2259
|
}
|
|
2260
|
+
const signatureBytes = hexToBytes(signatureHeader.trim());
|
|
2261
|
+
if (!signatureBytes) {
|
|
2262
|
+
throw new Error("Invalid webhook signature format");
|
|
2263
|
+
}
|
|
2215
2264
|
const encoder = new TextEncoder();
|
|
2265
|
+
const bodyBytes = typeof rawBody === "string" ? encoder.encode(rawBody) : rawBody;
|
|
2216
2266
|
const asBufferSource = (bytes) => bytes;
|
|
2217
2267
|
const key = await subtle.importKey(
|
|
2218
2268
|
"raw",
|
|
2219
2269
|
asBufferSource(encoder.encode(secret)),
|
|
2220
|
-
{ name: "HMAC", hash: "SHA-
|
|
2270
|
+
{ name: "HMAC", hash: "SHA-512" },
|
|
2221
2271
|
false,
|
|
2222
2272
|
["verify"]
|
|
2223
2273
|
);
|
|
2224
|
-
const
|
|
2225
|
-
|
|
2226
|
-
|
|
2274
|
+
const valid = await subtle.verify(
|
|
2275
|
+
"HMAC",
|
|
2276
|
+
key,
|
|
2277
|
+
asBufferSource(signatureBytes),
|
|
2278
|
+
asBufferSource(bodyBytes)
|
|
2279
|
+
);
|
|
2280
|
+
if (!valid) {
|
|
2227
2281
|
throw new Error("Invalid webhook signature");
|
|
2228
2282
|
}
|
|
2229
|
-
const
|
|
2230
|
-
|
|
2231
|
-
throw new Error("Webhook timestamp too old");
|
|
2232
|
-
}
|
|
2233
|
-
return JSON.parse(rawBody);
|
|
2283
|
+
const bodyText = typeof rawBody === "string" ? rawBody : new TextDecoder("utf-8").decode(rawBody);
|
|
2284
|
+
return JSON.parse(bodyText);
|
|
2234
2285
|
}
|
|
2235
2286
|
};
|
|
2236
2287
|
|