@solvapay/server 1.0.7 → 1.0.8-preview.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -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
- return Buffer.from(padded, "base64").toString("utf8");
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 config = getSolvaPayConfig2();
2370
- const solvapaySecretKey = config.apiKey;
2371
- const solvapayApiBaseUrl = config.apiBaseUrl;
2372
- if (!solvapaySecretKey) {
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.7",
3
+ "version": "1.0.8-preview.1",
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.7"
40
+ "@solvapay/core": "1.0.8-preview.1"
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.7"
45
+ "@solvapay/auth": "1.0.8-preview.1"
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.7",
63
+ "@solvapay/auth": "1.0.8-preview.1",
64
64
  "@solvapay/demo-services": "0.0.0",
65
65
  "@solvapay/test-utils": "^0.0.0"
66
66
  },