@paykit-sdk/stripe 1.1.9 → 1.1.93
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 +48 -41
- package/dist/index.js +343 -80
- package/dist/index.mjs +344 -81
- package/dist/stripe-provider.d.mts +2 -1
- package/dist/stripe-provider.d.ts +2 -1
- package/dist/stripe-provider.js +333 -78
- package/dist/stripe-provider.mjs +334 -79
- package/package.json +9 -10
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { schema, validateRequiredKeys, AbstractPayKitProvider,
|
|
1
|
+
import { schema, validateRequiredKeys, AbstractPayKitProvider, createCheckoutSchema, ValidationError, stringifyMetadataValues, InvalidTypeError, updateCheckoutSchema, ResourceNotFoundError, createCustomerSchema, createSubscriptionSchema, updateSubscriptionSchema, retrieveSubscriptionSchema, createPaymentSchema, PAYKIT_METADATA_KEY, updatePaymentSchema, retrievePaymentSchema, tryCatchAsync, deletePaymentSchema, capturePaymentSchema, createRefundSchema, WebhookError, paykitEvent$InboundSchema, billingModeSchema, omitInternalMetadata, invoiceStatusSchema } from '@paykit-sdk/core';
|
|
2
2
|
import Stripe from 'stripe';
|
|
3
3
|
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -4046,13 +4046,16 @@ var coerce = {
|
|
|
4046
4046
|
date: (arg) => ZodDate.create({ ...arg, coerce: true })
|
|
4047
4047
|
};
|
|
4048
4048
|
var NEVER = INVALID;
|
|
4049
|
-
var paykitCheckout$InboundSchema = (checkout) => {
|
|
4049
|
+
var paykitCheckout$InboundSchema = (checkout, lineItems) => {
|
|
4050
4050
|
return {
|
|
4051
4051
|
id: checkout.id,
|
|
4052
4052
|
customer: typeof checkout.customer === "string" ? checkout.customer : checkout.customer?.id ?? "",
|
|
4053
4053
|
session_type: checkout.mode === "subscription" ? "recurring" : "one_time",
|
|
4054
4054
|
payment_url: checkout.url,
|
|
4055
|
-
products:
|
|
4055
|
+
products: lineItems.map((item) => ({
|
|
4056
|
+
id: item.id,
|
|
4057
|
+
quantity: item.quantity
|
|
4058
|
+
})),
|
|
4056
4059
|
currency: checkout.currency,
|
|
4057
4060
|
amount: checkout.amount_total,
|
|
4058
4061
|
subscription: null,
|
|
@@ -4071,10 +4074,13 @@ var paykitCustomer$InboundSchema = (customer) => {
|
|
|
4071
4074
|
var paykitSubscription$InboundSchema = (subscription) => {
|
|
4072
4075
|
const status = (() => {
|
|
4073
4076
|
if (["active", "trialing"].includes(subscription.status)) return "active";
|
|
4074
|
-
if (["incomplete_expired", "incomplete", "past_due"].includes(subscription.status))
|
|
4077
|
+
if (["incomplete_expired", "incomplete", "past_due"].includes(subscription.status)) {
|
|
4078
|
+
return "past_due";
|
|
4079
|
+
}
|
|
4075
4080
|
if (["canceled"].includes(subscription.status)) return "canceled";
|
|
4076
4081
|
if (["expired"].includes(subscription.status)) return "expired";
|
|
4077
|
-
|
|
4082
|
+
console.log(`Unknown subscription status: ${subscription.status}`);
|
|
4083
|
+
return "pending";
|
|
4078
4084
|
})();
|
|
4079
4085
|
const metadata = omitInternalMetadata(subscription.metadata ?? {});
|
|
4080
4086
|
return {
|
|
@@ -4094,7 +4100,8 @@ var paykitSubscription$InboundSchema = (subscription) => {
|
|
|
4094
4100
|
var paykitInvoice$InboundSchema = (invoice) => {
|
|
4095
4101
|
const status = (() => {
|
|
4096
4102
|
if (invoice.status == "paid") return "paid";
|
|
4097
|
-
if (["draft", "open", "uncollectible", "void"].includes(invoice.status))
|
|
4103
|
+
if (["draft", "open", "uncollectible", "void"].includes(invoice.status))
|
|
4104
|
+
return "open";
|
|
4098
4105
|
throw new Error(`Unknown status: ${invoice.status}`);
|
|
4099
4106
|
})();
|
|
4100
4107
|
const customerId = (() => {
|
|
@@ -4108,7 +4115,10 @@ var paykitInvoice$InboundSchema = (invoice) => {
|
|
|
4108
4115
|
customer: customerId,
|
|
4109
4116
|
billing_mode: invoice.billingMode,
|
|
4110
4117
|
amount_paid: invoice.amount_paid,
|
|
4111
|
-
line_items: invoice.lines.data.map((line) => ({
|
|
4118
|
+
line_items: invoice.lines.data.map((line) => ({
|
|
4119
|
+
id: line.id,
|
|
4120
|
+
quantity: line.quantity
|
|
4121
|
+
})),
|
|
4112
4122
|
subscription_id: invoice.parent?.subscription_details?.subscription?.toString() ?? null,
|
|
4113
4123
|
status,
|
|
4114
4124
|
paid_at: new Date(invoice.created * 1e3).toISOString(),
|
|
@@ -4142,6 +4152,7 @@ var stripeToPaykitStatus = (status) => {
|
|
|
4142
4152
|
}
|
|
4143
4153
|
};
|
|
4144
4154
|
var paykitPayment$InboundSchema = (intent) => {
|
|
4155
|
+
const itemId = JSON.parse(intent.metadata?.[PAYKIT_METADATA_KEY] ?? "{}").itemId;
|
|
4145
4156
|
return {
|
|
4146
4157
|
id: intent.id,
|
|
4147
4158
|
amount: intent.amount,
|
|
@@ -4149,7 +4160,7 @@ var paykitPayment$InboundSchema = (intent) => {
|
|
|
4149
4160
|
customer: intent.customer ?? "",
|
|
4150
4161
|
status: stripeToPaykitStatus(intent.status),
|
|
4151
4162
|
metadata: omitInternalMetadata(intent.metadata ?? {}),
|
|
4152
|
-
|
|
4163
|
+
item_id: itemId
|
|
4153
4164
|
};
|
|
4154
4165
|
};
|
|
4155
4166
|
var paykitRefund$InboundSchema = (refund) => {
|
|
@@ -4161,6 +4172,22 @@ var paykitRefund$InboundSchema = (refund) => {
|
|
|
4161
4172
|
metadata: omitInternalMetadata(refund.metadata ?? {})
|
|
4162
4173
|
};
|
|
4163
4174
|
};
|
|
4175
|
+
var paykitRefundReason$OutboundSchema = (reason) => {
|
|
4176
|
+
if (!reason) return void 0;
|
|
4177
|
+
const normalized = reason.toLowerCase().trim();
|
|
4178
|
+
if (/duplicate|duplicated|double.*charge|charged.*twice/i.test(normalized)) {
|
|
4179
|
+
return "duplicate";
|
|
4180
|
+
}
|
|
4181
|
+
if (/fraud|fraudulent|unauthorized|scam|stolen.*card|not.*authorized/i.test(normalized)) {
|
|
4182
|
+
return "fraudulent";
|
|
4183
|
+
}
|
|
4184
|
+
if (/customer.*request|requested.*customer|customer.*want|cancel|refund.*request|changed.*mind/i.test(
|
|
4185
|
+
normalized
|
|
4186
|
+
)) {
|
|
4187
|
+
return "requested_by_customer";
|
|
4188
|
+
}
|
|
4189
|
+
return "requested_by_customer";
|
|
4190
|
+
};
|
|
4164
4191
|
|
|
4165
4192
|
// src/stripe-provider.ts
|
|
4166
4193
|
var stripeOptionsSchema = schema()(
|
|
@@ -4171,26 +4198,53 @@ var stripeOptionsSchema = schema()(
|
|
|
4171
4198
|
);
|
|
4172
4199
|
var providerName = "stripe";
|
|
4173
4200
|
var StripeProvider = class extends AbstractPayKitProvider {
|
|
4174
|
-
constructor(
|
|
4175
|
-
super(stripeOptionsSchema,
|
|
4201
|
+
constructor(opts) {
|
|
4202
|
+
super(stripeOptionsSchema, opts, providerName);
|
|
4176
4203
|
this.providerName = providerName;
|
|
4177
4204
|
/**
|
|
4178
4205
|
* Checkout management
|
|
4179
4206
|
*/
|
|
4180
4207
|
this.createCheckout = async (params) => {
|
|
4181
|
-
const
|
|
4208
|
+
const { error, data } = createCheckoutSchema.safeParse(params);
|
|
4209
|
+
if (error) {
|
|
4210
|
+
throw ValidationError.fromZodError(error, this.providerName, "createCheckout");
|
|
4211
|
+
}
|
|
4212
|
+
const checkoutMetadata = stringifyMetadataValues(data.metadata ?? {});
|
|
4182
4213
|
const checkoutOptions = {
|
|
4183
|
-
...
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
...params.session_type == "recurring" && { subscription_data: { metadata } },
|
|
4189
|
-
...params.provider_metadata
|
|
4214
|
+
...data.provider_metadata,
|
|
4215
|
+
mode: data.session_type === "one_time" ? "payment" : "subscription",
|
|
4216
|
+
line_items: [{ price: data.item_id, quantity: data.quantity }],
|
|
4217
|
+
success_url: data.success_url,
|
|
4218
|
+
cancel_url: data.cancel_url
|
|
4190
4219
|
};
|
|
4220
|
+
if (params.session_type == "recurring") {
|
|
4221
|
+
checkoutOptions.subscription_data = { metadata: checkoutMetadata };
|
|
4222
|
+
} else if (params.session_type == "one_time") {
|
|
4223
|
+
checkoutOptions.metadata = checkoutMetadata;
|
|
4224
|
+
checkoutOptions.payment_intent_data = {
|
|
4225
|
+
setup_future_usage: "off_session"
|
|
4226
|
+
};
|
|
4227
|
+
}
|
|
4228
|
+
if (typeof params.customer === "string") {
|
|
4229
|
+
checkoutOptions.customer = params.customer;
|
|
4230
|
+
} else if (typeof params.customer === "object" && "email" in params.customer) {
|
|
4231
|
+
checkoutOptions.customer_email = params.customer.email;
|
|
4232
|
+
} else {
|
|
4233
|
+
throw new InvalidTypeError(
|
|
4234
|
+
"customer",
|
|
4235
|
+
"string (customer ID) or object (customer) with email",
|
|
4236
|
+
"object",
|
|
4237
|
+
{
|
|
4238
|
+
provider: this.providerName,
|
|
4239
|
+
method: "createCheckout"
|
|
4240
|
+
}
|
|
4241
|
+
);
|
|
4242
|
+
}
|
|
4191
4243
|
if (params.billing) {
|
|
4192
4244
|
checkoutOptions.shipping_address_collection = {
|
|
4193
|
-
allowed_countries: [
|
|
4245
|
+
allowed_countries: [
|
|
4246
|
+
params.billing.address.country
|
|
4247
|
+
]
|
|
4194
4248
|
};
|
|
4195
4249
|
checkoutOptions.shipping_options = [
|
|
4196
4250
|
{
|
|
@@ -4203,18 +4257,48 @@ var StripeProvider = class extends AbstractPayKitProvider {
|
|
|
4203
4257
|
];
|
|
4204
4258
|
}
|
|
4205
4259
|
const checkout = await this.stripe.checkout.sessions.create(checkoutOptions);
|
|
4206
|
-
return paykitCheckout$InboundSchema(checkout
|
|
4260
|
+
return paykitCheckout$InboundSchema(checkout, [
|
|
4261
|
+
{ id: params.item_id, quantity: params.quantity }
|
|
4262
|
+
]);
|
|
4207
4263
|
};
|
|
4208
4264
|
this.retrieveCheckout = async (id) => {
|
|
4209
|
-
const checkout = await this.stripe.checkout.sessions.retrieve(id
|
|
4210
|
-
|
|
4265
|
+
const checkout = await this.stripe.checkout.sessions.retrieve(id, {
|
|
4266
|
+
expand: ["line_items"]
|
|
4267
|
+
});
|
|
4268
|
+
return paykitCheckout$InboundSchema(
|
|
4269
|
+
checkout,
|
|
4270
|
+
checkout.line_items?.data.map((item) => ({
|
|
4271
|
+
id: item.price?.id ?? "",
|
|
4272
|
+
quantity: item.quantity ?? 0
|
|
4273
|
+
})) ?? []
|
|
4274
|
+
);
|
|
4211
4275
|
};
|
|
4212
4276
|
this.updateCheckout = async (id, params) => {
|
|
4213
|
-
const
|
|
4214
|
-
|
|
4277
|
+
const { error, data } = updateCheckoutSchema.safeParse(params);
|
|
4278
|
+
if (error) {
|
|
4279
|
+
throw ValidationError.fromZodError(error, this.providerName, "updateCheckout");
|
|
4280
|
+
}
|
|
4281
|
+
const originalCheckout = await this.stripe.checkout.sessions.retrieve(id, {
|
|
4282
|
+
expand: ["line_items"]
|
|
4283
|
+
});
|
|
4284
|
+
if (!originalCheckout) {
|
|
4285
|
+
throw new ResourceNotFoundError("checkout", id, this.providerName);
|
|
4286
|
+
}
|
|
4287
|
+
const updatedCheckout = await this.stripe.checkout.sessions.update(id, {
|
|
4288
|
+
...data,
|
|
4289
|
+
metadata: stringifyMetadataValues(data.metadata ?? {})
|
|
4290
|
+
});
|
|
4291
|
+
return paykitCheckout$InboundSchema(
|
|
4292
|
+
updatedCheckout,
|
|
4293
|
+
updatedCheckout.line_items?.data.map((item) => ({
|
|
4294
|
+
id: item.price?.id ?? "",
|
|
4295
|
+
quantity: item.quantity ?? 0
|
|
4296
|
+
})) ?? []
|
|
4297
|
+
);
|
|
4215
4298
|
};
|
|
4216
4299
|
this.deleteCheckout = async (id) => {
|
|
4217
|
-
|
|
4300
|
+
await this.stripe.checkout.sessions.expire(id);
|
|
4301
|
+
return null;
|
|
4218
4302
|
};
|
|
4219
4303
|
/**
|
|
4220
4304
|
* Customer management
|
|
@@ -4230,7 +4314,11 @@ var StripeProvider = class extends AbstractPayKitProvider {
|
|
|
4230
4314
|
};
|
|
4231
4315
|
this.updateCustomer = async (id, params) => {
|
|
4232
4316
|
const { provider_metadata, ...rest } = params;
|
|
4233
|
-
const customer = await this.stripe.customers.update(id, {
|
|
4317
|
+
const customer = await this.stripe.customers.update(id, {
|
|
4318
|
+
...provider_metadata,
|
|
4319
|
+
...rest,
|
|
4320
|
+
metadata: stringifyMetadataValues(rest.metadata ?? {})
|
|
4321
|
+
});
|
|
4234
4322
|
return paykitCustomer$InboundSchema(customer);
|
|
4235
4323
|
};
|
|
4236
4324
|
this.deleteCustomer = async (id) => {
|
|
@@ -4256,11 +4344,20 @@ var StripeProvider = class extends AbstractPayKitProvider {
|
|
|
4256
4344
|
method: "createSubscription"
|
|
4257
4345
|
});
|
|
4258
4346
|
}
|
|
4347
|
+
if (this.opts.debug) {
|
|
4348
|
+
console.info(
|
|
4349
|
+
"Creating subscription with default payment method, this can be overridden by passing `default_payment_method` in the provider_metadata e.g pm_xxx"
|
|
4350
|
+
);
|
|
4351
|
+
}
|
|
4352
|
+
const defaultPaymentMethod = data.provider_metadata?.default_payment_method;
|
|
4259
4353
|
const subscription = await this.stripe.subscriptions.create({
|
|
4354
|
+
...data.provider_metadata,
|
|
4355
|
+
...defaultPaymentMethod && { default_payment_method: defaultPaymentMethod },
|
|
4260
4356
|
customer: data.customer,
|
|
4261
4357
|
items: [{ price: data.item_id }],
|
|
4262
|
-
metadata:
|
|
4263
|
-
|
|
4358
|
+
metadata: stringifyMetadataValues(data.metadata ?? {}),
|
|
4359
|
+
payment_behavior: "default_incomplete"
|
|
4360
|
+
// customer's default payment method will be used if available
|
|
4264
4361
|
});
|
|
4265
4362
|
return paykitSubscription$InboundSchema(subscription);
|
|
4266
4363
|
};
|
|
@@ -4273,19 +4370,19 @@ var StripeProvider = class extends AbstractPayKitProvider {
|
|
|
4273
4370
|
if (error) {
|
|
4274
4371
|
throw ValidationError.fromZodError(error, this.providerName, "updateSubscription");
|
|
4275
4372
|
}
|
|
4276
|
-
const subscription = await this.stripe.subscriptions.retrieve(id);
|
|
4277
|
-
const metadata = Object.fromEntries(
|
|
4278
|
-
Object.entries({ ...subscription.metadata ?? {}, ...data.metadata ?? {} }).map(([key, value]) => [key, JSON.stringify(value)])
|
|
4279
|
-
);
|
|
4280
4373
|
const updatedSubscription = await this.stripe.subscriptions.update(id, {
|
|
4281
|
-
metadata
|
|
4374
|
+
metadata: stringifyMetadataValues(data.metadata ?? {})
|
|
4282
4375
|
});
|
|
4283
4376
|
return paykitSubscription$InboundSchema(updatedSubscription);
|
|
4284
4377
|
};
|
|
4285
4378
|
this.retrieveSubscription = async (id) => {
|
|
4286
4379
|
const { error, data } = retrieveSubscriptionSchema.safeParse({ id });
|
|
4287
4380
|
if (error) {
|
|
4288
|
-
throw ValidationError.fromZodError(
|
|
4381
|
+
throw ValidationError.fromZodError(
|
|
4382
|
+
error,
|
|
4383
|
+
this.providerName,
|
|
4384
|
+
"retrieveSubscription"
|
|
4385
|
+
);
|
|
4289
4386
|
}
|
|
4290
4387
|
const subscription = await this.stripe.subscriptions.retrieve(data.id);
|
|
4291
4388
|
return paykitSubscription$InboundSchema(subscription);
|
|
@@ -4303,20 +4400,56 @@ var StripeProvider = class extends AbstractPayKitProvider {
|
|
|
4303
4400
|
*/
|
|
4304
4401
|
this.createPayment = async (params) => {
|
|
4305
4402
|
const { error, data } = createPaymentSchema.safeParse(params);
|
|
4306
|
-
if (error)
|
|
4307
|
-
|
|
4403
|
+
if (error)
|
|
4404
|
+
throw new ValidationError(error.message.split("\n").join(" "), {
|
|
4405
|
+
provider: this.providerName,
|
|
4406
|
+
method: "createPayment"
|
|
4407
|
+
});
|
|
4408
|
+
const { provider_metadata, customer, capture_method, ...rest } = data;
|
|
4308
4409
|
if (typeof customer === "object") {
|
|
4309
4410
|
throw new InvalidTypeError("customer", "string (customer ID)", "object", {
|
|
4310
4411
|
provider: this.providerName,
|
|
4311
4412
|
method: "createPayment"
|
|
4312
4413
|
});
|
|
4313
4414
|
}
|
|
4314
|
-
const
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
)
|
|
4415
|
+
const paymentMetadata = stringifyMetadataValues({
|
|
4416
|
+
...rest.metadata,
|
|
4417
|
+
...provider_metadata?.metadata ?? {},
|
|
4418
|
+
[PAYKIT_METADATA_KEY]: JSON.stringify({ itemId: data.item_id ?? null })
|
|
4419
|
+
});
|
|
4420
|
+
const customerWithDefaultPaymentMethod = await this.stripe.customers.retrieve(
|
|
4421
|
+
customer,
|
|
4422
|
+
{ expand: ["invoice_settings.default_payment_method"] }
|
|
4318
4423
|
);
|
|
4319
|
-
|
|
4424
|
+
if ("deleted" in customerWithDefaultPaymentMethod) {
|
|
4425
|
+
throw new ValidationError("Customer has been deleted", {
|
|
4426
|
+
provider: this.providerName,
|
|
4427
|
+
method: "createPayment"
|
|
4428
|
+
});
|
|
4429
|
+
}
|
|
4430
|
+
let defaultPaymentMethod = customerWithDefaultPaymentMethod.invoice_settings?.default_payment_method;
|
|
4431
|
+
if (!defaultPaymentMethod) {
|
|
4432
|
+
const paymentMethods = await this.stripe.paymentMethods.list({ customer });
|
|
4433
|
+
if (paymentMethods.data.length === 0) {
|
|
4434
|
+
throw new ValidationError(
|
|
4435
|
+
`Customer ${customer} has no payment methods. Add a payment method for the customer before creating a payment intent`,
|
|
4436
|
+
{ provider: this.providerName, method: "createPayment" }
|
|
4437
|
+
);
|
|
4438
|
+
}
|
|
4439
|
+
defaultPaymentMethod = paymentMethods.data[0].id;
|
|
4440
|
+
}
|
|
4441
|
+
const paymentIntentOptions = {
|
|
4442
|
+
currency: rest.currency,
|
|
4443
|
+
amount: rest.amount,
|
|
4444
|
+
metadata: paymentMetadata,
|
|
4445
|
+
customer,
|
|
4446
|
+
capture_method,
|
|
4447
|
+
confirm: true,
|
|
4448
|
+
// automatically confirms the payment
|
|
4449
|
+
payment_method: defaultPaymentMethod,
|
|
4450
|
+
off_session: true
|
|
4451
|
+
// uses customer's default payment method, avoids 3Ds/authentication
|
|
4452
|
+
};
|
|
4320
4453
|
if (data.billing) {
|
|
4321
4454
|
paymentIntentOptions.shipping = {
|
|
4322
4455
|
name: data.billing.address.name,
|
|
@@ -4340,21 +4473,38 @@ var StripeProvider = class extends AbstractPayKitProvider {
|
|
|
4340
4473
|
throw ValidationError.fromZodError(error, this.providerName, "updatePayment");
|
|
4341
4474
|
}
|
|
4342
4475
|
const { provider_metadata, customer, ...rest } = data;
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4476
|
+
const payment = await this.stripe.paymentIntents.retrieve(id);
|
|
4477
|
+
const paymentOptions = {
|
|
4478
|
+
...provider_metadata,
|
|
4479
|
+
metadata: stringifyMetadataValues({
|
|
4480
|
+
...rest.metadata,
|
|
4481
|
+
...provider_metadata?.metadata ?? {}
|
|
4482
|
+
})
|
|
4483
|
+
};
|
|
4484
|
+
if (["requires_payment_method", "requires_confirmation", "requires_action"].includes(
|
|
4485
|
+
payment.status
|
|
4486
|
+
)) {
|
|
4487
|
+
paymentOptions.amount = rest.amount;
|
|
4488
|
+
paymentOptions.currency = rest.currency;
|
|
4348
4489
|
}
|
|
4349
|
-
|
|
4350
|
-
|
|
4490
|
+
if (typeof customer === "string") {
|
|
4491
|
+
paymentOptions.customer = customer;
|
|
4492
|
+
} else if (typeof customer == "object" && "email" in customer) {
|
|
4493
|
+
paymentOptions.receipt_email = customer.email;
|
|
4494
|
+
}
|
|
4495
|
+
const updatedPayment = await this.stripe.paymentIntents.update(id, paymentOptions);
|
|
4496
|
+
return paykitPayment$InboundSchema(updatedPayment);
|
|
4351
4497
|
};
|
|
4352
4498
|
this.retrievePayment = async (id) => {
|
|
4353
4499
|
const { error, data } = retrievePaymentSchema.safeParse({ id });
|
|
4354
4500
|
if (error) {
|
|
4355
4501
|
throw ValidationError.fromZodError(error, this.providerName, "retrievePayment");
|
|
4356
4502
|
}
|
|
4357
|
-
const payment = await
|
|
4503
|
+
const [payment, paymentError] = await tryCatchAsync(
|
|
4504
|
+
this.stripe.paymentIntents.retrieve(data.id)
|
|
4505
|
+
);
|
|
4506
|
+
if (!payment || paymentError?.code === "resource_missing")
|
|
4507
|
+
return null;
|
|
4358
4508
|
return paykitPayment$InboundSchema(payment);
|
|
4359
4509
|
};
|
|
4360
4510
|
this.deletePayment = async (id) => {
|
|
@@ -4367,13 +4517,17 @@ var StripeProvider = class extends AbstractPayKitProvider {
|
|
|
4367
4517
|
};
|
|
4368
4518
|
this.capturePayment = async (id, params) => {
|
|
4369
4519
|
const { error, data } = capturePaymentSchema.safeParse(params);
|
|
4370
|
-
if (error)
|
|
4371
|
-
|
|
4520
|
+
if (error) {
|
|
4521
|
+
throw ValidationError.fromZodError(error, this.providerName, "capturePayment");
|
|
4522
|
+
}
|
|
4523
|
+
const payment = await this.stripe.paymentIntents.capture(id, {
|
|
4524
|
+
amount_to_capture: data.amount
|
|
4525
|
+
});
|
|
4372
4526
|
return paykitPayment$InboundSchema(payment);
|
|
4373
4527
|
};
|
|
4374
4528
|
this.cancelPayment = async (id) => {
|
|
4375
|
-
const
|
|
4376
|
-
return paykitPayment$InboundSchema(
|
|
4529
|
+
const canceledPayment = await this.stripe.paymentIntents.cancel(id);
|
|
4530
|
+
return paykitPayment$InboundSchema(canceledPayment);
|
|
4377
4531
|
};
|
|
4378
4532
|
/**
|
|
4379
4533
|
* Refund management
|
|
@@ -4383,8 +4537,19 @@ var StripeProvider = class extends AbstractPayKitProvider {
|
|
|
4383
4537
|
if (error) {
|
|
4384
4538
|
throw ValidationError.fromZodError(error, this.providerName, "createRefund");
|
|
4385
4539
|
}
|
|
4386
|
-
const { provider_metadata, ...rest } =
|
|
4387
|
-
const
|
|
4540
|
+
const { provider_metadata, ...rest } = data;
|
|
4541
|
+
const stripeRefundOptions = {
|
|
4542
|
+
...provider_metadata,
|
|
4543
|
+
reason: paykitRefundReason$OutboundSchema(rest.reason),
|
|
4544
|
+
amount: rest.amount,
|
|
4545
|
+
metadata: stringifyMetadataValues(rest.metadata ?? {})
|
|
4546
|
+
};
|
|
4547
|
+
if (data.payment_id.startsWith("pi_")) {
|
|
4548
|
+
stripeRefundOptions.payment_intent = data.payment_id;
|
|
4549
|
+
} else {
|
|
4550
|
+
stripeRefundOptions.charge = data.payment_id;
|
|
4551
|
+
}
|
|
4552
|
+
const refund = await this.stripe.refunds.create(stripeRefundOptions);
|
|
4388
4553
|
return paykitRefund$InboundSchema(refund);
|
|
4389
4554
|
};
|
|
4390
4555
|
/**
|
|
@@ -4392,9 +4557,17 @@ var StripeProvider = class extends AbstractPayKitProvider {
|
|
|
4392
4557
|
*/
|
|
4393
4558
|
this.handleWebhook = async (params) => {
|
|
4394
4559
|
const { body, headers, webhookSecret } = params;
|
|
4395
|
-
const
|
|
4396
|
-
|
|
4397
|
-
|
|
4560
|
+
const stripeSignature = headers.get("stripe-signature");
|
|
4561
|
+
if (!stripeSignature) {
|
|
4562
|
+
throw new WebhookError("Missing Stripe signature", {
|
|
4563
|
+
provider: this.providerName
|
|
4564
|
+
});
|
|
4565
|
+
}
|
|
4566
|
+
const event = this.stripe.webhooks.constructEvent(
|
|
4567
|
+
body,
|
|
4568
|
+
stripeSignature,
|
|
4569
|
+
webhookSecret
|
|
4570
|
+
);
|
|
4398
4571
|
const stripePaymentIntentUpdateEventsWithHandlers = [
|
|
4399
4572
|
"payment_intent.processing",
|
|
4400
4573
|
"payment_intent.requires_action",
|
|
@@ -4429,20 +4602,29 @@ var StripeProvider = class extends AbstractPayKitProvider {
|
|
|
4429
4602
|
paid_at: new Date(event2.created * 1e3).toISOString(),
|
|
4430
4603
|
amount_paid: data.amount_total ?? 0,
|
|
4431
4604
|
currency: data.currency ?? "",
|
|
4432
|
-
metadata:
|
|
4605
|
+
metadata: omitInternalMetadata(data.metadata ?? {}),
|
|
4433
4606
|
customer: typeof data.customer === "string" ? data.customer : data.customer?.id ?? "",
|
|
4434
4607
|
billing_mode: billingModeSchema.parse("one_time"),
|
|
4435
4608
|
subscription_id: null,
|
|
4436
4609
|
custom_fields: customFields ?? null,
|
|
4437
|
-
line_items: data.line_items?.data.map((item) => ({
|
|
4610
|
+
line_items: data.line_items?.data.map((item) => ({
|
|
4611
|
+
id: item.price.id,
|
|
4612
|
+
quantity: item.quantity
|
|
4613
|
+
})) ?? []
|
|
4614
|
+
};
|
|
4615
|
+
const invoice = {
|
|
4616
|
+
type: "invoice.generated",
|
|
4617
|
+
created: event2.created,
|
|
4618
|
+
id: event2.id,
|
|
4619
|
+
data: invoiceData
|
|
4438
4620
|
};
|
|
4439
|
-
const invoice = { type: "invoice.generated", created: event2.created, id: event2.id, data: invoiceData };
|
|
4440
4621
|
return [paykitEvent$InboundSchema(invoice)];
|
|
4441
4622
|
},
|
|
4442
4623
|
"invoice.paid": async (event2) => {
|
|
4443
4624
|
const data = event2.data.object;
|
|
4444
4625
|
const relevantBillingReasons = ["subscription_create", "subscription_cycle"];
|
|
4445
|
-
if (data.status !== "paid" && !relevantBillingReasons.includes(data.billing_reason))
|
|
4626
|
+
if (data.status !== "paid" && !relevantBillingReasons.includes(data.billing_reason))
|
|
4627
|
+
return null;
|
|
4446
4628
|
const invoice = {
|
|
4447
4629
|
type: "invoice.generated",
|
|
4448
4630
|
created: event2.created,
|
|
@@ -4456,16 +4638,31 @@ var StripeProvider = class extends AbstractPayKitProvider {
|
|
|
4456
4638
|
*/
|
|
4457
4639
|
"customer.created": async (event2) => {
|
|
4458
4640
|
const data = event2.data.object;
|
|
4459
|
-
const customer = {
|
|
4641
|
+
const customer = {
|
|
4642
|
+
type: "customer.created",
|
|
4643
|
+
created: event2.created,
|
|
4644
|
+
id: event2.id,
|
|
4645
|
+
data: paykitCustomer$InboundSchema(data)
|
|
4646
|
+
};
|
|
4460
4647
|
return [paykitEvent$InboundSchema(customer)];
|
|
4461
4648
|
},
|
|
4462
4649
|
"customer.updated": async (event2) => {
|
|
4463
4650
|
const data = event2.data.object;
|
|
4464
|
-
const customer = {
|
|
4651
|
+
const customer = {
|
|
4652
|
+
type: "customer.updated",
|
|
4653
|
+
created: event2.created,
|
|
4654
|
+
id: event2.id,
|
|
4655
|
+
data: paykitCustomer$InboundSchema(data)
|
|
4656
|
+
};
|
|
4465
4657
|
return [paykitEvent$InboundSchema(customer)];
|
|
4466
4658
|
},
|
|
4467
4659
|
"customer.deleted": async (event2) => {
|
|
4468
|
-
const customer = {
|
|
4660
|
+
const customer = {
|
|
4661
|
+
type: "customer.deleted",
|
|
4662
|
+
created: event2.created,
|
|
4663
|
+
id: event2.id,
|
|
4664
|
+
data: null
|
|
4665
|
+
};
|
|
4469
4666
|
return [paykitEvent$InboundSchema(customer)];
|
|
4470
4667
|
},
|
|
4471
4668
|
/**
|
|
@@ -4474,46 +4671,104 @@ var StripeProvider = class extends AbstractPayKitProvider {
|
|
|
4474
4671
|
"customer.subscription.created": async (event2) => {
|
|
4475
4672
|
const data = event2.data.object;
|
|
4476
4673
|
const subscription = paykitSubscription$InboundSchema(data);
|
|
4477
|
-
return [
|
|
4674
|
+
return [
|
|
4675
|
+
paykitEvent$InboundSchema({
|
|
4676
|
+
type: "subscription.created",
|
|
4677
|
+
created: event2.created,
|
|
4678
|
+
id: event2.id,
|
|
4679
|
+
data: subscription
|
|
4680
|
+
})
|
|
4681
|
+
];
|
|
4478
4682
|
},
|
|
4479
4683
|
"customer.subscription.updated": async (event2) => {
|
|
4480
4684
|
const data = event2.data.object;
|
|
4481
4685
|
const subscription = paykitSubscription$InboundSchema(data);
|
|
4482
|
-
return [
|
|
4686
|
+
return [
|
|
4687
|
+
paykitEvent$InboundSchema({
|
|
4688
|
+
type: "subscription.updated",
|
|
4689
|
+
created: event2.created,
|
|
4690
|
+
id: event2.id,
|
|
4691
|
+
data: subscription
|
|
4692
|
+
})
|
|
4693
|
+
];
|
|
4483
4694
|
},
|
|
4484
4695
|
"customer.subscription.deleted": async (event2) => {
|
|
4485
4696
|
const subscription = null;
|
|
4486
|
-
return [
|
|
4697
|
+
return [
|
|
4698
|
+
paykitEvent$InboundSchema({
|
|
4699
|
+
type: "subscription.canceled",
|
|
4700
|
+
created: event2.created,
|
|
4701
|
+
id: event2.id,
|
|
4702
|
+
data: subscription
|
|
4703
|
+
})
|
|
4704
|
+
];
|
|
4487
4705
|
},
|
|
4488
4706
|
"payment_intent.created": async (event2) => {
|
|
4489
4707
|
const data = event2.data.object;
|
|
4490
4708
|
const payment = paykitPayment$InboundSchema(data);
|
|
4491
|
-
return [
|
|
4709
|
+
return [
|
|
4710
|
+
paykitEvent$InboundSchema({
|
|
4711
|
+
type: "payment.created",
|
|
4712
|
+
created: event2.created,
|
|
4713
|
+
id: event2.id,
|
|
4714
|
+
data: payment
|
|
4715
|
+
})
|
|
4716
|
+
];
|
|
4492
4717
|
},
|
|
4493
|
-
...stripePaymentIntentUpdateEventsWithHandlers.map(
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4718
|
+
...stripePaymentIntentUpdateEventsWithHandlers.map(
|
|
4719
|
+
() => async (event2) => {
|
|
4720
|
+
const data = event2.data.object;
|
|
4721
|
+
const payment = paykitPayment$InboundSchema(data);
|
|
4722
|
+
return [
|
|
4723
|
+
paykitEvent$InboundSchema({
|
|
4724
|
+
type: "payment.updated",
|
|
4725
|
+
created: event2.created,
|
|
4726
|
+
id: event2.id,
|
|
4727
|
+
data: payment
|
|
4728
|
+
})
|
|
4729
|
+
];
|
|
4730
|
+
}
|
|
4731
|
+
),
|
|
4498
4732
|
"payment_intent.canceled": async (event2) => {
|
|
4499
4733
|
const data = event2.data.object;
|
|
4500
4734
|
const payment = paykitPayment$InboundSchema(data);
|
|
4501
|
-
return [
|
|
4735
|
+
return [
|
|
4736
|
+
paykitEvent$InboundSchema({
|
|
4737
|
+
type: "payment.canceled",
|
|
4738
|
+
created: event2.created,
|
|
4739
|
+
id: event2.id,
|
|
4740
|
+
data: payment
|
|
4741
|
+
})
|
|
4742
|
+
];
|
|
4502
4743
|
},
|
|
4503
4744
|
"refund.created": async (event2) => {
|
|
4504
4745
|
const data = event2.data.object;
|
|
4505
4746
|
const refund = paykitRefund$InboundSchema(data);
|
|
4506
|
-
return [
|
|
4747
|
+
return [
|
|
4748
|
+
paykitEvent$InboundSchema({
|
|
4749
|
+
type: "refund.created",
|
|
4750
|
+
created: event2.created,
|
|
4751
|
+
id: event2.id,
|
|
4752
|
+
data: refund
|
|
4753
|
+
})
|
|
4754
|
+
];
|
|
4507
4755
|
}
|
|
4508
4756
|
};
|
|
4509
4757
|
const handler = webhookHandlers[event.type];
|
|
4510
|
-
if (!handler)
|
|
4758
|
+
if (!handler)
|
|
4759
|
+
throw new WebhookError(`Unhandled event type: ${event.type}`, {
|
|
4760
|
+
provider: this.providerName
|
|
4761
|
+
});
|
|
4511
4762
|
const result = await handler(event);
|
|
4512
|
-
if (!result)
|
|
4763
|
+
if (!result)
|
|
4764
|
+
throw new WebhookError(`Unhandled event type: ${event.type}`, {
|
|
4765
|
+
provider: this.providerName
|
|
4766
|
+
});
|
|
4513
4767
|
return result;
|
|
4514
4768
|
};
|
|
4515
|
-
const { debug, apiKey, ...rest } =
|
|
4769
|
+
const { debug = true, apiKey, ...rest } = opts;
|
|
4516
4770
|
this.stripe = new Stripe(apiKey, rest);
|
|
4771
|
+
this.opts = opts;
|
|
4517
4772
|
}
|
|
4518
4773
|
};
|
|
4519
4774
|
|
|
@@ -4522,9 +4777,17 @@ var createStripe = (config) => {
|
|
|
4522
4777
|
return new StripeProvider(config);
|
|
4523
4778
|
};
|
|
4524
4779
|
var stripe = () => {
|
|
4525
|
-
const envVars = validateRequiredKeys(
|
|
4780
|
+
const envVars = validateRequiredKeys(
|
|
4781
|
+
["STRIPE_API_KEY"],
|
|
4782
|
+
process.env,
|
|
4783
|
+
"Missing required environment variables: {keys}"
|
|
4784
|
+
);
|
|
4526
4785
|
const isSandbox = process.env.NODE_ENV === "development";
|
|
4527
|
-
return createStripe({
|
|
4786
|
+
return createStripe({
|
|
4787
|
+
apiKey: envVars.STRIPE_API_KEY,
|
|
4788
|
+
debug: isSandbox,
|
|
4789
|
+
apiVersion: "2025-07-30.basil"
|
|
4790
|
+
});
|
|
4528
4791
|
};
|
|
4529
4792
|
|
|
4530
4793
|
export { createStripe, stripe };
|
|
@@ -6,7 +6,8 @@ interface StripeOptions extends PaykitProviderOptions<Stripe.StripeConfig> {
|
|
|
6
6
|
}
|
|
7
7
|
declare class StripeProvider extends AbstractPayKitProvider implements PayKitProvider {
|
|
8
8
|
private stripe;
|
|
9
|
-
|
|
9
|
+
private opts;
|
|
10
|
+
constructor(opts: StripeOptions);
|
|
10
11
|
readonly providerName = "stripe";
|
|
11
12
|
/**
|
|
12
13
|
* Checkout management
|