@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 CHANGED
@@ -23,7 +23,10 @@ import { createSolvaPay } from '@solvapay/server'
23
23
  const solvaPay = createSolvaPay({ apiKey: process.env.SOLVAPAY_SECRET_KEY })
24
24
  const payable = solvaPay.payable({ product: 'prd_YOUR_PRODUCT' })
25
25
 
26
- app.post('/tasks', payable.http(async args => ({ id: 'task_1', ...args })))
26
+ app.post(
27
+ '/tasks',
28
+ payable.http(async args => ({ id: 'task_1', ...args })),
29
+ )
27
30
  ```
28
31
 
29
32
  Guide: [Express integration](https://docs.solvapay.com/sdks/typescript/guides/express)
@@ -68,12 +71,12 @@ server.setRequestHandler(..., payable.mcp(handler)) // MCP (low-level)
68
71
  const fn = await payable.function(handler) // Direct / jobs / tests
69
72
  ```
70
73
 
71
- | Adapter | Use when |
72
- | --- | --- |
73
- | `payable.http()` | Express, Fastify, traditional HTTP |
74
- | `payable.next()` | Next.js App Router |
75
- | `payable.mcp()` | MCP tool handlers (low-level) |
76
- | `payable.function()` | Tests, cron, non-HTTP contexts |
74
+ | Adapter | Use when |
75
+ | -------------------- | ---------------------------------- |
76
+ | `payable.http()` | Express, Fastify, traditional HTTP |
77
+ | `payable.next()` | Next.js App Router |
78
+ | `payable.mcp()` | MCP tool handlers (low-level) |
79
+ | `payable.function()` | Tests, cron, non-HTTP contexts |
77
80
 
78
81
  ### Authentication
79
82
 
@@ -109,7 +112,9 @@ Guide: [MCP](https://docs.solvapay.com/sdks/typescript/guides/mcp)
109
112
  `createSolvaPayClient` implements:
110
113
 
111
114
  - `checkLimits(params)` — usage limits; auto-enrolls on first call for free default plans
112
- - `trackUsage(params)` — metered billing
115
+ - `trackUsage(params)` — metered billing; returns the recorded usage reference and any credit debit result
116
+ - `trackUsageBulk({ events })` — record several metered usage events in one request
117
+ - `assignCredits(params)` — grant credits to a customer balance with optional idempotency
113
118
  - `createCustomer(params)` / `getCustomer(params)` — customer lifecycle
114
119
 
115
120
  Full reference: [Server SDK docs](https://docs.solvapay.com/sdks/typescript/intro)
package/dist/edge.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;
@@ -2014,12 +2144,7 @@ interface operations {
2014
2144
  [name: string]: unknown;
2015
2145
  };
2016
2146
  content: {
2017
- "application/json": {
2018
- /** @example true */
2019
- success?: boolean;
2020
- /** @example usage_A1B2C3D4 */
2021
- reference?: string;
2022
- };
2147
+ "application/json": components["schemas"]["UsageRecordResponse"];
2023
2148
  };
2024
2149
  };
2025
2150
  /** @description Validation failed */
@@ -2049,7 +2174,9 @@ interface operations {
2049
2174
  headers: {
2050
2175
  [name: string]: unknown;
2051
2176
  };
2052
- content?: never;
2177
+ content: {
2178
+ "application/json": components["schemas"]["BulkUsageResponse"];
2179
+ };
2053
2180
  };
2054
2181
  /** @description Validation failed */
2055
2182
  400: {
@@ -2581,6 +2708,43 @@ interface operations {
2581
2708
  };
2582
2709
  };
2583
2710
  };
