@solvapay/server 1.0.9-preview.1 → 1.0.9
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 +80 -2
- package/dist/edge.d.ts +516 -49
- package/dist/edge.js +691 -197
- package/dist/fetch/index.cjs +3073 -0
- package/dist/fetch/index.d.cts +112 -0
- package/dist/fetch/index.d.ts +112 -0
- package/dist/fetch/index.js +3019 -0
- package/dist/index.cjs +731 -4739
- package/dist/index.d.cts +534 -112
- package/dist/index.d.ts +534 -112
- package/dist/index.js +688 -416
- package/package.json +19 -13
- package/dist/chunk-MLKGABMK.js +0 -9
- package/dist/webapi-K5XBCEO6.js +0 -3775
package/dist/edge.d.ts
CHANGED
|
@@ -49,6 +49,58 @@ type WebhookEvent = {
|
|
|
49
49
|
|
|
50
50
|
interface components {
|
|
51
51
|
schemas: {
|
|
52
|
+
SdkMerchantResponseDto: {
|
|
53
|
+
/**
|
|
54
|
+
* Brand name shown in UI
|
|
55
|
+
* @example Acme
|
|
56
|
+
*/
|
|
57
|
+
displayName: string;
|
|
58
|
+
/**
|
|
59
|
+
* Legal entity name used in SCA mandate copy
|
|
60
|
+
* @example Acme Inc.
|
|
61
|
+
*/
|
|
62
|
+
legalName: string;
|
|
63
|
+
/** @example support@acme.com */
|
|
64
|
+
supportEmail?: string;
|
|
65
|
+
/** @example https://acme.com/support */
|
|
66
|
+
supportUrl?: string;
|
|
67
|
+
/** @example https://acme.com/terms */
|
|
68
|
+
termsUrl?: string;
|
|
69
|
+
/** @example https://acme.com/privacy */
|
|
70
|
+
privacyUrl?: string;
|
|
71
|
+
/**
|
|
72
|
+
* ISO-3166 alpha-2 country code of the merchant
|
|
73
|
+
* @example US
|
|
74
|
+
*/
|
|
75
|
+
country?: string;
|
|
76
|
+
/**
|
|
77
|
+
* ISO-4217 default settlement currency
|
|
78
|
+
* @example usd
|
|
79
|
+
*/
|
|
80
|
+
defaultCurrency?: string;
|
|
81
|
+
/**
|
|
82
|
+
* Descriptor appearing on the customer card statement
|
|
83
|
+
* @example ACME INC
|
|
84
|
+
*/
|
|
85
|
+
statementDescriptor?: string;
|
|
86
|
+
/**
|
|
87
|
+
* Absolute URL to the merchant logo
|
|
88
|
+
* @example https://cdn.acme.com/logo.png
|
|
89
|
+
*/
|
|
90
|
+
logoUrl?: string;
|
|
91
|
+
/**
|
|
92
|
+
* Absolute URL to the square app icon / logomark. Consumed by MCP host chromes, mobile avatar slots, and any surface where the landscape `logoUrl` would need letterboxing.
|
|
93
|
+
* @example https://cdn.acme.com/icon.png
|
|
94
|
+
*/
|
|
95
|
+
iconUrl?: string;
|
|
96
|
+
};
|
|
97
|
+
SdkPlatformConfigResponseDto: {
|
|
98
|
+
/**
|
|
99
|
+
* SolvaPay's platform Stripe publishable key for the authenticated provider's environment. Safe to expose browser-side; paired with the connected `accountId` returned from `create-payment-intent` for Stripe Connect direct charges. Omitted when not configured so callers can fall back cleanly to a hosted flow.
|
|
100
|
+
* @example pk_test_...
|
|
101
|
+
*/
|
|
102
|
+
stripePublishableKey?: string;
|
|
103
|
+
};
|
|
52
104
|
CreatePaymentIntentDto: {
|
|
53
105
|
productRef?: string;
|
|
54
106
|
customerRef: string;
|
|
@@ -1047,6 +1099,14 @@ interface components {
|
|
|
1047
1099
|
/** @description Active purchases */
|
|
1048
1100
|
purchases?: components["schemas"]["PurchaseInfo"][];
|
|
1049
1101
|
};
|
|
1102
|
+
UpdateCustomerRequest: {
|
|
1103
|
+
/** Format: email */
|
|
1104
|
+
email?: string;
|
|
1105
|
+
name?: string;
|
|
1106
|
+
telephone?: string;
|
|
1107
|
+
metadata?: unknown;
|
|
1108
|
+
externalRef?: string;
|
|
1109
|
+
};
|
|
1050
1110
|
CreateCustomerSessionResponse: {
|
|
1051
1111
|
/**
|
|
1052
1112
|
* Customer session ID/token
|
|
@@ -1180,6 +1240,53 @@ interface components {
|
|
|
1180
1240
|
pathItems: never;
|
|
1181
1241
|
}
|
|
1182
1242
|
interface operations {
|
|
1243
|
+
getMerchant: {
|
|
1244
|
+
parameters: {
|
|
1245
|
+
query?: never;
|
|
1246
|
+
header?: never;
|
|
1247
|
+
path?: never;
|
|
1248
|
+
cookie?: never;
|
|
1249
|
+
};
|
|
1250
|
+
requestBody?: never;
|
|
1251
|
+
responses: {
|
|
1252
|
+
/** @description Merchant identity */
|
|
1253
|
+
200: {
|
|
1254
|
+
headers: {
|
|
1255
|
+
[name: string]: unknown;
|
|
1256
|
+
};
|
|
1257
|
+
content: {
|
|
1258
|
+
"application/json": components["schemas"]["SdkMerchantResponseDto"];
|
|
1259
|
+
};
|
|
1260
|
+
};
|
|
1261
|
+
/** @description Provider not found */
|
|
1262
|
+
404: {
|
|
1263
|
+
headers: {
|
|
1264
|
+
[name: string]: unknown;
|
|
1265
|
+
};
|
|
1266
|
+
content?: never;
|
|
1267
|
+
};
|
|
1268
|
+
};
|
|
1269
|
+
};
|
|
1270
|
+
getPlatformConfig: {
|
|
1271
|
+
parameters: {
|
|
1272
|
+
query?: never;
|
|
1273
|
+
header?: never;
|
|
1274
|
+
path?: never;
|
|
1275
|
+
cookie?: never;
|
|
1276
|
+
};
|
|
1277
|
+
requestBody?: never;
|
|
1278
|
+
responses: {
|
|
1279
|
+
/** @description Platform config */
|
|
1280
|
+
200: {
|
|
1281
|
+
headers: {
|
|
1282
|
+
[name: string]: unknown;
|
|
1283
|
+
};
|
|
1284
|
+
content: {
|
|
1285
|
+
"application/json": components["schemas"]["SdkPlatformConfigResponseDto"];
|
|
1286
|
+
};
|
|
1287
|
+
};
|
|
1288
|
+
};
|
|
1289
|
+
};
|
|
1183
1290
|
PaymentIntentSdkController_getPaymentIntents: {
|
|
1184
1291
|
parameters: {
|
|
1185
1292
|
query?: {
|
|
@@ -2258,7 +2365,7 @@ interface operations {
|
|
|
2258
2365
|
};
|
|
2259
2366
|
};
|
|
2260
2367
|
};
|
|
2261
|
-
|
|
2368
|
+
CustomerSdkController_getCustomer: {
|
|
2262
2369
|
parameters: {
|
|
2263
2370
|
query?: never;
|
|
2264
2371
|
header?: never;
|
|
@@ -2270,13 +2377,13 @@ interface operations {
|
|
|
2270
2377
|
};
|
|
2271
2378
|
requestBody?: never;
|
|
2272
2379
|
responses: {
|
|
2273
|
-
/** @description Customer
|
|
2380
|
+
/** @description Customer retrieved successfully */
|
|
2274
2381
|
200: {
|
|
2275
2382
|
headers: {
|
|
2276
2383
|
[name: string]: unknown;
|
|
2277
2384
|
};
|
|
2278
2385
|
content: {
|
|
2279
|
-
"application/json":
|
|
2386
|
+
"application/json": components["schemas"]["CustomerResponse"];
|
|
2280
2387
|
};
|
|
2281
2388
|
};
|
|
2282
2389
|
/** @description Customer not found */
|
|
@@ -2290,7 +2397,7 @@ interface operations {
|
|
|
2290
2397
|
};
|
|
2291
2398
|
};
|
|
2292
2399
|
};
|
|
2293
|
-
|
|
2400
|
+
CustomerSdkController_updateCustomer: {
|
|
2294
2401
|
parameters: {
|
|
2295
2402
|
query?: never;
|
|
2296
2403
|
header?: never;
|
|
@@ -2300,9 +2407,14 @@ interface operations {
|
|
|
2300
2407
|
};
|
|
2301
2408
|
cookie?: never;
|
|
2302
2409
|
};
|
|
2303
|
-
|
|
2410
|
+
/** @description Fields to update (all optional) */
|
|
2411
|
+
requestBody: {
|
|
2412
|
+
content: {
|
|
2413
|
+
"application/json": components["schemas"]["UpdateCustomerRequest"];
|
|
2414
|
+
};
|
|
2415
|
+
};
|
|
2304
2416
|
responses: {
|
|
2305
|
-
/** @description Customer
|
|
2417
|
+
/** @description Customer updated successfully */
|
|
2306
2418
|
200: {
|
|
2307
2419
|
headers: {
|
|
2308
2420
|
[name: string]: unknown;
|
|
@@ -2311,6 +2423,43 @@ interface operations {
|
|
|
2311
2423
|
"application/json": components["schemas"]["CustomerResponse"];
|
|
2312
2424
|
};
|
|
2313
2425
|
};
|
|
2426
|
+
/** @description Invalid update payload */
|
|
2427
|
+
400: {
|
|
2428
|
+
headers: {
|
|
2429
|
+
[name: string]: unknown;
|
|
2430
|
+
};
|
|
2431
|
+
content?: never;
|
|
2432
|
+
};
|
|
2433
|
+
/** @description Customer not found */
|
|
2434
|
+
404: {
|
|
2435
|
+
headers: {
|
|
2436
|
+
[name: string]: unknown;
|
|
2437
|
+
};
|
|
2438
|
+
content?: never;
|
|
2439
|
+
};
|
|
2440
|
+
};
|
|
2441
|
+
};
|
|
2442
|
+
CustomerSdkController_getCustomerBalance: {
|
|
2443
|
+
parameters: {
|
|
2444
|
+
query?: never;
|
|
2445
|
+
header?: never;
|
|
2446
|
+
path: {
|
|
2447
|
+
/** @description Customer reference identifier */
|
|
2448
|
+
reference: string;
|
|
2449
|
+
};
|
|
2450
|
+
cookie?: never;
|
|
2451
|
+
};
|
|
2452
|
+
requestBody?: never;
|
|
2453
|
+
responses: {
|
|
2454
|
+
/** @description Customer balance retrieved successfully */
|
|
2455
|
+
200: {
|
|
2456
|
+
headers: {
|
|
2457
|
+
[name: string]: unknown;
|
|
2458
|
+
};
|
|
2459
|
+
content: {
|
|
2460
|
+
"application/json": unknown;
|
|
2461
|
+
};
|
|
2462
|
+
};
|
|
2314
2463
|
/** @description Customer not found */
|
|
2315
2464
|
404: {
|
|
2316
2465
|
headers: {
|
|
@@ -2435,6 +2584,43 @@ interface operations {
|
|
|
2435
2584
|
};
|
|
2436
2585
|
};
|
|
2437
2586
|
};
|
|
2587
|
+
PaymentMethodSdkController_getPaymentMethod: {
|
|
2588
|
+
parameters: {
|
|
2589
|
+
query: {
|
|
2590
|
+
/** @description Customer reference (e.g. `customer_...`). */
|
|
2591
|
+
customerRef: string;
|
|
2592
|
+
};
|
|
2593
|
+
header?: never;
|
|
2594
|
+
path?: never;
|
|
2595
|
+
cookie?: never;
|
|
2596
|
+
};
|
|
2597
|
+
requestBody?: never;
|
|
2598
|
+
responses: {
|
|
2599
|
+
/** @description The customer's default card, or `{ kind: 'none' }` when no card is on file. */
|
|
2600
|
+
200: {
|
|
2601
|
+
headers: {
|
|
2602
|
+
[name: string]: unknown;
|
|
2603
|
+
};
|
|
2604
|
+
content: {
|
|
2605
|
+
"application/json": {
|
|
2606
|
+
/** @enum {string} */
|
|
2607
|
+
kind: "card";
|
|
2608
|
+
/** @example visa */
|
|
2609
|
+
brand: string;
|
|
2610
|
+
/** @example 4242 */
|
|
2611
|
+
last4: string;
|
|
2612
|
+
/** @example 12 */
|
|
2613
|
+
expMonth: number;
|
|
2614
|
+
/** @example 2030 */
|
|
2615
|
+
expYear: number;
|
|
2616
|
+
} | {
|
|
2617
|
+
/** @enum {string} */
|
|
2618
|
+
kind: "none";
|
|
2619
|
+
};
|
|
2620
|
+
};
|
|
2621
|
+
};
|
|
2622
|
+
};
|
|
2623
|
+
};
|
|
2438
2624
|
}
|
|
2439
2625
|
|
|
2440
2626
|
/**
|
|
@@ -2488,7 +2674,35 @@ interface ProcessPaymentResult {
|
|
|
2488
2674
|
status: 'completed';
|
|
2489
2675
|
}
|
|
2490
2676
|
type ActivatePlanResult = components['schemas']['ActivatePlanResponseDto'];
|
|
2677
|
+
/**
|
|
2678
|
+
* SDK-facing payment-method projection returned by
|
|
2679
|
+
* `GET /v1/sdk/payment-method?customerRef=...`.
|
|
2680
|
+
*
|
|
2681
|
+
* Derived from the generated operation response so any backend shape
|
|
2682
|
+
* change propagates through a single `npm run generate:types` run. The
|
|
2683
|
+
* inline `oneOf` schema on the backend controller translates to a clean
|
|
2684
|
+
* `{ kind: 'card', ... } | { kind: 'none' }` discriminated union here.
|
|
2685
|
+
*/
|
|
2686
|
+
type PaymentMethodInfo = operations['PaymentMethodSdkController_getPaymentMethod']['responses']['200']['content']['application/json'];
|
|
2687
|
+
/**
|
|
2688
|
+
* SDK-facing merchant identity (source: GET /v1/sdk/merchant).
|
|
2689
|
+
*/
|
|
2690
|
+
type SdkMerchantResponse = components['schemas']['SdkMerchantResponseDto'];
|
|
2691
|
+
/**
|
|
2692
|
+
* SDK-facing platform config (source: GET /v1/sdk/platform-config).
|
|
2693
|
+
*
|
|
2694
|
+
* Environment-aware platform values resolved against the authenticated
|
|
2695
|
+
* provider. Primary consumer today is the MCP checkout app, which uses
|
|
2696
|
+
* `stripePublishableKey` to boot Stripe.js for a CSP probe before a
|
|
2697
|
+
* PaymentIntent exists.
|
|
2698
|
+
*/
|
|
2699
|
+
type SdkPlatformConfigResponse = components['schemas']['SdkPlatformConfigResponseDto'];
|
|
2700
|
+
/** SDK-facing product projection. Sourced from the existing OpenAPI spec. */
|
|
2701
|
+
type SdkProductResponse = components['schemas']['SdkProductResponse'];
|
|
2702
|
+
type McpBootstrapPlanInput = NonNullable<components['schemas']['McpBootstrapDto']['plans']>[number];
|
|
2703
|
+
type ToolPlanMappingInput = NonNullable<components['schemas']['McpBootstrapDto']['tools']>[number];
|
|
2491
2704
|
type McpBootstrapRequest = components['schemas']['McpBootstrapDto'];
|
|
2705
|
+
type McpToolPlanMappingInput = NonNullable<components['schemas']['ConfigureMcpPlansDto']['toolMapping']>[number];
|
|
2492
2706
|
interface McpBootstrapResponse {
|
|
2493
2707
|
product: components['schemas']['SdkProductResponse'];
|
|
2494
2708
|
mcpServer: {
|
|
@@ -2548,11 +2762,41 @@ interface SolvaPayClient {
|
|
|
2548
2762
|
createCustomer?(params: components['schemas']['CreateCustomerRequest']): Promise<{
|
|
2549
2763
|
customerRef: string;
|
|
2550
2764
|
}>;
|
|
2765
|
+
/**
|
|
2766
|
+
* PATCH: /v1/sdk/customers/{customerRef}
|
|
2767
|
+
* Update mutable customer fields. Used by `ensureCustomer` to backfill
|
|
2768
|
+
* `externalRef` on an existing email-matched customer, and exposed
|
|
2769
|
+
* directly for integrators who need it.
|
|
2770
|
+
*/
|
|
2771
|
+
updateCustomer?(customerRef: string, params: {
|
|
2772
|
+
email?: string;
|
|
2773
|
+
name?: string;
|
|
2774
|
+
telephone?: string;
|
|
2775
|
+
metadata?: Record<string, unknown>;
|
|
2776
|
+
externalRef?: string;
|
|
2777
|
+
}): Promise<{
|
|
2778
|
+
customerRef: string;
|
|
2779
|
+
}>;
|
|
2551
2780
|
getCustomer(params: {
|
|
2552
2781
|
customerRef?: string;
|
|
2553
2782
|
externalRef?: string;
|
|
2554
2783
|
email?: string;
|
|
2555
2784
|
}): Promise<CustomerResponseMapped>;
|
|
2785
|
+
/**
|
|
2786
|
+
* SDK-facing merchant identity (GET /v1/sdk/merchant).
|
|
2787
|
+
* Returns the subset of provider fields safe for browser consumption —
|
|
2788
|
+
* used by `<MandateText>`, `<CheckoutSummary>`, and trust signals.
|
|
2789
|
+
*/
|
|
2790
|
+
getMerchant?(): Promise<SdkMerchantResponse>;
|
|
2791
|
+
/**
|
|
2792
|
+
* SDK-facing platform config (GET /v1/sdk/platform-config).
|
|
2793
|
+
* Returns environment-aware browser-safe values (resolved sandbox/live
|
|
2794
|
+
* against the authenticated provider). Primary consumer today is the
|
|
2795
|
+
* MCP checkout app, which uses `stripePublishableKey` to boot Stripe.js
|
|
2796
|
+
* for a CSP probe before a PaymentIntent exists.
|
|
2797
|
+
*/
|
|
2798
|
+
getPlatformConfig?(): Promise<SdkPlatformConfigResponse>;
|
|
2799
|
+
getProduct?(productRef: string): Promise<SdkProductResponse>;
|
|
2556
2800
|
listProducts?(): Promise<Array<{
|
|
2557
2801
|
reference: string;
|
|
2558
2802
|
name: string;
|
|
@@ -2631,6 +2875,9 @@ interface SolvaPayClient {
|
|
|
2631
2875
|
createCheckoutSession(params: operations['CheckoutSessionSdkController_createCheckoutSession']['requestBody']['content']['application/json']): Promise<components['schemas']['CreateCheckoutSessionResponse']>;
|
|
2632
2876
|
createCustomerSession(params: components['schemas']['CreateCustomerSessionRequest']): Promise<components['schemas']['CreateCustomerSessionResponse']>;
|
|
2633
2877
|
activatePlan?(params: components['schemas']['ActivatePlanDto']): Promise<ActivatePlanResult>;
|
|
2878
|
+
getPaymentMethod?(params: {
|
|
2879
|
+
customerRef: string;
|
|
2880
|
+
}): Promise<PaymentMethodInfo>;
|
|
2634
2881
|
}
|
|
2635
2882
|
|
|
2636
2883
|
/**
|
|
@@ -2667,6 +2914,15 @@ type PaywallStructuredContent = {
|
|
|
2667
2914
|
product: string;
|
|
2668
2915
|
checkoutUrl: string;
|
|
2669
2916
|
message: string;
|
|
2917
|
+
/**
|
|
2918
|
+
* Quota balance at the moment the paywall tripped. Optional so
|
|
2919
|
+
* older server versions (pre-balance-on-payment_required) stay
|
|
2920
|
+
* compatible; the React `PaywallNotice.Message` prefers this
|
|
2921
|
+
* structured data over the raw `message` when available.
|
|
2922
|
+
*/
|
|
2923
|
+
balance?: LimitActivationBalance;
|
|
2924
|
+
/** Rich product context from checkLimits (name, ref, provider slug/id) */
|
|
2925
|
+
productDetails?: LimitActivationProduct;
|
|
2670
2926
|
} | {
|
|
2671
2927
|
kind: 'activation_required';
|
|
2672
2928
|
/** Product ref from paywall metadata (or env default) */
|
|
@@ -2683,18 +2939,47 @@ type PaywallStructuredContent = {
|
|
|
2683
2939
|
productDetails?: LimitActivationProduct;
|
|
2684
2940
|
};
|
|
2685
2941
|
/**
|
|
2686
|
-
*
|
|
2942
|
+
* Runtime type guard for `PaywallStructuredContent`.
|
|
2943
|
+
*
|
|
2944
|
+
* Used by the MCP registration layer to detect paywall-shaped tool results
|
|
2945
|
+
* coming out of `.mcp()` so it knows whether to attach the `_meta.ui`
|
|
2946
|
+
* envelope that tells MCP hosts which UI resource to open.
|
|
2947
|
+
*
|
|
2948
|
+
* @since 1.0.9
|
|
2687
2949
|
*/
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2950
|
+
declare function isPaywallStructuredContent(value: unknown): value is PaywallStructuredContent;
|
|
2951
|
+
/**
|
|
2952
|
+
* Discriminated union returned from `paywall.decide(args, metadata)` that
|
|
2953
|
+
* surfaces the pre-check outcome as data instead of an exception.
|
|
2954
|
+
*
|
|
2955
|
+
* Replaces the throw-based `PaywallError` control flow adapters previously
|
|
2956
|
+
* relied on: `allow` carries the resolved customer ref + fresh
|
|
2957
|
+
* `LimitResponseWithPlan` so the handler can run, while `gate` carries the
|
|
2958
|
+
* ready-to-serialise `PaywallStructuredContent` so the adapter's
|
|
2959
|
+
* `formatGate` can emit the transport-specific paywall response.
|
|
2960
|
+
*
|
|
2961
|
+
* The `args` field on `allow` is the same shape passed in — threaded
|
|
2962
|
+
* through so callers can hand it directly to the handler without having
|
|
2963
|
+
* to hold onto a reference across the call.
|
|
2964
|
+
*
|
|
2965
|
+
* @since 1.1.0
|
|
2966
|
+
*/
|
|
2967
|
+
type PaywallDecision<T> = {
|
|
2968
|
+
outcome: 'allow';
|
|
2969
|
+
args: T;
|
|
2970
|
+
limits: LimitResponseWithPlan;
|
|
2971
|
+
customerRef: string;
|
|
2972
|
+
} | {
|
|
2973
|
+
outcome: 'gate';
|
|
2974
|
+
gate: PaywallStructuredContent;
|
|
2975
|
+
/**
|
|
2976
|
+
* The `LimitResponseWithPlan` consulted when the gate tripped. May
|
|
2977
|
+
* be `null` on degraded paths that couldn't produce a fresh
|
|
2978
|
+
* response (defensive — normal flow always populates this).
|
|
2979
|
+
*/
|
|
2980
|
+
limits: LimitResponseWithPlan | null;
|
|
2981
|
+
customerRef: string;
|
|
2982
|
+
};
|
|
2698
2983
|
|
|
2699
2984
|
/**
|
|
2700
2985
|
* Configuration Options Type Definitions
|
|
@@ -2735,16 +3020,33 @@ interface RetryOptions {
|
|
|
2735
3020
|
*/
|
|
2736
3021
|
onRetry?: (error: Error, attempt: number) => void;
|
|
2737
3022
|
}
|
|
3023
|
+
/**
|
|
3024
|
+
* Extra context passed into MCP tool handlers — structural copy of
|
|
3025
|
+
* `McpToolExtra` from `@solvapay/mcp` kept here to avoid a build-time
|
|
3026
|
+
* circular dependency between `@solvapay/server` and `@solvapay/mcp`.
|
|
3027
|
+
*
|
|
3028
|
+
* The canonical version lives in `@solvapay/mcp/types.ts`. Keep the two
|
|
3029
|
+
* in lockstep — a `vitest` snapshot in `@solvapay/mcp` guards the
|
|
3030
|
+
* shape.
|
|
3031
|
+
*/
|
|
2738
3032
|
interface McpToolExtra {
|
|
2739
3033
|
authInfo?: {
|
|
2740
|
-
token
|
|
2741
|
-
clientId
|
|
2742
|
-
scopes
|
|
3034
|
+
token?: string;
|
|
3035
|
+
clientId?: string;
|
|
3036
|
+
scopes?: string[];
|
|
2743
3037
|
expiresAt?: number;
|
|
2744
3038
|
extra?: Record<string, unknown>;
|
|
2745
3039
|
};
|
|
2746
3040
|
[key: string]: unknown;
|
|
2747
3041
|
}
|
|
3042
|
+
/**
|
|
3043
|
+
* MCP adapter options — structural copy of `McpAdapterOptions` from
|
|
3044
|
+
* `@solvapay/mcp`.
|
|
3045
|
+
*/
|
|
3046
|
+
interface McpAdapterOptions {
|
|
3047
|
+
getCustomerRef?: (args: any, extra?: McpToolExtra) => string | Promise<string>;
|
|
3048
|
+
transformResponse?: (result: any) => any;
|
|
3049
|
+
}
|
|
2748
3050
|
/**
|
|
2749
3051
|
* Options for configuring payable protection
|
|
2750
3052
|
*/
|
|
@@ -2800,19 +3102,6 @@ interface NextAdapterOptions {
|
|
|
2800
3102
|
*/
|
|
2801
3103
|
transformResponse?: (result: any) => any;
|
|
2802
3104
|
}
|
|
2803
|
-
/**
|
|
2804
|
-
* MCP adapter options for MCP servers
|
|
2805
|
-
*/
|
|
2806
|
-
interface McpAdapterOptions {
|
|
2807
|
-
/**
|
|
2808
|
-
* Extract customer reference from MCP args
|
|
2809
|
-
*/
|
|
2810
|
-
getCustomerRef?: (args: any, extra?: McpToolExtra) => string | Promise<string>;
|
|
2811
|
-
/**
|
|
2812
|
-
* Transform the response before wrapping in MCP format
|
|
2813
|
-
*/
|
|
2814
|
-
transformResponse?: (result: any) => any;
|
|
2815
|
-
}
|
|
2816
3105
|
|
|
2817
3106
|
/**
|
|
2818
3107
|
* SolvaPay Server SDK - API Client
|
|
@@ -3553,30 +3842,48 @@ declare function createSolvaPay(config?: CreateSolvaPayConfig): SolvaPay;
|
|
|
3553
3842
|
*/
|
|
3554
3843
|
|
|
3555
3844
|
/**
|
|
3556
|
-
* Error
|
|
3845
|
+
* Error representing a paywall gate outcome (purchase required or usage
|
|
3846
|
+
* limit exceeded).
|
|
3557
3847
|
*
|
|
3558
|
-
*
|
|
3559
|
-
*
|
|
3560
|
-
*
|
|
3561
|
-
*
|
|
3848
|
+
* Soft-deprecated since 1.1.0 as the internal control-flow signal —
|
|
3849
|
+
* `paywall.decide()` returns a typed `PaywallDecision<T>` union instead,
|
|
3850
|
+
* and adapters route gate outcomes through `formatGate` without
|
|
3851
|
+
* throwing. `PaywallError` is retained as a compat shim for three paths
|
|
3852
|
+
* that keep working without migration:
|
|
3562
3853
|
*
|
|
3563
|
-
*
|
|
3564
|
-
*
|
|
3854
|
+
* 1. `paywall.protect(handler, ...)` still throws `PaywallError` on
|
|
3855
|
+
* gate outcomes (the legacy throw-based API).
|
|
3856
|
+
* 2. Merchant code that `throw new PaywallError(...)` (or
|
|
3857
|
+
* `ctx.gate(reason)`, which is implemented on top of
|
|
3858
|
+
* `PaywallError`) — caught at the adapter boundary and routed
|
|
3859
|
+
* through `formatGate` so transport responses stay consistent.
|
|
3860
|
+
* 3. Custom third-party adapters that didn't implement `formatGate` —
|
|
3861
|
+
* `AbstractAdapter.formatGate` falls back to wrapping in
|
|
3862
|
+
* `PaywallError` and delegating to `formatError`.
|
|
3565
3863
|
*
|
|
3566
|
-
*
|
|
3864
|
+
* The error includes structured content with checkout URLs and metadata
|
|
3865
|
+
* for building custom paywall UIs.
|
|
3866
|
+
*
|
|
3867
|
+
* @example Preferred (decide()/formatGate)
|
|
3567
3868
|
* ```typescript
|
|
3568
|
-
*
|
|
3869
|
+
* const decision = await solvaPay.paywall.decide(args, { product })
|
|
3870
|
+
* if (decision.outcome === 'gate') {
|
|
3871
|
+
* return res.status(402).json(paywallErrorToClientPayload(
|
|
3872
|
+
* new PaywallError(decision.gate.message, decision.gate),
|
|
3873
|
+
* ))
|
|
3874
|
+
* }
|
|
3875
|
+
* ```
|
|
3569
3876
|
*
|
|
3877
|
+
* @example Compat (try/catch on throw-based legacy path)
|
|
3878
|
+
* ```typescript
|
|
3570
3879
|
* try {
|
|
3571
3880
|
* const result = await payable.http(createTask)(req, res);
|
|
3572
3881
|
* return result;
|
|
3573
3882
|
* } catch (error) {
|
|
3574
3883
|
* if (error instanceof PaywallError) {
|
|
3575
|
-
* // Custom paywall handling
|
|
3576
3884
|
* return res.status(402).json({
|
|
3577
3885
|
* error: error.message,
|
|
3578
3886
|
* checkoutUrl: error.structuredContent.checkoutUrl,
|
|
3579
|
-
* // Additional metadata available in error.structuredContent
|
|
3580
3887
|
* });
|
|
3581
3888
|
* }
|
|
3582
3889
|
* throw error;
|
|
@@ -3584,6 +3891,7 @@ declare function createSolvaPay(config?: CreateSolvaPayConfig): SolvaPay;
|
|
|
3584
3891
|
* ```
|
|
3585
3892
|
*
|
|
3586
3893
|
* @see {@link PaywallStructuredContent} for the structured content format
|
|
3894
|
+
* @see {@link PaywallDecision} for the preferred decision-based API
|
|
3587
3895
|
* @since 1.0.0
|
|
3588
3896
|
*/
|
|
3589
3897
|
declare class PaywallError extends Error {
|
|
@@ -3599,6 +3907,86 @@ declare class PaywallError extends Error {
|
|
|
3599
3907
|
/** JSON body shape for HTTP adapters and MCP text content (stable fields for clients). */
|
|
3600
3908
|
declare function paywallErrorToClientPayload(error: PaywallError): Record<string, unknown>;
|
|
3601
3909
|
|
|
3910
|
+
/**
|
|
3911
|
+
* Pure state engine that classifies a `LimitResponseWithPlan` into a
|
|
3912
|
+
* recovery-tool-specific `PaywallState`, and produces the human-readable
|
|
3913
|
+
* gate / nudge message templates the MCP transport ships as
|
|
3914
|
+
* `content[0].text` on gate/nudge responses.
|
|
3915
|
+
*
|
|
3916
|
+
* This module has no UI dependencies — it's framework-neutral so
|
|
3917
|
+
* `@solvapay/server`, `@solvapay/mcp-core`, and any HTTP adapter can
|
|
3918
|
+
* reuse the classification + copy. The text-only paywall design puts
|
|
3919
|
+
* the full narration (including a clickable `checkoutUrl` for
|
|
3920
|
+
* terminal-first hosts) on `gate.message`, and names exactly one
|
|
3921
|
+
* primary recovery tool so LLMs chain naturally toward it.
|
|
3922
|
+
*/
|
|
3923
|
+
|
|
3924
|
+
/**
|
|
3925
|
+
* Discriminated union describing which recovery path the customer
|
|
3926
|
+
* needs. Every state maps to exactly one primary recovery tool except
|
|
3927
|
+
* `reactivation_required`, which surfaces two alternatives (rare).
|
|
3928
|
+
*/
|
|
3929
|
+
type PaywallState = {
|
|
3930
|
+
kind: 'activation_required';
|
|
3931
|
+
} | {
|
|
3932
|
+
kind: 'topup_required';
|
|
3933
|
+
} | {
|
|
3934
|
+
kind: 'upgrade_required';
|
|
3935
|
+
} | {
|
|
3936
|
+
kind: 'reactivation_required';
|
|
3937
|
+
};
|
|
3938
|
+
/**
|
|
3939
|
+
* Classify a `LimitResponseWithPlan` (or `null` on degraded paths) into
|
|
3940
|
+
* a `PaywallState`. Pure — safe to call multiple times per request.
|
|
3941
|
+
*
|
|
3942
|
+
* Precedence:
|
|
3943
|
+
* 1. `activationRequired === true` — trumps everything else; the
|
|
3944
|
+
* backend explicitly flagged that no plan is live yet.
|
|
3945
|
+
* 2. Usage-based plan out of credits — the customer has a plan but
|
|
3946
|
+
* ran out, so a topup is the right action. "Out of credits" is
|
|
3947
|
+
* determined from (in order): the nested
|
|
3948
|
+
* `balance.creditBalance === 0` block, the top-level
|
|
3949
|
+
* `creditBalance === 0` field, or `remaining === 0` as a
|
|
3950
|
+
* fallback for older backend responses that omit both credit
|
|
3951
|
+
* fields on usage-based plans.
|
|
3952
|
+
* 3. Everything else → `upgrade_required`, including:
|
|
3953
|
+
* - `limits === null` (defensive),
|
|
3954
|
+
* - no active plan on the product,
|
|
3955
|
+
* - recurring plan at period cap (`remaining <= 0`).
|
|
3956
|
+
*
|
|
3957
|
+
* `reactivation_required` is deferred — it needs a distinct backend
|
|
3958
|
+
* signal (future `LimitResponse.inactivePurchaseRef`) which isn't
|
|
3959
|
+
* emitted yet. Kept in the type so downstream code compiles against
|
|
3960
|
+
* the full discriminated union; `classifyPaywallState` will never
|
|
3961
|
+
* return it under current backend behaviour.
|
|
3962
|
+
*/
|
|
3963
|
+
declare function classifyPaywallState(limits: LimitResponseWithPlan | null): PaywallState;
|
|
3964
|
+
/**
|
|
3965
|
+
* Produce the terminal-friendly gate message. Names exactly one
|
|
3966
|
+
* recovery tool (`upgrade` / `topup` / `activate_plan`), except for
|
|
3967
|
+
* the rare `reactivation_required` path which names two alternatives
|
|
3968
|
+
* (`manage_account` / `upgrade`). Inlines `gate.checkoutUrl` when
|
|
3969
|
+
* present so terminal-only MCP hosts (Claude Code, CLI clients) can
|
|
3970
|
+
* open a browser directly.
|
|
3971
|
+
*
|
|
3972
|
+
* Kept as a pure string so the adapter layer can concatenate it with
|
|
3973
|
+
* an optional narrator prefix without parsing structured copy.
|
|
3974
|
+
*/
|
|
3975
|
+
declare function buildGateMessage(state: PaywallState, gate: PaywallStructuredContent): string;
|
|
3976
|
+
/**
|
|
3977
|
+
* Low-balance / approaching-cap nudge copy used as a plain text suffix
|
|
3978
|
+
* on a successful merchant response (no `structuredContent` switch, no
|
|
3979
|
+
* view switch). Mirrors the `buildGateMessage` surface so nudges feel
|
|
3980
|
+
* like a softer version of the same text-only nudge path.
|
|
3981
|
+
*
|
|
3982
|
+
* Receives the `PaywallState` the classifier would have produced if
|
|
3983
|
+
* the customer had tripped the gate. `upgrade_required` and
|
|
3984
|
+
* `topup_required` are the only kinds that currently produce nudge
|
|
3985
|
+
* copy; the others are no-ops (shouldn't happen — nudges only fire
|
|
3986
|
+
* on successful calls).
|
|
3987
|
+
*/
|
|
3988
|
+
declare function buildNudgeMessage(state: PaywallState, limits: LimitResponseWithPlan | null): string;
|
|
3989
|
+
|
|
3602
3990
|
/**
|
|
3603
3991
|
* Utility functions for the SolvaPay Server SDK
|
|
3604
3992
|
*/
|
|
@@ -3693,8 +4081,16 @@ declare function handleRouteError(error: unknown, operationName: string, default
|
|
|
3693
4081
|
* and name from authenticated requests. Works with any framework that uses
|
|
3694
4082
|
* the standard Web API Request (Express, Fastify, Next.js, Edge Functions, etc.).
|
|
3695
4083
|
*
|
|
3696
|
-
*
|
|
3697
|
-
*
|
|
4084
|
+
* Resolution order:
|
|
4085
|
+
* 1. `x-user-id` header — set by Next.js-style middleware (unchanged).
|
|
4086
|
+
* 2. `Authorization: Bearer <jwt>` — verified via HS256 when a secret is
|
|
4087
|
+
* configured (`SOLVAPAY_JWT_SECRET` or `SUPABASE_JWT_SECRET`), or
|
|
4088
|
+
* unverified-decoded when no secret is configured. The unverified path
|
|
4089
|
+
* covers platforms that verify JWTs at the gateway (e.g. Supabase Edge
|
|
4090
|
+
* with `verify_jwt = true`, which is the default) and asymmetric signing
|
|
4091
|
+
* keys (ES256/RS256) that the SDK does not have keys for.
|
|
4092
|
+
* 3. Set `SOLVAPAY_AUTH_STRICT=true` to require cryptographic verification
|
|
4093
|
+
* inside the handler (the unverified-decode fallback is then disabled).
|
|
3698
4094
|
*
|
|
3699
4095
|
* @param request - Standard Web API Request object
|
|
3700
4096
|
* @param options - Configuration options
|
|
@@ -4014,6 +4410,21 @@ declare function activatePlanCore(request: Request, body: {
|
|
|
4014
4410
|
includeName?: boolean;
|
|
4015
4411
|
}): Promise<ActivatePlanResult | ErrorResult>;
|
|
4016
4412
|
|
|
4413
|
+
/**
|
|
4414
|
+
* Payment-method helpers (core).
|
|
4415
|
+
*
|
|
4416
|
+
* Thin wrapper over `GET /v1/sdk/payment-method`. Extracts the authenticated
|
|
4417
|
+
* user from the request via `syncCustomerCore`, then asks the SolvaPay API
|
|
4418
|
+
* for the customer's default card. Returns `{ kind: 'none' }` gracefully
|
|
4419
|
+
* when no card is on file; any other failure surfaces as an `ErrorResult`.
|
|
4420
|
+
*/
|
|
4421
|
+
|
|
4422
|
+
declare function getPaymentMethodCore(request: Request, options?: {
|
|
4423
|
+
solvaPay?: SolvaPay;
|
|
4424
|
+
includeEmail?: boolean;
|
|
4425
|
+
includeName?: boolean;
|
|
4426
|
+
}): Promise<PaymentMethodInfo | ErrorResult>;
|
|
4427
|
+
|
|
4017
4428
|
/**
|
|
4018
4429
|
* Plans Helper (Core)
|
|
4019
4430
|
*
|
|
@@ -4024,13 +4435,42 @@ declare function activatePlanCore(request: Request, body: {
|
|
|
4024
4435
|
|
|
4025
4436
|
type Plan = components['schemas']['Plan'];
|
|
4026
4437
|
/**
|
|
4027
|
-
* List plans - core implementation
|
|
4438
|
+
* List plans - core implementation.
|
|
4439
|
+
*
|
|
4440
|
+
* Pass `options.solvaPay` to route through a pre-configured SolvaPay instance
|
|
4441
|
+
* (e.g. stub-backed in examples). When omitted, the helper reads
|
|
4442
|
+
* `SOLVAPAY_SECRET_KEY` from environment and constructs a real API client.
|
|
4028
4443
|
*/
|
|
4029
|
-
declare function listPlansCore(request: Request
|
|
4444
|
+
declare function listPlansCore(request: Request, options?: {
|
|
4445
|
+
solvaPay?: SolvaPay;
|
|
4446
|
+
}): Promise<{
|
|
4030
4447
|
plans: Plan[];
|
|
4031
4448
|
productRef: string;
|
|
4032
4449
|
} | ErrorResult>;
|
|
4033
4450
|
|
|
4451
|
+
/**
|
|
4452
|
+
* Merchant Helper (Core)
|
|
4453
|
+
*
|
|
4454
|
+
* Generic helper for GET /api/merchant — returns the SDK-facing merchant
|
|
4455
|
+
* identity used by `<MandateText>`, `<CheckoutSummary>`, and trust signals.
|
|
4456
|
+
* Works with standard Web API Request (Express, Fastify, Next.js, Edge).
|
|
4457
|
+
*/
|
|
4458
|
+
|
|
4459
|
+
declare function getMerchantCore(_request: Request, options?: {
|
|
4460
|
+
solvaPay?: SolvaPay;
|
|
4461
|
+
}): Promise<SdkMerchantResponse | ErrorResult>;
|
|
4462
|
+
|
|
4463
|
+
/**
|
|
4464
|
+
* Product Helper (Core)
|
|
4465
|
+
*
|
|
4466
|
+
* Generic helper for GET /api/get-product?productRef=...
|
|
4467
|
+
* Returns a single product by reference, used by the `useProduct` React hook.
|
|
4468
|
+
*/
|
|
4469
|
+
|
|
4470
|
+
declare function getProductCore(request: Request, options?: {
|
|
4471
|
+
solvaPay?: SolvaPay;
|
|
4472
|
+
}): Promise<SdkProductResponse | ErrorResult>;
|
|
4473
|
+
|
|
4034
4474
|
interface PurchaseCheckResult {
|
|
4035
4475
|
customerRef: string;
|
|
4036
4476
|
email?: string;
|
|
@@ -4062,6 +4502,33 @@ declare function checkPurchaseCore(request: Request, options?: {
|
|
|
4062
4502
|
includeName?: boolean;
|
|
4063
4503
|
}): Promise<PurchaseCheckResult | ErrorResult>;
|
|
4064
4504
|
|
|
4505
|
+
/**
|
|
4506
|
+
* Usage snapshot derived from the authenticated customer's active purchase.
|
|
4507
|
+
*
|
|
4508
|
+
* Shape matches the backend's `UserInfoUsageDto` so the React `useUsage`
|
|
4509
|
+
* hook gets a canonical set of fields regardless of transport.
|
|
4510
|
+
*/
|
|
4511
|
+
interface GetUsageResult {
|
|
4512
|
+
meterRef: string | null;
|
|
4513
|
+
total: number | null;
|
|
4514
|
+
used: number;
|
|
4515
|
+
remaining: number | null;
|
|
4516
|
+
/** 0–100, rounded to 2dp. `null` when `total` is unknown. */
|
|
4517
|
+
percentUsed: number | null;
|
|
4518
|
+
periodStart?: string;
|
|
4519
|
+
periodEnd?: string;
|
|
4520
|
+
/** Raw purchase ref the usage belongs to (when a usage-based plan is active). */
|
|
4521
|
+
purchaseRef?: string;
|
|
4522
|
+
}
|
|
4523
|
+
/**
|
|
4524
|
+
* Fetch the authenticated customer's usage snapshot for the active purchase.
|
|
4525
|
+
*
|
|
4526
|
+
* Derives the values from `checkPurchaseCore` — no extra backend call.
|
|
4527
|
+
* Returns `null` values when no usage-based plan is active.
|
|
4528
|
+
*/
|
|
4529
|
+
declare function getUsageCore(request: Request, options?: {
|
|
4530
|
+
solvaPay?: SolvaPay;
|
|
4531
|
+
}): Promise<GetUsageResult | ErrorResult>;
|
|
4065
4532
|
declare function trackUsageCore(request: Request, body: {
|
|
4066
4533
|
actionType?: 'transaction' | 'api_call' | 'hour' | 'email' | 'storage' | 'custom';
|
|
4067
4534
|
units?: number;
|
|
@@ -4087,4 +4554,4 @@ declare function verifyWebhook({ body, signature, secret, }: {
|
|
|
4087
4554
|
secret: string;
|
|
4088
4555
|
}): Promise<WebhookEvent>;
|
|
4089
4556
|
|
|
4090
|
-
export { type AuthenticatedUser, type CreateSolvaPayConfig, type CustomerBalanceResult, type CustomerWebhookObject, type ErrorResult, type HttpAdapterOptions, type LimitActivationBalance, type LimitActivationProduct, type LimitPlanSummary, type
|
|
4557
|
+
export { type ActivatePlanResult, type AuthenticatedUser, type ConfigureMcpPlansRequest, type ConfigureMcpPlansResponse, type CreateSolvaPayConfig, type CustomerBalanceResult, type CustomerResponseMapped, type CustomerWebhookObject, type ErrorResult, type GetUsageResult, type HttpAdapterOptions, type LimitActivationBalance, type LimitActivationProduct, type LimitPlanSummary, type LimitResponseWithPlan, type McpBootstrapPlanInput, type McpBootstrapRequest, type McpBootstrapResponse, type McpToolPlanMappingInput, type NextAdapterOptions, type OneTimePurchaseInfo, type PayableFunction, type PayableOptions, type PaymentMethodInfo, type PaywallArgs, type PaywallDecision, PaywallError, type PaywallMetadata, type PaywallState, type PaywallStructuredContent, type ProcessPaymentResult, type PurchaseCheckResult, type RetryOptions, type SdkMerchantResponse, type SdkProductResponse, type ServerClientOptions, type SolvaPay, type SolvaPayClient, type ToolPlanMappingInput, type WebhookEvent, type WebhookEventForType, type WebhookEventObjectMap, type WebhookEventType, type WebhookProduct, activatePlanCore, buildGateMessage, buildNudgeMessage, cancelPurchaseCore, checkPurchaseCore, classifyPaywallState, type components, createCheckoutSessionCore, createCustomerSessionCore, createPaymentIntentCore, createSolvaPay, createSolvaPayClient, createTopupPaymentIntentCore, getAuthenticatedUserCore, getCustomerBalanceCore, getMerchantCore, getPaymentMethodCore, getProductCore, getUsageCore, handleRouteError, isErrorResult, isPaywallStructuredContent, listPlansCore, paywallErrorToClientPayload, processPaymentIntentCore, reactivatePurchaseCore, syncCustomerCore, trackUsageCore, verifyWebhook, withRetry };
|