UNPKG

@paykit-sdk/stripe

Version:

Stripe provider for PayKit

246 lines (240 loc) 9.67 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { createStripe: () => createStripe, stripe: () => stripe }); module.exports = __toCommonJS(index_exports); var import_core3 = require("@paykit-sdk/core"); // src/stripe-provider.ts var import_core2 = require("@paykit-sdk/core"); var import_stripe = __toESM(require("stripe")); // lib/mapper.ts var import_core = require("@paykit-sdk/core"); var toPaykitCheckout = (checkout) => { return { id: checkout.id, customer_id: checkout.customer, session_type: checkout.mode === "subscription" ? "recurring" : "one_time", // todo: handle `setup` mode payment_url: checkout.url, products: checkout.line_items.data.map((item) => ({ id: item.price.id, quantity: item.quantity })), currency: checkout.currency, amount: checkout.amount_total, metadata: checkout.metadata }; }; var toPaykitCustomer = (customer) => { return { id: customer.id, email: customer.email ?? void 0, name: customer.name ?? void 0, metadata: (0, import_core.stringifyObjectValues)(customer.metadata ?? {}) }; }; var toPaykitSubscriptionStatus = (status) => { if (["active", "trialing"].includes(status)) return "active"; if (["incomplete_expired", "incomplete", "past_due"].includes(status)) return "past_due"; if (["canceled"].includes(status)) return "canceled"; if (["expired"].includes(status)) return "expired"; throw new Error(`Unknown status: ${status}`); }; var toPaykitSubscription = (subscription) => { return { id: subscription.id, customer_id: subscription.customer?.toString(), status: toPaykitSubscriptionStatus(subscription.status), current_period_start: new Date(subscription.start_date), current_period_end: new Date(subscription.cancel_at), metadata: (0, import_core.stringifyObjectValues)(subscription.metadata ?? {}) }; }; var toPaykitInvoice = (invoice) => { return { id: invoice.id, amount: invoice.amount_paid, currency: invoice.currency, metadata: (0, import_core.stringifyObjectValues)(invoice.metadata ?? {}), customer_id: invoice.customer?.toString() ?? "", billing_mode: invoice.billingMode }; }; // src/stripe-provider.ts var StripeProvider = class { constructor(config) { /** * Checkout management */ this.createCheckout = async (params) => { const { customer_id, item_id, metadata, session_type, provider_metadata } = params; const checkout = await this.stripe.checkout.sessions.create({ customer: customer_id, mode: session_type === "one_time" ? "payment" : "subscription", ...session_type == "one_time" && { metadata }, ...session_type == "recurring" && { subscription_data: { metadata } }, line_items: [{ price: item_id }], ...provider_metadata }); return toPaykitCheckout(checkout); }; this.retrieveCheckout = async (id) => { const checkout = await this.stripe.checkout.sessions.retrieve(id); return toPaykitCheckout(checkout); }; /** * Customer management */ this.createCustomer = async (params) => { const customer = await this.stripe.customers.create(params); return toPaykitCustomer(customer); }; this.updateCustomer = async (id, params) => { const customer = await this.stripe.customers.update(id, params); return toPaykitCustomer(customer); }; this.deleteCustomer = async (id) => { await this.stripe.customers.del(id); return null; }; this.retrieveCustomer = async (id) => { const customer = await this.stripe.customers.retrieve(id); if ("deleted" in customer) return null; return toPaykitCustomer(customer); }; /** * Subscription management */ this.cancelSubscription = async (id) => { await this.stripe.subscriptions.cancel(id); return null; }; this.updateSubscription = async (id, params) => { const subscription = await this.stripe.subscriptions.update(id, { metadata: params.metadata }); return toPaykitSubscription(subscription); }; this.retrieveSubscription = async (id) => { const subscription = await this.stripe.subscriptions.retrieve(id); return toPaykitSubscription(subscription); }; /** * Webhook management */ this.handleWebhook = async (params) => { const { body, headers, webhookSecret } = params; const stripeHeaders = (0, import_core2.headersExtractor)(headers, ["x-stripe-signature"]); const signature = stripeHeaders[0].value; const event = this.stripe.webhooks.constructEvent(body, signature, webhookSecret); const webhookHandlers = { /** * Invoice */ "checkout.session.completed": (event2) => { const data = event2.data.object; if (data.mode !== "payment") return null; return (0, import_core2.toPaykitEvent)({ type: "$invoicePaid", created: event2.created, id: event2.id, data: { id: data.id, amount: data.amount_total ?? 0, currency: data.currency ?? "", metadata: (0, import_core2.stringifyObjectValues)({ ...data.metadata ?? {}, $mode: data.mode }), customer_id: data.customer?.toString() ?? "", billing_mode: "one_time" } }); }, "invoice.paid": (event2) => { const data = event2.data.object; if (data.status !== "paid" && !["subscription_create", "subscription_cycle"].includes(data.billing_reason)) { return null; } return (0, import_core2.toPaykitEvent)({ type: "$invoicePaid", created: event2.created, id: event2.id, data: toPaykitInvoice({ ...data, billingMode: "recurring" }) }); }, /** * Customer */ "customer.created": (event2) => { const data = event2.data.object; return (0, import_core2.toPaykitEvent)({ type: "$customerCreated", created: event2.created, id: event2.id, data: toPaykitCustomer(data) }); }, "customer.updated": (event2) => { const data = event2.data.object; return (0, import_core2.toPaykitEvent)({ type: "$customerUpdated", created: event2.created, id: event2.id, data: toPaykitCustomer(data) }); }, "customer.deleted": (event2) => { return (0, import_core2.toPaykitEvent)({ type: "$customerDeleted", created: event2.created, id: event2.id, data: null }); }, /** * Subscription */ "customer.subscription.created": (event2) => { const data = event2.data.object; return (0, import_core2.toPaykitEvent)({ type: "$subscriptionCreated", created: event2.created, id: event2.id, data: toPaykitSubscription(data) }); }, "customer.subscription.updated": (event2) => { const data = event2.data.object; return (0, import_core2.toPaykitEvent)({ type: "$subscriptionUpdated", created: event2.created, id: event2.id, data: toPaykitSubscription(data) }); }, "customer.subscription.deleted": (event2) => { return (0, import_core2.toPaykitEvent)({ type: "$subscriptionCancelled", created: event2.created, id: event2.id, data: null }); } }; const handler = webhookHandlers[event.type]; if (!handler) throw new Error(`Unhandled event type: ${event.type}`); const result = handler(event); if (!result) throw new Error(`Unhandled event type: ${event.type}`); return result; }; const { debug, apiKey, ...rest } = config; this.stripe = new import_stripe.default(apiKey, rest); } }; // src/index.ts var createStripe = (config) => { return new StripeProvider(config); }; var stripe = () => { const envVars = (0, import_core3.validateEnvVars)(["STRIPE_API_KEY"], process.env); const isDev = process.env.NODE_ENV === "development"; return createStripe({ apiKey: envVars.STRIPE_API_KEY, debug: isDev, apiVersion: "2025-07-30.basil" }); }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { createStripe, stripe });