@solvapay/server 1.2.0 → 1.2.1-preview-e89fa52f99b6d0c7bf9834fcf2d1403141051fa0
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 +13 -8
- package/dist/edge.d.ts +210 -44
- package/dist/edge.js +153 -43
- package/dist/fetch/index.cjs +153 -43
- package/dist/fetch/index.d.cts +130 -0
- package/dist/fetch/index.d.ts +130 -0
- package/dist/fetch/index.js +153 -43
- package/dist/index.cjs +153 -43
- package/dist/index.d.cts +213 -45
- package/dist/index.d.ts +213 -45
- package/dist/index.js +153 -43
- package/package.json +8 -7
package/dist/fetch/index.d.ts
CHANGED
|
@@ -29,6 +29,15 @@ interface components {
|
|
|
29
29
|
* @example usd
|
|
30
30
|
*/
|
|
31
31
|
defaultCurrency?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Full set of currencies a customer may pay credit topups in, including the default currency. Omitted/single-entry means single-currency behavior.
|
|
34
|
+
* @example [
|
|
35
|
+
* "USD",
|
|
36
|
+
* "EUR",
|
|
37
|
+
* "GBP"
|
|
38
|
+
* ]
|
|
39
|
+
*/
|
|
40
|
+
supportedTopupCurrencies?: string[];
|
|
32
41
|
/**
|
|
33
42
|
* Descriptor appearing on the customer card statement
|
|
34
43
|
* @example ACME INC
|
|
@@ -246,6 +255,33 @@ interface components {
|
|
|
246
255
|
*/
|
|
247
256
|
checkoutUrl: string;
|
|
248
257
|
};
|
|
258
|
+
PlanPricingOptionDto: {
|
|
259
|
+
/**
|
|
260
|
+
* ISO 4217 currency code
|
|
261
|
+
* @example USD
|
|
262
|
+
*/
|
|
263
|
+
currency: string;
|
|
264
|
+
/**
|
|
265
|
+
* Price in smallest currency unit (e.g. cents)
|
|
266
|
+
* @example 2999
|
|
267
|
+
*/
|
|
268
|
+
price: number;
|
|
269
|
+
/**
|
|
270
|
+
* Base price in smallest currency unit (hybrid plans)
|
|
271
|
+
* @example 1999
|
|
272
|
+
*/
|
|
273
|
+
basePrice?: number;
|
|
274
|
+
/**
|
|
275
|
+
* One-time setup fee in smallest currency unit
|
|
276
|
+
* @example 500
|
|
277
|
+
*/
|
|
278
|
+
setupFee?: number;
|
|
279
|
+
/**
|
|
280
|
+
* Whether this is the default currency option for the plan
|
|
281
|
+
* @example true
|
|
282
|
+
*/
|
|
283
|
+
default?: boolean;
|
|
284
|
+
};
|
|
249
285
|
Plan: {
|
|
250
286
|
/**
|
|
251
287
|
* Plan type exposed in SDK
|
|
@@ -283,6 +319,8 @@ interface components {
|
|
|
283
319
|
* @example USD
|
|
284
320
|
*/
|
|
285
321
|
currency: string;
|
|
322
|
+
/** @description Per-currency price options for this plan */
|
|
323
|
+
pricingOptions?: components["schemas"]["PlanPricingOptionDto"][];
|
|
286
324
|
/**
|
|
287
325
|
* Currency symbol (derived from currency)
|
|
288
326
|
* @example $
|
|
@@ -376,6 +414,13 @@ interface components {
|
|
|
376
414
|
price?: number;
|
|
377
415
|
creditsPerUnit?: number;
|
|
378
416
|
currency?: string;
|
|
417
|
+
pricingOptions?: {
|
|
418
|
+
currency: string;
|
|
419
|
+
price: number;
|
|
420
|
+
basePrice?: number;
|
|
421
|
+
setupFee?: number;
|
|
422
|
+
default?: boolean;
|
|
423
|
+
}[];
|
|
379
424
|
/** @enum {string} */
|
|
380
425
|
billingModel?: "pre-paid" | "post-paid";
|
|
381
426
|
freeUnits?: number;
|
|
@@ -414,6 +459,13 @@ interface components {
|
|
|
414
459
|
price?: number;
|
|
415
460
|
creditsPerUnit?: number;
|
|
416
461
|
currency?: string;
|
|
462
|
+
pricingOptions?: {
|
|
463
|
+
currency: string;
|
|
464
|
+
price: number;
|
|
465
|
+
basePrice?: number;
|
|
466
|
+
setupFee?: number;
|
|
467
|
+
default?: boolean;
|
|
468
|
+
}[];
|
|
417
469
|
/** @enum {string} */
|
|
418
470
|
billingModel?: "pre-paid" | "post-paid";
|
|
419
471
|
freeUnits?: number;
|
|
@@ -658,6 +710,13 @@ interface components {
|
|
|
658
710
|
name: string;
|
|
659
711
|
price: number;
|
|
660
712
|
currency: string;
|
|
713
|
+
pricingOptions?: {
|
|
714
|
+
currency: string;
|
|
715
|
+
price: number;
|
|
716
|
+
basePrice?: number;
|
|
717
|
+
setupFee?: number;
|
|
718
|
+
default?: boolean;
|
|
719
|
+
}[];
|
|
661
720
|
/** @enum {string} */
|
|
662
721
|
billingCycle?: "weekly" | "monthly" | "quarterly" | "yearly" | "custom";
|
|
663
722
|
/** @enum {string} */
|
|
@@ -726,6 +785,13 @@ interface components {
|
|
|
726
785
|
name: string;
|
|
727
786
|
price: number;
|
|
728
787
|
currency: string;
|
|
788
|
+
pricingOptions?: {
|
|
789
|
+
currency: string;
|
|
790
|
+
price: number;
|
|
791
|
+
basePrice?: number;
|
|
792
|
+
setupFee?: number;
|
|
793
|
+
default?: boolean;
|
|
794
|
+
}[];
|
|
729
795
|
/** @enum {string} */
|
|
730
796
|
billingCycle?: "weekly" | "monthly" | "quarterly" | "yearly" | "custom";
|
|
731
797
|
/** @enum {string} */
|
|
@@ -759,6 +825,52 @@ interface components {
|
|
|
759
825
|
CloneProductDto: {
|
|
760
826
|
name?: string;
|
|
761
827
|
};
|
|
828
|
+
CreditDebitSuccessResponse: {
|
|
829
|
+
/** @enum {number} */
|
|
830
|
+
debited: true;
|
|
831
|
+
/**
|
|
832
|
+
* Credits debited for this usage event
|
|
833
|
+
* @example 10
|
|
834
|
+
*/
|
|
835
|
+
amount: number;
|
|
836
|
+
/**
|
|
837
|
+
* Estimated remaining units after debit
|
|
838
|
+
* @example 99
|
|
839
|
+
*/
|
|
840
|
+
unitsRemaining: number;
|
|
841
|
+
};
|
|
842
|
+
CreditDebitSkippedResponse: {
|
|
843
|
+
/** @enum {number} */
|
|
844
|
+
debited: false;
|
|
845
|
+
/**
|
|
846
|
+
* Reason no credit debit was recorded
|
|
847
|
+
* @example duplicate
|
|
848
|
+
* @enum {string}
|
|
849
|
+
*/
|
|
850
|
+
reason: "duplicate" | "no_product_ref" | "customer_not_found" | "no_active_purchase" | "plan_not_credit_based";
|
|
851
|
+
};
|
|
852
|
+
UsageRecordResponse: {
|
|
853
|
+
/** @example true */
|
|
854
|
+
success: boolean;
|
|
855
|
+
/** @example usage_A1B2C3D4 */
|
|
856
|
+
reference: string;
|
|
857
|
+
creditDebit?: components["schemas"]["CreditDebitSuccessResponse"] | components["schemas"]["CreditDebitSkippedResponse"];
|
|
858
|
+
};
|
|
859
|
+
BulkUsageResultResponse: {
|
|
860
|
+
/** @example usage_A1B2C3D4 */
|
|
861
|
+
reference: string;
|
|
862
|
+
creditDebit?: components["schemas"]["CreditDebitSuccessResponse"] | components["schemas"]["CreditDebitSkippedResponse"];
|
|
863
|
+
};
|
|
864
|
+
BulkUsageResponse: {
|
|
865
|
+
/** @example true */
|
|
866
|
+
success: boolean;
|
|
867
|
+
/**
|
|
868
|
+
* Number of usage events inserted
|
|
869
|
+
* @example 2
|
|
870
|
+
*/
|
|
871
|
+
inserted: number;
|
|
872
|
+
results: components["schemas"]["BulkUsageResultResponse"][];
|
|
873
|
+
};
|
|
762
874
|
CreateUsageRequest: {
|
|
763
875
|
customerRef: string;
|
|
764
876
|
/**
|
|
@@ -1028,6 +1140,8 @@ interface components {
|
|
|
1028
1140
|
creditsPerUnit?: number;
|
|
1029
1141
|
billingModel?: string;
|
|
1030
1142
|
billingCycle?: string;
|
|
1143
|
+
/** @description Per-currency price options for this plan */
|
|
1144
|
+
pricingOptions?: components["schemas"]["PlanPricingOptionDto"][];
|
|
1031
1145
|
};
|
|
1032
1146
|
LimitBalanceDto: {
|
|
1033
1147
|
/** @description Credit balance in mils */
|
|
@@ -1111,6 +1225,22 @@ interface components {
|
|
|
1111
1225
|
};
|
|
1112
1226
|
externalRef?: string;
|
|
1113
1227
|
};
|
|
1228
|
+
GrantCustomerCreditsRequest: {
|
|
1229
|
+
credits: number;
|
|
1230
|
+
reason?: string;
|
|
1231
|
+
};
|
|
1232
|
+
GrantCustomerCreditsResponse: {
|
|
1233
|
+
/** @description Whether the grant was recorded */
|
|
1234
|
+
success: boolean;
|
|
1235
|
+
/** @description Customer reference identifier */
|
|
1236
|
+
customerRef: string;
|
|
1237
|
+
/** @description Granted credit amount */
|
|
1238
|
+
credits: number;
|
|
1239
|
+
/** @description Customer credit balance after the grant */
|
|
1240
|
+
balance: number;
|
|
1241
|
+
/** @description Machine-readable grant reason */
|
|
1242
|
+
reason?: string;
|
|
1243
|
+
};
|
|
1114
1244
|
CreateCustomerSessionRequest: {
|
|
1115
1245
|
customerRef: string;
|
|
1116
1246
|
productRef?: string;
|
package/dist/fetch/index.js
CHANGED
|
@@ -23,6 +23,7 @@ function handleRouteError(error, operationName, defaultMessage) {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
// src/helpers/auth.ts
|
|
26
|
+
import { SOLVAPAY_USER_ID_HEADER } from "@solvapay/auth";
|
|
26
27
|
function base64UrlDecode(input) {
|
|
27
28
|
const padded = input.replace(/-/g, "+").replace(/_/g, "/");
|
|
28
29
|
const padding = padded.length % 4 === 0 ? "" : "=".repeat(4 - padded.length % 4);
|
|
@@ -99,7 +100,7 @@ async function getAuthenticatedUserCore(request, options = {}) {
|
|
|
99
100
|
try {
|
|
100
101
|
const includeEmail = options.includeEmail !== false;
|
|
101
102
|
const includeName = options.includeName !== false;
|
|
102
|
-
const headerUserId = request.headers.get(
|
|
103
|
+
const headerUserId = request.headers.get(SOLVAPAY_USER_ID_HEADER);
|
|
103
104
|
if (headerUserId) {
|
|
104
105
|
let email = null;
|
|
105
106
|
let name = null;
|
|
@@ -178,7 +179,9 @@ function createSolvaPayClient(opts) {
|
|
|
178
179
|
if (!res.ok) {
|
|
179
180
|
const error = await res.text();
|
|
180
181
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
181
|
-
throw new SolvaPayError2(`Check limits failed (${res.status}): ${error}`, {
|
|
182
|
+
throw new SolvaPayError2(`Check limits failed (${res.status}): ${error}`, {
|
|
183
|
+
status: res.status
|
|
184
|
+
});
|
|
182
185
|
}
|
|
183
186
|
const result = await res.json();
|
|
184
187
|
return result;
|
|
@@ -194,8 +197,28 @@ function createSolvaPayClient(opts) {
|
|
|
194
197
|
if (!res.ok) {
|
|
195
198
|
const error = await res.text();
|
|
196
199
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
197
|
-
throw new SolvaPayError2(`Track usage failed (${res.status}): ${error}`, {
|
|
200
|
+
throw new SolvaPayError2(`Track usage failed (${res.status}): ${error}`, {
|
|
201
|
+
status: res.status
|
|
202
|
+
});
|
|
198
203
|
}
|
|
204
|
+
return await res.json();
|
|
205
|
+
},
|
|
206
|
+
// POST: /v1/sdk/usages/bulk
|
|
207
|
+
async trackUsageBulk(params) {
|
|
208
|
+
const url = `${base}/v1/sdk/usages/bulk`;
|
|
209
|
+
const res = await fetch(url, {
|
|
210
|
+
method: "POST",
|
|
211
|
+
headers,
|
|
212
|
+
body: JSON.stringify(params)
|
|
213
|
+
});
|
|
214
|
+
if (!res.ok) {
|
|
215
|
+
const error = await res.text();
|
|
216
|
+
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
217
|
+
throw new SolvaPayError2(`Track usage bulk failed (${res.status}): ${error}`, {
|
|
218
|
+
status: res.status
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
return await res.json();
|
|
199
222
|
},
|
|
200
223
|
// POST: /v1/sdk/customers
|
|
201
224
|
async createCustomer(params) {
|
|
@@ -208,7 +231,9 @@ function createSolvaPayClient(opts) {
|
|
|
208
231
|
if (!res.ok) {
|
|
209
232
|
const error = await res.text();
|
|
210
233
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
211
|
-
throw new SolvaPayError2(`Create customer failed (${res.status}): ${error}`, {
|
|
234
|
+
throw new SolvaPayError2(`Create customer failed (${res.status}): ${error}`, {
|
|
235
|
+
status: res.status
|
|
236
|
+
});
|
|
212
237
|
}
|
|
213
238
|
const result = await res.json();
|
|
214
239
|
return {
|
|
@@ -226,7 +251,9 @@ function createSolvaPayClient(opts) {
|
|
|
226
251
|
if (!res.ok) {
|
|
227
252
|
const error = await res.text();
|
|
228
253
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
229
|
-
throw new SolvaPayError2(`Update customer failed (${res.status}): ${error}`, {
|
|
254
|
+
throw new SolvaPayError2(`Update customer failed (${res.status}): ${error}`, {
|
|
255
|
+
status: res.status
|
|
256
|
+
});
|
|
230
257
|
}
|
|
231
258
|
const result = await res.json();
|
|
232
259
|
return {
|
|
@@ -256,7 +283,9 @@ function createSolvaPayClient(opts) {
|
|
|
256
283
|
if (!res.ok) {
|
|
257
284
|
const error = await res.text();
|
|
258
285
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
259
|
-
throw new SolvaPayError2(`Get customer failed (${res.status}): ${error}`, {
|
|
286
|
+
throw new SolvaPayError2(`Get customer failed (${res.status}): ${error}`, {
|
|
287
|
+
status: res.status
|
|
288
|
+
});
|
|
260
289
|
}
|
|
261
290
|
const result = await res.json();
|
|
262
291
|
let customer = result;
|
|
@@ -277,6 +306,27 @@ function createSolvaPayClient(opts) {
|
|
|
277
306
|
purchases: customer.purchases || []
|
|
278
307
|
};
|
|
279
308
|
},
|
|
309
|
+
// POST: /v1/sdk/customers/{reference}/credits
|
|
310
|
+
async assignCredits(params) {
|
|
311
|
+
const { customerRef, idempotencyKey, ...body } = params;
|
|
312
|
+
const url = `${base}/v1/sdk/customers/${encodeURIComponent(customerRef)}/credits`;
|
|
313
|
+
const res = await fetch(url, {
|
|
314
|
+
method: "POST",
|
|
315
|
+
headers: {
|
|
316
|
+
...headers,
|
|
317
|
+
...idempotencyKey ? { "Idempotency-Key": idempotencyKey } : {}
|
|
318
|
+
},
|
|
319
|
+
body: JSON.stringify(body)
|
|
320
|
+
});
|
|
321
|
+
if (!res.ok) {
|
|
322
|
+
const error = await res.text();
|
|
323
|
+
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
324
|
+
throw new SolvaPayError2(`Assign credits failed (${res.status}): ${error}`, {
|
|
325
|
+
status: res.status
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
return await res.json();
|
|
329
|
+
},
|
|
280
330
|
// GET: /v1/sdk/merchant
|
|
281
331
|
async getMerchant() {
|
|
282
332
|
const url = `${base}/v1/sdk/merchant`;
|
|
@@ -287,7 +337,9 @@ function createSolvaPayClient(opts) {
|
|
|
287
337
|
if (!res.ok) {
|
|
288
338
|
const error = await res.text();
|
|
289
339
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
290
|
-
throw new SolvaPayError2(`Get merchant failed (${res.status}): ${error}`, {
|
|
340
|
+
throw new SolvaPayError2(`Get merchant failed (${res.status}): ${error}`, {
|
|
341
|
+
status: res.status
|
|
342
|
+
});
|
|
291
343
|
}
|
|
292
344
|
return res.json();
|
|
293
345
|
},
|
|
@@ -301,7 +353,9 @@ function createSolvaPayClient(opts) {
|
|
|
301
353
|
if (!res.ok) {
|
|
302
354
|
const error = await res.text();
|
|
303
355
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
304
|
-
throw new SolvaPayError2(`Get platform config failed (${res.status}): ${error}`, {
|
|
356
|
+
throw new SolvaPayError2(`Get platform config failed (${res.status}): ${error}`, {
|
|
357
|
+
status: res.status
|
|
358
|
+
});
|
|
305
359
|
}
|
|
306
360
|
return res.json();
|
|
307
361
|
},
|
|
@@ -315,7 +369,9 @@ function createSolvaPayClient(opts) {
|
|
|
315
369
|
if (!res.ok) {
|
|
316
370
|
const error = await res.text();
|
|
317
371
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
318
|
-
throw new SolvaPayError2(`Get product failed (${res.status}): ${error}`, {
|
|
372
|
+
throw new SolvaPayError2(`Get product failed (${res.status}): ${error}`, {
|
|
373
|
+
status: res.status
|
|
374
|
+
});
|
|
319
375
|
}
|
|
320
376
|
const result = await res.json();
|
|
321
377
|
const data = result.data || {};
|
|
@@ -332,7 +388,9 @@ function createSolvaPayClient(opts) {
|
|
|
332
388
|
if (!res.ok) {
|
|
333
389
|
const error = await res.text();
|
|
334
390
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
335
|
-
throw new SolvaPayError2(`List products failed (${res.status}): ${error}`, {
|
|
391
|
+
throw new SolvaPayError2(`List products failed (${res.status}): ${error}`, {
|
|
392
|
+
status: res.status
|
|
393
|
+
});
|
|
336
394
|
}
|
|
337
395
|
const result = await res.json();
|
|
338
396
|
const products = Array.isArray(result) ? result : result.products || [];
|
|
@@ -352,7 +410,9 @@ function createSolvaPayClient(opts) {
|
|
|
352
410
|
if (!res.ok) {
|
|
353
411
|
const error = await res.text();
|
|
354
412
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
355
|
-
throw new SolvaPayError2(`Create product failed (${res.status}): ${error}`, {
|
|
413
|
+
throw new SolvaPayError2(`Create product failed (${res.status}): ${error}`, {
|
|
414
|
+
status: res.status
|
|
415
|
+
});
|
|
356
416
|
}
|
|
357
417
|
const result = await res.json();
|
|
358
418
|
return result;
|
|
@@ -368,7 +428,9 @@ function createSolvaPayClient(opts) {
|
|
|
368
428
|
if (!res.ok) {
|
|
369
429
|
const error = await res.text();
|
|
370
430
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
371
|
-
throw new SolvaPayError2(`Bootstrap MCP product failed (${res.status}): ${error}`, {
|
|
431
|
+
throw new SolvaPayError2(`Bootstrap MCP product failed (${res.status}): ${error}`, {
|
|
432
|
+
status: res.status
|
|
433
|
+
});
|
|
372
434
|
}
|
|
373
435
|
return await res.json();
|
|
374
436
|
},
|
|
@@ -383,7 +445,9 @@ function createSolvaPayClient(opts) {
|
|
|
383
445
|
if (!res.ok) {
|
|
384
446
|
const error = await res.text();
|
|
385
447
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
386
|
-
throw new SolvaPayError2(`Configure MCP plans failed (${res.status}): ${error}`, {
|
|
448
|
+
throw new SolvaPayError2(`Configure MCP plans failed (${res.status}): ${error}`, {
|
|
449
|
+
status: res.status
|
|
450
|
+
});
|
|
387
451
|
}
|
|
388
452
|
return await res.json();
|
|
389
453
|
},
|
|
@@ -397,7 +461,9 @@ function createSolvaPayClient(opts) {
|
|
|
397
461
|
if (!res.ok && res.status !== 404) {
|
|
398
462
|
const error = await res.text();
|
|
399
463
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
400
|
-
throw new SolvaPayError2(`Delete product failed (${res.status}): ${error}`, {
|
|
464
|
+
throw new SolvaPayError2(`Delete product failed (${res.status}): ${error}`, {
|
|
465
|
+
status: res.status
|
|
466
|
+
});
|
|
401
467
|
}
|
|
402
468
|
},
|
|
403
469
|
// POST: /v1/sdk/products/{productRef}/clone
|
|
@@ -411,7 +477,9 @@ function createSolvaPayClient(opts) {
|
|
|
411
477
|
if (!res.ok) {
|
|
412
478
|
const error = await res.text();
|
|
413
479
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
414
|
-
throw new SolvaPayError2(`Clone product failed (${res.status}): ${error}`, {
|
|
480
|
+
throw new SolvaPayError2(`Clone product failed (${res.status}): ${error}`, {
|
|
481
|
+
status: res.status
|
|
482
|
+
});
|
|
415
483
|
}
|
|
416
484
|
return await res.json();
|
|
417
485
|
},
|
|
@@ -425,7 +493,9 @@ function createSolvaPayClient(opts) {
|
|
|
425
493
|
if (!res.ok) {
|
|
426
494
|
const error = await res.text();
|
|
427
495
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
428
|
-
throw new SolvaPayError2(`List plans failed (${res.status}): ${error}`, {
|
|
496
|
+
throw new SolvaPayError2(`List plans failed (${res.status}): ${error}`, {
|
|
497
|
+
status: res.status
|
|
498
|
+
});
|
|
429
499
|
}
|
|
430
500
|
const result = await res.json();
|
|
431
501
|
const plans = Array.isArray(result) ? result : result.plans || [];
|
|
@@ -452,7 +522,9 @@ function createSolvaPayClient(opts) {
|
|
|
452
522
|
if (!res.ok) {
|
|
453
523
|
const error = await res.text();
|
|
454
524
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
455
|
-
throw new SolvaPayError2(`Create plan failed (${res.status}): ${error}`, {
|
|
525
|
+
throw new SolvaPayError2(`Create plan failed (${res.status}): ${error}`, {
|
|
526
|
+
status: res.status
|
|
527
|
+
});
|
|
456
528
|
}
|
|
457
529
|
const result = await res.json();
|
|
458
530
|
return result;
|
|
@@ -468,7 +540,9 @@ function createSolvaPayClient(opts) {
|
|
|
468
540
|
if (!res.ok) {
|
|
469
541
|
const error = await res.text();
|
|
470
542
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
471
|
-
throw new SolvaPayError2(`Update plan failed (${res.status}): ${error}`, {
|
|
543
|
+
throw new SolvaPayError2(`Update plan failed (${res.status}): ${error}`, {
|
|
544
|
+
status: res.status
|
|
545
|
+
});
|
|
472
546
|
}
|
|
473
547
|
return await res.json();
|
|
474
548
|
},
|
|
@@ -482,7 +556,9 @@ function createSolvaPayClient(opts) {
|
|
|
482
556
|
if (!res.ok && res.status !== 404) {
|
|
483
557
|
const error = await res.text();
|
|
484
558
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
485
|
-
throw new SolvaPayError2(`Delete plan failed (${res.status}): ${error}`, {
|
|
559
|
+
throw new SolvaPayError2(`Delete plan failed (${res.status}): ${error}`, {
|
|
560
|
+
status: res.status
|
|
561
|
+
});
|
|
486
562
|
}
|
|
487
563
|
},
|
|
488
564
|
// POST: /payment-intents
|
|
@@ -498,13 +574,16 @@ function createSolvaPayClient(opts) {
|
|
|
498
574
|
body: JSON.stringify({
|
|
499
575
|
productRef: params.productRef,
|
|
500
576
|
planRef: params.planRef,
|
|
501
|
-
customerRef: params.customerRef
|
|
577
|
+
customerRef: params.customerRef,
|
|
578
|
+
...params.currency && { currency: params.currency }
|
|
502
579
|
})
|
|
503
580
|
});
|
|
504
581
|
if (!res.ok) {
|
|
505
582
|
const error = await res.text();
|
|
506
583
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
507
|
-
throw new SolvaPayError2(`Create payment intent failed (${res.status}): ${error}`, {
|
|
584
|
+
throw new SolvaPayError2(`Create payment intent failed (${res.status}): ${error}`, {
|
|
585
|
+
status: res.status
|
|
586
|
+
});
|
|
508
587
|
}
|
|
509
588
|
return await res.json();
|
|
510
589
|
},
|
|
@@ -529,7 +608,9 @@ function createSolvaPayClient(opts) {
|
|
|
529
608
|
if (!res.ok) {
|
|
530
609
|
const error = await res.text();
|
|
531
610
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
532
|
-
throw new SolvaPayError2(`Create topup payment intent failed (${res.status}): ${error}`, {
|
|
611
|
+
throw new SolvaPayError2(`Create topup payment intent failed (${res.status}): ${error}`, {
|
|
612
|
+
status: res.status
|
|
613
|
+
});
|
|
533
614
|
}
|
|
534
615
|
return await res.json();
|
|
535
616
|
},
|
|
@@ -551,7 +632,9 @@ function createSolvaPayClient(opts) {
|
|
|
551
632
|
if (!res.ok) {
|
|
552
633
|
const error = await res.text();
|
|
553
634
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
554
|
-
throw new SolvaPayError2(`Process payment failed (${res.status}): ${error}`, {
|
|
635
|
+
throw new SolvaPayError2(`Process payment failed (${res.status}): ${error}`, {
|
|
636
|
+
status: res.status
|
|
637
|
+
});
|
|
555
638
|
}
|
|
556
639
|
const result = await res.json();
|
|
557
640
|
return result;
|
|
@@ -579,7 +662,9 @@ function createSolvaPayClient(opts) {
|
|
|
579
662
|
{ status: 400 }
|
|
580
663
|
);
|
|
581
664
|
}
|
|
582
|
-
throw new SolvaPayError2(`Cancel purchase failed (${res.status}): ${error}`, {
|
|
665
|
+
throw new SolvaPayError2(`Cancel purchase failed (${res.status}): ${error}`, {
|
|
666
|
+
status: res.status
|
|
667
|
+
});
|
|
583
668
|
}
|
|
584
669
|
const responseText = await res.text();
|
|
585
670
|
let responseData;
|
|
@@ -623,12 +708,11 @@ function createSolvaPayClient(opts) {
|
|
|
623
708
|
throw new SolvaPayError2(`Purchase not found: ${error}`, { status: 404 });
|
|
624
709
|
}
|
|
625
710
|
if (res.status === 400) {
|
|
626
|
-
throw new SolvaPayError2(
|
|
627
|
-
`Purchase cannot be reactivated: ${error}`,
|
|
628
|
-
{ status: 400 }
|
|
629
|
-
);
|
|
711
|
+
throw new SolvaPayError2(`Purchase cannot be reactivated: ${error}`, { status: 400 });
|
|
630
712
|
}
|
|
631
|
-
throw new SolvaPayError2(`Reactivate purchase failed (${res.status}): ${error}`, {
|
|
713
|
+
throw new SolvaPayError2(`Reactivate purchase failed (${res.status}): ${error}`, {
|
|
714
|
+
status: res.status
|
|
715
|
+
});
|
|
632
716
|
}
|
|
633
717
|
const responseText = await res.text();
|
|
634
718
|
let responseData;
|
|
@@ -669,7 +753,9 @@ function createSolvaPayClient(opts) {
|
|
|
669
753
|
if (!res.ok) {
|
|
670
754
|
const error = await res.text();
|
|
671
755
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
672
|
-
throw new SolvaPayError2(`Get user info failed (${res.status}): ${error}`, {
|
|
756
|
+
throw new SolvaPayError2(`Get user info failed (${res.status}): ${error}`, {
|
|
757
|
+
status: res.status
|
|
758
|
+
});
|
|
673
759
|
}
|
|
674
760
|
return await res.json();
|
|
675
761
|
},
|
|
@@ -683,7 +769,9 @@ function createSolvaPayClient(opts) {
|
|
|
683
769
|
if (!res.ok) {
|
|
684
770
|
const error = await res.text();
|
|
685
771
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
686
|
-
throw new SolvaPayError2(`Get customer balance failed (${res.status}): ${error}`, {
|
|
772
|
+
throw new SolvaPayError2(`Get customer balance failed (${res.status}): ${error}`, {
|
|
773
|
+
status: res.status
|
|
774
|
+
});
|
|
687
775
|
}
|
|
688
776
|
return await res.json();
|
|
689
777
|
},
|
|
@@ -698,7 +786,9 @@ function createSolvaPayClient(opts) {
|
|
|
698
786
|
if (!res.ok) {
|
|
699
787
|
const error = await res.text();
|
|
700
788
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
701
|
-
throw new SolvaPayError2(`Create checkout session failed (${res.status}): ${error}`, {
|
|
789
|
+
throw new SolvaPayError2(`Create checkout session failed (${res.status}): ${error}`, {
|
|
790
|
+
status: res.status
|
|
791
|
+
});
|
|
702
792
|
}
|
|
703
793
|
const result = await res.json();
|
|
704
794
|
return result;
|
|
@@ -714,7 +804,9 @@ function createSolvaPayClient(opts) {
|
|
|
714
804
|
if (!res.ok) {
|
|
715
805
|
const error = await res.text();
|
|
716
806
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
717
|
-
throw new SolvaPayError2(`Create customer session failed (${res.status}): ${error}`, {
|
|
807
|
+
throw new SolvaPayError2(`Create customer session failed (${res.status}): ${error}`, {
|
|
808
|
+
status: res.status
|
|
809
|
+
});
|
|
718
810
|
}
|
|
719
811
|
const result = await res.json();
|
|
720
812
|
return result;
|
|
@@ -730,7 +822,9 @@ function createSolvaPayClient(opts) {
|
|
|
730
822
|
if (!res.ok) {
|
|
731
823
|
const error = await res.text();
|
|
732
824
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
733
|
-
throw new SolvaPayError2(`Activate plan failed (${res.status}): ${error}`, {
|
|
825
|
+
throw new SolvaPayError2(`Activate plan failed (${res.status}): ${error}`, {
|
|
826
|
+
status: res.status
|
|
827
|
+
});
|
|
734
828
|
}
|
|
735
829
|
return await res.json();
|
|
736
830
|
},
|
|
@@ -741,7 +835,9 @@ function createSolvaPayClient(opts) {
|
|
|
741
835
|
if (!res.ok) {
|
|
742
836
|
const error = await res.text();
|
|
743
837
|
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
744
|
-
throw new SolvaPayError2(`Get payment method failed (${res.status}): ${error}`, {
|
|
838
|
+
throw new SolvaPayError2(`Get payment method failed (${res.status}): ${error}`, {
|
|
839
|
+
status: res.status
|
|
840
|
+
});
|
|
745
841
|
}
|
|
746
842
|
return await res.json();
|
|
747
843
|
}
|
|
@@ -2016,6 +2112,12 @@ function createSolvaPay(config) {
|
|
|
2016
2112
|
trackUsage(params) {
|
|
2017
2113
|
return apiClient.trackUsage(params);
|
|
2018
2114
|
},
|
|
2115
|
+
trackUsageBulk(params) {
|
|
2116
|
+
if (!apiClient.trackUsageBulk) {
|
|
2117
|
+
throw new SolvaPayError3("trackUsageBulk is not available on this API client");
|
|
2118
|
+
}
|
|
2119
|
+
return apiClient.trackUsageBulk(params);
|
|
2120
|
+
},
|
|
2019
2121
|
createCustomer(params) {
|
|
2020
2122
|
if (!apiClient.createCustomer) {
|
|
2021
2123
|
throw new SolvaPayError3("createCustomer is not available on this API client");
|
|
@@ -2025,6 +2127,12 @@ function createSolvaPay(config) {
|
|
|
2025
2127
|
getCustomer(params) {
|
|
2026
2128
|
return apiClient.getCustomer(params);
|
|
2027
2129
|
},
|
|
2130
|
+
assignCredits(params) {
|
|
2131
|
+
if (!apiClient.assignCredits) {
|
|
2132
|
+
throw new SolvaPayError3("assignCredits is not available on this API client");
|
|
2133
|
+
}
|
|
2134
|
+
return apiClient.assignCredits(params);
|
|
2135
|
+
},
|
|
2028
2136
|
getCustomerBalance(params) {
|
|
2029
2137
|
if (!apiClient.getCustomerBalance) {
|
|
2030
2138
|
throw new SolvaPayError3("getCustomerBalance is not available on this API client");
|
|
@@ -2110,7 +2218,9 @@ function createSolvaPay(config) {
|
|
|
2110
2218
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2111
2219
|
async function(businessLogic) {
|
|
2112
2220
|
const getCustomerRef = (args) => {
|
|
2113
|
-
const configuredRef = options.getCustomerRef?.(
|
|
2221
|
+
const configuredRef = options.getCustomerRef?.(
|
|
2222
|
+
args
|
|
2223
|
+
);
|
|
2114
2224
|
if (typeof configuredRef === "string") {
|
|
2115
2225
|
return configuredRef;
|
|
2116
2226
|
}
|
|
@@ -2129,9 +2239,7 @@ function createSolvaPay(config) {
|
|
|
2129
2239
|
);
|
|
2130
2240
|
if (decision.outcome === "gate") {
|
|
2131
2241
|
const errorMessage = decision.gate.kind === "activation_required" ? "Activation required" : "Payment required";
|
|
2132
|
-
const body = paywallErrorToClientPayload(
|
|
2133
|
-
new PaywallError(errorMessage, decision.gate)
|
|
2134
|
-
);
|
|
2242
|
+
const body = paywallErrorToClientPayload(new PaywallError(errorMessage, decision.gate));
|
|
2135
2243
|
const response = new Response(JSON.stringify(body), {
|
|
2136
2244
|
status: 402,
|
|
2137
2245
|
headers: { "content-type": "application/json" }
|
|
@@ -2258,7 +2366,8 @@ async function createPaymentIntentCore(request, body, options = {}) {
|
|
|
2258
2366
|
const paymentIntent = await solvaPay.createPaymentIntent({
|
|
2259
2367
|
productRef: body.productRef,
|
|
2260
2368
|
planRef: body.planRef,
|
|
2261
|
-
customerRef
|
|
2369
|
+
customerRef,
|
|
2370
|
+
...body.currency && { currency: body.currency }
|
|
2262
2371
|
});
|
|
2263
2372
|
return {
|
|
2264
2373
|
processorPaymentId: paymentIntent.processorPaymentId,
|
|
@@ -2788,15 +2897,16 @@ async function trackUsageCore(request, body, options = {}) {
|
|
|
2788
2897
|
email: email || void 0,
|
|
2789
2898
|
name: name || void 0
|
|
2790
2899
|
});
|
|
2791
|
-
await solvaPay.trackUsage({
|
|
2900
|
+
const result = await solvaPay.trackUsage({
|
|
2792
2901
|
customerRef,
|
|
2793
2902
|
actionType: body.actionType,
|
|
2794
2903
|
units: body.units,
|
|
2795
2904
|
productRef: body.productRef,
|
|
2796
2905
|
description: body.description,
|
|
2797
|
-
metadata: body.metadata
|
|
2906
|
+
metadata: body.metadata,
|
|
2907
|
+
idempotencyKey: body.idempotencyKey
|
|
2798
2908
|
});
|
|
2799
|
-
return
|
|
2909
|
+
return result;
|
|
2800
2910
|
} catch (error) {
|
|
2801
2911
|
return handleRouteError(error, "Track usage", "Track usage failed");
|
|
2802
2912
|
}
|