2711
+ CustomerSdkController_grantCredits: {
2712
+ parameters: {
2713
+ query?: never;
2714
+ header?: {
2715
+ /** @description Provider-scoped idempotency key for safe grant retries */
2716
+ "Idempotency-Key"?: string;
2717
+ };
2718
+ path: {
2719
+ /** @description Customer reference identifier */
2720
+ reference: string;
2721
+ };
2722
+ cookie?: never;
2723
+ };
2724
+ requestBody: {
2725
+ content: {
2726
+ "application/json": components["schemas"]["GrantCustomerCreditsRequest"];
2727
+ };
2728
+ };
2729
+ responses: {
2730
+ /** @description Credits granted successfully */
2731
+ 200: {
2732
+ headers: {
2733
+ [name: string]: unknown;
2734
+ };
2735
+ content: {
2736
+ "application/json": components["schemas"]["GrantCustomerCreditsResponse"];
2737
+ };
2738
+ };
2739
+ /** @description Customer not found */
2740
+ 404: {
2741
+ headers: {
2742
+ [name: string]: unknown;
2743
+ };
2744
+ content?: never;
2745
+ };
2746
+ };
2747
+ };
2584
2748
  CustomerSdkController_createCustomerSession: {
2585
2749
  parameters: {
2586
2750
  query?: never;
@@ -2974,6 +3138,20 @@ type SdkMerchantResponse = components['schemas']['SdkMerchantResponseDto'];
2974
3138
  type SdkPlatformConfigResponse = components['schemas']['SdkPlatformConfigResponseDto'];
2975
3139
  /** SDK-facing product projection. Sourced from the existing OpenAPI spec. */
2976
3140
  type SdkProductResponse = components['schemas']['SdkProductResponse'];
3141
+ type TrackUsageRequest = Omit<Partial<components['schemas']['CreateUsageRequest']>, 'customerRef' | 'metadata'> & {
3142
+ customerRef: string;
3143
+ metadata?: Record<string, unknown>;
3144
+ };
3145
+ type TrackUsageResponse = components['schemas']['UsageRecordResponse'];
3146
+ interface TrackUsageBulkRequest {
3147
+ events: TrackUsageRequest[];
3148
+ }
3149
+ type TrackUsageBulkResponse = components['schemas']['BulkUsageResponse'];
3150
+ type AssignCreditsRequest = components['schemas']['GrantCustomerCreditsRequest'] & {
3151
+ customerRef: string;
3152
+ idempotencyKey?: string;
3153
+ };
3154
+ type AssignCreditsResponse = components['schemas']['GrantCustomerCreditsResponse'];
2977
3155
  type McpBootstrapPlanInput = NonNullable<components['schemas']['McpBootstrapDto']['plans']>[number];
2978
3156
  type ToolPlanMappingInput = NonNullable<components['schemas']['McpBootstrapDto']['tools']>[number];
2979
3157
  type McpBootstrapRequest = components['schemas']['McpBootstrapDto'];
@@ -3021,19 +3199,8 @@ interface ConfigureMcpPlansResponse {
3021
3199
  */
3022
3200
  interface SolvaPayClient {
3023
3201
  checkLimits(params: CheckLimitsRequest): Promise<LimitResponseWithPlan>;
3024
- trackUsage(params: {
3025
- customerRef: string;
3026
- actionType?: 'transaction' | 'api_call' | 'hour' | 'email' | 'storage' | 'custom';
3027
- units?: number;
3028
- outcome?: 'success' | 'paywall' | 'fail';
3029
- productRef?: string;
3030
- purchaseRef?: string;
3031
- description?: string;
3032
- metadata?: Record<string, unknown>;
3033
- duration?: number;
3034
- timestamp?: string;
3035
- idempotencyKey?: string;
3036
- }): Promise<void>;
3202
+ trackUsage(params: TrackUsageRequest): Promise<TrackUsageResponse>;
3203
+ trackUsageBulk?(params: TrackUsageBulkRequest): Promise<TrackUsageBulkResponse>;
3037
3204
  createCustomer?(params: components['schemas']['CreateCustomerRequest']): Promise<{
3038
3205
  customerRef: string;
3039
3206
  }>;
@@ -3057,6 +3224,7 @@ interface SolvaPayClient {
3057
3224
  externalRef?: string;
3058
3225
  email?: string;
3059
3226
  }): Promise<CustomerResponseMapped>;
3227
+ assignCredits?(params: AssignCreditsRequest): Promise<AssignCreditsResponse>;
3060
3228
  /**
3061
3229
  * SDK-facing merchant identity (GET /v1/sdk/merchant).
3062
3230
  * Returns the subset of provider fields safe for browser consumption —
@@ -3102,6 +3270,7 @@ interface SolvaPayClient {
3102
3270
  productRef: string;
3103
3271
  planRef: string;
3104
3272
  customerRef: string;
3273
+ currency?: string;
3105
3274
  idempotencyKey?: string;
3106
3275
  }): Promise<{
3107
3276
  processorPaymentId: string;
@@ -3768,12 +3937,12 @@ interface PayableFunction {
3768
3937
  * const solvaPay = createSolvaPay();
3769
3938
  *
3770
3939
  * // Create payable handlers
3771
- * const payable = solvaPay.payable({ product: 'prd_myapi' });
3772
- *
3773
- * // Manage customers
3774
- * const customerRef = await solvaPay.ensureCustomer('user_123', 'user_123', {
3775
- * email: 'user@example.com'
3776
- * });
3940
+ * const payable = solvaPay.payable({ product: 'prd_myapi' });
3941
+ *
3942
+ * // Manage customers
3943
+ * const customerRef = await solvaPay.ensureCustomer('user_123', 'user_123', {
3944
+ * email: 'user@example.com'
3945
+ * });
3777
3946
  * ```
3778
3947
  */
3779
3948
  interface SolvaPay {
@@ -3853,6 +4022,7 @@ interface SolvaPay {
3853
4022
  productRef: string;
3854
4023
  planRef: string;
3855
4024
  customerRef: string;
4025
+ currency?: string;
3856
4026
  idempotencyKey?: string;
3857
4027
  }): Promise<{
3858
4028
  processorPaymentId: string;
@@ -3980,19 +4150,11 @@ interface SolvaPay {
3980
4150
  * });
3981
4151
  * ```
3982
4152
  */
3983
- trackUsage(params: {
3984
- customerRef: string;
3985
- actionType?: 'transaction' | 'api_call' | 'hour' | 'email' | 'storage' | 'custom';
3986
- units?: number;
3987
- outcome?: 'success' | 'paywall' | 'fail';
3988
- productRef?: string;
3989
- purchaseRef?: string;
3990
- description?: string;
3991
- metadata?: Record<string, unknown>;
3992
- duration?: number;
3993
- timestamp?: string;
3994
- idempotencyKey?: string;
3995
- }): Promise<void>;
4153
+ trackUsage(params: TrackUsageRequest): Promise<TrackUsageResponse>;
4154
+ /**
4155
+ * Track usage events in bulk.
4156
+ */
4157
+ trackUsageBulk(params: TrackUsageBulkRequest): Promise<TrackUsageBulkResponse>;
3996
4158
  /**
3997
4159
  * Create a new customer in SolvaPay backend.
3998
4160
  *
@@ -4047,6 +4209,10 @@ interface SolvaPay {
4047
4209
  customerRef?: string;
4048
4210
  externalRef?: string;
4049
4211
  }): Promise<CustomerResponseMapped>;
4212
+ /**
4213
+ * Assign credits to a customer balance.
4214
+ */
4215
+ assignCredits(params: AssignCreditsRequest): Promise<AssignCreditsResponse>;
4050
4216
  /**
4051
4217
  * Get credits for a customer.
4052
4218
  *
@@ -4221,7 +4387,7 @@ interface SolvaPay {
4221
4387
  *
4222
4388
  * This factory function creates a SolvaPay instance that can be used to
4223
4389
  * protect API endpoints, functions, and MCP tools with usage limits and
4224
- * purchase checks.
4390
+ * purchase checks.
4225
4391
  *
4226
4392
  * @param config - Optional configuration object
4227
4393
  * @param config.apiKey - API key for production use (defaults to `SOLVAPAY_SECRET_KEY` env var)
@@ -4535,7 +4701,7 @@ declare function handleRouteError(error: unknown, operationName: string, default
4535
4701
  * the standard Web API Request (Express, Fastify, Next.js, Edge Functions, etc.).
4536
4702
  *
4537
4703
  * Resolution order:
4538
- * 1. `x-user-id` header — set by Next.js-style middleware (unchanged).
4704
+ * 1. `SOLVAPAY_USER_ID_HEADER` header — set by Next.js-style middleware (unchanged).
4539
4705
  * 2. `Authorization: Bearer <jwt>` — verified via HS256 when a secret is
4540
4706
  * configured (`SOLVAPAY_JWT_SECRET` or `SUPABASE_JWT_SECRET`), or
4541
4707
  * unverified-decoded when no secret is configured. The unverified path
@@ -4687,6 +4853,7 @@ declare function getCustomerBalanceCore(request: Request, options?: {
4687
4853
  declare function createPaymentIntentCore(request: Request, body: {
4688
4854
  planRef: string;
4689
4855
  productRef: string;
4856
+ currency?: string;
4690
4857
  }, options?: {
4691
4858
  solvaPay?: SolvaPay;
4692
4859
  includeEmail?: boolean;
@@ -5095,11 +5262,10 @@ declare function trackUsageCore(request: Request, body: {
5095
5262
  productRef?: string;
5096
5263
  description?: string;
5097
5264
  metadata?: Record<string, unknown>;
5265
+ idempotencyKey?: string;
5098
5266
  }, options?: {
5099
5267
  solvaPay?: SolvaPay;
5100
- }): Promise<{
5101
- success: true;
5102
- } | ErrorResult>;
5268
+ }): Promise<TrackUsageResponse | ErrorResult>;
5103
5269
 
5104
5270
  /**
5105
5271
  * SolvaPay Server SDK - Edge Runtime Entry Point