@solvapay/server 1.0.8-preview.9 → 1.0.8
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 +472 -61
- package/dist/edge.js +576 -187
- package/dist/fetch/index.cjs +3071 -0
- package/dist/fetch/index.d.cts +112 -0
- package/dist/fetch/index.d.ts +112 -0
- package/dist/fetch/index.js +3017 -0
- package/dist/index.cjs +606 -4721
- package/dist/index.d.cts +490 -124
- package/dist/index.d.ts +490 -124
- package/dist/index.js +573 -406
- package/package.json +16 -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,27 +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'];
|
|
2491
2687
|
/**
|
|
2492
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).
|
|
2493
2693
|
*
|
|
2494
|
-
*
|
|
2495
|
-
*
|
|
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.
|
|
2496
2698
|
*/
|
|
2497
|
-
type
|
|
2498
|
-
displayName: string;
|
|
2499
|
-
legalName: string;
|
|
2500
|
-
supportEmail?: string;
|
|
2501
|
-
supportUrl?: string;
|
|
2502
|
-
termsUrl?: string;
|
|
2503
|
-
privacyUrl?: string;
|
|
2504
|
-
country?: string;
|
|
2505
|
-
defaultCurrency?: string;
|
|
2506
|
-
statementDescriptor?: string;
|
|
2507
|
-
logoUrl?: string;
|
|
2508
|
-
};
|
|
2699
|
+
type SdkPlatformConfigResponse = components['schemas']['SdkPlatformConfigResponseDto'];
|
|
2509
2700
|
/** SDK-facing product projection. Sourced from the existing OpenAPI spec. */
|
|
2510
2701
|
type SdkProductResponse = components['schemas']['SdkProductResponse'];
|
|
2702
|
+
type McpBootstrapPlanInput = NonNullable<components['schemas']['McpBootstrapDto']['plans']>[number];
|
|
2703
|
+
type ToolPlanMappingInput = NonNullable<components['schemas']['McpBootstrapDto']['tools']>[number];
|
|
2511
2704
|
type McpBootstrapRequest = components['schemas']['McpBootstrapDto'];
|
|
2705
|
+
type McpToolPlanMappingInput = NonNullable<components['schemas']['ConfigureMcpPlansDto']['toolMapping']>[number];
|
|
2512
2706
|
interface McpBootstrapResponse {
|
|
2513
2707
|
product: components['schemas']['SdkProductResponse'];
|
|
2514
2708
|
mcpServer: {
|
|
@@ -2568,6 +2762,21 @@ interface SolvaPayClient {
|
|
|
2568
2762
|
createCustomer?(params: components['schemas']['CreateCustomerRequest']): Promise<{
|
|
2569
2763
|
customerRef: string;
|
|
2570
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
|
+
}>;
|
|
2571
2780
|
getCustomer(params: {
|
|
2572
2781
|
customerRef?: string;
|
|
2573
2782
|
externalRef?: string;
|
|
@@ -2579,6 +2788,14 @@ interface SolvaPayClient {
|
|
|
2579
2788
|
* used by `<MandateText>`, `<CheckoutSummary>`, and trust signals.
|
|
2580
2789
|
*/
|
|
2581
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>;
|
|
2582
2799
|
getProduct?(productRef: string): Promise<SdkProductResponse>;
|
|
2583
2800
|
listProducts?(): Promise<Array<{
|
|
2584
2801
|
reference: string;
|
|
@@ -2658,6 +2875,9 @@ interface SolvaPayClient {
|
|
|
2658
2875
|
createCheckoutSession(params: operations['CheckoutSessionSdkController_createCheckoutSession']['requestBody']['content']['application/json']): Promise<components['schemas']['CreateCheckoutSessionResponse']>;
|
|
2659
2876
|
createCustomerSession(params: components['schemas']['CreateCustomerSessionRequest']): Promise<components['schemas']['CreateCustomerSessionResponse']>;
|
|
2660
2877
|
activatePlan?(params: components['schemas']['ActivatePlanDto']): Promise<ActivatePlanResult>;
|
|
2878
|
+
getPaymentMethod?(params: {
|
|
2879
|
+
customerRef: string;
|
|
2880
|
+
}): Promise<PaymentMethodInfo>;
|
|
2661
2881
|
}
|
|
2662
2882
|
|
|
2663
2883
|
/**
|
|
@@ -2694,6 +2914,15 @@ type PaywallStructuredContent = {
|
|
|
2694
2914
|
product: string;
|
|
2695
2915
|
checkoutUrl: string;
|
|
2696
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;
|
|
2697
2926
|
} | {
|
|
2698
2927
|
kind: 'activation_required';
|
|
2699
2928
|
/** Product ref from paywall metadata (or env default) */
|
|
@@ -2710,18 +2939,47 @@ type PaywallStructuredContent = {
|
|
|
2710
2939
|
productDetails?: LimitActivationProduct;
|
|
2711
2940
|
};
|
|
2712
2941
|
/**
|
|
2713
|
-
*
|
|
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
|
|
2714
2949
|
*/
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
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
|
+
};
|
|
2725
2983
|
|
|
2726
2984
|
/**
|
|
2727
2985
|
* Configuration Options Type Definitions
|
|
@@ -2762,16 +3020,33 @@ interface RetryOptions {
|
|
|
2762
3020
|
*/
|
|
2763
3021
|
onRetry?: (error: Error, attempt: number) => void;
|
|
2764
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
|
+
*/
|
|
2765
3032
|
interface McpToolExtra {
|
|
2766
3033
|
authInfo?: {
|
|
2767
|
-
token
|
|
2768
|
-
clientId
|
|
2769
|
-
scopes
|
|
3034
|
+
token?: string;
|
|
3035
|
+
clientId?: string;
|
|
3036
|
+
scopes?: string[];
|
|
2770
3037
|
expiresAt?: number;
|
|
2771
3038
|
extra?: Record<string, unknown>;
|
|
2772
3039
|
};
|
|
2773
3040
|
[key: string]: unknown;
|
|
2774
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
|
+
}
|
|
2775
3050
|
/**
|
|
2776
3051
|
* Options for configuring payable protection
|
|
2777
3052
|
*/
|
|
@@ -2827,19 +3102,6 @@ interface NextAdapterOptions {
|
|
|
2827
3102
|
*/
|
|
2828
3103
|
transformResponse?: (result: any) => any;
|
|
2829
3104
|
}
|
|
2830
|
-
/**
|
|
2831
|
-
* MCP adapter options for MCP servers
|
|
2832
|
-
*/
|
|
2833
|
-
interface McpAdapterOptions {
|
|
2834
|
-
/**
|
|
2835
|
-
* Extract customer reference from MCP args
|
|
2836
|
-
*/
|
|
2837
|
-
getCustomerRef?: (args: any, extra?: McpToolExtra) => string | Promise<string>;
|
|
2838
|
-
/**
|
|
2839
|
-
* Transform the response before wrapping in MCP format
|
|
2840
|
-
*/
|
|
2841
|
-
transformResponse?: (result: any) => any;
|
|
2842
|
-
}
|
|
2843
3105
|
|
|
2844
3106
|
/**
|
|
2845
3107
|
* SolvaPay Server SDK - API Client
|
|
@@ -3580,30 +3842,48 @@ declare function createSolvaPay(config?: CreateSolvaPayConfig): SolvaPay;
|
|
|
3580
3842
|
*/
|
|
3581
3843
|
|
|
3582
3844
|
/**
|
|
3583
|
-
* Error
|
|
3845
|
+
* Error representing a paywall gate outcome (purchase required or usage
|
|
3846
|
+
* limit exceeded).
|
|
3584
3847
|
*
|
|
3585
|
-
*
|
|
3586
|
-
*
|
|
3587
|
-
*
|
|
3588
|
-
*
|
|
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:
|
|
3589
3853
|
*
|
|
3590
|
-
*
|
|
3591
|
-
*
|
|
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`.
|
|
3592
3863
|
*
|
|
3593
|
-
*
|
|
3864
|
+
* The error includes structured content with checkout URLs and metadata
|
|
3865
|
+
* for building custom paywall UIs.
|
|
3866
|
+
*
|
|
3867
|
+
* @example Preferred (decide()/formatGate)
|
|
3594
3868
|
* ```typescript
|
|
3595
|
-
*
|
|
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
|
+
* ```
|
|
3596
3876
|
*
|
|
3877
|
+
* @example Compat (try/catch on throw-based legacy path)
|
|
3878
|
+
* ```typescript
|
|
3597
3879
|
* try {
|
|
3598
3880
|
* const result = await payable.http(createTask)(req, res);
|
|
3599
3881
|
* return result;
|
|
3600
3882
|
* } catch (error) {
|
|
3601
3883
|
* if (error instanceof PaywallError) {
|
|
3602
|
-
* // Custom paywall handling
|
|
3603
3884
|
* return res.status(402).json({
|
|
3604
3885
|
* error: error.message,
|
|
3605
3886
|
* checkoutUrl: error.structuredContent.checkoutUrl,
|
|
3606
|
-
* // Additional metadata available in error.structuredContent
|
|
3607
3887
|
* });
|
|
3608
3888
|
* }
|
|
3609
3889
|
* throw error;
|
|
@@ -3611,6 +3891,7 @@ declare function createSolvaPay(config?: CreateSolvaPayConfig): SolvaPay;
|
|
|
3611
3891
|
* ```
|
|
3612
3892
|
*
|
|
3613
3893
|
* @see {@link PaywallStructuredContent} for the structured content format
|
|
3894
|
+
* @see {@link PaywallDecision} for the preferred decision-based API
|
|
3614
3895
|
* @since 1.0.0
|
|
3615
3896
|
*/
|
|
3616
3897
|
declare class PaywallError extends Error {
|
|
@@ -3626,6 +3907,86 @@ declare class PaywallError extends Error {
|
|
|
3626
3907
|
/** JSON body shape for HTTP adapters and MCP text content (stable fields for clients). */
|
|
3627
3908
|
declare function paywallErrorToClientPayload(error: PaywallError): Record<string, unknown>;
|
|
3628
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
|
+
|
|
3629
3990
|
/**
|
|
3630
3991
|
* Utility functions for the SolvaPay Server SDK
|
|
3631
3992
|
*/
|
|
@@ -3720,8 +4081,16 @@ declare function handleRouteError(error: unknown, operationName: string, default
|
|
|
3720
4081
|
* and name from authenticated requests. Works with any framework that uses
|
|
3721
4082
|
* the standard Web API Request (Express, Fastify, Next.js, Edge Functions, etc.).
|
|
3722
4083
|
*
|
|
3723
|
-
*
|
|
3724
|
-
*
|
|
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).
|
|
3725
4094
|
*
|
|
3726
4095
|
* @param request - Standard Web API Request object
|
|
3727
4096
|
* @param options - Configuration options
|
|
@@ -4041,6 +4410,21 @@ declare function activatePlanCore(request: Request, body: {
|
|
|
4041
4410
|
includeName?: boolean;
|
|
4042
4411
|
}): Promise<ActivatePlanResult | ErrorResult>;
|
|
4043
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
|
+
|
|
4044
4428
|
/**
|
|
4045
4429
|
* Plans Helper (Core)
|
|
4046
4430
|
*
|
|
@@ -4118,6 +4502,33 @@ declare function checkPurchaseCore(request: Request, options?: {
|
|
|
4118
4502
|
includeName?: boolean;
|
|
4119
4503
|
}): Promise<PurchaseCheckResult | ErrorResult>;
|
|
4120
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>;
|
|
4121
4532
|
declare function trackUsageCore(request: Request, body: {
|
|
4122
4533
|
actionType?: 'transaction' | 'api_call' | 'hour' | 'email' | 'storage' | 'custom';
|
|
4123
4534
|
units?: number;
|
|
@@ -4143,4 +4554,4 @@ declare function verifyWebhook({ body, signature, secret, }: {
|
|
|
4143
4554
|
secret: string;
|
|
4144
4555
|
}): Promise<WebhookEvent>;
|
|
4145
4556
|
|
|
4146
|
-
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 };
|