@solvapay/server 1.0.7 → 1.0.8-preview.2
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/edge.d.ts +123 -3
- package/dist/edge.js +243 -9
- package/dist/index.cjs +211 -18
- package/dist/index.d.cts +102 -3
- package/dist/index.d.ts +102 -3
- package/dist/index.js +199 -10
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -110,6 +110,36 @@ function createSolvaPayClient(opts) {
|
|
|
110
110
|
purchases: customer.purchases || []
|
|
111
111
|
};
|
|
112
112
|
},
|
|
113
|
+
// GET: /v1/sdk/merchant
|
|
114
|
+
async getMerchant() {
|
|
115
|
+
const url = `${base}/v1/sdk/merchant`;
|
|
116
|
+
const res = await fetch(url, {
|
|
117
|
+
method: "GET",
|
|
118
|
+
headers
|
|
119
|
+
});
|
|
120
|
+
if (!res.ok) {
|
|
121
|
+
const error = await res.text();
|
|
122
|
+
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
123
|
+
throw new SolvaPayError(`Get merchant failed (${res.status}): ${error}`);
|
|
124
|
+
}
|
|
125
|
+
return res.json();
|
|
126
|
+
},
|
|
127
|
+
// GET: /v1/sdk/products/{productRef}
|
|
128
|
+
async getProduct(productRef) {
|
|
129
|
+
const url = `${base}/v1/sdk/products/${encodeURIComponent(productRef)}`;
|
|
130
|
+
const res = await fetch(url, {
|
|
131
|
+
method: "GET",
|
|
132
|
+
headers
|
|
133
|
+
});
|
|
134
|
+
if (!res.ok) {
|
|
135
|
+
const error = await res.text();
|
|
136
|
+
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
137
|
+
throw new SolvaPayError(`Get product failed (${res.status}): ${error}`);
|
|
138
|
+
}
|
|
139
|
+
const result = await res.json();
|
|
140
|
+
const data = result.data || {};
|
|
141
|
+
return { ...data, ...result };
|
|
142
|
+
},
|
|
113
143
|
// Product management methods (primarily for integration tests)
|
|
114
144
|
// GET: /v1/sdk/products
|
|
115
145
|
async listProducts() {
|
|
@@ -1715,7 +1745,8 @@ var McpBearerAuthError = class extends Error {
|
|
|
1715
1745
|
function base64UrlDecode(input) {
|
|
1716
1746
|
const normalized = input.replace(/-/g, "+").replace(/_/g, "/");
|
|
1717
1747
|
const padded = normalized.padEnd(normalized.length + (4 - normalized.length % 4) % 4, "=");
|
|
1718
|
-
|
|
1748
|
+
const bytes = Uint8Array.from(atob(padded), (c) => c.charCodeAt(0));
|
|
1749
|
+
return new TextDecoder().decode(bytes);
|
|
1719
1750
|
}
|
|
1720
1751
|
function extractBearerToken(authorization) {
|
|
1721
1752
|
if (!authorization) return null;
|
|
@@ -2356,7 +2387,7 @@ async function activatePlanCore(request, body, options = {}) {
|
|
|
2356
2387
|
|
|
2357
2388
|
// src/helpers/plans.ts
|
|
2358
2389
|
import { getSolvaPayConfig as getSolvaPayConfig2 } from "@solvapay/core";
|
|
2359
|
-
async function listPlansCore(request) {
|
|
2390
|
+
async function listPlansCore(request, options = {}) {
|
|
2360
2391
|
try {
|
|
2361
2392
|
const url = new URL(request.url);
|
|
2362
2393
|
const productRef = url.searchParams.get("productRef");
|
|
@@ -2366,19 +2397,20 @@ async function listPlansCore(request) {
|
|
|
2366
2397
|
status: 400
|
|
2367
2398
|
};
|
|
2368
2399
|
}
|
|
2369
|
-
const
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2400
|
+
const apiClient = options.solvaPay?.apiClient ?? (() => {
|
|
2401
|
+
const config = getSolvaPayConfig2();
|
|
2402
|
+
if (!config.apiKey) return null;
|
|
2403
|
+
return createSolvaPayClient({
|
|
2404
|
+
apiKey: config.apiKey,
|
|
2405
|
+
apiBaseUrl: config.apiBaseUrl
|
|
2406
|
+
});
|
|
2407
|
+
})();
|
|
2408
|
+
if (!apiClient) {
|
|
2373
2409
|
return {
|
|
2374
2410
|
error: "Server configuration error: SolvaPay secret key not configured",
|
|
2375
2411
|
status: 500
|
|
2376
2412
|
};
|
|
2377
2413
|
}
|
|
2378
|
-
const apiClient = createSolvaPayClient({
|
|
2379
|
-
apiKey: solvapaySecretKey,
|
|
2380
|
-
apiBaseUrl: solvapayApiBaseUrl
|
|
2381
|
-
});
|
|
2382
2414
|
if (!apiClient.listPlans) {
|
|
2383
2415
|
return {
|
|
2384
2416
|
error: "List plans method not available",
|
|
@@ -2395,6 +2427,159 @@ async function listPlansCore(request) {
|
|
|
2395
2427
|
}
|
|
2396
2428
|
}
|
|
2397
2429
|
|
|
2430
|
+
// src/helpers/merchant.ts
|
|
2431
|
+
import { getSolvaPayConfig as getSolvaPayConfig3 } from "@solvapay/core";
|
|
2432
|
+
async function getMerchantCore(_request, options = {}) {
|
|
2433
|
+
try {
|
|
2434
|
+
const apiClient = options.solvaPay?.apiClient ?? (() => {
|
|
2435
|
+
const config = getSolvaPayConfig3();
|
|
2436
|
+
if (!config.apiKey) return null;
|
|
2437
|
+
return createSolvaPayClient({
|
|
2438
|
+
apiKey: config.apiKey,
|
|
2439
|
+
apiBaseUrl: config.apiBaseUrl
|
|
2440
|
+
});
|
|
2441
|
+
})();
|
|
2442
|
+
if (!apiClient) {
|
|
2443
|
+
return {
|
|
2444
|
+
error: "Server configuration error: SolvaPay secret key not configured",
|
|
2445
|
+
status: 500
|
|
2446
|
+
};
|
|
2447
|
+
}
|
|
2448
|
+
if (!apiClient.getMerchant) {
|
|
2449
|
+
return {
|
|
2450
|
+
error: "Get merchant method not available",
|
|
2451
|
+
status: 500
|
|
2452
|
+
};
|
|
2453
|
+
}
|
|
2454
|
+
const merchant = await apiClient.getMerchant();
|
|
2455
|
+
return merchant;
|
|
2456
|
+
} catch (error) {
|
|
2457
|
+
return handleRouteError(error, "Get merchant", "Failed to fetch merchant");
|
|
2458
|
+
}
|
|
2459
|
+
}
|
|
2460
|
+
|
|
2461
|
+
// src/helpers/product.ts
|
|
2462
|
+
import { getSolvaPayConfig as getSolvaPayConfig4 } from "@solvapay/core";
|
|
2463
|
+
async function getProductCore(request, options = {}) {
|
|
2464
|
+
try {
|
|
2465
|
+
const url = new URL(request.url);
|
|
2466
|
+
const productRef = url.searchParams.get("productRef");
|
|
2467
|
+
if (!productRef) {
|
|
2468
|
+
return {
|
|
2469
|
+
error: "Missing required parameter: productRef",
|
|
2470
|
+
status: 400
|
|
2471
|
+
};
|
|
2472
|
+
}
|
|
2473
|
+
const apiClient = options.solvaPay?.apiClient ?? (() => {
|
|
2474
|
+
const config = getSolvaPayConfig4();
|
|
2475
|
+
if (!config.apiKey) return null;
|
|
2476
|
+
return createSolvaPayClient({
|
|
2477
|
+
apiKey: config.apiKey,
|
|
2478
|
+
apiBaseUrl: config.apiBaseUrl
|
|
2479
|
+
});
|
|
2480
|
+
})();
|
|
2481
|
+
if (!apiClient) {
|
|
2482
|
+
return {
|
|
2483
|
+
error: "Server configuration error: SolvaPay secret key not configured",
|
|
2484
|
+
status: 500
|
|
2485
|
+
};
|
|
2486
|
+
}
|
|
2487
|
+
if (!apiClient.getProduct) {
|
|
2488
|
+
return {
|
|
2489
|
+
error: "Get product method not available",
|
|
2490
|
+
status: 500
|
|
2491
|
+
};
|
|
2492
|
+
}
|
|
2493
|
+
const product = await apiClient.getProduct(productRef);
|
|
2494
|
+
return product;
|
|
2495
|
+
} catch (error) {
|
|
2496
|
+
return handleRouteError(error, "Get product", "Failed to fetch product");
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
|
|
2500
|
+
// src/helpers/purchase.ts
|
|
2501
|
+
async function checkPurchaseCore(request, options = {}) {
|
|
2502
|
+
try {
|
|
2503
|
+
const userResult = await getAuthenticatedUserCore(request, {
|
|
2504
|
+
includeEmail: options.includeEmail,
|
|
2505
|
+
includeName: options.includeName
|
|
2506
|
+
});
|
|
2507
|
+
if (isErrorResult(userResult)) {
|
|
2508
|
+
return userResult;
|
|
2509
|
+
}
|
|
2510
|
+
const { userId, email, name } = userResult;
|
|
2511
|
+
const solvaPay = options.solvaPay || createSolvaPay();
|
|
2512
|
+
const cachedCustomerRef = request.headers.get("x-solvapay-customer-ref");
|
|
2513
|
+
if (cachedCustomerRef) {
|
|
2514
|
+
try {
|
|
2515
|
+
const customer = await solvaPay.getCustomer({ customerRef: cachedCustomerRef });
|
|
2516
|
+
if (customer && customer.customerRef) {
|
|
2517
|
+
if (customer.externalRef && customer.externalRef === userId) {
|
|
2518
|
+
const filteredPurchases = (customer.purchases || []).filter(
|
|
2519
|
+
(p) => p.status === "active"
|
|
2520
|
+
);
|
|
2521
|
+
return {
|
|
2522
|
+
customerRef: customer.customerRef,
|
|
2523
|
+
email: customer.email,
|
|
2524
|
+
name: customer.name,
|
|
2525
|
+
purchases: filteredPurchases
|
|
2526
|
+
};
|
|
2527
|
+
}
|
|
2528
|
+
}
|
|
2529
|
+
} catch {
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
try {
|
|
2533
|
+
const customerRef = await solvaPay.ensureCustomer(userId, userId, {
|
|
2534
|
+
email: email || void 0,
|
|
2535
|
+
name: name || void 0
|
|
2536
|
+
});
|
|
2537
|
+
const customer = await solvaPay.getCustomer({ customerRef });
|
|
2538
|
+
const filteredPurchases = (customer.purchases || []).filter((p) => p.status === "active");
|
|
2539
|
+
return {
|
|
2540
|
+
customerRef: customer.customerRef || userId,
|
|
2541
|
+
email: customer.email,
|
|
2542
|
+
name: customer.name,
|
|
2543
|
+
purchases: filteredPurchases
|
|
2544
|
+
};
|
|
2545
|
+
} catch {
|
|
2546
|
+
return {
|
|
2547
|
+
customerRef: userId,
|
|
2548
|
+
purchases: []
|
|
2549
|
+
};
|
|
2550
|
+
}
|
|
2551
|
+
} catch (error) {
|
|
2552
|
+
return handleRouteError(error, "Check purchase", "Failed to check purchase");
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2555
|
+
|
|
2556
|
+
// src/helpers/usage.ts
|
|
2557
|
+
async function trackUsageCore(request, body, options = {}) {
|
|
2558
|
+
try {
|
|
2559
|
+
const userResult = await getAuthenticatedUserCore(request);
|
|
2560
|
+
if (isErrorResult(userResult)) {
|
|
2561
|
+
return userResult;
|
|
2562
|
+
}
|
|
2563
|
+
const { userId, email, name } = userResult;
|
|
2564
|
+
const solvaPay = options.solvaPay || createSolvaPay();
|
|
2565
|
+
const customerRef = await solvaPay.ensureCustomer(userId, userId, {
|
|
2566
|
+
email: email || void 0,
|
|
2567
|
+
name: name || void 0
|
|
2568
|
+
});
|
|
2569
|
+
await solvaPay.trackUsage({
|
|
2570
|
+
customerRef,
|
|
2571
|
+
actionType: body.actionType,
|
|
2572
|
+
units: body.units,
|
|
2573
|
+
productRef: body.productRef,
|
|
2574
|
+
description: body.description,
|
|
2575
|
+
metadata: body.metadata
|
|
2576
|
+
});
|
|
2577
|
+
return { success: true };
|
|
2578
|
+
} catch (error) {
|
|
2579
|
+
return handleRouteError(error, "Track usage", "Track usage failed");
|
|
2580
|
+
}
|
|
2581
|
+
}
|
|
2582
|
+
|
|
2398
2583
|
// src/index.ts
|
|
2399
2584
|
function verifyWebhook({
|
|
2400
2585
|
body,
|
|
@@ -2439,6 +2624,7 @@ export {
|
|
|
2439
2624
|
activatePlanCore,
|
|
2440
2625
|
buildAuthInfoFromBearer,
|
|
2441
2626
|
cancelPurchaseCore,
|
|
2627
|
+
checkPurchaseCore,
|
|
2442
2628
|
createCheckoutSessionCore,
|
|
2443
2629
|
createCustomerSessionCore,
|
|
2444
2630
|
createMcpOAuthBridge,
|
|
@@ -2453,8 +2639,10 @@ export {
|
|
|
2453
2639
|
getCustomerBalanceCore,
|
|
2454
2640
|
getCustomerRefFromBearerAuthHeader,
|
|
2455
2641
|
getCustomerRefFromJwtPayload,
|
|
2642
|
+
getMerchantCore,
|
|
2456
2643
|
getOAuthAuthorizationServerResponse,
|
|
2457
2644
|
getOAuthProtectedResourceResponse,
|
|
2645
|
+
getProductCore,
|
|
2458
2646
|
handleRouteError,
|
|
2459
2647
|
isErrorResult,
|
|
2460
2648
|
jsonSchemaToZodRawShape,
|
|
@@ -2464,6 +2652,7 @@ export {
|
|
|
2464
2652
|
reactivatePurchaseCore,
|
|
2465
2653
|
registerVirtualToolsMcpImpl,
|
|
2466
2654
|
syncCustomerCore,
|
|
2655
|
+
trackUsageCore,
|
|
2467
2656
|
verifyWebhook,
|
|
2468
2657
|
withRetry
|
|
2469
2658
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solvapay/server",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8-preview.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -37,12 +37,12 @@
|
|
|
37
37
|
},
|
|
38
38
|
"sideEffects": false,
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@solvapay/core": "1.0.
|
|
40
|
+
"@solvapay/core": "1.0.8-preview.2"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"@modelcontextprotocol/sdk": "^1.28.0",
|
|
44
44
|
"zod": "^3.25.0 || ^4.0.0",
|
|
45
|
-
"@solvapay/auth": "1.0.
|
|
45
|
+
"@solvapay/auth": "1.0.8-preview.2"
|
|
46
46
|
},
|
|
47
47
|
"peerDependenciesMeta": {
|
|
48
48
|
"@modelcontextprotocol/sdk": {
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"tsx": "^4.21.0",
|
|
61
61
|
"typescript": "^5.9.3",
|
|
62
62
|
"vitest": "^4.1.2",
|
|
63
|
-
"@solvapay/auth": "1.0.
|
|
63
|
+
"@solvapay/auth": "1.0.8-preview.2",
|
|
64
64
|
"@solvapay/demo-services": "0.0.0",
|
|
65
65
|
"@solvapay/test-utils": "^0.0.0"
|
|
66
66
|
},
|