@solvapay/server 1.0.7 → 1.0.9-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/edge.d.ts CHANGED
@@ -3733,6 +3733,13 @@ declare function getAuthenticatedUserCore(request: Request, options?: {
3733
3733
  * Works with standard Web API Request (works everywhere).
3734
3734
  */
3735
3735
 
3736
+ type CustomerBalanceResult = {
3737
+ customerRef: string;
3738
+ credits: number;
3739
+ displayCurrency: string;
3740
+ creditsPerMinorUnit: number;
3741
+ displayExchangeRate: number;
3742
+ };
3736
3743
  /**
3737
3744
  * Sync customer with SolvaPay backend (ensure customer exists).
3738
3745
  *
@@ -3775,6 +3782,18 @@ declare function syncCustomerCore(request: Request, options?: {
3775
3782
  includeEmail?: boolean;
3776
3783
  includeName?: boolean;
3777
3784
  }): Promise<string | ErrorResult>;
3785
+ /**
3786
+ * Get credits for the authenticated customer.
3787
+ *
3788
+ * Authenticates the request, syncs the customer, then fetches credits.
3789
+ *
3790
+ * @param request - Standard Web API Request object
3791
+ * @param options - Configuration options
3792
+ * @returns Customer credits result or error result
3793
+ */
3794
+ declare function getCustomerBalanceCore(request: Request, options?: {
3795
+ solvaPay?: SolvaPay;
3796
+ }): Promise<CustomerBalanceResult | ErrorResult>;
3778
3797
 
3779
3798
  /**
3780
3799
  * Create a payment intent for a customer to purchase a plan.
@@ -3969,6 +3988,31 @@ declare function cancelPurchaseCore(request: Request, body: {
3969
3988
  }, options?: {
3970
3989
  solvaPay?: SolvaPay;
3971
3990
  }): Promise<Record<string, unknown> | ErrorResult>;
3991
+ /**
3992
+ * Reactivate purchase - core implementation
3993
+ *
3994
+ * Undoes a pending cancellation, restoring auto-renewal and clearing cancellation fields.
3995
+ * Only works while the purchase is still active and the end date hasn't passed.
3996
+ *
3997
+ * @param request - Standard Web API Request
3998
+ * @param body - Reactivation parameters
3999
+ * @param options - Configuration options
4000
+ * @returns Reactivated purchase response or error result
4001
+ */
4002
+ declare function reactivatePurchaseCore(request: Request, body: {
4003
+ purchaseRef: string;
4004
+ }, options?: {
4005
+ solvaPay?: SolvaPay;
4006
+ }): Promise<Record<string, unknown> | ErrorResult>;
4007
+
4008
+ declare function activatePlanCore(request: Request, body: {
4009
+ productRef: string;
4010
+ planRef: string;
4011
+ }, options?: {
4012
+ solvaPay?: SolvaPay;
4013
+ includeEmail?: boolean;
4014
+ includeName?: boolean;
4015
+ }): Promise<ActivatePlanResult | ErrorResult>;
3972
4016
 
3973
4017
  /**
3974
4018
  * Plans Helper (Core)
@@ -3987,6 +4031,49 @@ declare function listPlansCore(request: Request): Promise<{
3987
4031
  productRef: string;
3988
4032
  } | ErrorResult>;
3989
4033
 
4034
+ interface PurchaseCheckResult {
4035
+ customerRef: string;
4036
+ email?: string;
4037
+ name?: string;
4038
+ purchases: Array<{
4039
+ reference: string;
4040
+ productName?: string;
4041
+ productRef?: string;
4042
+ status?: string;
4043
+ startDate?: string;
4044
+ planSnapshot?: {
4045
+ meterId?: string;
4046
+ limit?: number;
4047
+ freeUnits?: number;
4048
+ };
4049
+ usage?: {
4050
+ used?: number;
4051
+ overageUnits?: number;
4052
+ overageCost?: number;
4053
+ periodStart?: string;
4054
+ periodEnd?: string;
4055
+ };
4056
+ [key: string]: unknown;
4057
+ }>;
4058
+ }
4059
+ declare function checkPurchaseCore(request: Request, options?: {
4060
+ solvaPay?: SolvaPay;
4061
+ includeEmail?: boolean;
4062
+ includeName?: boolean;
4063
+ }): Promise<PurchaseCheckResult | ErrorResult>;
4064
+
4065
+ declare function trackUsageCore(request: Request, body: {
4066
+ actionType?: 'transaction' | 'api_call' | 'hour' | 'email' | 'storage' | 'custom';
4067
+ units?: number;
4068
+ productRef?: string;
4069
+ description?: string;
4070
+ metadata?: Record<string, unknown>;
4071
+ }, options?: {
4072
+ solvaPay?: SolvaPay;
4073
+ }): Promise<{
4074
+ success: true;
4075
+ } | ErrorResult>;
4076
+
3990
4077
  /**
3991
4078
  * SolvaPay Server SDK - Edge Runtime Entry Point
3992
4079
  *
@@ -4000,4 +4087,4 @@ declare function verifyWebhook({ body, signature, secret, }: {
4000
4087
  secret: string;
4001
4088
  }): Promise<WebhookEvent>;
4002
4089
 
4003
- export { type AuthenticatedUser, type CreateSolvaPayConfig, type CustomerWebhookObject, type ErrorResult, type HttpAdapterOptions, type LimitActivationBalance, type LimitActivationProduct, type LimitPlanSummary, type McpAdapterOptions, type NextAdapterOptions, type PayableFunction, type PayableOptions, type PaywallArgs, PaywallError, type PaywallMetadata, type PaywallStructuredContent, type PaywallToolResult, type RetryOptions, type ServerClientOptions, type SolvaPay, type SolvaPayClient, type WebhookEvent, type WebhookEventForType, type WebhookEventObjectMap, type WebhookEventType, type WebhookProduct, cancelPurchaseCore, createCheckoutSessionCore, createCustomerSessionCore, createPaymentIntentCore, createSolvaPay, createSolvaPayClient, createTopupPaymentIntentCore, getAuthenticatedUserCore, handleRouteError, isErrorResult, listPlansCore, paywallErrorToClientPayload, processPaymentIntentCore, syncCustomerCore, verifyWebhook, withRetry };
4090
+ export { type AuthenticatedUser, type CreateSolvaPayConfig, type CustomerBalanceResult, type CustomerWebhookObject, type ErrorResult, type HttpAdapterOptions, type LimitActivationBalance, type LimitActivationProduct, type LimitPlanSummary, type McpAdapterOptions, type NextAdapterOptions, type PayableFunction, type PayableOptions, type PaywallArgs, PaywallError, type PaywallMetadata, type PaywallStructuredContent, type PaywallToolResult, type PurchaseCheckResult, type RetryOptions, type ServerClientOptions, type SolvaPay, type SolvaPayClient, type WebhookEvent, type WebhookEventForType, type WebhookEventObjectMap, type WebhookEventType, type WebhookProduct, activatePlanCore, cancelPurchaseCore, checkPurchaseCore, createCheckoutSessionCore, createCustomerSessionCore, createPaymentIntentCore, createSolvaPay, createSolvaPayClient, createTopupPaymentIntentCore, getAuthenticatedUserCore, getCustomerBalanceCore, handleRouteError, isErrorResult, listPlansCore, paywallErrorToClientPayload, processPaymentIntentCore, reactivatePurchaseCore, syncCustomerCore, trackUsageCore, verifyWebhook, withRetry };
package/dist/edge.js CHANGED
@@ -1775,6 +1775,24 @@ async function syncCustomerCore(request, options = {}) {
1775
1775
  return handleRouteError(error, "Sync customer", "Failed to sync customer");
1776
1776
  }
1777
1777
  }
1778
+ async function getCustomerBalanceCore(request, options = {}) {
1779
+ try {
1780
+ const userResult = await getAuthenticatedUserCore(request);
1781
+ if (isErrorResult(userResult)) {
1782
+ return userResult;
1783
+ }
1784
+ const { userId, email, name } = userResult;
1785
+ const solvaPay = options.solvaPay || createSolvaPay();
1786
+ const customerRef = await solvaPay.ensureCustomer(userId, userId, {
1787
+ email: email || void 0,
1788
+ name: name || void 0
1789
+ });
1790
+ const result = await solvaPay.getCustomerBalance({ customerRef });
1791
+ return result;
1792
+ } catch (error) {
1793
+ return handleRouteError(error, "Get customer credits", "Failed to get customer credits");
1794
+ }
1795
+ }
1778
1796
 
1779
1797
  // src/helpers/payment.ts
1780
1798
  async function createPaymentIntentCore(request, body, options = {}) {
@@ -2024,6 +2042,103 @@ async function cancelPurchaseCore(request, body, options = {}) {
2024
2042
  return handleRouteError(error, "Cancel purchase", "Failed to cancel purchase");
2025
2043
  }
2026
2044
  }
2045
+ async function reactivatePurchaseCore(request, body, options = {}) {
2046
+ try {
2047
+ if (!body.purchaseRef) {
2048
+ return {
2049
+ error: "Missing required parameter: purchaseRef is required",
2050
+ status: 400
2051
+ };
2052
+ }
2053
+ const solvaPay = options.solvaPay || createSolvaPay();
2054
+ if (!solvaPay.apiClient.reactivatePurchase) {
2055
+ return {
2056
+ error: "Reactivate purchase method not available on SDK client",
2057
+ status: 500
2058
+ };
2059
+ }
2060
+ let reactivatedPurchase = await solvaPay.apiClient.reactivatePurchase({
2061
+ purchaseRef: body.purchaseRef
2062
+ });
2063
+ if (!reactivatedPurchase || typeof reactivatedPurchase !== "object") {
2064
+ return {
2065
+ error: "Invalid response from reactivate purchase endpoint",
2066
+ status: 500
2067
+ };
2068
+ }
2069
+ const responseObj = reactivatedPurchase;
2070
+ if (responseObj.purchase && typeof responseObj.purchase === "object") {
2071
+ reactivatedPurchase = responseObj.purchase;
2072
+ }
2073
+ if (!reactivatedPurchase.reference) {
2074
+ return {
2075
+ error: "Reactivate purchase response missing required fields",
2076
+ status: 500
2077
+ };
2078
+ }
2079
+ if (reactivatedPurchase.cancelledAt) {
2080
+ return {
2081
+ error: `Purchase reactivation failed: cancelledAt is still set`,
2082
+ status: 500
2083
+ };
2084
+ }
2085
+ await new Promise((resolve) => setTimeout(resolve, 500));
2086
+ return reactivatedPurchase;
2087
+ } catch (error) {
2088
+ if (error instanceof SolvaPayError4) {
2089
+ const errorMessage = error.message;
2090
+ if (errorMessage.includes("not found")) {
2091
+ return {
2092
+ error: "Purchase not found",
2093
+ status: 404,
2094
+ details: errorMessage
2095
+ };
2096
+ }
2097
+ if (errorMessage.includes("cannot be reactivated") || errorMessage.includes("not pending cancellation") || errorMessage.includes("already been fully cancelled") || errorMessage.includes("already ended")) {
2098
+ return {
2099
+ error: "Purchase cannot be reactivated",
2100
+ status: 400,
2101
+ details: errorMessage
2102
+ };
2103
+ }
2104
+ return {
2105
+ error: errorMessage,
2106
+ status: 500,
2107
+ details: errorMessage
2108
+ };
2109
+ }
2110
+ return handleRouteError(error, "Reactivate purchase", "Failed to reactivate purchase");
2111
+ }
2112
+ }
2113
+
2114
+ // src/helpers/activation.ts
2115
+ async function activatePlanCore(request, body, options = {}) {
2116
+ try {
2117
+ if (!body.productRef || !body.planRef) {
2118
+ return {
2119
+ error: "Missing required parameters: productRef and planRef are required",
2120
+ status: 400
2121
+ };
2122
+ }
2123
+ const customerResult = await syncCustomerCore(request, {
2124
+ solvaPay: options.solvaPay,
2125
+ includeEmail: options.includeEmail,
2126
+ includeName: options.includeName
2127
+ });
2128
+ if (isErrorResult(customerResult)) {
2129
+ return customerResult;
2130
+ }
2131
+ const customerRef = customerResult;
2132
+ const solvaPay = options.solvaPay || createSolvaPay();
2133
+ return await solvaPay.activatePlan({
2134
+ customerRef,
2135
+ productRef: body.productRef,
2136
+ planRef: body.planRef
2137
+ });
2138
+ } catch (error) {
2139
+ return handleRouteError(error, "Activate plan", "Plan activation failed");
2140
+ }
2141
+ }
2027
2142
 
2028
2143
  // src/helpers/plans.ts
2029
2144
  import { getSolvaPayConfig as getSolvaPayConfig2 } from "@solvapay/core";
@@ -2066,6 +2181,89 @@ async function listPlansCore(request) {
2066
2181
  }
2067
2182
  }
2068
2183
 
2184
+ // src/helpers/purchase.ts
2185
+ async function checkPurchaseCore(request, options = {}) {
2186
+ try {
2187
+ const userResult = await getAuthenticatedUserCore(request, {
2188
+ includeEmail: options.includeEmail,
2189
+ includeName: options.includeName
2190
+ });
2191
+ if (isErrorResult(userResult)) {
2192
+ return userResult;
2193
+ }
2194
+ const { userId, email, name } = userResult;
2195
+ const solvaPay = options.solvaPay || createSolvaPay();
2196
+ const cachedCustomerRef = request.headers.get("x-solvapay-customer-ref");
2197
+ if (cachedCustomerRef) {
2198
+ try {
2199
+ const customer = await solvaPay.getCustomer({ customerRef: cachedCustomerRef });
2200
+ if (customer && customer.customerRef) {
2201
+ if (customer.externalRef && customer.externalRef === userId) {
2202
+ const filteredPurchases = (customer.purchases || []).filter(
2203
+ (p) => p.status === "active"
2204
+ );
2205
+ return {
2206
+ customerRef: customer.customerRef,
2207
+ email: customer.email,
2208
+ name: customer.name,
2209
+ purchases: filteredPurchases
2210
+ };
2211
+ }
2212
+ }
2213
+ } catch {
2214
+ }
2215
+ }
2216
+ try {
2217
+ const customerRef = await solvaPay.ensureCustomer(userId, userId, {
2218
+ email: email || void 0,
2219
+ name: name || void 0
2220
+ });
2221
+ const customer = await solvaPay.getCustomer({ customerRef });
2222
+ const filteredPurchases = (customer.purchases || []).filter((p) => p.status === "active");
2223
+ return {
2224
+ customerRef: customer.customerRef || userId,
2225
+ email: customer.email,
2226
+ name: customer.name,
2227
+ purchases: filteredPurchases
2228
+ };
2229
+ } catch {
2230
+ return {
2231
+ customerRef: userId,
2232
+ purchases: []
2233
+ };
2234
+ }
2235
+ } catch (error) {
2236
+ return handleRouteError(error, "Check purchase", "Failed to check purchase");
2237
+ }
2238
+ }
2239
+
2240
+ // src/helpers/usage.ts
2241
+ async function trackUsageCore(request, body, options = {}) {
2242
+ try {
2243
+ const userResult = await getAuthenticatedUserCore(request);
2244
+ if (isErrorResult(userResult)) {
2245
+ return userResult;
2246
+ }
2247
+ const { userId, email, name } = userResult;
2248
+ const solvaPay = options.solvaPay || createSolvaPay();
2249
+ const customerRef = await solvaPay.ensureCustomer(userId, userId, {
2250
+ email: email || void 0,
2251
+ name: name || void 0
2252
+ });
2253
+ await solvaPay.trackUsage({
2254
+ customerRef,
2255
+ actionType: body.actionType,
2256
+ units: body.units,
2257
+ productRef: body.productRef,
2258
+ description: body.description,
2259
+ metadata: body.metadata
2260
+ });
2261
+ return { success: true };
2262
+ } catch (error) {
2263
+ return handleRouteError(error, "Track usage", "Track usage failed");
2264
+ }
2265
+ }
2266
+
2069
2267
  // src/edge.ts
2070
2268
  function timingSafeEqual(a, b) {
2071
2269
  if (a.length !== b.length) return false;
@@ -2120,7 +2318,9 @@ async function verifyWebhook({
2120
2318
  }
2121
2319
  export {
2122
2320
  PaywallError,
2321
+ activatePlanCore,
2123
2322
  cancelPurchaseCore,
2323
+ checkPurchaseCore,
2124
2324
  createCheckoutSessionCore,
2125
2325
  createCustomerSessionCore,
2126
2326
  createPaymentIntentCore,
@@ -2128,12 +2328,15 @@ export {
2128
2328
  createSolvaPayClient,
2129
2329
  createTopupPaymentIntentCore,
2130
2330
  getAuthenticatedUserCore,
2331
+ getCustomerBalanceCore,
2131
2332
  handleRouteError,
2132
2333
  isErrorResult,
2133
2334
  listPlansCore,
2134
2335
  paywallErrorToClientPayload,
2135
2336
  processPaymentIntentCore,
2337
+ reactivatePurchaseCore,
2136
2338
  syncCustomerCore,
2339
+ trackUsageCore,
2137
2340
  verifyWebhook,
2138
2341
  withRetry
2139
2342
  };
package/dist/index.cjs CHANGED
@@ -4317,6 +4317,7 @@ __export(index_exports, {
4317
4317
  activatePlanCore: () => activatePlanCore,
4318
4318
  buildAuthInfoFromBearer: () => buildAuthInfoFromBearer,
4319
4319
  cancelPurchaseCore: () => cancelPurchaseCore,
4320
+ checkPurchaseCore: () => checkPurchaseCore,
4320
4321
  createCheckoutSessionCore: () => createCheckoutSessionCore,
4321
4322
  createCustomerSessionCore: () => createCustomerSessionCore,
4322
4323
  createMcpOAuthBridge: () => createMcpOAuthBridge,
@@ -4342,6 +4343,7 @@ __export(index_exports, {
4342
4343
  reactivatePurchaseCore: () => reactivatePurchaseCore,
4343
4344
  registerVirtualToolsMcpImpl: () => registerVirtualToolsMcpImpl,
4344
4345
  syncCustomerCore: () => syncCustomerCore,
4346
+ trackUsageCore: () => trackUsageCore,
4345
4347
  verifyWebhook: () => verifyWebhook,
4346
4348
  withRetry: () => withRetry
4347
4349
  });
@@ -6060,7 +6062,8 @@ var McpBearerAuthError = class extends Error {
6060
6062
  function base64UrlDecode(input) {
6061
6063
  const normalized = input.replace(/-/g, "+").replace(/_/g, "/");
6062
6064
  const padded = normalized.padEnd(normalized.length + (4 - normalized.length % 4) % 4, "=");
6063
- return Buffer.from(padded, "base64").toString("utf8");
6065
+ const bytes = Uint8Array.from(atob(padded), (c) => c.charCodeAt(0));
6066
+ return new TextDecoder().decode(bytes);
6064
6067
  }
6065
6068
  function extractBearerToken(authorization) {
6066
6069
  if (!authorization) return null;
@@ -6740,6 +6743,89 @@ async function listPlansCore(request) {
6740
6743
  }
6741
6744
  }
6742
6745
 
6746
+ // src/helpers/purchase.ts
6747
+ async function checkPurchaseCore(request, options = {}) {
6748
+ try {
6749
+ const userResult = await getAuthenticatedUserCore(request, {
6750
+ includeEmail: options.includeEmail,
6751
+ includeName: options.includeName
6752
+ });
6753
+ if (isErrorResult(userResult)) {
6754
+ return userResult;
6755
+ }
6756
+ const { userId, email, name } = userResult;
6757
+ const solvaPay = options.solvaPay || createSolvaPay();
6758
+ const cachedCustomerRef = request.headers.get("x-solvapay-customer-ref");
6759
+ if (cachedCustomerRef) {
6760
+ try {
6761
+ const customer = await solvaPay.getCustomer({ customerRef: cachedCustomerRef });
6762
+ if (customer && customer.customerRef) {
6763
+ if (customer.externalRef && customer.externalRef === userId) {
6764
+ const filteredPurchases = (customer.purchases || []).filter(
6765
+ (p) => p.status === "active"
6766
+ );
6767
+ return {
6768
+ customerRef: customer.customerRef,
6769
+ email: customer.email,
6770
+ name: customer.name,
6771
+ purchases: filteredPurchases
6772
+ };
6773
+ }
6774
+ }
6775
+ } catch {
6776
+ }
6777
+ }
6778
+ try {
6779
+ const customerRef = await solvaPay.ensureCustomer(userId, userId, {
6780
+ email: email || void 0,
6781
+ name: name || void 0
6782
+ });
6783
+ const customer = await solvaPay.getCustomer({ customerRef });
6784
+ const filteredPurchases = (customer.purchases || []).filter((p) => p.status === "active");
6785
+ return {
6786
+ customerRef: customer.customerRef || userId,
6787
+ email: customer.email,
6788
+ name: customer.name,
6789
+ purchases: filteredPurchases
6790
+ };
6791
+ } catch {
6792
+ return {
6793
+ customerRef: userId,
6794
+ purchases: []
6795
+ };
6796
+ }
6797
+ } catch (error) {
6798
+ return handleRouteError(error, "Check purchase", "Failed to check purchase");
6799
+ }
6800
+ }
6801
+
6802
+ // src/helpers/usage.ts
6803
+ async function trackUsageCore(request, body, options = {}) {
6804
+ try {
6805
+ const userResult = await getAuthenticatedUserCore(request);
6806
+ if (isErrorResult(userResult)) {
6807
+ return userResult;
6808
+ }
6809
+ const { userId, email, name } = userResult;
6810
+ const solvaPay = options.solvaPay || createSolvaPay();
6811
+ const customerRef = await solvaPay.ensureCustomer(userId, userId, {
6812
+ email: email || void 0,
6813
+ name: name || void 0
6814
+ });
6815
+ await solvaPay.trackUsage({
6816
+ customerRef,
6817
+ actionType: body.actionType,
6818
+ units: body.units,
6819
+ productRef: body.productRef,
6820
+ description: body.description,
6821
+ metadata: body.metadata
6822
+ });
6823
+ return { success: true };
6824
+ } catch (error) {
6825
+ return handleRouteError(error, "Track usage", "Track usage failed");
6826
+ }
6827
+ }
6828
+
6743
6829
  // src/index.ts
6744
6830
  function verifyWebhook({
6745
6831
  body,
@@ -6785,6 +6871,7 @@ function verifyWebhook({
6785
6871
  activatePlanCore,
6786
6872
  buildAuthInfoFromBearer,
6787
6873
  cancelPurchaseCore,
6874
+ checkPurchaseCore,
6788
6875
  createCheckoutSessionCore,
6789
6876
  createCustomerSessionCore,
6790
6877
  createMcpOAuthBridge,
@@ -6810,6 +6897,7 @@ function verifyWebhook({
6810
6897
  reactivatePurchaseCore,
6811
6898
  registerVirtualToolsMcpImpl,
6812
6899
  syncCustomerCore,
6900
+ trackUsageCore,
6813
6901
  verifyWebhook,
6814
6902
  withRetry
6815
6903
  });
package/dist/index.d.cts CHANGED
@@ -4123,6 +4123,49 @@ declare function listPlansCore(request: Request): Promise<{
4123
4123
  productRef: string;
4124
4124
  } | ErrorResult>;
4125
4125
 
4126
+ interface PurchaseCheckResult {
4127
+ customerRef: string;
4128
+ email?: string;
4129
+ name?: string;
4130
+ purchases: Array<{
4131
+ reference: string;
4132
+ productName?: string;
4133
+ productRef?: string;
4134
+ status?: string;
4135
+ startDate?: string;
4136
+ planSnapshot?: {
4137
+ meterId?: string;
4138
+ limit?: number;
4139
+ freeUnits?: number;
4140
+ };
4141
+ usage?: {
4142
+ used?: number;
4143
+ overageUnits?: number;
4144
+ overageCost?: number;
4145
+ periodStart?: string;
4146
+ periodEnd?: string;
4147
+ };
4148
+ [key: string]: unknown;
4149
+ }>;
4150
+ }
4151
+ declare function checkPurchaseCore(request: Request, options?: {
4152
+ solvaPay?: SolvaPay;
4153
+ includeEmail?: boolean;
4154
+ includeName?: boolean;
4155
+ }): Promise<PurchaseCheckResult | ErrorResult>;
4156
+
4157
+ declare function trackUsageCore(request: Request, body: {
4158
+ actionType?: 'transaction' | 'api_call' | 'hour' | 'email' | 'storage' | 'custom';
4159
+ units?: number;
4160
+ productRef?: string;
4161
+ description?: string;
4162
+ metadata?: Record<string, unknown>;
4163
+ }, options?: {
4164
+ solvaPay?: SolvaPay;
4165
+ }): Promise<{
4166
+ success: true;
4167
+ } | ErrorResult>;
4168
+
4126
4169
  /**
4127
4170
  * SolvaPay Server SDK
4128
4171
  *
@@ -4178,4 +4221,4 @@ declare function verifyWebhook({ body, signature, secret, }: {
4178
4221
  secret: string;
4179
4222
  }): WebhookEvent;
4180
4223
 
4181
- export { type ActivatePlanResult, type AuthenticatedUser, type ConfigureMcpPlansRequest, type ConfigureMcpPlansResponse, type CreateSolvaPayConfig, type CustomerBalanceResult, type CustomerResponseMapped, type CustomerWebhookObject, type ErrorResult, type HttpAdapterOptions, type LimitActivationBalance, type LimitActivationProduct, type LimitPlanSummary, type McpAdapterOptions, McpBearerAuthError, type McpBootstrapPlanInput, type McpBootstrapRequest, type McpBootstrapResponse, type McpServerLike, type McpToolExtra, type McpToolPlanMappingInput, type NextAdapterOptions, type OneTimePurchaseInfo, type PayableFunction, type PayableOptions, type PaywallArgs, PaywallError, type PaywallMetadata, type PaywallStructuredContent, type PaywallToolResult, type ProcessPaymentResult, type RegisterVirtualToolsMcpOptions, type RetryOptions, type ServerClientOptions, type SolvaPay, type SolvaPayClient, type ToolPlanMappingInput, VIRTUAL_TOOL_DEFINITIONS, type VirtualToolDefinition, type VirtualToolsOptions, type WebhookEvent, type WebhookEventForType, type WebhookEventObjectMap, type WebhookEventType, type WebhookProduct, activatePlanCore, buildAuthInfoFromBearer, cancelPurchaseCore, type components, createCheckoutSessionCore, createCustomerSessionCore, createMcpOAuthBridge, createPaymentIntentCore, createSolvaPay, createSolvaPayClient, createTopupPaymentIntentCore, createVirtualTools, decodeJwtPayload, extractBearerToken, getAuthenticatedUserCore, getCustomerBalanceCore, getCustomerRefFromBearerAuthHeader, getCustomerRefFromJwtPayload, getOAuthAuthorizationServerResponse, getOAuthProtectedResourceResponse, handleRouteError, isErrorResult, jsonSchemaToZodRawShape, listPlansCore, paywallErrorToClientPayload, processPaymentIntentCore, reactivatePurchaseCore, registerVirtualToolsMcpImpl, syncCustomerCore, verifyWebhook, withRetry };
4224
+ export { type ActivatePlanResult, type AuthenticatedUser, type ConfigureMcpPlansRequest, type ConfigureMcpPlansResponse, type CreateSolvaPayConfig, type CustomerBalanceResult, type CustomerResponseMapped, type CustomerWebhookObject, type ErrorResult, type HttpAdapterOptions, type LimitActivationBalance, type LimitActivationProduct, type LimitPlanSummary, type McpAdapterOptions, McpBearerAuthError, type McpBootstrapPlanInput, type McpBootstrapRequest, type McpBootstrapResponse, type McpServerLike, type McpToolExtra, type McpToolPlanMappingInput, type NextAdapterOptions, type OneTimePurchaseInfo, type PayableFunction, type PayableOptions, type PaywallArgs, PaywallError, type PaywallMetadata, type PaywallStructuredContent, type PaywallToolResult, type ProcessPaymentResult, type PurchaseCheckResult, type RegisterVirtualToolsMcpOptions, type RetryOptions, type ServerClientOptions, type SolvaPay, type SolvaPayClient, type ToolPlanMappingInput, VIRTUAL_TOOL_DEFINITIONS, type VirtualToolDefinition, type VirtualToolsOptions, type WebhookEvent, type WebhookEventForType, type WebhookEventObjectMap, type WebhookEventType, type WebhookProduct, activatePlanCore, buildAuthInfoFromBearer, cancelPurchaseCore, checkPurchaseCore, type components, createCheckoutSessionCore, createCustomerSessionCore, createMcpOAuthBridge, createPaymentIntentCore, createSolvaPay, createSolvaPayClient, createTopupPaymentIntentCore, createVirtualTools, decodeJwtPayload, extractBearerToken, getAuthenticatedUserCore, getCustomerBalanceCore, getCustomerRefFromBearerAuthHeader, getCustomerRefFromJwtPayload, getOAuthAuthorizationServerResponse, getOAuthProtectedResourceResponse, handleRouteError, isErrorResult, jsonSchemaToZodRawShape, listPlansCore, paywallErrorToClientPayload, processPaymentIntentCore, reactivatePurchaseCore, registerVirtualToolsMcpImpl, syncCustomerCore, trackUsageCore, verifyWebhook, withRetry };
package/dist/index.d.ts CHANGED
@@ -4123,6 +4123,49 @@ declare function listPlansCore(request: Request): Promise<{
4123
4123
  productRef: string;
4124
4124
  } | ErrorResult>;
4125
4125
 
4126
+ interface PurchaseCheckResult {
4127
+ customerRef: string;
4128
+ email?: string;
4129
+ name?: string;
4130
+ purchases: Array<{
4131
+ reference: string;
4132
+ productName?: string;
4133
+ productRef?: string;
4134
+ status?: string;
4135
+ startDate?: string;
4136
+ planSnapshot?: {
4137
+ meterId?: string;
4138
+ limit?: number;
4139
+ freeUnits?: number;
4140
+ };
4141
+ usage?: {
4142
+ used?: number;
4143
+ overageUnits?: number;
4144
+ overageCost?: number;
4145
+ periodStart?: string;
4146
+ periodEnd?: string;
4147
+ };
4148
+ [key: string]: unknown;
4149
+ }>;
4150
+ }
4151
+ declare function checkPurchaseCore(request: Request, options?: {
4152
+ solvaPay?: SolvaPay;
4153
+ includeEmail?: boolean;
4154
+ includeName?: boolean;
4155
+ }): Promise<PurchaseCheckResult | ErrorResult>;
4156
+
4157
+ declare function trackUsageCore(request: Request, body: {
4158
+ actionType?: 'transaction' | 'api_call' | 'hour' | 'email' | 'storage' | 'custom';
4159
+ units?: number;
4160
+ productRef?: string;
4161
+ description?: string;
4162
+ metadata?: Record<string, unknown>;
4163
+ }, options?: {
4164
+ solvaPay?: SolvaPay;
4165
+ }): Promise<{
4166
+ success: true;
4167
+ } | ErrorResult>;
4168
+
4126
4169
  /**
4127
4170
  * SolvaPay Server SDK
4128
4171
  *
@@ -4178,4 +4221,4 @@ declare function verifyWebhook({ body, signature, secret, }: {
4178
4221
  secret: string;
4179
4222
  }): WebhookEvent;
4180
4223
 
4181
- export { type ActivatePlanResult, type AuthenticatedUser, type ConfigureMcpPlansRequest, type ConfigureMcpPlansResponse, type CreateSolvaPayConfig, type CustomerBalanceResult, type CustomerResponseMapped, type CustomerWebhookObject, type ErrorResult, type HttpAdapterOptions, type LimitActivationBalance, type LimitActivationProduct, type LimitPlanSummary, type McpAdapterOptions, McpBearerAuthError, type McpBootstrapPlanInput, type McpBootstrapRequest, type McpBootstrapResponse, type McpServerLike, type McpToolExtra, type McpToolPlanMappingInput, type NextAdapterOptions, type OneTimePurchaseInfo, type PayableFunction, type PayableOptions, type PaywallArgs, PaywallError, type PaywallMetadata, type PaywallStructuredContent, type PaywallToolResult, type ProcessPaymentResult, type RegisterVirtualToolsMcpOptions, type RetryOptions, type ServerClientOptions, type SolvaPay, type SolvaPayClient, type ToolPlanMappingInput, VIRTUAL_TOOL_DEFINITIONS, type VirtualToolDefinition, type VirtualToolsOptions, type WebhookEvent, type WebhookEventForType, type WebhookEventObjectMap, type WebhookEventType, type WebhookProduct, activatePlanCore, buildAuthInfoFromBearer, cancelPurchaseCore, type components, createCheckoutSessionCore, createCustomerSessionCore, createMcpOAuthBridge, createPaymentIntentCore, createSolvaPay, createSolvaPayClient, createTopupPaymentIntentCore, createVirtualTools, decodeJwtPayload, extractBearerToken, getAuthenticatedUserCore, getCustomerBalanceCore, getCustomerRefFromBearerAuthHeader, getCustomerRefFromJwtPayload, getOAuthAuthorizationServerResponse, getOAuthProtectedResourceResponse, handleRouteError, isErrorResult, jsonSchemaToZodRawShape, listPlansCore, paywallErrorToClientPayload, processPaymentIntentCore, reactivatePurchaseCore, registerVirtualToolsMcpImpl, syncCustomerCore, verifyWebhook, withRetry };
4224
+ export { type ActivatePlanResult, type AuthenticatedUser, type ConfigureMcpPlansRequest, type ConfigureMcpPlansResponse, type CreateSolvaPayConfig, type CustomerBalanceResult, type CustomerResponseMapped, type CustomerWebhookObject, type ErrorResult, type HttpAdapterOptions, type LimitActivationBalance, type LimitActivationProduct, type LimitPlanSummary, type McpAdapterOptions, McpBearerAuthError, type McpBootstrapPlanInput, type McpBootstrapRequest, type McpBootstrapResponse, type McpServerLike, type McpToolExtra, type McpToolPlanMappingInput, type NextAdapterOptions, type OneTimePurchaseInfo, type PayableFunction, type PayableOptions, type PaywallArgs, PaywallError, type PaywallMetadata, type PaywallStructuredContent, type PaywallToolResult, type ProcessPaymentResult, type PurchaseCheckResult, type RegisterVirtualToolsMcpOptions, type RetryOptions, type ServerClientOptions, type SolvaPay, type SolvaPayClient, type ToolPlanMappingInput, VIRTUAL_TOOL_DEFINITIONS, type VirtualToolDefinition, type VirtualToolsOptions, type WebhookEvent, type WebhookEventForType, type WebhookEventObjectMap, type WebhookEventType, type WebhookProduct, activatePlanCore, buildAuthInfoFromBearer, cancelPurchaseCore, checkPurchaseCore, type components, createCheckoutSessionCore, createCustomerSessionCore, createMcpOAuthBridge, createPaymentIntentCore, createSolvaPay, createSolvaPayClient, createTopupPaymentIntentCore, createVirtualTools, decodeJwtPayload, extractBearerToken, getAuthenticatedUserCore, getCustomerBalanceCore, getCustomerRefFromBearerAuthHeader, getCustomerRefFromJwtPayload, getOAuthAuthorizationServerResponse, getOAuthProtectedResourceResponse, handleRouteError, isErrorResult, jsonSchemaToZodRawShape, listPlansCore, paywallErrorToClientPayload, processPaymentIntentCore, reactivatePurchaseCore, registerVirtualToolsMcpImpl, syncCustomerCore, trackUsageCore, verifyWebhook, withRetry };
package/dist/index.js CHANGED
@@ -1715,7 +1715,8 @@ var McpBearerAuthError = class extends Error {
1715
1715
  function base64UrlDecode(input) {
1716
1716
  const normalized = input.replace(/-/g, "+").replace(/_/g, "/");
1717
1717
  const padded = normalized.padEnd(normalized.length + (4 - normalized.length % 4) % 4, "=");
1718
- return Buffer.from(padded, "base64").toString("utf8");
1718
+ const bytes = Uint8Array.from(atob(padded), (c) => c.charCodeAt(0));
1719
+ return new TextDecoder().decode(bytes);
1719
1720
  }
1720
1721
  function extractBearerToken(authorization) {
1721
1722
  if (!authorization) return null;
@@ -2395,6 +2396,89 @@ async function listPlansCore(request) {
2395
2396
  }
2396
2397
  }
2397
2398
 
2399
+ // src/helpers/purchase.ts
2400
+ async function checkPurchaseCore(request, options = {}) {
2401
+ try {
2402
+ const userResult = await getAuthenticatedUserCore(request, {
2403
+ includeEmail: options.includeEmail,
2404
+ includeName: options.includeName
2405
+ });
2406
+ if (isErrorResult(userResult)) {
2407
+ return userResult;
2408
+ }
2409
+ const { userId, email, name } = userResult;
2410
+ const solvaPay = options.solvaPay || createSolvaPay();
2411
+ const cachedCustomerRef = request.headers.get("x-solvapay-customer-ref");
2412
+ if (cachedCustomerRef) {
2413
+ try {
2414
+ const customer = await solvaPay.getCustomer({ customerRef: cachedCustomerRef });
2415
+ if (customer && customer.customerRef) {
2416
+ if (customer.externalRef && customer.externalRef === userId) {
2417
+ const filteredPurchases = (customer.purchases || []).filter(
2418
+ (p) => p.status === "active"
2419
+ );
2420
+ return {
2421
+ customerRef: customer.customerRef,
2422
+ email: customer.email,
2423
+ name: customer.name,
2424
+ purchases: filteredPurchases
2425
+ };
2426
+ }
2427
+ }
2428
+ } catch {
2429
+ }
2430
+ }
2431
+ try {
2432
+ const customerRef = await solvaPay.ensureCustomer(userId, userId, {
2433
+ email: email || void 0,
2434
+ name: name || void 0
2435
+ });
2436
+ const customer = await solvaPay.getCustomer({ customerRef });
2437
+ const filteredPurchases = (customer.purchases || []).filter((p) => p.status === "active");
2438
+ return {
2439
+ customerRef: customer.customerRef || userId,
2440
+ email: customer.email,
2441
+ name: customer.name,
2442
+ purchases: filteredPurchases
2443
+ };
2444
+ } catch {
2445
+ return {
2446
+ customerRef: userId,
2447
+ purchases: []
2448
+ };
2449
+ }
2450
+ } catch (error) {
2451
+ return handleRouteError(error, "Check purchase", "Failed to check purchase");
2452
+ }
2453
+ }
2454
+
2455
+ // src/helpers/usage.ts
2456
+ async function trackUsageCore(request, body, options = {}) {
2457
+ try {
2458
+ const userResult = await getAuthenticatedUserCore(request);
2459
+ if (isErrorResult(userResult)) {
2460
+ return userResult;
2461
+ }
2462
+ const { userId, email, name } = userResult;
2463
+ const solvaPay = options.solvaPay || createSolvaPay();
2464
+ const customerRef = await solvaPay.ensureCustomer(userId, userId, {
2465
+ email: email || void 0,
2466
+ name: name || void 0
2467
+ });
2468
+ await solvaPay.trackUsage({
2469
+ customerRef,
2470
+ actionType: body.actionType,
2471
+ units: body.units,
2472
+ productRef: body.productRef,
2473
+ description: body.description,
2474
+ metadata: body.metadata
2475
+ });
2476
+ return { success: true };
2477
+ } catch (error) {
2478
+ return handleRouteError(error, "Track usage", "Track usage failed");
2479
+ }
2480
+ }
2481
+
2398
2482
  // src/index.ts
2399
2483
  function verifyWebhook({
2400
2484
  body,
@@ -2439,6 +2523,7 @@ export {
2439
2523
  activatePlanCore,
2440
2524
  buildAuthInfoFromBearer,
2441
2525
  cancelPurchaseCore,
2526
+ checkPurchaseCore,
2442
2527
  createCheckoutSessionCore,
2443
2528
  createCustomerSessionCore,
2444
2529
  createMcpOAuthBridge,
@@ -2464,6 +2549,7 @@ export {
2464
2549
  reactivatePurchaseCore,
2465
2550
  registerVirtualToolsMcpImpl,
2466
2551
  syncCustomerCore,
2552
+ trackUsageCore,
2467
2553
  verifyWebhook,
2468
2554
  withRetry
2469
2555
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solvapay/server",
3
- "version": "1.0.7",
3
+ "version": "1.0.9-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.9-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.9-preview.1"
46
46
  },
47
47
  "peerDependenciesMeta": {
48
48
  "@modelcontextprotocol/sdk": {
@@ -60,9 +60,9 @@
60
60
  "tsx": "^4.21.0",
61
61
  "typescript": "^5.9.3",
62
62
  "vitest": "^4.1.2",
63
- "@solvapay/auth": "1.0.7",
64
63
  "@solvapay/demo-services": "0.0.0",
65
- "@solvapay/test-utils": "^0.0.0"
64
+ "@solvapay/test-utils": "^0.0.0",
65
+ "@solvapay/auth": "1.0.9-preview.1"
66
66
  },
67
67
  "scripts": {
68
68
  "build": "tsup src/index.ts --format esm,cjs --dts --tsconfig tsconfig.build.json && tsup src/edge.ts --format esm --dts --tsconfig tsconfig.build.json",