@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/dist/index.js CHANGED
@@ -29,7 +29,9 @@ function createSolvaPayClient(opts) {
29
29
  if (!res.ok) {
30
30
  const error = await res.text();
31
31
  log(`\u274C API Error: ${res.status} - ${error}`);
32
- throw new SolvaPayError(`Check limits failed (${res.status}): ${error}`, { status: res.status });
32
+ throw new SolvaPayError(`Check limits failed (${res.status}): ${error}`, {
33
+ status: res.status
34
+ });
33
35
  }
34
36
  const result = await res.json();
35
37
  return result;
@@ -45,8 +47,28 @@ function createSolvaPayClient(opts) {
45
47
  if (!res.ok) {
46
48
  const error = await res.text();
47
49
  log(`\u274C API Error: ${res.status} - ${error}`);
48
- throw new SolvaPayError(`Track usage failed (${res.status}): ${error}`, { status: res.status });
50
+ throw new SolvaPayError(`Track usage failed (${res.status}): ${error}`, {
51
+ status: res.status
52
+ });
49
53
  }
54
+ return await res.json();
55
+ },
56
+ // POST: /v1/sdk/usages/bulk
57
+ async trackUsageBulk(params) {
58
+ const url = `${base}/v1/sdk/usages/bulk`;
59
+ const res = await fetch(url, {
60
+ method: "POST",
61
+ headers,
62
+ body: JSON.stringify(params)
63
+ });
64
+ if (!res.ok) {
65
+ const error = await res.text();
66
+ log(`\u274C API Error: ${res.status} - ${error}`);
67
+ throw new SolvaPayError(`Track usage bulk failed (${res.status}): ${error}`, {
68
+ status: res.status
69
+ });
70
+ }
71
+ return await res.json();
50
72
  },
51
73
  // POST: /v1/sdk/customers
52
74
  async createCustomer(params) {
@@ -59,7 +81,9 @@ function createSolvaPayClient(opts) {
59
81
  if (!res.ok) {
60
82
  const error = await res.text();
61
83
  log(`\u274C API Error: ${res.status} - ${error}`);
62
- throw new SolvaPayError(`Create customer failed (${res.status}): ${error}`, { status: res.status });
84
+ throw new SolvaPayError(`Create customer failed (${res.status}): ${error}`, {
85
+ status: res.status
86
+ });
63
87
  }
64
88
  const result = await res.json();
65
89
  return {
@@ -77,7 +101,9 @@ function createSolvaPayClient(opts) {
77
101
  if (!res.ok) {
78
102
  const error = await res.text();
79
103
  log(`\u274C API Error: ${res.status} - ${error}`);
80
- throw new SolvaPayError(`Update customer failed (${res.status}): ${error}`, { status: res.status });
104
+ throw new SolvaPayError(`Update customer failed (${res.status}): ${error}`, {
105
+ status: res.status
106
+ });
81
107
  }
82
108
  const result = await res.json();
83
109
  return {
@@ -107,7 +133,9 @@ function createSolvaPayClient(opts) {
107
133
  if (!res.ok) {
108
134
  const error = await res.text();
109
135
  log(`\u274C API Error: ${res.status} - ${error}`);
110
- throw new SolvaPayError(`Get customer failed (${res.status}): ${error}`, { status: res.status });
136
+ throw new SolvaPayError(`Get customer failed (${res.status}): ${error}`, {
137
+ status: res.status
138
+ });
111
139
  }
112
140
  const result = await res.json();
113
141
  let customer = result;
@@ -128,6 +156,27 @@ function createSolvaPayClient(opts) {
128
156
  purchases: customer.purchases || []
129
157
  };
130
158
  },
159
+ // POST: /v1/sdk/customers/{reference}/credits
160
+ async assignCredits(params) {
161
+ const { customerRef, idempotencyKey, ...body } = params;
162
+ const url = `${base}/v1/sdk/customers/${encodeURIComponent(customerRef)}/credits`;
163
+ const res = await fetch(url, {
164
+ method: "POST",
165
+ headers: {
166
+ ...headers,
167
+ ...idempotencyKey ? { "Idempotency-Key": idempotencyKey } : {}
168
+ },
169
+ body: JSON.stringify(body)
170
+ });
171
+ if (!res.ok) {
172
+ const error = await res.text();
173
+ log(`\u274C API Error: ${res.status} - ${error}`);
174
+ throw new SolvaPayError(`Assign credits failed (${res.status}): ${error}`, {
175
+ status: res.status
176
+ });
177
+ }
178
+ return await res.json();
179
+ },
131
180
  // GET: /v1/sdk/merchant
132
181
  async getMerchant() {
133
182
  const url = `${base}/v1/sdk/merchant`;
@@ -138,7 +187,9 @@ function createSolvaPayClient(opts) {
138
187
  if (!res.ok) {
139
188
  const error = await res.text();
140
189
  log(`\u274C API Error: ${res.status} - ${error}`);
141
- throw new SolvaPayError(`Get merchant failed (${res.status}): ${error}`, { status: res.status });
190
+ throw new SolvaPayError(`Get merchant failed (${res.status}): ${error}`, {
191
+ status: res.status
192
+ });
142
193
  }
143
194
  return res.json();
144
195
  },
@@ -152,7 +203,9 @@ function createSolvaPayClient(opts) {
152
203
  if (!res.ok) {
153
204
  const error = await res.text();
154
205
  log(`\u274C API Error: ${res.status} - ${error}`);
155
- throw new SolvaPayError(`Get platform config failed (${res.status}): ${error}`, { status: res.status });
206
+ throw new SolvaPayError(`Get platform config failed (${res.status}): ${error}`, {
207
+ status: res.status
208
+ });
156
209
  }
157
210
  return res.json();
158
211
  },
@@ -166,7 +219,9 @@ function createSolvaPayClient(opts) {
166
219
  if (!res.ok) {
167
220
  const error = await res.text();
168
221
  log(`\u274C API Error: ${res.status} - ${error}`);
169
- throw new SolvaPayError(`Get product failed (${res.status}): ${error}`, { status: res.status });
222
+ throw new SolvaPayError(`Get product failed (${res.status}): ${error}`, {
223
+ status: res.status
224
+ });
170
225
  }
171
226
  const result = await res.json();
172
227
  const data = result.data || {};
@@ -183,7 +238,9 @@ function createSolvaPayClient(opts) {
183
238
  if (!res.ok) {
184
239
  const error = await res.text();
185
240
  log(`\u274C API Error: ${res.status} - ${error}`);
186
- throw new SolvaPayError(`List products failed (${res.status}): ${error}`, { status: res.status });
241
+ throw new SolvaPayError(`List products failed (${res.status}): ${error}`, {
242
+ status: res.status
243
+ });
187
244
  }
188
245
  const result = await res.json();
189
246
  const products = Array.isArray(result) ? result : result.products || [];
@@ -203,7 +260,9 @@ function createSolvaPayClient(opts) {
203
260
  if (!res.ok) {
204
261
  const error = await res.text();
205
262
  log(`\u274C API Error: ${res.status} - ${error}`);
206
- throw new SolvaPayError(`Create product failed (${res.status}): ${error}`, { status: res.status });
263
+ throw new SolvaPayError(`Create product failed (${res.status}): ${error}`, {
264
+ status: res.status
265
+ });
207
266
  }
208
267
  const result = await res.json();
209
268
  return result;
@@ -219,7 +278,9 @@ function createSolvaPayClient(opts) {
219
278
  if (!res.ok) {
220
279
  const error = await res.text();
221
280
  log(`\u274C API Error: ${res.status} - ${error}`);
222
- throw new SolvaPayError(`Bootstrap MCP product failed (${res.status}): ${error}`, { status: res.status });
281
+ throw new SolvaPayError(`Bootstrap MCP product failed (${res.status}): ${error}`, {
282
+ status: res.status
283
+ });
223
284
  }
224
285
  return await res.json();
225
286
  },
@@ -234,7 +295,9 @@ function createSolvaPayClient(opts) {
234
295
  if (!res.ok) {
235
296
  const error = await res.text();
236
297
  log(`\u274C API Error: ${res.status} - ${error}`);
237
- throw new SolvaPayError(`Configure MCP plans failed (${res.status}): ${error}`, { status: res.status });
298
+ throw new SolvaPayError(`Configure MCP plans failed (${res.status}): ${error}`, {
299
+ status: res.status
300
+ });
238
301
  }
239
302
  return await res.json();
240
303
  },
@@ -248,7 +311,9 @@ function createSolvaPayClient(opts) {
248
311
  if (!res.ok && res.status !== 404) {
249
312
  const error = await res.text();
250
313
  log(`\u274C API Error: ${res.status} - ${error}`);
251
- throw new SolvaPayError(`Delete product failed (${res.status}): ${error}`, { status: res.status });
314
+ throw new SolvaPayError(`Delete product failed (${res.status}): ${error}`, {
315
+ status: res.status
316
+ });
252
317
  }
253
318
  },
254
319
  // POST: /v1/sdk/products/{productRef}/clone
@@ -262,7 +327,9 @@ function createSolvaPayClient(opts) {
262
327
  if (!res.ok) {
263
328
  const error = await res.text();
264
329
  log(`\u274C API Error: ${res.status} - ${error}`);
265
- throw new SolvaPayError(`Clone product failed (${res.status}): ${error}`, { status: res.status });
330
+ throw new SolvaPayError(`Clone product failed (${res.status}): ${error}`, {
331
+ status: res.status
332
+ });
266
333
  }
267
334
  return await res.json();
268
335
  },
@@ -276,7 +343,9 @@ function createSolvaPayClient(opts) {
276
343
  if (!res.ok) {
277
344
  const error = await res.text();
278
345
  log(`\u274C API Error: ${res.status} - ${error}`);
279
- throw new SolvaPayError(`List plans failed (${res.status}): ${error}`, { status: res.status });
346
+ throw new SolvaPayError(`List plans failed (${res.status}): ${error}`, {
347
+ status: res.status
348
+ });
280
349
  }
281
350
  const result = await res.json();
282
351
  const plans = Array.isArray(result) ? result : result.plans || [];
@@ -303,7 +372,9 @@ function createSolvaPayClient(opts) {
303
372
  if (!res.ok) {
304
373
  const error = await res.text();
305
374
  log(`\u274C API Error: ${res.status} - ${error}`);
306
- throw new SolvaPayError(`Create plan failed (${res.status}): ${error}`, { status: res.status });
375
+ throw new SolvaPayError(`Create plan failed (${res.status}): ${error}`, {
376
+ status: res.status
377
+ });
307
378
  }
308
379
  const result = await res.json();
309
380
  return result;
@@ -319,7 +390,9 @@ function createSolvaPayClient(opts) {
319
390
  if (!res.ok) {
320
391
  const error = await res.text();
321
392
  log(`\u274C API Error: ${res.status} - ${error}`);
322
- throw new SolvaPayError(`Update plan failed (${res.status}): ${error}`, { status: res.status });
393
+ throw new SolvaPayError(`Update plan failed (${res.status}): ${error}`, {
394
+ status: res.status
395
+ });
323
396
  }
324
397
  return await res.json();
325
398
  },
@@ -333,7 +406,9 @@ function createSolvaPayClient(opts) {
333
406
  if (!res.ok && res.status !== 404) {
334
407
  const error = await res.text();
335
408
  log(`\u274C API Error: ${res.status} - ${error}`);
336
- throw new SolvaPayError(`Delete plan failed (${res.status}): ${error}`, { status: res.status });
409
+ throw new SolvaPayError(`Delete plan failed (${res.status}): ${error}`, {
410
+ status: res.status
411
+ });
337
412
  }
338
413
  },
339
414
  // POST: /payment-intents
@@ -349,13 +424,16 @@ function createSolvaPayClient(opts) {
349
424
  body: JSON.stringify({
350
425
  productRef: params.productRef,
351
426
  planRef: params.planRef,
352
- customerRef: params.customerRef
427
+ customerRef: params.customerRef,
428
+ ...params.currency && { currency: params.currency }
353
429
  })
354
430
  });
355
431
  if (!res.ok) {
356
432
  const error = await res.text();
357
433
  log(`\u274C API Error: ${res.status} - ${error}`);
358
- throw new SolvaPayError(`Create payment intent failed (${res.status}): ${error}`, { status: res.status });
434
+ throw new SolvaPayError(`Create payment intent failed (${res.status}): ${error}`, {
435
+ status: res.status
436
+ });
359
437
  }
360
438
  return await res.json();
361
439
  },
@@ -380,7 +458,9 @@ function createSolvaPayClient(opts) {
380
458
  if (!res.ok) {
381
459
  const error = await res.text();
382
460
  log(`\u274C API Error: ${res.status} - ${error}`);
383
- throw new SolvaPayError(`Create topup payment intent failed (${res.status}): ${error}`, { status: res.status });
461
+ throw new SolvaPayError(`Create topup payment intent failed (${res.status}): ${error}`, {
462
+ status: res.status
463
+ });
384
464
  }
385
465
  return await res.json();
386
466
  },
@@ -402,7 +482,9 @@ function createSolvaPayClient(opts) {
402
482
  if (!res.ok) {
403
483
  const error = await res.text();
404
484
  log(`\u274C API Error: ${res.status} - ${error}`);
405
- throw new SolvaPayError(`Process payment failed (${res.status}): ${error}`, { status: res.status });
485
+ throw new SolvaPayError(`Process payment failed (${res.status}): ${error}`, {
486
+ status: res.status
487
+ });
406
488
  }
407
489
  const result = await res.json();
408
490
  return result;
@@ -430,7 +512,9 @@ function createSolvaPayClient(opts) {
430
512
  { status: 400 }
431
513
  );
432
514
  }
433
- throw new SolvaPayError(`Cancel purchase failed (${res.status}): ${error}`, { status: res.status });
515
+ throw new SolvaPayError(`Cancel purchase failed (${res.status}): ${error}`, {
516
+ status: res.status
517
+ });
434
518
  }
435
519
  const responseText = await res.text();
436
520
  let responseData;
@@ -474,12 +558,11 @@ function createSolvaPayClient(opts) {
474
558
  throw new SolvaPayError(`Purchase not found: ${error}`, { status: 404 });
475
559
  }
476
560
  if (res.status === 400) {
477
- throw new SolvaPayError(
478
- `Purchase cannot be reactivated: ${error}`,
479
- { status: 400 }
480
- );
561
+ throw new SolvaPayError(`Purchase cannot be reactivated: ${error}`, { status: 400 });
481
562
  }
482
- throw new SolvaPayError(`Reactivate purchase failed (${res.status}): ${error}`, { status: res.status });
563
+ throw new SolvaPayError(`Reactivate purchase failed (${res.status}): ${error}`, {
564
+ status: res.status
565
+ });
483
566
  }
484
567
  const responseText = await res.text();
485
568
  let responseData;
@@ -520,7 +603,9 @@ function createSolvaPayClient(opts) {
520
603
  if (!res.ok) {
521
604
  const error = await res.text();
522
605
  log(`\u274C API Error: ${res.status} - ${error}`);
523
- throw new SolvaPayError(`Get user info failed (${res.status}): ${error}`, { status: res.status });
606
+ throw new SolvaPayError(`Get user info failed (${res.status}): ${error}`, {
607
+ status: res.status
608
+ });
524
609
  }
525
610
  return await res.json();
526
611
  },
@@ -534,7 +619,9 @@ function createSolvaPayClient(opts) {
534
619
  if (!res.ok) {
535
620
  const error = await res.text();
536
621
  log(`\u274C API Error: ${res.status} - ${error}`);
537
- throw new SolvaPayError(`Get customer balance failed (${res.status}): ${error}`, { status: res.status });
622
+ throw new SolvaPayError(`Get customer balance failed (${res.status}): ${error}`, {
623
+ status: res.status
624
+ });
538
625
  }
539
626
  return await res.json();
540
627
  },
@@ -549,7 +636,9 @@ function createSolvaPayClient(opts) {
549
636
  if (!res.ok) {
550
637
  const error = await res.text();
551
638
  log(`\u274C API Error: ${res.status} - ${error}`);
552
- throw new SolvaPayError(`Create checkout session failed (${res.status}): ${error}`, { status: res.status });
639
+ throw new SolvaPayError(`Create checkout session failed (${res.status}): ${error}`, {
640
+ status: res.status
641
+ });
553
642
  }
554
643
  const result = await res.json();
555
644
  return result;
@@ -565,7 +654,9 @@ function createSolvaPayClient(opts) {
565
654
  if (!res.ok) {
566
655
  const error = await res.text();
567
656
  log(`\u274C API Error: ${res.status} - ${error}`);
568
- throw new SolvaPayError(`Create customer session failed (${res.status}): ${error}`, { status: res.status });
657
+ throw new SolvaPayError(`Create customer session failed (${res.status}): ${error}`, {
658
+ status: res.status
659
+ });
569
660
  }
570
661
  const result = await res.json();
571
662
  return result;
@@ -581,7 +672,9 @@ function createSolvaPayClient(opts) {
581
672
  if (!res.ok) {
582
673
  const error = await res.text();
583
674
  log(`\u274C API Error: ${res.status} - ${error}`);
584
- throw new SolvaPayError(`Activate plan failed (${res.status}): ${error}`, { status: res.status });
675
+ throw new SolvaPayError(`Activate plan failed (${res.status}): ${error}`, {
676
+ status: res.status
677
+ });
585
678
  }
586
679
  return await res.json();
587
680
  },
@@ -592,7 +685,9 @@ function createSolvaPayClient(opts) {
592
685
  if (!res.ok) {
593
686
  const error = await res.text();
594
687
  log(`\u274C API Error: ${res.status} - ${error}`);
595
- throw new SolvaPayError(`Get payment method failed (${res.status}): ${error}`, { status: res.status });
688
+ throw new SolvaPayError(`Get payment method failed (${res.status}): ${error}`, {
689
+ status: res.status
690
+ });
596
691
  }
597
692
  return await res.json();
598
693
  }
@@ -1882,6 +1977,12 @@ function createSolvaPay(config) {
1882
1977
  trackUsage(params) {
1883
1978
  return apiClient.trackUsage(params);
1884
1979
  },
1980
+ trackUsageBulk(params) {
1981
+ if (!apiClient.trackUsageBulk) {
1982
+ throw new SolvaPayError2("trackUsageBulk is not available on this API client");
1983
+ }
1984
+ return apiClient.trackUsageBulk(params);
1985
+ },
1885
1986
  createCustomer(params) {
1886
1987
  if (!apiClient.createCustomer) {
1887
1988
  throw new SolvaPayError2("createCustomer is not available on this API client");
@@ -1891,6 +1992,12 @@ function createSolvaPay(config) {
1891
1992
  getCustomer(params) {
1892
1993
  return apiClient.getCustomer(params);
1893
1994
  },
1995
+ assignCredits(params) {
1996
+ if (!apiClient.assignCredits) {
1997
+ throw new SolvaPayError2("assignCredits is not available on this API client");
1998
+ }
1999
+ return apiClient.assignCredits(params);
2000
+ },
1894
2001
  getCustomerBalance(params) {
1895
2002
  if (!apiClient.getCustomerBalance) {
1896
2003
  throw new SolvaPayError2("getCustomerBalance is not available on this API client");
@@ -1976,7 +2083,9 @@ function createSolvaPay(config) {
1976
2083
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1977
2084
  async function(businessLogic) {
1978
2085
  const getCustomerRef = (args) => {
1979
- const configuredRef = options.getCustomerRef?.(args);
2086
+ const configuredRef = options.getCustomerRef?.(
2087
+ args
2088
+ );
1980
2089
  if (typeof configuredRef === "string") {
1981
2090
  return configuredRef;
1982
2091
  }
@@ -1995,9 +2104,7 @@ function createSolvaPay(config) {
1995
2104
  );
1996
2105
  if (decision.outcome === "gate") {
1997
2106
  const errorMessage = decision.gate.kind === "activation_required" ? "Activation required" : "Payment required";
1998
- const body = paywallErrorToClientPayload(
1999
- new PaywallError(errorMessage, decision.gate)
2000
- );
2107
+ const body = paywallErrorToClientPayload(new PaywallError(errorMessage, decision.gate));
2001
2108
  const response = new Response(JSON.stringify(body), {
2002
2109
  status: 402,
2003
2110
  headers: { "content-type": "application/json" }
@@ -2096,6 +2203,7 @@ function handleRouteError(error, operationName, defaultMessage) {
2096
2203
  }
2097
2204
 
2098
2205
  // src/helpers/auth.ts
2206
+ import { SOLVAPAY_USER_ID_HEADER } from "@solvapay/auth";
2099
2207
  function base64UrlDecode(input) {
2100
2208
  const padded = input.replace(/-/g, "+").replace(/_/g, "/");
2101
2209
  const padding = padded.length % 4 === 0 ? "" : "=".repeat(4 - padded.length % 4);
@@ -2172,7 +2280,7 @@ async function getAuthenticatedUserCore(request, options = {}) {
2172
2280
  try {
2173
2281
  const includeEmail = options.includeEmail !== false;
2174
2282
  const includeName = options.includeName !== false;
2175
- const headerUserId = request.headers.get("x-user-id");
2283
+ const headerUserId = request.headers.get(SOLVAPAY_USER_ID_HEADER);
2176
2284
  if (headerUserId) {
2177
2285
  let email = null;
2178
2286
  let name = null;
@@ -2286,7 +2394,8 @@ async function createPaymentIntentCore(request, body, options = {}) {
2286
2394
  const paymentIntent = await solvaPay.createPaymentIntent({
2287
2395
  productRef: body.productRef,
2288
2396
  planRef: body.planRef,
2289
- customerRef
2397
+ customerRef,
2398
+ ...body.currency && { currency: body.currency }
2290
2399
  });
2291
2400
  return {
2292
2401
  processorPaymentId: paymentIntent.processorPaymentId,
@@ -2942,15 +3051,16 @@ async function trackUsageCore(request, body, options = {}) {
2942
3051
  email: email || void 0,
2943
3052
  name: name || void 0
2944
3053
  });
2945
- await solvaPay.trackUsage({
3054
+ const result = await solvaPay.trackUsage({
2946
3055
  customerRef,
2947
3056
  actionType: body.actionType,
2948
3057
  units: body.units,
2949
3058
  productRef: body.productRef,
2950
3059
  description: body.description,
2951
- metadata: body.metadata
3060
+ metadata: body.metadata,
3061
+ idempotencyKey: body.idempotencyKey
2952
3062
  });
2953
- return { success: true };
3063
+ return result;
2954
3064
  } catch (error) {
2955
3065
  return handleRouteError(error, "Track usage", "Track usage failed");
2956
3066
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solvapay/server",
3
- "version": "1.2.0",
3
+ "version": "1.2.1-preview-e89fa52f99b6d0c7bf9834fcf2d1403141051fa0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
@@ -46,7 +46,7 @@
46
46
  },
47
47
  "peerDependencies": {
48
48
  "zod": "^3.25.0 || ^4.0.0",
49
- "@solvapay/auth": "1.0.8"
49
+ "@solvapay/auth": "^1.1.0-preview-e89fa52f99b6d0c7bf9834fcf2d1403141051fa0"
50
50
  },
51
51
  "peerDependenciesMeta": {
52
52
  "zod": {
@@ -62,7 +62,7 @@
62
62
  "typescript": "^5.9.3",
63
63
  "vitest": "^4.1.2",
64
64
  "zod": "^4.3.6",
65
- "@solvapay/auth": "1.0.8",
65
+ "@solvapay/auth": "1.1.0-preview-e89fa52f99b6d0c7bf9834fcf2d1403141051fa0",
66
66
  "@solvapay/demo-services": "0.0.0",
67
67
  "@solvapay/test-utils": "^0.0.0"
68
68
  },
@@ -70,13 +70,14 @@
70
70
  "build": "tsup",
71
71
  "dev": "tsup --watch",
72
72
  "generate:types": "tsx scripts/generate-types.ts",
73
- "test": "vitest run __tests__/paywall.unit.test.ts __tests__/paywall-state.unit.test.ts __tests__/paywall-gate.unit.test.ts __tests__/payable-gate.unit.test.ts __tests__/bootstrap-mcp.unit.test.ts __tests__/verify-webhook.unit.test.ts __tests__/edge-exports.unit.test.ts src/__tests__/edge-exports.test.ts src/helpers/payment.test.ts __tests__/auth-core.unit.test.ts __tests__/ensure-customer.unit.test.ts __tests__/create-customer.unit.test.ts __tests__/fetch/cors.test.ts __tests__/fetch/handlers.test.ts __tests__/fetch/utils.test.ts",
74
- "test:unit": "vitest run __tests__/paywall.unit.test.ts __tests__/paywall-state.unit.test.ts __tests__/paywall-gate.unit.test.ts __tests__/payable-gate.unit.test.ts __tests__/bootstrap-mcp.unit.test.ts __tests__/verify-webhook.unit.test.ts __tests__/edge-exports.unit.test.ts src/__tests__/edge-exports.test.ts src/helpers/payment.test.ts __tests__/auth-core.unit.test.ts __tests__/ensure-customer.unit.test.ts __tests__/create-customer.unit.test.ts __tests__/fetch/cors.test.ts __tests__/fetch/handlers.test.ts __tests__/fetch/utils.test.ts",
75
- "test:integration": "vitest run --no-file-parallelism __tests__/backend.integration.test.ts __tests__/customer-update.integration.test.ts",
73
+ "test": "vitest run __tests__/paywall.unit.test.ts __tests__/paywall-state.unit.test.ts __tests__/paywall-gate.unit.test.ts __tests__/payable-gate.unit.test.ts __tests__/bootstrap-mcp.unit.test.ts __tests__/verify-webhook.unit.test.ts __tests__/edge-exports.unit.test.ts __tests__/credits-usage.unit.test.ts src/__tests__/edge-exports.test.ts src/helpers/payment.test.ts src/helpers/usage.test.ts __tests__/auth-core.unit.test.ts __tests__/ensure-customer.unit.test.ts __tests__/create-customer.unit.test.ts __tests__/fetch/cors.test.ts __tests__/fetch/handlers.test.ts __tests__/fetch/utils.test.ts",
74
+ "test:unit": "vitest run __tests__/paywall.unit.test.ts __tests__/paywall-state.unit.test.ts __tests__/paywall-gate.unit.test.ts __tests__/payable-gate.unit.test.ts __tests__/bootstrap-mcp.unit.test.ts __tests__/verify-webhook.unit.test.ts __tests__/edge-exports.unit.test.ts __tests__/credits-usage.unit.test.ts src/__tests__/edge-exports.test.ts src/helpers/payment.test.ts src/helpers/usage.test.ts __tests__/auth-core.unit.test.ts __tests__/ensure-customer.unit.test.ts __tests__/create-customer.unit.test.ts __tests__/fetch/cors.test.ts __tests__/fetch/handlers.test.ts __tests__/fetch/utils.test.ts",
75
+ "test:integration": "vitest run --no-file-parallelism __tests__/backend.integration.test.ts __tests__/customer-update.integration.test.ts __tests__/multi-currency-plans.integration.test.ts",
76
76
  "test:integration:backend": "vitest run __tests__/backend.integration.test.ts",
77
77
  "test:integration:customer": "vitest run __tests__/customer-update.integration.test.ts",
78
+ "test:integration:multi-currency": "vitest run __tests__/multi-currency-plans.integration.test.ts",
78
79
  "test:integration:payment": "vitest run __tests__/payment-stripe.integration.test.ts",
79
- "test:integration:all": "vitest run --no-file-parallelism __tests__/backend.integration.test.ts __tests__/customer-update.integration.test.ts __tests__/payment-stripe.integration.test.ts",
80
+ "test:integration:all": "vitest run --no-file-parallelism __tests__/backend.integration.test.ts __tests__/customer-update.integration.test.ts __tests__/multi-currency-plans.integration.test.ts __tests__/payment-stripe.integration.test.ts",
80
81
  "test:all": "vitest run",
81
82
  "test:all:integration": "vitest run",
82
83
  "test:watch": "vitest",