@solvapay/server 1.0.1-preview.3 → 1.0.1-preview.4

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.js CHANGED
@@ -162,6 +162,21 @@ function createSolvaPayClient(opts) {
162
162
  }
163
163
  return await res.json();
164
164
  },
165
+ // PUT: /v1/sdk/products/{productRef}/mcp/plans
166
+ async configureMcpPlans(productRef, params) {
167
+ const url = `${base}/v1/sdk/products/${productRef}/mcp/plans`;
168
+ const res = await fetch(url, {
169
+ method: "PUT",
170
+ headers,
171
+ body: JSON.stringify(params)
172
+ });
173
+ if (!res.ok) {
174
+ const error = await res.text();
175
+ log(`\u274C API Error: ${res.status} - ${error}`);
176
+ throw new SolvaPayError(`Configure MCP plans failed (${res.status}): ${error}`);
177
+ }
178
+ return await res.json();
179
+ },
165
180
  // DELETE: /v1/sdk/products/{productRef}
166
181
  async deleteProduct(productRef) {
167
182
  const url = `${base}/v1/sdk/products/${productRef}`;
@@ -560,6 +575,24 @@ var PaywallError = class extends Error {
560
575
  this.name = "PaywallError";
561
576
  }
562
577
  };
578
+ function paywallErrorToClientPayload(error) {
579
+ const sc = error.structuredContent;
580
+ const base = {
581
+ success: false,
582
+ error: sc.kind === "activation_required" ? "Activation required" : "Payment required",
583
+ product: sc.product,
584
+ checkoutUrl: sc.checkoutUrl,
585
+ message: sc.message
586
+ };
587
+ if (sc.kind === "activation_required") {
588
+ base.kind = "activation_required";
589
+ if (sc.plans !== void 0) base.plans = sc.plans;
590
+ if (sc.balance !== void 0) base.balance = sc.balance;
591
+ if (sc.productDetails !== void 0) base.productDetails = sc.productDetails;
592
+ if (sc.confirmationUrl !== void 0) base.confirmationUrl = sc.confirmationUrl;
593
+ }
594
+ return base;
595
+ }
563
596
  var sharedCustomerLookupDeduplicator = createRequestDeduplicator({
564
597
  cacheTTL: 6e4,
565
598
  // Cache results for 60 seconds (reduces API calls significantly)
@@ -619,6 +652,7 @@ var SolvaPayPaywall = class {
619
652
  let withinLimits;
620
653
  let remaining;
621
654
  let checkoutUrl;
655
+ let lastLimitsCheck;
622
656
  const hasFreshCachedLimits = cachedLimits && now - cachedLimits.timestamp < this.limitsCacheTTL;
623
657
  if (hasFreshCachedLimits) {
624
658
  checkoutUrl = cachedLimits.checkoutUrl;
@@ -645,6 +679,7 @@ var SolvaPayPaywall = class {
645
679
  ...configuredPlanRef ? { planRef: configuredPlanRef } : {},
646
680
  meterName: usageType
647
681
  });
682
+ lastLimitsCheck = limitsCheck;
648
683
  withinLimits = limitsCheck.withinLimits;
649
684
  remaining = limitsCheck.remaining;
650
685
  checkoutUrl = limitsCheck.checkoutUrl;
@@ -673,6 +708,20 @@ var SolvaPayPaywall = class {
673
708
  requestId,
674
709
  latencyMs2
675
710
  );
711
+ if (lastLimitsCheck?.activationRequired) {
712
+ const confirmationUrl = lastLimitsCheck.confirmationUrl;
713
+ const payCheckoutUrl = confirmationUrl || lastLimitsCheck.checkoutUrl || checkoutUrl || "";
714
+ throw new PaywallError("Activation required", {
715
+ kind: "activation_required",
716
+ product,
717
+ message: "Product activation is required before this tool can be used.",
718
+ checkoutUrl: payCheckoutUrl,
719
+ confirmationUrl,
720
+ plans: lastLimitsCheck.plans,
721
+ balance: lastLimitsCheck.balance,
722
+ productDetails: lastLimitsCheck.product
723
+ });
724
+ }
676
725
  throw new PaywallError("Payment required", {
677
726
  kind: "payment_required",
678
727
  product,
@@ -775,7 +824,8 @@ var SolvaPayPaywall = class {
775
824
  this.customerCreationAttempts.add(customerRef);
776
825
  try {
777
826
  const createParams = {
778
- email: options?.email || `${customerRef}-${Date.now()}@auto-created.local`
827
+ email: options?.email || `${customerRef}-${Date.now()}@auto-created.local`,
828
+ metadata: {}
779
829
  };
780
830
  if (options?.name) {
781
831
  createParams.name = options.name;
@@ -799,7 +849,10 @@ var SolvaPayPaywall = class {
799
849
  return searchResult.customerRef;
800
850
  }
801
851
  } catch (lookupError) {
802
- this.log(`\u26A0\uFE0F Failed to lookup existing customer by externalRef after 409:`, lookupError instanceof Error ? lookupError.message : lookupError);
852
+ this.log(
853
+ `\u26A0\uFE0F Failed to lookup existing customer by externalRef after 409:`,
854
+ lookupError instanceof Error ? lookupError.message : lookupError
855
+ );
803
856
  }
804
857
  }
805
858
  const isEmailConflict = errorMessage.includes("email") || errorMessage.includes("identifier email");
@@ -822,7 +875,8 @@ var SolvaPayPaywall = class {
822
875
  try {
823
876
  const retryParams = {
824
877
  email: `${customerRef}-${Date.now()}@auto-created.local`,
825
- externalRef
878
+ externalRef,
879
+ metadata: {}
826
880
  };
827
881
  if (options?.name) {
828
882
  retryParams.name = options.name;
@@ -1143,17 +1197,7 @@ var McpAdapter = class {
1143
1197
  content: [
1144
1198
  {
1145
1199
  type: "text",
1146
- text: JSON.stringify(
1147
- {
1148
- success: false,
1149
- error: "Payment required",
1150
- product: error.structuredContent.product,
1151
- checkoutUrl: error.structuredContent.checkoutUrl,
1152
- message: error.structuredContent.message
1153
- },
1154
- null,
1155
- 2
1156
- )
1200
+ text: JSON.stringify(paywallErrorToClientPayload(error), null, 2)
1157
1201
  }
1158
1202
  ],
1159
1203
  isError: true,
@@ -1455,7 +1499,7 @@ function createSolvaPay(config) {
1455
1499
  if (!apiClient.createCustomer) {
1456
1500
  throw new SolvaPayError2("createCustomer is not available on this API client");
1457
1501
  }
1458
- return apiClient.createCustomer(params);
1502
+ return apiClient.createCustomer({ ...params, metadata: params.metadata ?? {} });
1459
1503
  },
1460
1504
  getCustomer(params) {
1461
1505
  return apiClient.getCustomer(params);
@@ -1476,6 +1520,12 @@ function createSolvaPay(config) {
1476
1520
  }
1477
1521
  return apiClient.bootstrapMcpProduct(params);
1478
1522
  },
1523
+ configureMcpPlans(productRef, params) {
1524
+ if (!apiClient.configureMcpPlans) {
1525
+ throw new SolvaPayError2("configureMcpPlans is not available on this API client");
1526
+ }
1527
+ return apiClient.configureMcpPlans(productRef, params);
1528
+ },
1479
1529
  getVirtualTools(options) {
1480
1530
  return createVirtualTools(apiClient, options);
1481
1531
  },
@@ -1917,6 +1967,7 @@ export {
1917
1967
  handleRouteError,
1918
1968
  isErrorResult,
1919
1969
  listPlansCore,
1970
+ paywallErrorToClientPayload,
1920
1971
  processPaymentIntentCore,
1921
1972
  syncCustomerCore,
1922
1973
  verifyWebhook,
package/dist/index.cjs CHANGED
@@ -4334,6 +4334,7 @@ __export(index_exports, {
4334
4334
  isErrorResult: () => isErrorResult,
4335
4335
  jsonSchemaToZodRawShape: () => jsonSchemaToZodRawShape,
4336
4336
  listPlansCore: () => listPlansCore,
4337
+ paywallErrorToClientPayload: () => paywallErrorToClientPayload,
4337
4338
  processPaymentIntentCore: () => processPaymentIntentCore,
4338
4339
  registerVirtualToolsMcpImpl: () => registerVirtualToolsMcpImpl,
4339
4340
  syncCustomerCore: () => syncCustomerCore,
@@ -4503,6 +4504,21 @@ function createSolvaPayClient(opts) {
4503
4504
  }
4504
4505
  return await res.json();
4505
4506
  },
4507
+ // PUT: /v1/sdk/products/{productRef}/mcp/plans
4508
+ async configureMcpPlans(productRef, params) {
4509
+ const url = `${base}/v1/sdk/products/${productRef}/mcp/plans`;
4510
+ const res = await fetch(url, {
4511
+ method: "PUT",
4512
+ headers,
4513
+ body: JSON.stringify(params)
4514
+ });
4515
+ if (!res.ok) {
4516
+ const error = await res.text();
4517
+ log(`\u274C API Error: ${res.status} - ${error}`);
4518
+ throw new import_core.SolvaPayError(`Configure MCP plans failed (${res.status}): ${error}`);
4519
+ }
4520
+ return await res.json();
4521
+ },
4506
4522
  // DELETE: /v1/sdk/products/{productRef}
4507
4523
  async deleteProduct(productRef) {
4508
4524
  const url = `${base}/v1/sdk/products/${productRef}`;
@@ -4901,6 +4917,24 @@ var PaywallError = class extends Error {
4901
4917
  this.name = "PaywallError";
4902
4918
  }
4903
4919
  };
4920
+ function paywallErrorToClientPayload(error) {
4921
+ const sc = error.structuredContent;
4922
+ const base = {
4923
+ success: false,
4924
+ error: sc.kind === "activation_required" ? "Activation required" : "Payment required",
4925
+ product: sc.product,
4926
+ checkoutUrl: sc.checkoutUrl,
4927
+ message: sc.message
4928
+ };
4929
+ if (sc.kind === "activation_required") {
4930
+ base.kind = "activation_required";
4931
+ if (sc.plans !== void 0) base.plans = sc.plans;
4932
+ if (sc.balance !== void 0) base.balance = sc.balance;
4933
+ if (sc.productDetails !== void 0) base.productDetails = sc.productDetails;
4934
+ if (sc.confirmationUrl !== void 0) base.confirmationUrl = sc.confirmationUrl;
4935
+ }
4936
+ return base;
4937
+ }
4904
4938
  var sharedCustomerLookupDeduplicator = createRequestDeduplicator({
4905
4939
  cacheTTL: 6e4,
4906
4940
  // Cache results for 60 seconds (reduces API calls significantly)
@@ -4960,6 +4994,7 @@ var SolvaPayPaywall = class {
4960
4994
  let withinLimits;
4961
4995
  let remaining;
4962
4996
  let checkoutUrl;
4997
+ let lastLimitsCheck;
4963
4998
  const hasFreshCachedLimits = cachedLimits && now - cachedLimits.timestamp < this.limitsCacheTTL;
4964
4999
  if (hasFreshCachedLimits) {
4965
5000
  checkoutUrl = cachedLimits.checkoutUrl;
@@ -4986,6 +5021,7 @@ var SolvaPayPaywall = class {
4986
5021
  ...configuredPlanRef ? { planRef: configuredPlanRef } : {},
4987
5022
  meterName: usageType
4988
5023
  });
5024
+ lastLimitsCheck = limitsCheck;
4989
5025
  withinLimits = limitsCheck.withinLimits;
4990
5026
  remaining = limitsCheck.remaining;
4991
5027
  checkoutUrl = limitsCheck.checkoutUrl;
@@ -5014,6 +5050,20 @@ var SolvaPayPaywall = class {
5014
5050
  requestId,
5015
5051
  latencyMs2
5016
5052
  );
5053
+ if (lastLimitsCheck?.activationRequired) {
5054
+ const confirmationUrl = lastLimitsCheck.confirmationUrl;
5055
+ const payCheckoutUrl = confirmationUrl || lastLimitsCheck.checkoutUrl || checkoutUrl || "";
5056
+ throw new PaywallError("Activation required", {
5057
+ kind: "activation_required",
5058
+ product,
5059
+ message: "Product activation is required before this tool can be used.",
5060
+ checkoutUrl: payCheckoutUrl,
5061
+ confirmationUrl,
5062
+ plans: lastLimitsCheck.plans,
5063
+ balance: lastLimitsCheck.balance,
5064
+ productDetails: lastLimitsCheck.product
5065
+ });
5066
+ }
5017
5067
  throw new PaywallError("Payment required", {
5018
5068
  kind: "payment_required",
5019
5069
  product,
@@ -5116,7 +5166,8 @@ var SolvaPayPaywall = class {
5116
5166
  this.customerCreationAttempts.add(customerRef);
5117
5167
  try {
5118
5168
  const createParams = {
5119
- email: options?.email || `${customerRef}-${Date.now()}@auto-created.local`
5169
+ email: options?.email || `${customerRef}-${Date.now()}@auto-created.local`,
5170
+ metadata: {}
5120
5171
  };
5121
5172
  if (options?.name) {
5122
5173
  createParams.name = options.name;
@@ -5140,7 +5191,10 @@ var SolvaPayPaywall = class {
5140
5191
  return searchResult.customerRef;
5141
5192
  }
5142
5193
  } catch (lookupError) {
5143
- this.log(`\u26A0\uFE0F Failed to lookup existing customer by externalRef after 409:`, lookupError instanceof Error ? lookupError.message : lookupError);
5194
+ this.log(
5195
+ `\u26A0\uFE0F Failed to lookup existing customer by externalRef after 409:`,
5196
+ lookupError instanceof Error ? lookupError.message : lookupError
5197
+ );
5144
5198
  }
5145
5199
  }
5146
5200
  const isEmailConflict = errorMessage.includes("email") || errorMessage.includes("identifier email");
@@ -5163,7 +5217,8 @@ var SolvaPayPaywall = class {
5163
5217
  try {
5164
5218
  const retryParams = {
5165
5219
  email: `${customerRef}-${Date.now()}@auto-created.local`,
5166
- externalRef
5220
+ externalRef,
5221
+ metadata: {}
5167
5222
  };
5168
5223
  if (options?.name) {
5169
5224
  retryParams.name = options.name;
@@ -5484,17 +5539,7 @@ var McpAdapter = class {
5484
5539
  content: [
5485
5540
  {
5486
5541
  type: "text",
5487
- text: JSON.stringify(
5488
- {
5489
- success: false,
5490
- error: "Payment required",
5491
- product: error.structuredContent.product,
5492
- checkoutUrl: error.structuredContent.checkoutUrl,
5493
- message: error.structuredContent.message
5494
- },
5495
- null,
5496
- 2
5497
- )
5542
+ text: JSON.stringify(paywallErrorToClientPayload(error), null, 2)
5498
5543
  }
5499
5544
  ],
5500
5545
  isError: true,
@@ -5797,7 +5842,7 @@ function createSolvaPay(config) {
5797
5842
  if (!apiClient.createCustomer) {
5798
5843
  throw new import_core2.SolvaPayError("createCustomer is not available on this API client");
5799
5844
  }
5800
- return apiClient.createCustomer(params);
5845
+ return apiClient.createCustomer({ ...params, metadata: params.metadata ?? {} });
5801
5846
  },
5802
5847
  getCustomer(params) {
5803
5848
  return apiClient.getCustomer(params);
@@ -5818,6 +5863,12 @@ function createSolvaPay(config) {
5818
5863
  }
5819
5864
  return apiClient.bootstrapMcpProduct(params);
5820
5865
  },
5866
+ configureMcpPlans(productRef, params) {
5867
+ if (!apiClient.configureMcpPlans) {
5868
+ throw new import_core2.SolvaPayError("configureMcpPlans is not available on this API client");
5869
+ }
5870
+ return apiClient.configureMcpPlans(productRef, params);
5871
+ },
5821
5872
  getVirtualTools(options) {
5822
5873
  return createVirtualTools(apiClient, options);
5823
5874
  },
@@ -6469,6 +6520,7 @@ function verifyWebhook({
6469
6520
  isErrorResult,
6470
6521
  jsonSchemaToZodRawShape,
6471
6522
  listPlansCore,
6523
+ paywallErrorToClientPayload,
6472
6524
  processPaymentIntentCore,
6473
6525
  registerVirtualToolsMcpImpl,
6474
6526
  syncCustomerCore,