@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/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/edge.d.ts
CHANGED
|
@@ -2488,6 +2488,26 @@ interface ProcessPaymentResult {
|
|
|
2488
2488
|
status: 'completed';
|
|
2489
2489
|
}
|
|
2490
2490
|
type ActivatePlanResult = components['schemas']['ActivatePlanResponseDto'];
|
|
2491
|
+
/**
|
|
2492
|
+
* SDK-facing merchant identity (source: GET /v1/sdk/merchant).
|
|
2493
|
+
*
|
|
2494
|
+
* Hand-typed here until the OpenAPI generator picks up the new endpoint.
|
|
2495
|
+
* Fields match `SdkMerchantResponseDto` on the backend.
|
|
2496
|
+
*/
|
|
2497
|
+
type SdkMerchantResponse = {
|
|
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
|
+
};
|
|
2509
|
+
/** SDK-facing product projection. Sourced from the existing OpenAPI spec. */
|
|
2510
|
+
type SdkProductResponse = components['schemas']['SdkProductResponse'];
|
|
2491
2511
|
type McpBootstrapRequest = components['schemas']['McpBootstrapDto'];
|
|
2492
2512
|
interface McpBootstrapResponse {
|
|
2493
2513
|
product: components['schemas']['SdkProductResponse'];
|
|
@@ -2553,6 +2573,13 @@ interface SolvaPayClient {
|
|
|
2553
2573
|
externalRef?: string;
|
|
2554
2574
|
email?: string;
|
|
2555
2575
|
}): Promise<CustomerResponseMapped>;
|
|
2576
|
+
/**
|
|
2577
|
+
* SDK-facing merchant identity (GET /v1/sdk/merchant).
|
|
2578
|
+
* Returns the subset of provider fields safe for browser consumption —
|
|
2579
|
+
* used by `<MandateText>`, `<CheckoutSummary>`, and trust signals.
|
|
2580
|
+
*/
|
|
2581
|
+
getMerchant?(): Promise<SdkMerchantResponse>;
|
|
2582
|
+
getProduct?(productRef: string): Promise<SdkProductResponse>;
|
|
2556
2583
|
listProducts?(): Promise<Array<{
|
|
2557
2584
|
reference: string;
|
|
2558
2585
|
name: string;
|
|
@@ -3733,6 +3760,13 @@ declare function getAuthenticatedUserCore(request: Request, options?: {
|
|
|
3733
3760
|
* Works with standard Web API Request (works everywhere).
|
|
3734
3761
|
*/
|
|
3735
3762
|
|
|
3763
|
+
type CustomerBalanceResult = {
|
|
3764
|
+
customerRef: string;
|
|
3765
|
+
credits: number;
|
|
3766
|
+
displayCurrency: string;
|
|
3767
|
+
creditsPerMinorUnit: number;
|
|
3768
|
+
displayExchangeRate: number;
|
|
3769
|
+
};
|
|
3736
3770
|
/**
|
|
3737
3771
|
* Sync customer with SolvaPay backend (ensure customer exists).
|
|
3738
3772
|
*
|
|
@@ -3775,6 +3809,18 @@ declare function syncCustomerCore(request: Request, options?: {
|
|
|
3775
3809
|
includeEmail?: boolean;
|
|
3776
3810
|
includeName?: boolean;
|
|
3777
3811
|
}): Promise<string | ErrorResult>;
|
|
3812
|
+
/**
|
|
3813
|
+
* Get credits for the authenticated customer.
|
|
3814
|
+
*
|
|
3815
|
+
* Authenticates the request, syncs the customer, then fetches credits.
|
|
3816
|
+
*
|
|
3817
|
+
* @param request - Standard Web API Request object
|
|
3818
|
+
* @param options - Configuration options
|
|
3819
|
+
* @returns Customer credits result or error result
|
|
3820
|
+
*/
|
|
3821
|
+
declare function getCustomerBalanceCore(request: Request, options?: {
|
|
3822
|
+
solvaPay?: SolvaPay;
|
|
3823
|
+
}): Promise<CustomerBalanceResult | ErrorResult>;
|
|
3778
3824
|
|
|
3779
3825
|
/**
|
|
3780
3826
|
* Create a payment intent for a customer to purchase a plan.
|
|
@@ -3969,6 +4015,31 @@ declare function cancelPurchaseCore(request: Request, body: {
|
|
|
3969
4015
|
}, options?: {
|
|
3970
4016
|
solvaPay?: SolvaPay;
|
|
3971
4017
|
}): Promise<Record<string, unknown> | ErrorResult>;
|
|
4018
|
+
/**
|
|
4019
|
+
* Reactivate purchase - core implementation
|
|
4020
|
+
*
|
|
4021
|
+
* Undoes a pending cancellation, restoring auto-renewal and clearing cancellation fields.
|
|
4022
|
+
* Only works while the purchase is still active and the end date hasn't passed.
|
|
4023
|
+
*
|
|
4024
|
+
* @param request - Standard Web API Request
|
|
4025
|
+
* @param body - Reactivation parameters
|
|
4026
|
+
* @param options - Configuration options
|
|
4027
|
+
* @returns Reactivated purchase response or error result
|
|
4028
|
+
*/
|
|
4029
|
+
declare function reactivatePurchaseCore(request: Request, body: {
|
|
4030
|
+
purchaseRef: string;
|
|
4031
|
+
}, options?: {
|
|
4032
|
+
solvaPay?: SolvaPay;
|
|
4033
|
+
}): Promise<Record<string, unknown> | ErrorResult>;
|
|
4034
|
+
|
|
4035
|
+
declare function activatePlanCore(request: Request, body: {
|
|
4036
|
+
productRef: string;
|
|
4037
|
+
planRef: string;
|
|
4038
|
+
}, options?: {
|
|
4039
|
+
solvaPay?: SolvaPay;
|
|
4040
|
+
includeEmail?: boolean;
|
|
4041
|
+
includeName?: boolean;
|
|
4042
|
+
}): Promise<ActivatePlanResult | ErrorResult>;
|
|
3972
4043
|
|
|
3973
4044
|
/**
|
|
3974
4045
|
* Plans Helper (Core)
|
|
@@ -3980,13 +4051,62 @@ declare function cancelPurchaseCore(request: Request, body: {
|
|
|
3980
4051
|
|
|
3981
4052
|
type Plan = components['schemas']['Plan'];
|
|
3982
4053
|
/**
|
|
3983
|
-
* List plans - core implementation
|
|
4054
|
+
* List plans - core implementation.
|
|
4055
|
+
*
|
|
4056
|
+
* Pass `options.solvaPay` to route through a pre-configured SolvaPay instance
|
|
4057
|
+
* (e.g. stub-backed in examples). When omitted, the helper reads
|
|
4058
|
+
* `SOLVAPAY_SECRET_KEY` from environment and constructs a real API client.
|
|
3984
4059
|
*/
|
|
3985
|
-
declare function listPlansCore(request: Request
|
|
4060
|
+
declare function listPlansCore(request: Request, options?: {
|
|
4061
|
+
solvaPay?: SolvaPay;
|
|
4062
|
+
}): Promise<{
|
|
3986
4063
|
plans: Plan[];
|
|
3987
4064
|
productRef: string;
|
|
3988
4065
|
} | ErrorResult>;
|
|
3989
4066
|
|
|
4067
|
+
interface PurchaseCheckResult {
|
|
4068
|
+
customerRef: string;
|
|
4069
|
+
email?: string;
|
|
4070
|
+
name?: string;
|
|
4071
|
+
purchases: Array<{
|
|
4072
|
+
reference: string;
|
|
4073
|
+
productName?: string;
|
|
4074
|
+
productRef?: string;
|
|
4075
|
+
status?: string;
|
|
4076
|
+
startDate?: string;
|
|
4077
|
+
planSnapshot?: {
|
|
4078
|
+
meterId?: string;
|
|
4079
|
+
limit?: number;
|
|
4080
|
+
freeUnits?: number;
|
|
4081
|
+
};
|
|
4082
|
+
usage?: {
|
|
4083
|
+
used?: number;
|
|
4084
|
+
overageUnits?: number;
|
|
4085
|
+
overageCost?: number;
|
|
4086
|
+
periodStart?: string;
|
|
4087
|
+
periodEnd?: string;
|
|
4088
|
+
};
|
|
4089
|
+
[key: string]: unknown;
|
|
4090
|
+
}>;
|
|
4091
|
+
}
|
|
4092
|
+
declare function checkPurchaseCore(request: Request, options?: {
|
|
4093
|
+
solvaPay?: SolvaPay;
|
|
4094
|
+
includeEmail?: boolean;
|
|
4095
|
+
includeName?: boolean;
|
|
4096
|
+
}): Promise<PurchaseCheckResult | ErrorResult>;
|
|
4097
|
+
|
|
4098
|
+
declare function trackUsageCore(request: Request, body: {
|
|
4099
|
+
actionType?: 'transaction' | 'api_call' | 'hour' | 'email' | 'storage' | 'custom';
|
|
4100
|
+
units?: number;
|
|
4101
|
+
productRef?: string;
|
|
4102
|
+
description?: string;
|
|
4103
|
+
metadata?: Record<string, unknown>;
|
|
4104
|
+
}, options?: {
|
|
4105
|
+
solvaPay?: SolvaPay;
|
|
4106
|
+
}): Promise<{
|
|
4107
|
+
success: true;
|
|
4108
|
+
} | ErrorResult>;
|
|
4109
|
+
|
|
3990
4110
|
/**
|
|
3991
4111
|
* SolvaPay Server SDK - Edge Runtime Entry Point
|
|
3992
4112
|
*
|
|
@@ -4000,4 +4120,4 @@ declare function verifyWebhook({ body, signature, secret, }: {
|
|
|
4000
4120
|
secret: string;
|
|
4001
4121
|
}): Promise<WebhookEvent>;
|
|
4002
4122
|
|
|
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 };
|
|
4123
|
+
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
|
@@ -109,6 +109,36 @@ function createSolvaPayClient(opts) {
|
|
|
109
109
|
purchases: customer.purchases || []
|
|
110
110
|
};
|
|
111
111
|
},
|
|
112
|
+
// GET: /v1/sdk/merchant
|
|
113
|
+
async getMerchant() {
|
|
114
|
+
const url = `${base}/v1/sdk/merchant`;
|
|
115
|
+
const res = await fetch(url, {
|
|
116
|
+
method: "GET",
|
|
117
|
+
headers
|
|
118
|
+
});
|
|
119
|
+
if (!res.ok) {
|
|
120
|
+
const error = await res.text();
|
|
121
|
+
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
122
|
+
throw new SolvaPayError(`Get merchant failed (${res.status}): ${error}`);
|
|
123
|
+
}
|
|
124
|
+
return res.json();
|
|
125
|
+
},
|
|
126
|
+
// GET: /v1/sdk/products/{productRef}
|
|
127
|
+
async getProduct(productRef) {
|
|
128
|
+
const url = `${base}/v1/sdk/products/${encodeURIComponent(productRef)}`;
|
|
129
|
+
const res = await fetch(url, {
|
|
130
|
+
method: "GET",
|
|
131
|
+
headers
|
|
132
|
+
});
|
|
133
|
+
if (!res.ok) {
|
|
134
|
+
const error = await res.text();
|
|
135
|
+
log(`\u274C API Error: ${res.status} - ${error}`);
|
|
136
|
+
throw new SolvaPayError(`Get product failed (${res.status}): ${error}`);
|
|
137
|
+
}
|
|
138
|
+
const result = await res.json();
|
|
139
|
+
const data = result.data || {};
|
|
140
|
+
return { ...data, ...result };
|
|
141
|
+
},
|
|
112
142
|
// Product management methods (primarily for integration tests)
|
|
113
143
|
// GET: /v1/sdk/products
|
|
114
144
|
async listProducts() {
|
|
@@ -1775,6 +1805,24 @@ async function syncCustomerCore(request, options = {}) {
|
|
|
1775
1805
|
return handleRouteError(error, "Sync customer", "Failed to sync customer");
|
|
1776
1806
|
}
|
|
1777
1807
|
}
|
|
1808
|
+
async function getCustomerBalanceCore(request, options = {}) {
|
|
1809
|
+
try {
|
|
1810
|
+
const userResult = await getAuthenticatedUserCore(request);
|
|
1811
|
+
if (isErrorResult(userResult)) {
|
|
1812
|
+
return userResult;
|
|
1813
|
+
}
|
|
1814
|
+
const { userId, email, name } = userResult;
|
|
1815
|
+
const solvaPay = options.solvaPay || createSolvaPay();
|
|
1816
|
+
const customerRef = await solvaPay.ensureCustomer(userId, userId, {
|
|
1817
|
+
email: email || void 0,
|
|
1818
|
+
name: name || void 0
|
|
1819
|
+
});
|
|
1820
|
+
const result = await solvaPay.getCustomerBalance({ customerRef });
|
|
1821
|
+
return result;
|
|
1822
|
+
} catch (error) {
|
|
1823
|
+
return handleRouteError(error, "Get customer credits", "Failed to get customer credits");
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1778
1826
|
|
|
1779
1827
|
// src/helpers/payment.ts
|
|
1780
1828
|
async function createPaymentIntentCore(request, body, options = {}) {
|
|
@@ -2024,10 +2072,107 @@ async function cancelPurchaseCore(request, body, options = {}) {
|
|
|
2024
2072
|
return handleRouteError(error, "Cancel purchase", "Failed to cancel purchase");
|
|
2025
2073
|
}
|
|
2026
2074
|
}
|
|
2075
|
+
async function reactivatePurchaseCore(request, body, options = {}) {
|
|
2076
|
+
try {
|
|
2077
|
+
if (!body.purchaseRef) {
|
|
2078
|
+
return {
|
|
2079
|
+
error: "Missing required parameter: purchaseRef is required",
|
|
2080
|
+
status: 400
|
|
2081
|
+
};
|
|
2082
|
+
}
|
|
2083
|
+
const solvaPay = options.solvaPay || createSolvaPay();
|
|
2084
|
+
if (!solvaPay.apiClient.reactivatePurchase) {
|
|
2085
|
+
return {
|
|
2086
|
+
error: "Reactivate purchase method not available on SDK client",
|
|
2087
|
+
status: 500
|
|
2088
|
+
};
|
|
2089
|
+
}
|
|
2090
|
+
let reactivatedPurchase = await solvaPay.apiClient.reactivatePurchase({
|
|
2091
|
+
purchaseRef: body.purchaseRef
|
|
2092
|
+
});
|
|
2093
|
+
if (!reactivatedPurchase || typeof reactivatedPurchase !== "object") {
|
|
2094
|
+
return {
|
|
2095
|
+
error: "Invalid response from reactivate purchase endpoint",
|
|
2096
|
+
status: 500
|
|
2097
|
+
};
|
|
2098
|
+
}
|
|
2099
|
+
const responseObj = reactivatedPurchase;
|
|
2100
|
+
if (responseObj.purchase && typeof responseObj.purchase === "object") {
|
|
2101
|
+
reactivatedPurchase = responseObj.purchase;
|
|
2102
|
+
}
|
|
2103
|
+
if (!reactivatedPurchase.reference) {
|
|
2104
|
+
return {
|
|
2105
|
+
error: "Reactivate purchase response missing required fields",
|
|
2106
|
+
status: 500
|
|
2107
|
+
};
|
|
2108
|
+
}
|
|
2109
|
+
if (reactivatedPurchase.cancelledAt) {
|
|
2110
|
+
return {
|
|
2111
|
+
error: `Purchase reactivation failed: cancelledAt is still set`,
|
|
2112
|
+
status: 500
|
|
2113
|
+
};
|
|
2114
|
+
}
|
|
2115
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
2116
|
+
return reactivatedPurchase;
|
|
2117
|
+
} catch (error) {
|
|
2118
|
+
if (error instanceof SolvaPayError4) {
|
|
2119
|
+
const errorMessage = error.message;
|
|
2120
|
+
if (errorMessage.includes("not found")) {
|
|
2121
|
+
return {
|
|
2122
|
+
error: "Purchase not found",
|
|
2123
|
+
status: 404,
|
|
2124
|
+
details: errorMessage
|
|
2125
|
+
};
|
|
2126
|
+
}
|
|
2127
|
+
if (errorMessage.includes("cannot be reactivated") || errorMessage.includes("not pending cancellation") || errorMessage.includes("already been fully cancelled") || errorMessage.includes("already ended")) {
|
|
2128
|
+
return {
|
|
2129
|
+
error: "Purchase cannot be reactivated",
|
|
2130
|
+
status: 400,
|
|
2131
|
+
details: errorMessage
|
|
2132
|
+
};
|
|
2133
|
+
}
|
|
2134
|
+
return {
|
|
2135
|
+
error: errorMessage,
|
|
2136
|
+
status: 500,
|
|
2137
|
+
details: errorMessage
|
|
2138
|
+
};
|
|
2139
|
+
}
|
|
2140
|
+
return handleRouteError(error, "Reactivate purchase", "Failed to reactivate purchase");
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2143
|
+
|
|
2144
|
+
// src/helpers/activation.ts
|
|
2145
|
+
async function activatePlanCore(request, body, options = {}) {
|
|
2146
|
+
try {
|
|
2147
|
+
if (!body.productRef || !body.planRef) {
|
|
2148
|
+
return {
|
|
2149
|
+
error: "Missing required parameters: productRef and planRef are required",
|
|
2150
|
+
status: 400
|
|
2151
|
+
};
|
|
2152
|
+
}
|
|
2153
|
+
const customerResult = await syncCustomerCore(request, {
|
|
2154
|
+
solvaPay: options.solvaPay,
|
|
2155
|
+
includeEmail: options.includeEmail,
|
|
2156
|
+
includeName: options.includeName
|
|
2157
|
+
});
|
|
2158
|
+
if (isErrorResult(customerResult)) {
|
|
2159
|
+
return customerResult;
|
|
2160
|
+
}
|
|
2161
|
+
const customerRef = customerResult;
|
|
2162
|
+
const solvaPay = options.solvaPay || createSolvaPay();
|
|
2163
|
+
return await solvaPay.activatePlan({
|
|
2164
|
+
customerRef,
|
|
2165
|
+
productRef: body.productRef,
|
|
2166
|
+
planRef: body.planRef
|
|
2167
|
+
});
|
|
2168
|
+
} catch (error) {
|
|
2169
|
+
return handleRouteError(error, "Activate plan", "Plan activation failed");
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2027
2172
|
|
|
2028
2173
|
// src/helpers/plans.ts
|
|
2029
2174
|
import { getSolvaPayConfig as getSolvaPayConfig2 } from "@solvapay/core";
|
|
2030
|
-
async function listPlansCore(request) {
|
|
2175
|
+
async function listPlansCore(request, options = {}) {
|
|
2031
2176
|
try {
|
|
2032
2177
|
const url = new URL(request.url);
|
|
2033
2178
|
const productRef = url.searchParams.get("productRef");
|
|
@@ -2037,19 +2182,20 @@ async function listPlansCore(request) {
|
|
|
2037
2182
|
status: 400
|
|
2038
2183
|
};
|
|
2039
2184
|
}
|
|
2040
|
-
const
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2185
|
+
const apiClient = options.solvaPay?.apiClient ?? (() => {
|
|
2186
|
+
const config = getSolvaPayConfig2();
|
|
2187
|
+
if (!config.apiKey) return null;
|
|
2188
|
+
return createSolvaPayClient({
|
|
2189
|
+
apiKey: config.apiKey,
|
|
2190
|
+
apiBaseUrl: config.apiBaseUrl
|
|
2191
|
+
});
|
|
2192
|
+
})();
|
|
2193
|
+
if (!apiClient) {
|
|
2044
2194
|
return {
|
|
2045
2195
|
error: "Server configuration error: SolvaPay secret key not configured",
|
|
2046
2196
|
status: 500
|
|
2047
2197
|
};
|
|
2048
2198
|
}
|
|
2049
|
-
const apiClient = createSolvaPayClient({
|
|
2050
|
-
apiKey: solvapaySecretKey,
|
|
2051
|
-
apiBaseUrl: solvapayApiBaseUrl
|
|
2052
|
-
});
|
|
2053
2199
|
if (!apiClient.listPlans) {
|
|
2054
2200
|
return {
|
|
2055
2201
|
error: "List plans method not available",
|
|
@@ -2066,6 +2212,89 @@ async function listPlansCore(request) {
|
|
|
2066
2212
|
}
|
|
2067
2213
|
}
|
|
2068
2214
|
|
|
2215
|
+
// src/helpers/purchase.ts
|
|
2216
|
+
async function checkPurchaseCore(request, options = {}) {
|
|
2217
|
+
try {
|
|
2218
|
+
const userResult = await getAuthenticatedUserCore(request, {
|
|
2219
|
+
includeEmail: options.includeEmail,
|
|
2220
|
+
includeName: options.includeName
|
|
2221
|
+
});
|
|
2222
|
+
if (isErrorResult(userResult)) {
|
|
2223
|
+
return userResult;
|
|
2224
|
+
}
|
|
2225
|
+
const { userId, email, name } = userResult;
|
|
2226
|
+
const solvaPay = options.solvaPay || createSolvaPay();
|
|
2227
|
+
const cachedCustomerRef = request.headers.get("x-solvapay-customer-ref");
|
|
2228
|
+
if (cachedCustomerRef) {
|
|
2229
|
+
try {
|
|
2230
|
+
const customer = await solvaPay.getCustomer({ customerRef: cachedCustomerRef });
|
|
2231
|
+
if (customer && customer.customerRef) {
|
|
2232
|
+
if (customer.externalRef && customer.externalRef === userId) {
|
|
2233
|
+
const filteredPurchases = (customer.purchases || []).filter(
|
|
2234
|
+
(p) => p.status === "active"
|
|
2235
|
+
);
|
|
2236
|
+
return {
|
|
2237
|
+
customerRef: customer.customerRef,
|
|
2238
|
+
email: customer.email,
|
|
2239
|
+
name: customer.name,
|
|
2240
|
+
purchases: filteredPurchases
|
|
2241
|
+
};
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
} catch {
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
try {
|
|
2248
|
+
const customerRef = await solvaPay.ensureCustomer(userId, userId, {
|
|
2249
|
+
email: email || void 0,
|
|
2250
|
+
name: name || void 0
|
|
2251
|
+
});
|
|
2252
|
+
const customer = await solvaPay.getCustomer({ customerRef });
|
|
2253
|
+
const filteredPurchases = (customer.purchases || []).filter((p) => p.status === "active");
|
|
2254
|
+
return {
|
|
2255
|
+
customerRef: customer.customerRef || userId,
|
|
2256
|
+
email: customer.email,
|
|
2257
|
+
name: customer.name,
|
|
2258
|
+
purchases: filteredPurchases
|
|
2259
|
+
};
|
|
2260
|
+
} catch {
|
|
2261
|
+
return {
|
|
2262
|
+
customerRef: userId,
|
|
2263
|
+
purchases: []
|
|
2264
|
+
};
|
|
2265
|
+
}
|
|
2266
|
+
} catch (error) {
|
|
2267
|
+
return handleRouteError(error, "Check purchase", "Failed to check purchase");
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2270
|
+
|
|
2271
|
+
// src/helpers/usage.ts
|
|
2272
|
+
async function trackUsageCore(request, body, options = {}) {
|
|
2273
|
+
try {
|
|
2274
|
+
const userResult = await getAuthenticatedUserCore(request);
|
|
2275
|
+
if (isErrorResult(userResult)) {
|
|
2276
|
+
return userResult;
|
|
2277
|
+
}
|
|
2278
|
+
const { userId, email, name } = userResult;
|
|
2279
|
+
const solvaPay = options.solvaPay || createSolvaPay();
|
|
2280
|
+
const customerRef = await solvaPay.ensureCustomer(userId, userId, {
|
|
2281
|
+
email: email || void 0,
|
|
2282
|
+
name: name || void 0
|
|
2283
|
+
});
|
|
2284
|
+
await solvaPay.trackUsage({
|
|
2285
|
+
customerRef,
|
|
2286
|
+
actionType: body.actionType,
|
|
2287
|
+
units: body.units,
|
|
2288
|
+
productRef: body.productRef,
|
|
2289
|
+
description: body.description,
|
|
2290
|
+
metadata: body.metadata
|
|
2291
|
+
});
|
|
2292
|
+
return { success: true };
|
|
2293
|
+
} catch (error) {
|
|
2294
|
+
return handleRouteError(error, "Track usage", "Track usage failed");
|
|
2295
|
+
}
|
|
2296
|
+
}
|
|
2297
|
+
|
|
2069
2298
|
// src/edge.ts
|
|
2070
2299
|
function timingSafeEqual(a, b) {
|
|
2071
2300
|
if (a.length !== b.length) return false;
|
|
@@ -2120,7 +2349,9 @@ async function verifyWebhook({
|
|
|
2120
2349
|
}
|
|
2121
2350
|
export {
|
|
2122
2351
|
PaywallError,
|
|
2352
|
+
activatePlanCore,
|
|
2123
2353
|
cancelPurchaseCore,
|
|
2354
|
+
checkPurchaseCore,
|
|
2124
2355
|
createCheckoutSessionCore,
|
|
2125
2356
|
createCustomerSessionCore,
|
|
2126
2357
|
createPaymentIntentCore,
|
|
@@ -2128,12 +2359,15 @@ export {
|
|
|
2128
2359
|
createSolvaPayClient,
|
|
2129
2360
|
createTopupPaymentIntentCore,
|
|
2130
2361
|
getAuthenticatedUserCore,
|
|
2362
|
+
getCustomerBalanceCore,
|
|
2131
2363
|
handleRouteError,
|
|
2132
2364
|
isErrorResult,
|
|
2133
2365
|
listPlansCore,
|
|
2134
2366
|
paywallErrorToClientPayload,
|
|
2135
2367
|
processPaymentIntentCore,
|
|
2368
|
+
reactivatePurchaseCore,
|
|
2136
2369
|
syncCustomerCore,
|
|
2370
|
+
trackUsageCore,
|
|
2137
2371
|
verifyWebhook,
|
|
2138
2372
|
withRetry
|
|
2139
2373
|
};
|