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