@stripe-sdk/core 1.0.0 → 1.0.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/README.md +88 -261
- package/dist/client/index.d.mts +0 -4
- package/dist/client/index.d.ts +0 -4
- package/dist/client/index.js +70 -11
- package/dist/client/index.mjs +71 -12
- package/dist/{index-D8rM_YD4.d.mts → index-BKDJf1Hz.d.mts} +1 -27
- package/dist/{index-D8rM_YD4.d.ts → index-BKDJf1Hz.d.ts} +1 -27
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +601 -231
- package/dist/index.mjs +602 -232
- package/dist/next/index.d.mts +55 -32
- package/dist/next/index.d.ts +55 -32
- package/dist/next/index.js +362 -143
- package/dist/next/index.mjs +362 -143
- package/dist/server/index.d.mts +61 -21
- package/dist/server/index.d.ts +61 -21
- package/dist/server/index.js +546 -237
- package/dist/server/index.mjs +546 -237
- package/dist/server/webhooks/index.d.mts +1 -1
- package/dist/server/webhooks/index.d.ts +1 -1
- package/dist/server/webhooks/index.js +19 -7
- package/dist/server/webhooks/index.mjs +19 -7
- package/package.json +8 -5
- package/dist/client/index.js.map +0 -1
- package/dist/client/index.mjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/next/index.js.map +0 -1
- package/dist/next/index.mjs.map +0 -1
- package/dist/server/index.js.map +0 -1
- package/dist/server/index.mjs.map +0 -1
- package/dist/server/webhooks/index.js.map +0 -1
- package/dist/server/webhooks/index.mjs.map +0 -1
package/dist/server/index.js
CHANGED
|
@@ -10,12 +10,16 @@ var Stripe__default = /*#__PURE__*/_interopDefault(Stripe);
|
|
|
10
10
|
var stripeInstance = null;
|
|
11
11
|
var currentConfig = null;
|
|
12
12
|
function initStripe(config) {
|
|
13
|
+
if (stripeInstance) {
|
|
14
|
+
console.warn("[@stripe-sdk/core] Stripe is already initialized. Re-initializing with new config.");
|
|
15
|
+
}
|
|
13
16
|
currentConfig = config;
|
|
14
17
|
stripeInstance = new Stripe__default.default(config.secretKey, {
|
|
15
18
|
apiVersion: config.apiVersion ?? "2025-01-27.acacia",
|
|
19
|
+
maxNetworkRetries: config.maxNetworkRetries ?? 2,
|
|
16
20
|
appInfo: config.appInfo ?? {
|
|
17
21
|
name: "@stripe-sdk/core",
|
|
18
|
-
version: "1.0.
|
|
22
|
+
version: "1.0.1"
|
|
19
23
|
}
|
|
20
24
|
});
|
|
21
25
|
return stripeInstance;
|
|
@@ -34,17 +38,27 @@ function getConfig() {
|
|
|
34
38
|
"[@stripe-sdk/core] Stripe not initialized. Call initStripe({ secretKey, publishableKey }) first."
|
|
35
39
|
);
|
|
36
40
|
}
|
|
37
|
-
|
|
41
|
+
const { secretKey: _sk, ...safeConfig } = currentConfig;
|
|
42
|
+
return safeConfig;
|
|
38
43
|
}
|
|
39
44
|
|
|
40
45
|
// src/utils/errors.ts
|
|
46
|
+
var SAFE_ERROR_MESSAGES = {
|
|
47
|
+
card_declined: "Your card was declined.",
|
|
48
|
+
expired_card: "Your card has expired.",
|
|
49
|
+
incorrect_cvc: "Incorrect security code.",
|
|
50
|
+
processing_error: "An error occurred while processing your card.",
|
|
51
|
+
incorrect_number: "The card number is incorrect.",
|
|
52
|
+
insufficient_funds: "Insufficient funds."
|
|
53
|
+
};
|
|
41
54
|
function handleStripeError(error) {
|
|
42
55
|
if (error?.type) {
|
|
43
56
|
const stripeError = error;
|
|
57
|
+
const safeMessage = stripeError.code && SAFE_ERROR_MESSAGES[stripeError.code] || getSafeMessage(stripeError.type);
|
|
44
58
|
return {
|
|
45
59
|
data: null,
|
|
46
60
|
error: {
|
|
47
|
-
message:
|
|
61
|
+
message: safeMessage,
|
|
48
62
|
type: stripeError.type,
|
|
49
63
|
code: stripeError.code,
|
|
50
64
|
statusCode: stripeError.statusCode
|
|
@@ -54,31 +68,147 @@ function handleStripeError(error) {
|
|
|
54
68
|
return {
|
|
55
69
|
data: null,
|
|
56
70
|
error: {
|
|
57
|
-
message:
|
|
71
|
+
message: "An unexpected error occurred",
|
|
58
72
|
type: "sdk_error"
|
|
59
73
|
}
|
|
60
74
|
};
|
|
61
75
|
}
|
|
76
|
+
function getSafeMessage(type) {
|
|
77
|
+
switch (type) {
|
|
78
|
+
case "card_error":
|
|
79
|
+
return "A card error occurred.";
|
|
80
|
+
case "invalid_request_error":
|
|
81
|
+
return "Invalid request. Please check your input.";
|
|
82
|
+
case "authentication_error":
|
|
83
|
+
return "Authentication failed.";
|
|
84
|
+
case "rate_limit_error":
|
|
85
|
+
return "Too many requests. Please try again later.";
|
|
86
|
+
case "api_error":
|
|
87
|
+
return "A payment processing error occurred. Please try again.";
|
|
88
|
+
default:
|
|
89
|
+
return "An unexpected error occurred.";
|
|
90
|
+
}
|
|
91
|
+
}
|
|
62
92
|
function success(data) {
|
|
63
93
|
return { data, error: null };
|
|
64
94
|
}
|
|
65
95
|
|
|
96
|
+
// src/utils/validators.ts
|
|
97
|
+
var STRIPE_ID_PREFIXES = {
|
|
98
|
+
customer: "cus_",
|
|
99
|
+
paymentIntent: "pi_",
|
|
100
|
+
paymentMethod: "pm_",
|
|
101
|
+
subscription: "sub_",
|
|
102
|
+
invoice: "in_",
|
|
103
|
+
invoiceItem: "ii_",
|
|
104
|
+
product: "prod_",
|
|
105
|
+
price: "price_",
|
|
106
|
+
coupon: "",
|
|
107
|
+
// coupons can have custom IDs
|
|
108
|
+
promotionCode: "promo_",
|
|
109
|
+
refund: "re_",
|
|
110
|
+
dispute: "dp_",
|
|
111
|
+
account: "acct_",
|
|
112
|
+
transfer: "tr_",
|
|
113
|
+
payout: "po_",
|
|
114
|
+
setupIntent: "seti_",
|
|
115
|
+
session: "cs_",
|
|
116
|
+
paymentLink: "plink_"
|
|
117
|
+
};
|
|
118
|
+
function validateStripeId(id, type) {
|
|
119
|
+
if (!id || typeof id !== "string") {
|
|
120
|
+
throw new Error(`${type} ID is required and must be a non-empty string`);
|
|
121
|
+
}
|
|
122
|
+
const prefix = STRIPE_ID_PREFIXES[type];
|
|
123
|
+
if (prefix && !id.startsWith(prefix)) {
|
|
124
|
+
throw new Error(`Invalid ${type} ID: expected prefix "${prefix}"`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function validateAmount(amount, label = "amount") {
|
|
128
|
+
if (typeof amount !== "number" || !Number.isFinite(amount)) {
|
|
129
|
+
throw new Error(`${label} must be a finite number`);
|
|
130
|
+
}
|
|
131
|
+
if (!Number.isInteger(amount)) {
|
|
132
|
+
throw new Error(`${label} must be an integer (amount in smallest currency unit)`);
|
|
133
|
+
}
|
|
134
|
+
if (amount < 0) {
|
|
135
|
+
throw new Error(`${label} must not be negative`);
|
|
136
|
+
}
|
|
137
|
+
if (amount > 99999999) {
|
|
138
|
+
throw new Error(`${label} exceeds maximum allowed value (99999999)`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function validateCurrency(currency) {
|
|
142
|
+
if (!currency || typeof currency !== "string") {
|
|
143
|
+
throw new Error("Currency is required");
|
|
144
|
+
}
|
|
145
|
+
const normalized = currency.trim().toLowerCase();
|
|
146
|
+
if (!/^[a-z]{3}$/.test(normalized)) {
|
|
147
|
+
throw new Error("Currency must be a valid 3-letter ISO 4217 code");
|
|
148
|
+
}
|
|
149
|
+
return normalized;
|
|
150
|
+
}
|
|
151
|
+
function validateUrl(url, label = "URL") {
|
|
152
|
+
if (!url || typeof url !== "string") {
|
|
153
|
+
throw new Error(`${label} is required`);
|
|
154
|
+
}
|
|
155
|
+
try {
|
|
156
|
+
const parsed = new URL(url);
|
|
157
|
+
if (!["http:", "https:"].includes(parsed.protocol)) {
|
|
158
|
+
throw new Error(`${label} must use http or https protocol`);
|
|
159
|
+
}
|
|
160
|
+
} catch (e) {
|
|
161
|
+
if (e instanceof Error && e.message.includes("protocol")) throw e;
|
|
162
|
+
throw new Error(`${label} must be a valid URL`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function validateMetadata(metadata) {
|
|
166
|
+
const keys = Object.keys(metadata);
|
|
167
|
+
if (keys.length > 50) {
|
|
168
|
+
throw new Error("Metadata cannot have more than 50 keys");
|
|
169
|
+
}
|
|
170
|
+
for (const [key, value] of Object.entries(metadata)) {
|
|
171
|
+
if (key.length > 40) {
|
|
172
|
+
throw new Error(`Metadata key "${key}" exceeds 40 characters`);
|
|
173
|
+
}
|
|
174
|
+
if (typeof value !== "string") {
|
|
175
|
+
throw new Error(`Metadata value for key "${key}" must be a string`);
|
|
176
|
+
}
|
|
177
|
+
if (value.length > 500) {
|
|
178
|
+
throw new Error(`Metadata value for key "${key}" exceeds 500 characters`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function sanitizeLimit(limit, defaultLimit = 10) {
|
|
183
|
+
if (limit === void 0) return defaultLimit;
|
|
184
|
+
return Math.min(Math.max(Math.floor(limit), 1), 100);
|
|
185
|
+
}
|
|
186
|
+
|
|
66
187
|
// src/server/payments/index.ts
|
|
67
|
-
async function createPaymentIntent(input) {
|
|
68
|
-
try {
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
188
|
+
async function createPaymentIntent(input, options) {
|
|
189
|
+
try {
|
|
190
|
+
validateAmount(input.amount);
|
|
191
|
+
const currency = validateCurrency(input.currency);
|
|
192
|
+
if (input.customerId) validateStripeId(input.customerId, "customer");
|
|
193
|
+
if (input.paymentMethodId) validateStripeId(input.paymentMethodId, "paymentMethod");
|
|
194
|
+
if (input.returnUrl) validateUrl(input.returnUrl, "returnUrl");
|
|
195
|
+
if (input.metadata) validateMetadata(input.metadata);
|
|
196
|
+
const stripe = getStripe();
|
|
197
|
+
const paymentIntent = await stripe.paymentIntents.create(
|
|
198
|
+
{
|
|
199
|
+
amount: input.amount,
|
|
200
|
+
currency,
|
|
201
|
+
customer: input.customerId,
|
|
202
|
+
payment_method: input.paymentMethodId,
|
|
203
|
+
metadata: input.metadata,
|
|
204
|
+
description: input.description,
|
|
205
|
+
receipt_email: input.receiptEmail,
|
|
206
|
+
setup_future_usage: input.setupFutureUsage,
|
|
207
|
+
automatic_payment_methods: input.automaticPaymentMethods === false || input.paymentMethodId ? void 0 : { enabled: true },
|
|
208
|
+
return_url: input.returnUrl
|
|
209
|
+
},
|
|
210
|
+
options?.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : void 0
|
|
211
|
+
);
|
|
82
212
|
return success(paymentIntent);
|
|
83
213
|
} catch (error) {
|
|
84
214
|
return handleStripeError(error);
|
|
@@ -86,6 +216,7 @@ async function createPaymentIntent(input) {
|
|
|
86
216
|
}
|
|
87
217
|
async function retrievePaymentIntent(paymentIntentId) {
|
|
88
218
|
try {
|
|
219
|
+
validateStripeId(paymentIntentId, "paymentIntent");
|
|
89
220
|
const stripe = getStripe();
|
|
90
221
|
const paymentIntent = await stripe.paymentIntents.retrieve(paymentIntentId);
|
|
91
222
|
return success(paymentIntent);
|
|
@@ -95,6 +226,9 @@ async function retrievePaymentIntent(paymentIntentId) {
|
|
|
95
226
|
}
|
|
96
227
|
async function confirmPaymentIntent(input) {
|
|
97
228
|
try {
|
|
229
|
+
validateStripeId(input.paymentIntentId, "paymentIntent");
|
|
230
|
+
if (input.paymentMethodId) validateStripeId(input.paymentMethodId, "paymentMethod");
|
|
231
|
+
if (input.returnUrl) validateUrl(input.returnUrl, "returnUrl");
|
|
98
232
|
const stripe = getStripe();
|
|
99
233
|
const paymentIntent = await stripe.paymentIntents.confirm(input.paymentIntentId, {
|
|
100
234
|
payment_method: input.paymentMethodId,
|
|
@@ -107,6 +241,7 @@ async function confirmPaymentIntent(input) {
|
|
|
107
241
|
}
|
|
108
242
|
async function cancelPaymentIntent(paymentIntentId) {
|
|
109
243
|
try {
|
|
244
|
+
validateStripeId(paymentIntentId, "paymentIntent");
|
|
110
245
|
const stripe = getStripe();
|
|
111
246
|
const paymentIntent = await stripe.paymentIntents.cancel(paymentIntentId);
|
|
112
247
|
return success(paymentIntent);
|
|
@@ -116,9 +251,10 @@ async function cancelPaymentIntent(paymentIntentId) {
|
|
|
116
251
|
}
|
|
117
252
|
async function listPaymentIntents(input) {
|
|
118
253
|
try {
|
|
254
|
+
if (input?.customerId) validateStripeId(input.customerId, "customer");
|
|
119
255
|
const stripe = getStripe();
|
|
120
256
|
const paymentIntents = await stripe.paymentIntents.list({
|
|
121
|
-
limit: input?.limit
|
|
257
|
+
limit: sanitizeLimit(input?.limit),
|
|
122
258
|
starting_after: input?.startingAfter,
|
|
123
259
|
ending_before: input?.endingBefore,
|
|
124
260
|
customer: input?.customerId
|
|
@@ -128,28 +264,35 @@ async function listPaymentIntents(input) {
|
|
|
128
264
|
return handleStripeError(error);
|
|
129
265
|
}
|
|
130
266
|
}
|
|
131
|
-
async function createCheckoutSession(input) {
|
|
132
|
-
try {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
267
|
+
async function createCheckoutSession(input, options) {
|
|
268
|
+
try {
|
|
269
|
+
validateUrl(input.successUrl, "successUrl");
|
|
270
|
+
validateUrl(input.cancelUrl, "cancelUrl");
|
|
271
|
+
if (input.customerId) validateStripeId(input.customerId, "customer");
|
|
272
|
+
if (input.metadata) validateMetadata(input.metadata);
|
|
273
|
+
const stripe = getStripe();
|
|
274
|
+
const session = await stripe.checkout.sessions.create(
|
|
275
|
+
{
|
|
276
|
+
mode: input.mode,
|
|
277
|
+
line_items: input.lineItems.map((item) => ({
|
|
278
|
+
price: item.priceId,
|
|
279
|
+
quantity: item.quantity
|
|
280
|
+
})),
|
|
281
|
+
success_url: input.successUrl,
|
|
282
|
+
cancel_url: input.cancelUrl,
|
|
283
|
+
customer: input.customerId,
|
|
284
|
+
customer_email: input.customerEmail,
|
|
285
|
+
metadata: input.metadata,
|
|
286
|
+
allow_promotion_codes: input.allowPromotionCodes,
|
|
287
|
+
shipping_address_collection: input.shippingAddressCollection ? { allowed_countries: input.shippingAddressCollection.allowedCountries } : void 0,
|
|
288
|
+
billing_address_collection: input.billingAddressCollection,
|
|
289
|
+
subscription_data: input.trialPeriodDays ? { trial_period_days: input.trialPeriodDays } : void 0,
|
|
290
|
+
tax_id_collection: input.taxIdCollection ? { enabled: true } : void 0,
|
|
291
|
+
automatic_tax: input.automaticTax ? { enabled: true } : void 0,
|
|
292
|
+
locale: input.locale
|
|
293
|
+
},
|
|
294
|
+
options?.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : void 0
|
|
295
|
+
);
|
|
153
296
|
return success(session);
|
|
154
297
|
} catch (error) {
|
|
155
298
|
return handleStripeError(error);
|
|
@@ -157,6 +300,7 @@ async function createCheckoutSession(input) {
|
|
|
157
300
|
}
|
|
158
301
|
async function retrieveCheckoutSession(sessionId) {
|
|
159
302
|
try {
|
|
303
|
+
validateStripeId(sessionId, "session");
|
|
160
304
|
const stripe = getStripe();
|
|
161
305
|
const session = await stripe.checkout.sessions.retrieve(sessionId, {
|
|
162
306
|
expand: ["line_items", "payment_intent", "subscription"]
|
|
@@ -170,7 +314,7 @@ async function listCheckoutSessions(input) {
|
|
|
170
314
|
try {
|
|
171
315
|
const stripe = getStripe();
|
|
172
316
|
const sessions = await stripe.checkout.sessions.list({
|
|
173
|
-
limit: input?.limit
|
|
317
|
+
limit: sanitizeLimit(input?.limit),
|
|
174
318
|
starting_after: input?.startingAfter,
|
|
175
319
|
ending_before: input?.endingBefore
|
|
176
320
|
});
|
|
@@ -179,29 +323,36 @@ async function listCheckoutSessions(input) {
|
|
|
179
323
|
return handleStripeError(error);
|
|
180
324
|
}
|
|
181
325
|
}
|
|
182
|
-
async function createPaymentLink(input) {
|
|
326
|
+
async function createPaymentLink(input, options) {
|
|
183
327
|
try {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
328
|
+
if (input.afterCompletion?.redirectUrl) {
|
|
329
|
+
validateUrl(input.afterCompletion.redirectUrl, "afterCompletion.redirectUrl");
|
|
330
|
+
}
|
|
331
|
+
if (input.metadata) validateMetadata(input.metadata);
|
|
332
|
+
const stripe = getStripe();
|
|
333
|
+
const paymentLink = await stripe.paymentLinks.create(
|
|
334
|
+
{
|
|
335
|
+
line_items: input.lineItems.map((item) => ({
|
|
336
|
+
price: item.priceId,
|
|
337
|
+
quantity: item.quantity,
|
|
338
|
+
adjustable_quantity: item.adjustableQuantity ? {
|
|
339
|
+
enabled: item.adjustableQuantity.enabled,
|
|
340
|
+
minimum: item.adjustableQuantity.minimum,
|
|
341
|
+
maximum: item.adjustableQuantity.maximum
|
|
342
|
+
} : void 0
|
|
343
|
+
})),
|
|
344
|
+
metadata: input.metadata,
|
|
345
|
+
after_completion: input.afterCompletion ? {
|
|
346
|
+
type: input.afterCompletion.type,
|
|
347
|
+
redirect: input.afterCompletion.redirectUrl ? { url: input.afterCompletion.redirectUrl } : void 0
|
|
348
|
+
} : void 0,
|
|
349
|
+
allow_promotion_codes: input.allowPromotionCodes,
|
|
350
|
+
automatic_tax: input.automaticTax ? { enabled: true } : void 0,
|
|
351
|
+
billing_address_collection: input.billingAddressCollection,
|
|
352
|
+
shipping_address_collection: input.shippingAddressCollection ? { allowed_countries: input.shippingAddressCollection.allowedCountries } : void 0
|
|
353
|
+
},
|
|
354
|
+
options?.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : void 0
|
|
355
|
+
);
|
|
205
356
|
return success(paymentLink);
|
|
206
357
|
} catch (error) {
|
|
207
358
|
return handleStripeError(error);
|
|
@@ -209,6 +360,7 @@ async function createPaymentLink(input) {
|
|
|
209
360
|
}
|
|
210
361
|
async function retrievePaymentLink(paymentLinkId) {
|
|
211
362
|
try {
|
|
363
|
+
validateStripeId(paymentLinkId, "paymentLink");
|
|
212
364
|
const stripe = getStripe();
|
|
213
365
|
const paymentLink = await stripe.paymentLinks.retrieve(paymentLinkId);
|
|
214
366
|
return success(paymentLink);
|
|
@@ -216,15 +368,20 @@ async function retrievePaymentLink(paymentLinkId) {
|
|
|
216
368
|
return handleStripeError(error);
|
|
217
369
|
}
|
|
218
370
|
}
|
|
219
|
-
async function createSetupIntent(input) {
|
|
371
|
+
async function createSetupIntent(input, options) {
|
|
220
372
|
try {
|
|
373
|
+
if (input.customerId) validateStripeId(input.customerId, "customer");
|
|
374
|
+
if (input.metadata) validateMetadata(input.metadata);
|
|
221
375
|
const stripe = getStripe();
|
|
222
|
-
const setupIntent = await stripe.setupIntents.create(
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
376
|
+
const setupIntent = await stripe.setupIntents.create(
|
|
377
|
+
{
|
|
378
|
+
customer: input.customerId,
|
|
379
|
+
payment_method_types: input.paymentMethodTypes,
|
|
380
|
+
usage: input.usage,
|
|
381
|
+
metadata: input.metadata
|
|
382
|
+
},
|
|
383
|
+
options?.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : void 0
|
|
384
|
+
);
|
|
228
385
|
return success(setupIntent);
|
|
229
386
|
} catch (error) {
|
|
230
387
|
return handleStripeError(error);
|
|
@@ -232,6 +389,7 @@ async function createSetupIntent(input) {
|
|
|
232
389
|
}
|
|
233
390
|
async function retrieveSetupIntent(setupIntentId) {
|
|
234
391
|
try {
|
|
392
|
+
validateStripeId(setupIntentId, "setupIntent");
|
|
235
393
|
const stripe = getStripe();
|
|
236
394
|
const setupIntent = await stripe.setupIntents.retrieve(setupIntentId);
|
|
237
395
|
return success(setupIntent);
|
|
@@ -241,6 +399,7 @@ async function retrieveSetupIntent(setupIntentId) {
|
|
|
241
399
|
}
|
|
242
400
|
async function listPaymentMethods(customerId, type) {
|
|
243
401
|
try {
|
|
402
|
+
validateStripeId(customerId, "customer");
|
|
244
403
|
const stripe = getStripe();
|
|
245
404
|
const paymentMethods = await stripe.paymentMethods.list({
|
|
246
405
|
customer: customerId,
|
|
@@ -253,6 +412,8 @@ async function listPaymentMethods(customerId, type) {
|
|
|
253
412
|
}
|
|
254
413
|
async function attachPaymentMethod(paymentMethodId, customerId) {
|
|
255
414
|
try {
|
|
415
|
+
validateStripeId(paymentMethodId, "paymentMethod");
|
|
416
|
+
validateStripeId(customerId, "customer");
|
|
256
417
|
const stripe = getStripe();
|
|
257
418
|
const paymentMethod = await stripe.paymentMethods.attach(paymentMethodId, {
|
|
258
419
|
customer: customerId
|
|
@@ -264,6 +425,7 @@ async function attachPaymentMethod(paymentMethodId, customerId) {
|
|
|
264
425
|
}
|
|
265
426
|
async function detachPaymentMethod(paymentMethodId) {
|
|
266
427
|
try {
|
|
428
|
+
validateStripeId(paymentMethodId, "paymentMethod");
|
|
267
429
|
const stripe = getStripe();
|
|
268
430
|
const paymentMethod = await stripe.paymentMethods.detach(paymentMethodId);
|
|
269
431
|
return success(paymentMethod);
|
|
@@ -273,26 +435,31 @@ async function detachPaymentMethod(paymentMethodId) {
|
|
|
273
435
|
}
|
|
274
436
|
|
|
275
437
|
// src/server/customers/index.ts
|
|
276
|
-
async function createCustomer(input) {
|
|
277
|
-
try {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
438
|
+
async function createCustomer(input, options) {
|
|
439
|
+
try {
|
|
440
|
+
if (input.paymentMethodId) validateStripeId(input.paymentMethodId, "paymentMethod");
|
|
441
|
+
if (input.metadata) validateMetadata(input.metadata);
|
|
442
|
+
const stripe = getStripe();
|
|
443
|
+
const customer = await stripe.customers.create(
|
|
444
|
+
{
|
|
445
|
+
email: input.email,
|
|
446
|
+
name: input.name,
|
|
447
|
+
phone: input.phone,
|
|
448
|
+
description: input.description,
|
|
449
|
+
metadata: input.metadata,
|
|
450
|
+
payment_method: input.paymentMethodId,
|
|
451
|
+
invoice_settings: input.paymentMethodId ? { default_payment_method: input.paymentMethodId } : void 0,
|
|
452
|
+
address: input.address ? {
|
|
453
|
+
line1: input.address.line1,
|
|
454
|
+
line2: input.address.line2,
|
|
455
|
+
city: input.address.city,
|
|
456
|
+
state: input.address.state,
|
|
457
|
+
postal_code: input.address.postalCode,
|
|
458
|
+
country: input.address.country
|
|
459
|
+
} : void 0
|
|
460
|
+
},
|
|
461
|
+
options?.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : void 0
|
|
462
|
+
);
|
|
296
463
|
return success(customer);
|
|
297
464
|
} catch (error) {
|
|
298
465
|
return handleStripeError(error);
|
|
@@ -300,6 +467,7 @@ async function createCustomer(input) {
|
|
|
300
467
|
}
|
|
301
468
|
async function retrieveCustomer(customerId) {
|
|
302
469
|
try {
|
|
470
|
+
validateStripeId(customerId, "customer");
|
|
303
471
|
const stripe = getStripe();
|
|
304
472
|
const customer = await stripe.customers.retrieve(customerId, {
|
|
305
473
|
expand: ["subscriptions", "sources"]
|
|
@@ -317,6 +485,9 @@ async function retrieveCustomer(customerId) {
|
|
|
317
485
|
}
|
|
318
486
|
async function updateCustomer(input) {
|
|
319
487
|
try {
|
|
488
|
+
validateStripeId(input.customerId, "customer");
|
|
489
|
+
if (input.defaultPaymentMethodId) validateStripeId(input.defaultPaymentMethodId, "paymentMethod");
|
|
490
|
+
if (input.metadata) validateMetadata(input.metadata);
|
|
320
491
|
const stripe = getStripe();
|
|
321
492
|
const customer = await stripe.customers.update(input.customerId, {
|
|
322
493
|
email: input.email,
|
|
@@ -341,6 +512,7 @@ async function updateCustomer(input) {
|
|
|
341
512
|
}
|
|
342
513
|
async function deleteCustomer(customerId) {
|
|
343
514
|
try {
|
|
515
|
+
validateStripeId(customerId, "customer");
|
|
344
516
|
const stripe = getStripe();
|
|
345
517
|
const deleted = await stripe.customers.del(customerId);
|
|
346
518
|
return success(deleted);
|
|
@@ -352,7 +524,7 @@ async function listCustomers(input) {
|
|
|
352
524
|
try {
|
|
353
525
|
const stripe = getStripe();
|
|
354
526
|
const customers = await stripe.customers.list({
|
|
355
|
-
limit: input?.limit
|
|
527
|
+
limit: sanitizeLimit(input?.limit),
|
|
356
528
|
starting_after: input?.startingAfter,
|
|
357
529
|
ending_before: input?.endingBefore,
|
|
358
530
|
email: input?.email
|
|
@@ -362,26 +534,42 @@ async function listCustomers(input) {
|
|
|
362
534
|
return handleStripeError(error);
|
|
363
535
|
}
|
|
364
536
|
}
|
|
365
|
-
async function searchCustomers(
|
|
537
|
+
async function searchCustomers(input) {
|
|
366
538
|
try {
|
|
539
|
+
const clauses = [];
|
|
540
|
+
if (input.email) clauses.push(`email:"${input.email.replace(/"/g, "")}"`);
|
|
541
|
+
if (input.name) clauses.push(`name:"${input.name.replace(/"/g, "")}"`);
|
|
542
|
+
if (input.phone) clauses.push(`phone:"${input.phone.replace(/"/g, "")}"`);
|
|
543
|
+
if (clauses.length === 0) {
|
|
544
|
+
return {
|
|
545
|
+
data: null,
|
|
546
|
+
error: { message: "At least one search field (email, name, phone) is required", type: "invalid_request_error" }
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
const query = clauses.join(" AND ");
|
|
367
550
|
const stripe = getStripe();
|
|
368
551
|
const customers = await stripe.customers.search({
|
|
369
552
|
query,
|
|
370
|
-
limit: limit
|
|
553
|
+
limit: sanitizeLimit(input.limit)
|
|
371
554
|
});
|
|
372
555
|
return success(customers);
|
|
373
556
|
} catch (error) {
|
|
374
557
|
return handleStripeError(error);
|
|
375
558
|
}
|
|
376
559
|
}
|
|
377
|
-
async function createPortalSession(input) {
|
|
560
|
+
async function createPortalSession(input, options) {
|
|
378
561
|
try {
|
|
562
|
+
validateStripeId(input.customerId, "customer");
|
|
563
|
+
if (input.returnUrl) validateUrl(input.returnUrl, "returnUrl");
|
|
379
564
|
const stripe = getStripe();
|
|
380
|
-
const session = await stripe.billingPortal.sessions.create(
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
565
|
+
const session = await stripe.billingPortal.sessions.create(
|
|
566
|
+
{
|
|
567
|
+
customer: input.customerId,
|
|
568
|
+
return_url: input.returnUrl,
|
|
569
|
+
configuration: input.configuration
|
|
570
|
+
},
|
|
571
|
+
options?.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : void 0
|
|
572
|
+
);
|
|
385
573
|
return success(session);
|
|
386
574
|
} catch (error) {
|
|
387
575
|
return handleStripeError(error);
|
|
@@ -389,23 +577,28 @@ async function createPortalSession(input) {
|
|
|
389
577
|
}
|
|
390
578
|
|
|
391
579
|
// src/server/subscriptions/index.ts
|
|
392
|
-
async function createSubscription(input) {
|
|
580
|
+
async function createSubscription(input, options) {
|
|
393
581
|
try {
|
|
582
|
+
validateStripeId(input.customerId, "customer");
|
|
583
|
+
if (input.metadata) validateMetadata(input.metadata);
|
|
394
584
|
const stripe = getStripe();
|
|
395
585
|
const items = input.items ? input.items.map((item) => ({ price: item.priceId, quantity: item.quantity })) : [{ price: input.priceId, quantity: input.quantity ?? 1 }];
|
|
396
|
-
const subscription = await stripe.subscriptions.create(
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
586
|
+
const subscription = await stripe.subscriptions.create(
|
|
587
|
+
{
|
|
588
|
+
customer: input.customerId,
|
|
589
|
+
items,
|
|
590
|
+
metadata: input.metadata,
|
|
591
|
+
trial_period_days: input.trialPeriodDays,
|
|
592
|
+
coupon: input.couponId,
|
|
593
|
+
promotion_code: input.promotionCodeId,
|
|
594
|
+
payment_behavior: input.paymentBehavior ?? "default_incomplete",
|
|
595
|
+
cancel_at_period_end: input.cancelAtPeriodEnd,
|
|
596
|
+
billing_cycle_anchor: input.billingCycleAnchor,
|
|
597
|
+
proration_behavior: input.prorationBehavior,
|
|
598
|
+
expand: ["latest_invoice.payment_intent"]
|
|
599
|
+
},
|
|
600
|
+
options?.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : void 0
|
|
601
|
+
);
|
|
409
602
|
return success(subscription);
|
|
410
603
|
} catch (error) {
|
|
411
604
|
return handleStripeError(error);
|
|
@@ -413,6 +606,7 @@ async function createSubscription(input) {
|
|
|
413
606
|
}
|
|
414
607
|
async function retrieveSubscription(subscriptionId) {
|
|
415
608
|
try {
|
|
609
|
+
validateStripeId(subscriptionId, "subscription");
|
|
416
610
|
const stripe = getStripe();
|
|
417
611
|
const subscription = await stripe.subscriptions.retrieve(subscriptionId, {
|
|
418
612
|
expand: ["latest_invoice.payment_intent", "default_payment_method"]
|
|
@@ -424,6 +618,8 @@ async function retrieveSubscription(subscriptionId) {
|
|
|
424
618
|
}
|
|
425
619
|
async function updateSubscription(input) {
|
|
426
620
|
try {
|
|
621
|
+
validateStripeId(input.subscriptionId, "subscription");
|
|
622
|
+
if (input.metadata) validateMetadata(input.metadata);
|
|
427
623
|
const stripe = getStripe();
|
|
428
624
|
const params = {
|
|
429
625
|
metadata: input.metadata,
|
|
@@ -446,6 +642,7 @@ async function updateSubscription(input) {
|
|
|
446
642
|
}
|
|
447
643
|
async function cancelSubscription(input) {
|
|
448
644
|
try {
|
|
645
|
+
validateStripeId(input.subscriptionId, "subscription");
|
|
449
646
|
const stripe = getStripe();
|
|
450
647
|
if (input.cancelAtPeriodEnd) {
|
|
451
648
|
const subscription2 = await stripe.subscriptions.update(input.subscriptionId, {
|
|
@@ -470,6 +667,7 @@ async function cancelSubscription(input) {
|
|
|
470
667
|
}
|
|
471
668
|
async function resumeSubscription(subscriptionId) {
|
|
472
669
|
try {
|
|
670
|
+
validateStripeId(subscriptionId, "subscription");
|
|
473
671
|
const stripe = getStripe();
|
|
474
672
|
const subscription = await stripe.subscriptions.update(subscriptionId, {
|
|
475
673
|
cancel_at_period_end: false
|
|
@@ -481,9 +679,10 @@ async function resumeSubscription(subscriptionId) {
|
|
|
481
679
|
}
|
|
482
680
|
async function listSubscriptions(input) {
|
|
483
681
|
try {
|
|
682
|
+
if (input?.customerId) validateStripeId(input.customerId, "customer");
|
|
484
683
|
const stripe = getStripe();
|
|
485
684
|
const subscriptions = await stripe.subscriptions.list({
|
|
486
|
-
limit: input?.limit
|
|
685
|
+
limit: sanitizeLimit(input?.limit),
|
|
487
686
|
starting_after: input?.startingAfter,
|
|
488
687
|
ending_before: input?.endingBefore,
|
|
489
688
|
customer: input?.customerId,
|
|
@@ -496,24 +695,32 @@ async function listSubscriptions(input) {
|
|
|
496
695
|
}
|
|
497
696
|
|
|
498
697
|
// src/server/products/index.ts
|
|
499
|
-
async function createProduct(input) {
|
|
698
|
+
async function createProduct(input, options) {
|
|
500
699
|
try {
|
|
700
|
+
if (input.metadata) validateMetadata(input.metadata);
|
|
701
|
+
if (input.defaultPriceData) {
|
|
702
|
+
validateAmount(input.defaultPriceData.unitAmount, "unitAmount");
|
|
703
|
+
validateCurrency(input.defaultPriceData.currency);
|
|
704
|
+
}
|
|
501
705
|
const stripe = getStripe();
|
|
502
|
-
const product = await stripe.products.create(
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
706
|
+
const product = await stripe.products.create(
|
|
707
|
+
{
|
|
708
|
+
name: input.name,
|
|
709
|
+
description: input.description,
|
|
710
|
+
images: input.images,
|
|
711
|
+
metadata: input.metadata,
|
|
712
|
+
active: input.active,
|
|
713
|
+
default_price_data: input.defaultPriceData ? {
|
|
714
|
+
unit_amount: input.defaultPriceData.unitAmount,
|
|
715
|
+
currency: input.defaultPriceData.currency,
|
|
716
|
+
recurring: input.defaultPriceData.recurring ? {
|
|
717
|
+
interval: input.defaultPriceData.recurring.interval,
|
|
718
|
+
interval_count: input.defaultPriceData.recurring.intervalCount
|
|
719
|
+
} : void 0
|
|
514
720
|
} : void 0
|
|
515
|
-
}
|
|
516
|
-
|
|
721
|
+
},
|
|
722
|
+
options?.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : void 0
|
|
723
|
+
);
|
|
517
724
|
return success(product);
|
|
518
725
|
} catch (error) {
|
|
519
726
|
return handleStripeError(error);
|
|
@@ -521,6 +728,7 @@ async function createProduct(input) {
|
|
|
521
728
|
}
|
|
522
729
|
async function retrieveProduct(productId) {
|
|
523
730
|
try {
|
|
731
|
+
validateStripeId(productId, "product");
|
|
524
732
|
const stripe = getStripe();
|
|
525
733
|
const product = await stripe.products.retrieve(productId);
|
|
526
734
|
return success(product);
|
|
@@ -530,6 +738,8 @@ async function retrieveProduct(productId) {
|
|
|
530
738
|
}
|
|
531
739
|
async function updateProduct(input) {
|
|
532
740
|
try {
|
|
741
|
+
validateStripeId(input.productId, "product");
|
|
742
|
+
if (input.metadata) validateMetadata(input.metadata);
|
|
533
743
|
const stripe = getStripe();
|
|
534
744
|
const product = await stripe.products.update(input.productId, {
|
|
535
745
|
name: input.name,
|
|
@@ -545,6 +755,7 @@ async function updateProduct(input) {
|
|
|
545
755
|
}
|
|
546
756
|
async function archiveProduct(productId) {
|
|
547
757
|
try {
|
|
758
|
+
validateStripeId(productId, "product");
|
|
548
759
|
const stripe = getStripe();
|
|
549
760
|
const product = await stripe.products.update(productId, { active: false });
|
|
550
761
|
return success(product);
|
|
@@ -556,7 +767,7 @@ async function listProducts(input) {
|
|
|
556
767
|
try {
|
|
557
768
|
const stripe = getStripe();
|
|
558
769
|
const products = await stripe.products.list({
|
|
559
|
-
limit: input?.limit
|
|
770
|
+
limit: sanitizeLimit(input?.limit),
|
|
560
771
|
starting_after: input?.startingAfter,
|
|
561
772
|
ending_before: input?.endingBefore,
|
|
562
773
|
active: input?.active
|
|
@@ -566,8 +777,12 @@ async function listProducts(input) {
|
|
|
566
777
|
return handleStripeError(error);
|
|
567
778
|
}
|
|
568
779
|
}
|
|
569
|
-
async function createPrice(input) {
|
|
780
|
+
async function createPrice(input, options) {
|
|
570
781
|
try {
|
|
782
|
+
validateStripeId(input.productId, "product");
|
|
783
|
+
validateCurrency(input.currency);
|
|
784
|
+
if (input.unitAmount !== void 0) validateAmount(input.unitAmount, "unitAmount");
|
|
785
|
+
if (input.metadata) validateMetadata(input.metadata);
|
|
571
786
|
const stripe = getStripe();
|
|
572
787
|
const params = {
|
|
573
788
|
product: input.productId,
|
|
@@ -595,7 +810,10 @@ async function createPrice(input) {
|
|
|
595
810
|
} else {
|
|
596
811
|
params.unit_amount = input.unitAmount;
|
|
597
812
|
}
|
|
598
|
-
const price = await stripe.prices.create(
|
|
813
|
+
const price = await stripe.prices.create(
|
|
814
|
+
params,
|
|
815
|
+
options?.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : void 0
|
|
816
|
+
);
|
|
599
817
|
return success(price);
|
|
600
818
|
} catch (error) {
|
|
601
819
|
return handleStripeError(error);
|
|
@@ -603,6 +821,7 @@ async function createPrice(input) {
|
|
|
603
821
|
}
|
|
604
822
|
async function retrievePrice(priceId) {
|
|
605
823
|
try {
|
|
824
|
+
validateStripeId(priceId, "price");
|
|
606
825
|
const stripe = getStripe();
|
|
607
826
|
const price = await stripe.prices.retrieve(priceId);
|
|
608
827
|
return success(price);
|
|
@@ -612,9 +831,10 @@ async function retrievePrice(priceId) {
|
|
|
612
831
|
}
|
|
613
832
|
async function listPrices(input) {
|
|
614
833
|
try {
|
|
834
|
+
if (input?.productId) validateStripeId(input.productId, "product");
|
|
615
835
|
const stripe = getStripe();
|
|
616
836
|
const prices = await stripe.prices.list({
|
|
617
|
-
limit: input?.limit
|
|
837
|
+
limit: sanitizeLimit(input?.limit),
|
|
618
838
|
starting_after: input?.startingAfter,
|
|
619
839
|
ending_before: input?.endingBefore,
|
|
620
840
|
product: input?.productId,
|
|
@@ -628,6 +848,7 @@ async function listPrices(input) {
|
|
|
628
848
|
}
|
|
629
849
|
async function archivePrice(priceId) {
|
|
630
850
|
try {
|
|
851
|
+
validateStripeId(priceId, "price");
|
|
631
852
|
const stripe = getStripe();
|
|
632
853
|
const price = await stripe.prices.update(priceId, { active: false });
|
|
633
854
|
return success(price);
|
|
@@ -637,17 +858,22 @@ async function archivePrice(priceId) {
|
|
|
637
858
|
}
|
|
638
859
|
|
|
639
860
|
// src/server/invoices/index.ts
|
|
640
|
-
async function createInvoice(input) {
|
|
641
|
-
try {
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
861
|
+
async function createInvoice(input, options) {
|
|
862
|
+
try {
|
|
863
|
+
validateStripeId(input.customerId, "customer");
|
|
864
|
+
if (input.metadata) validateMetadata(input.metadata);
|
|
865
|
+
const stripe = getStripe();
|
|
866
|
+
const invoice = await stripe.invoices.create(
|
|
867
|
+
{
|
|
868
|
+
customer: input.customerId,
|
|
869
|
+
collection_method: input.collectionMethod ?? "charge_automatically",
|
|
870
|
+
days_until_due: input.daysUntilDue,
|
|
871
|
+
metadata: input.metadata,
|
|
872
|
+
description: input.description,
|
|
873
|
+
auto_advance: input.autoAdvance
|
|
874
|
+
},
|
|
875
|
+
options?.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : void 0
|
|
876
|
+
);
|
|
651
877
|
return success(invoice);
|
|
652
878
|
} catch (error) {
|
|
653
879
|
return handleStripeError(error);
|
|
@@ -655,6 +881,7 @@ async function createInvoice(input) {
|
|
|
655
881
|
}
|
|
656
882
|
async function retrieveInvoice(invoiceId) {
|
|
657
883
|
try {
|
|
884
|
+
validateStripeId(invoiceId, "invoice");
|
|
658
885
|
const stripe = getStripe();
|
|
659
886
|
const invoice = await stripe.invoices.retrieve(invoiceId);
|
|
660
887
|
return success(invoice);
|
|
@@ -664,6 +891,7 @@ async function retrieveInvoice(invoiceId) {
|
|
|
664
891
|
}
|
|
665
892
|
async function finalizeInvoice(invoiceId) {
|
|
666
893
|
try {
|
|
894
|
+
validateStripeId(invoiceId, "invoice");
|
|
667
895
|
const stripe = getStripe();
|
|
668
896
|
const invoice = await stripe.invoices.finalizeInvoice(invoiceId);
|
|
669
897
|
return success(invoice);
|
|
@@ -673,6 +901,7 @@ async function finalizeInvoice(invoiceId) {
|
|
|
673
901
|
}
|
|
674
902
|
async function sendInvoice(invoiceId) {
|
|
675
903
|
try {
|
|
904
|
+
validateStripeId(invoiceId, "invoice");
|
|
676
905
|
const stripe = getStripe();
|
|
677
906
|
const invoice = await stripe.invoices.sendInvoice(invoiceId);
|
|
678
907
|
return success(invoice);
|
|
@@ -682,6 +911,7 @@ async function sendInvoice(invoiceId) {
|
|
|
682
911
|
}
|
|
683
912
|
async function payInvoice(invoiceId) {
|
|
684
913
|
try {
|
|
914
|
+
validateStripeId(invoiceId, "invoice");
|
|
685
915
|
const stripe = getStripe();
|
|
686
916
|
const invoice = await stripe.invoices.pay(invoiceId);
|
|
687
917
|
return success(invoice);
|
|
@@ -691,6 +921,7 @@ async function payInvoice(invoiceId) {
|
|
|
691
921
|
}
|
|
692
922
|
async function voidInvoice(invoiceId) {
|
|
693
923
|
try {
|
|
924
|
+
validateStripeId(invoiceId, "invoice");
|
|
694
925
|
const stripe = getStripe();
|
|
695
926
|
const invoice = await stripe.invoices.voidInvoice(invoiceId);
|
|
696
927
|
return success(invoice);
|
|
@@ -700,9 +931,10 @@ async function voidInvoice(invoiceId) {
|
|
|
700
931
|
}
|
|
701
932
|
async function listInvoices(input) {
|
|
702
933
|
try {
|
|
934
|
+
if (input?.customerId) validateStripeId(input.customerId, "customer");
|
|
703
935
|
const stripe = getStripe();
|
|
704
936
|
const invoices = await stripe.invoices.list({
|
|
705
|
-
limit: input?.limit
|
|
937
|
+
limit: sanitizeLimit(input?.limit),
|
|
706
938
|
starting_after: input?.startingAfter,
|
|
707
939
|
ending_before: input?.endingBefore,
|
|
708
940
|
customer: input?.customerId,
|
|
@@ -715,6 +947,8 @@ async function listInvoices(input) {
|
|
|
715
947
|
}
|
|
716
948
|
async function getUpcomingInvoice(customerId, subscriptionId) {
|
|
717
949
|
try {
|
|
950
|
+
validateStripeId(customerId, "customer");
|
|
951
|
+
if (subscriptionId) validateStripeId(subscriptionId, "subscription");
|
|
718
952
|
const stripe = getStripe();
|
|
719
953
|
const invoice = await stripe.invoices.retrieveUpcoming({
|
|
720
954
|
customer: customerId,
|
|
@@ -725,19 +959,28 @@ async function getUpcomingInvoice(customerId, subscriptionId) {
|
|
|
725
959
|
return handleStripeError(error);
|
|
726
960
|
}
|
|
727
961
|
}
|
|
728
|
-
async function createInvoiceItem(input) {
|
|
962
|
+
async function createInvoiceItem(input, options) {
|
|
729
963
|
try {
|
|
964
|
+
validateStripeId(input.customerId, "customer");
|
|
965
|
+
if (input.invoiceId) validateStripeId(input.invoiceId, "invoice");
|
|
966
|
+
if (input.priceId) validateStripeId(input.priceId, "price");
|
|
967
|
+
if (input.amount !== void 0) validateAmount(input.amount, "invoice item amount");
|
|
968
|
+
if (input.currency) validateCurrency(input.currency);
|
|
969
|
+
if (input.metadata) validateMetadata(input.metadata);
|
|
730
970
|
const stripe = getStripe();
|
|
731
|
-
const invoiceItem = await stripe.invoiceItems.create(
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
971
|
+
const invoiceItem = await stripe.invoiceItems.create(
|
|
972
|
+
{
|
|
973
|
+
customer: input.customerId,
|
|
974
|
+
invoice: input.invoiceId,
|
|
975
|
+
price: input.priceId,
|
|
976
|
+
amount: input.amount,
|
|
977
|
+
currency: input.currency,
|
|
978
|
+
description: input.description,
|
|
979
|
+
quantity: input.quantity,
|
|
980
|
+
metadata: input.metadata
|
|
981
|
+
},
|
|
982
|
+
options?.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : void 0
|
|
983
|
+
);
|
|
741
984
|
return success(invoiceItem);
|
|
742
985
|
} catch (error) {
|
|
743
986
|
return handleStripeError(error);
|
|
@@ -745,16 +988,22 @@ async function createInvoiceItem(input) {
|
|
|
745
988
|
}
|
|
746
989
|
|
|
747
990
|
// src/server/refunds/index.ts
|
|
748
|
-
async function createRefund(input) {
|
|
749
|
-
try {
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
991
|
+
async function createRefund(input, options) {
|
|
992
|
+
try {
|
|
993
|
+
if (input.paymentIntentId) validateStripeId(input.paymentIntentId, "paymentIntent");
|
|
994
|
+
if (input.amount !== void 0) validateAmount(input.amount, "refund amount");
|
|
995
|
+
if (input.metadata) validateMetadata(input.metadata);
|
|
996
|
+
const stripe = getStripe();
|
|
997
|
+
const refund = await stripe.refunds.create(
|
|
998
|
+
{
|
|
999
|
+
payment_intent: input.paymentIntentId,
|
|
1000
|
+
charge: input.chargeId,
|
|
1001
|
+
amount: input.amount,
|
|
1002
|
+
reason: input.reason,
|
|
1003
|
+
metadata: input.metadata
|
|
1004
|
+
},
|
|
1005
|
+
options?.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : void 0
|
|
1006
|
+
);
|
|
758
1007
|
return success(refund);
|
|
759
1008
|
} catch (error) {
|
|
760
1009
|
return handleStripeError(error);
|
|
@@ -762,6 +1011,7 @@ async function createRefund(input) {
|
|
|
762
1011
|
}
|
|
763
1012
|
async function retrieveRefund(refundId) {
|
|
764
1013
|
try {
|
|
1014
|
+
validateStripeId(refundId, "refund");
|
|
765
1015
|
const stripe = getStripe();
|
|
766
1016
|
const refund = await stripe.refunds.retrieve(refundId);
|
|
767
1017
|
return success(refund);
|
|
@@ -771,9 +1021,10 @@ async function retrieveRefund(refundId) {
|
|
|
771
1021
|
}
|
|
772
1022
|
async function listRefunds(input) {
|
|
773
1023
|
try {
|
|
1024
|
+
if (input?.paymentIntentId) validateStripeId(input.paymentIntentId, "paymentIntent");
|
|
774
1025
|
const stripe = getStripe();
|
|
775
1026
|
const refunds = await stripe.refunds.list({
|
|
776
|
-
limit: input?.limit
|
|
1027
|
+
limit: sanitizeLimit(input?.limit),
|
|
777
1028
|
starting_after: input?.startingAfter,
|
|
778
1029
|
ending_before: input?.endingBefore,
|
|
779
1030
|
payment_intent: input?.paymentIntentId,
|
|
@@ -786,6 +1037,7 @@ async function listRefunds(input) {
|
|
|
786
1037
|
}
|
|
787
1038
|
async function retrieveDispute(disputeId) {
|
|
788
1039
|
try {
|
|
1040
|
+
validateStripeId(disputeId, "dispute");
|
|
789
1041
|
const stripe = getStripe();
|
|
790
1042
|
const dispute = await stripe.disputes.retrieve(disputeId);
|
|
791
1043
|
return success(dispute);
|
|
@@ -795,6 +1047,8 @@ async function retrieveDispute(disputeId) {
|
|
|
795
1047
|
}
|
|
796
1048
|
async function updateDispute(input) {
|
|
797
1049
|
try {
|
|
1050
|
+
validateStripeId(input.disputeId, "dispute");
|
|
1051
|
+
if (input.metadata) validateMetadata(input.metadata);
|
|
798
1052
|
const stripe = getStripe();
|
|
799
1053
|
const dispute = await stripe.disputes.update(input.disputeId, {
|
|
800
1054
|
evidence: input.evidence ? {
|
|
@@ -816,6 +1070,7 @@ async function updateDispute(input) {
|
|
|
816
1070
|
}
|
|
817
1071
|
async function closeDispute(disputeId) {
|
|
818
1072
|
try {
|
|
1073
|
+
validateStripeId(disputeId, "dispute");
|
|
819
1074
|
const stripe = getStripe();
|
|
820
1075
|
const dispute = await stripe.disputes.close(disputeId);
|
|
821
1076
|
return success(dispute);
|
|
@@ -827,7 +1082,7 @@ async function listDisputes(input) {
|
|
|
827
1082
|
try {
|
|
828
1083
|
const stripe = getStripe();
|
|
829
1084
|
const disputes = await stripe.disputes.list({
|
|
830
|
-
limit: input?.limit
|
|
1085
|
+
limit: sanitizeLimit(input?.limit),
|
|
831
1086
|
starting_after: input?.startingAfter,
|
|
832
1087
|
ending_before: input?.endingBefore
|
|
833
1088
|
});
|
|
@@ -838,17 +1093,21 @@ async function listDisputes(input) {
|
|
|
838
1093
|
}
|
|
839
1094
|
|
|
840
1095
|
// src/server/connect/index.ts
|
|
841
|
-
async function createConnectAccount(input) {
|
|
842
|
-
try {
|
|
843
|
-
|
|
844
|
-
const
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
1096
|
+
async function createConnectAccount(input, options) {
|
|
1097
|
+
try {
|
|
1098
|
+
if (input.metadata) validateMetadata(input.metadata);
|
|
1099
|
+
const stripe = getStripe();
|
|
1100
|
+
const account = await stripe.accounts.create(
|
|
1101
|
+
{
|
|
1102
|
+
type: input.type,
|
|
1103
|
+
country: input.country,
|
|
1104
|
+
email: input.email,
|
|
1105
|
+
capabilities: input.capabilities,
|
|
1106
|
+
business_type: input.businessType,
|
|
1107
|
+
metadata: input.metadata
|
|
1108
|
+
},
|
|
1109
|
+
options?.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : void 0
|
|
1110
|
+
);
|
|
852
1111
|
return success(account);
|
|
853
1112
|
} catch (error) {
|
|
854
1113
|
return handleStripeError(error);
|
|
@@ -856,6 +1115,7 @@ async function createConnectAccount(input) {
|
|
|
856
1115
|
}
|
|
857
1116
|
async function retrieveConnectAccount(accountId) {
|
|
858
1117
|
try {
|
|
1118
|
+
validateStripeId(accountId, "account");
|
|
859
1119
|
const stripe = getStripe();
|
|
860
1120
|
const account = await stripe.accounts.retrieve(accountId);
|
|
861
1121
|
return success(account);
|
|
@@ -865,6 +1125,7 @@ async function retrieveConnectAccount(accountId) {
|
|
|
865
1125
|
}
|
|
866
1126
|
async function deleteConnectAccount(accountId) {
|
|
867
1127
|
try {
|
|
1128
|
+
validateStripeId(accountId, "account");
|
|
868
1129
|
const stripe = getStripe();
|
|
869
1130
|
const deleted = await stripe.accounts.del(accountId);
|
|
870
1131
|
return success(deleted);
|
|
@@ -876,7 +1137,7 @@ async function listConnectAccounts(input) {
|
|
|
876
1137
|
try {
|
|
877
1138
|
const stripe = getStripe();
|
|
878
1139
|
const accounts = await stripe.accounts.list({
|
|
879
|
-
limit: input?.limit
|
|
1140
|
+
limit: sanitizeLimit(input?.limit),
|
|
880
1141
|
starting_after: input?.startingAfter,
|
|
881
1142
|
ending_before: input?.endingBefore
|
|
882
1143
|
});
|
|
@@ -887,6 +1148,9 @@ async function listConnectAccounts(input) {
|
|
|
887
1148
|
}
|
|
888
1149
|
async function createAccountLink(input) {
|
|
889
1150
|
try {
|
|
1151
|
+
validateStripeId(input.accountId, "account");
|
|
1152
|
+
validateUrl(input.refreshUrl, "refreshUrl");
|
|
1153
|
+
validateUrl(input.returnUrl, "returnUrl");
|
|
890
1154
|
const stripe = getStripe();
|
|
891
1155
|
const accountLink = await stripe.accountLinks.create({
|
|
892
1156
|
account: input.accountId,
|
|
@@ -899,17 +1163,24 @@ async function createAccountLink(input) {
|
|
|
899
1163
|
return handleStripeError(error);
|
|
900
1164
|
}
|
|
901
1165
|
}
|
|
902
|
-
async function createTransfer(input) {
|
|
1166
|
+
async function createTransfer(input, options) {
|
|
903
1167
|
try {
|
|
1168
|
+
validateAmount(input.amount, "transfer amount");
|
|
1169
|
+
validateCurrency(input.currency);
|
|
1170
|
+
validateStripeId(input.destinationAccountId, "account");
|
|
1171
|
+
if (input.metadata) validateMetadata(input.metadata);
|
|
904
1172
|
const stripe = getStripe();
|
|
905
|
-
const transfer = await stripe.transfers.create(
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
1173
|
+
const transfer = await stripe.transfers.create(
|
|
1174
|
+
{
|
|
1175
|
+
amount: input.amount,
|
|
1176
|
+
currency: input.currency,
|
|
1177
|
+
destination: input.destinationAccountId,
|
|
1178
|
+
description: input.description,
|
|
1179
|
+
metadata: input.metadata,
|
|
1180
|
+
source_transaction: input.sourceTransaction
|
|
1181
|
+
},
|
|
1182
|
+
options?.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : void 0
|
|
1183
|
+
);
|
|
913
1184
|
return success(transfer);
|
|
914
1185
|
} catch (error) {
|
|
915
1186
|
return handleStripeError(error);
|
|
@@ -917,9 +1188,10 @@ async function createTransfer(input) {
|
|
|
917
1188
|
}
|
|
918
1189
|
async function listTransfers(input) {
|
|
919
1190
|
try {
|
|
1191
|
+
if (input?.destinationAccountId) validateStripeId(input.destinationAccountId, "account");
|
|
920
1192
|
const stripe = getStripe();
|
|
921
1193
|
const transfers = await stripe.transfers.list({
|
|
922
|
-
limit: input?.limit
|
|
1194
|
+
limit: sanitizeLimit(input?.limit),
|
|
923
1195
|
starting_after: input?.startingAfter,
|
|
924
1196
|
ending_before: input?.endingBefore,
|
|
925
1197
|
destination: input?.destinationAccountId
|
|
@@ -929,14 +1201,20 @@ async function listTransfers(input) {
|
|
|
929
1201
|
return handleStripeError(error);
|
|
930
1202
|
}
|
|
931
1203
|
}
|
|
932
|
-
async function createPayout(amount, currency, metadata) {
|
|
1204
|
+
async function createPayout(amount, currency, metadata, options) {
|
|
933
1205
|
try {
|
|
1206
|
+
validateAmount(amount, "payout amount");
|
|
1207
|
+
const normalizedCurrency = validateCurrency(currency);
|
|
1208
|
+
if (metadata) validateMetadata(metadata);
|
|
934
1209
|
const stripe = getStripe();
|
|
935
|
-
const payout = await stripe.payouts.create(
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
1210
|
+
const payout = await stripe.payouts.create(
|
|
1211
|
+
{
|
|
1212
|
+
amount,
|
|
1213
|
+
currency: normalizedCurrency,
|
|
1214
|
+
metadata
|
|
1215
|
+
},
|
|
1216
|
+
options?.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : void 0
|
|
1217
|
+
);
|
|
940
1218
|
return success(payout);
|
|
941
1219
|
} catch (error) {
|
|
942
1220
|
return handleStripeError(error);
|
|
@@ -946,7 +1224,7 @@ async function listPayouts(input) {
|
|
|
946
1224
|
try {
|
|
947
1225
|
const stripe = getStripe();
|
|
948
1226
|
const payouts = await stripe.payouts.list({
|
|
949
|
-
limit: input?.limit
|
|
1227
|
+
limit: sanitizeLimit(input?.limit),
|
|
950
1228
|
starting_after: input?.startingAfter,
|
|
951
1229
|
ending_before: input?.endingBefore,
|
|
952
1230
|
status: input?.status
|
|
@@ -969,7 +1247,7 @@ async function listBalanceTransactions(input) {
|
|
|
969
1247
|
try {
|
|
970
1248
|
const stripe = getStripe();
|
|
971
1249
|
const transactions = await stripe.balanceTransactions.list({
|
|
972
|
-
limit: input?.limit
|
|
1250
|
+
limit: sanitizeLimit(input?.limit),
|
|
973
1251
|
starting_after: input?.startingAfter,
|
|
974
1252
|
ending_before: input?.endingBefore,
|
|
975
1253
|
type: input?.type
|
|
@@ -981,20 +1259,26 @@ async function listBalanceTransactions(input) {
|
|
|
981
1259
|
}
|
|
982
1260
|
|
|
983
1261
|
// src/server/coupons/index.ts
|
|
984
|
-
async function createCoupon(input) {
|
|
985
|
-
try {
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
1262
|
+
async function createCoupon(input, options) {
|
|
1263
|
+
try {
|
|
1264
|
+
if (input.amountOff !== void 0) validateAmount(input.amountOff, "amountOff");
|
|
1265
|
+
if (input.currency) validateCurrency(input.currency);
|
|
1266
|
+
if (input.metadata) validateMetadata(input.metadata);
|
|
1267
|
+
const stripe = getStripe();
|
|
1268
|
+
const coupon = await stripe.coupons.create(
|
|
1269
|
+
{
|
|
1270
|
+
percent_off: input.percentOff,
|
|
1271
|
+
amount_off: input.amountOff,
|
|
1272
|
+
currency: input.currency,
|
|
1273
|
+
duration: input.duration,
|
|
1274
|
+
duration_in_months: input.durationInMonths,
|
|
1275
|
+
max_redemptions: input.maxRedemptions,
|
|
1276
|
+
redeem_by: input.redeemBy,
|
|
1277
|
+
name: input.name,
|
|
1278
|
+
metadata: input.metadata
|
|
1279
|
+
},
|
|
1280
|
+
options?.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : void 0
|
|
1281
|
+
);
|
|
998
1282
|
return success(coupon);
|
|
999
1283
|
} catch (error) {
|
|
1000
1284
|
return handleStripeError(error);
|
|
@@ -1002,6 +1286,7 @@ async function createCoupon(input) {
|
|
|
1002
1286
|
}
|
|
1003
1287
|
async function retrieveCoupon(couponId) {
|
|
1004
1288
|
try {
|
|
1289
|
+
validateStripeId(couponId, "coupon");
|
|
1005
1290
|
const stripe = getStripe();
|
|
1006
1291
|
const coupon = await stripe.coupons.retrieve(couponId);
|
|
1007
1292
|
return success(coupon);
|
|
@@ -1011,6 +1296,7 @@ async function retrieveCoupon(couponId) {
|
|
|
1011
1296
|
}
|
|
1012
1297
|
async function deleteCoupon(couponId) {
|
|
1013
1298
|
try {
|
|
1299
|
+
validateStripeId(couponId, "coupon");
|
|
1014
1300
|
const stripe = getStripe();
|
|
1015
1301
|
const deleted = await stripe.coupons.del(couponId);
|
|
1016
1302
|
return success(deleted);
|
|
@@ -1022,7 +1308,7 @@ async function listCoupons(input) {
|
|
|
1022
1308
|
try {
|
|
1023
1309
|
const stripe = getStripe();
|
|
1024
1310
|
const coupons = await stripe.coupons.list({
|
|
1025
|
-
limit: input?.limit
|
|
1311
|
+
limit: sanitizeLimit(input?.limit),
|
|
1026
1312
|
starting_after: input?.startingAfter,
|
|
1027
1313
|
ending_before: input?.endingBefore
|
|
1028
1314
|
});
|
|
@@ -1031,22 +1317,32 @@ async function listCoupons(input) {
|
|
|
1031
1317
|
return handleStripeError(error);
|
|
1032
1318
|
}
|
|
1033
1319
|
}
|
|
1034
|
-
async function createPromotionCode(input) {
|
|
1320
|
+
async function createPromotionCode(input, options) {
|
|
1035
1321
|
try {
|
|
1322
|
+
if (input.metadata) validateMetadata(input.metadata);
|
|
1323
|
+
if (input.restrictions?.minimumAmountCurrency) {
|
|
1324
|
+
validateCurrency(input.restrictions.minimumAmountCurrency);
|
|
1325
|
+
}
|
|
1326
|
+
if (input.restrictions?.minimumAmount !== void 0) {
|
|
1327
|
+
validateAmount(input.restrictions.minimumAmount, "minimumAmount");
|
|
1328
|
+
}
|
|
1036
1329
|
const stripe = getStripe();
|
|
1037
|
-
const promotionCode = await stripe.promotionCodes.create(
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1330
|
+
const promotionCode = await stripe.promotionCodes.create(
|
|
1331
|
+
{
|
|
1332
|
+
coupon: input.couponId,
|
|
1333
|
+
code: input.code,
|
|
1334
|
+
active: input.active,
|
|
1335
|
+
max_redemptions: input.maxRedemptions,
|
|
1336
|
+
expires_at: input.expiresAt,
|
|
1337
|
+
metadata: input.metadata,
|
|
1338
|
+
restrictions: input.restrictions ? {
|
|
1339
|
+
first_time_transaction: input.restrictions.firstTimeTransaction,
|
|
1340
|
+
minimum_amount: input.restrictions.minimumAmount,
|
|
1341
|
+
minimum_amount_currency: input.restrictions.minimumAmountCurrency
|
|
1342
|
+
} : void 0
|
|
1343
|
+
},
|
|
1344
|
+
options?.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : void 0
|
|
1345
|
+
);
|
|
1050
1346
|
return success(promotionCode);
|
|
1051
1347
|
} catch (error) {
|
|
1052
1348
|
return handleStripeError(error);
|
|
@@ -1054,6 +1350,7 @@ async function createPromotionCode(input) {
|
|
|
1054
1350
|
}
|
|
1055
1351
|
async function retrievePromotionCode(promotionCodeId) {
|
|
1056
1352
|
try {
|
|
1353
|
+
validateStripeId(promotionCodeId, "promotionCode");
|
|
1057
1354
|
const stripe = getStripe();
|
|
1058
1355
|
const promotionCode = await stripe.promotionCodes.retrieve(promotionCodeId);
|
|
1059
1356
|
return success(promotionCode);
|
|
@@ -1065,7 +1362,7 @@ async function listPromotionCodes(input) {
|
|
|
1065
1362
|
try {
|
|
1066
1363
|
const stripe = getStripe();
|
|
1067
1364
|
const promotionCodes = await stripe.promotionCodes.list({
|
|
1068
|
-
limit: input?.limit
|
|
1365
|
+
limit: sanitizeLimit(input?.limit),
|
|
1069
1366
|
starting_after: input?.startingAfter,
|
|
1070
1367
|
ending_before: input?.endingBefore,
|
|
1071
1368
|
coupon: input?.couponId,
|
|
@@ -1119,6 +1416,9 @@ function createWebhookHandler(config) {
|
|
|
1119
1416
|
function createNextWebhookHandler(config) {
|
|
1120
1417
|
const handler = createWebhookHandler(config);
|
|
1121
1418
|
return async function POST(request) {
|
|
1419
|
+
if (request.method !== "POST") {
|
|
1420
|
+
return new Response(null, { status: 405 });
|
|
1421
|
+
}
|
|
1122
1422
|
try {
|
|
1123
1423
|
const contentLength = request.headers.get("content-length");
|
|
1124
1424
|
if (contentLength && parseInt(contentLength, 10) > MAX_BODY_SIZE) {
|
|
@@ -1128,6 +1428,12 @@ function createNextWebhookHandler(config) {
|
|
|
1128
1428
|
});
|
|
1129
1429
|
}
|
|
1130
1430
|
const body = await request.text();
|
|
1431
|
+
if (body.length > MAX_BODY_SIZE) {
|
|
1432
|
+
return new Response(JSON.stringify({ error: "Webhook body too large" }), {
|
|
1433
|
+
status: 413,
|
|
1434
|
+
headers: { "Content-Type": "application/json" }
|
|
1435
|
+
});
|
|
1436
|
+
}
|
|
1131
1437
|
const signature = request.headers.get("stripe-signature");
|
|
1132
1438
|
if (!signature) {
|
|
1133
1439
|
return new Response(JSON.stringify({ error: "Missing stripe-signature header" }), {
|
|
@@ -1141,8 +1447,8 @@ function createNextWebhookHandler(config) {
|
|
|
1141
1447
|
headers: { "Content-Type": "application/json" }
|
|
1142
1448
|
});
|
|
1143
1449
|
} catch (error) {
|
|
1144
|
-
|
|
1145
|
-
return new Response(JSON.stringify({ error:
|
|
1450
|
+
console.error("[@stripe-sdk/core] Webhook error:", error instanceof Error ? error.message : "Unknown error");
|
|
1451
|
+
return new Response(JSON.stringify({ error: "Webhook processing failed" }), {
|
|
1146
1452
|
status: 400,
|
|
1147
1453
|
headers: { "Content-Type": "application/json" }
|
|
1148
1454
|
});
|
|
@@ -1166,8 +1472,8 @@ function createPagesWebhookHandler(webhookConfig) {
|
|
|
1166
1472
|
const result = await handler(body, signature);
|
|
1167
1473
|
res.status(200).json(result);
|
|
1168
1474
|
} catch (error) {
|
|
1169
|
-
|
|
1170
|
-
res.status(400).json({ error:
|
|
1475
|
+
console.error("[@stripe-sdk/core] Webhook error:", error instanceof Error ? error.message : "Unknown error");
|
|
1476
|
+
res.status(400).json({ error: "Webhook processing failed" });
|
|
1171
1477
|
}
|
|
1172
1478
|
};
|
|
1173
1479
|
}
|
|
@@ -1195,16 +1501,21 @@ function getRawBody(req) {
|
|
|
1195
1501
|
}
|
|
1196
1502
|
const chunks = [];
|
|
1197
1503
|
let totalLength = 0;
|
|
1504
|
+
let rejected = false;
|
|
1198
1505
|
req.on("data", (chunk) => {
|
|
1506
|
+
if (rejected) return;
|
|
1199
1507
|
const buf = Buffer.from(chunk);
|
|
1200
1508
|
totalLength += buf.length;
|
|
1201
1509
|
if (totalLength > MAX_BODY_SIZE) {
|
|
1510
|
+
rejected = true;
|
|
1202
1511
|
reject(new Error("Webhook body too large"));
|
|
1203
1512
|
return;
|
|
1204
1513
|
}
|
|
1205
1514
|
chunks.push(buf);
|
|
1206
1515
|
});
|
|
1207
|
-
req.on("end", () =>
|
|
1516
|
+
req.on("end", () => {
|
|
1517
|
+
if (!rejected) resolve(Buffer.concat(chunks).toString("utf8"));
|
|
1518
|
+
});
|
|
1208
1519
|
req.on("error", reject);
|
|
1209
1520
|
});
|
|
1210
1521
|
}
|
|
@@ -1286,5 +1597,3 @@ exports.updateDispute = updateDispute;
|
|
|
1286
1597
|
exports.updateProduct = updateProduct;
|
|
1287
1598
|
exports.updateSubscription = updateSubscription;
|
|
1288
1599
|
exports.voidInvoice = voidInvoice;
|
|
1289
|
-
//# sourceMappingURL=index.js.map
|
|
1290
|
-
//# sourceMappingURL=index.js.map
|