{"$schema":"https://ui.shadcn.com/schema/registry.json","name":"paykit","homepage":"https://usepaykit.dev","items":[{"name":"stripe-nextjs","type":"registry:block","description":"Stripe payment integration for Next.js App Router with type-safe API routes and webhook handling","dependencies":["@paykit-sdk/core","@paykit-sdk/stripe"],"devDependencies":[],"registryDependencies":[],"files":[{"path":"providers/stripe.ts","type":"registry:lib","target":"lib/paykit.ts","content":"import { PayKit, createEndpointHandlers } from '@paykit-sdk/core';\nimport { stripe } from '@paykit-sdk/stripe';\n\nexport const paykit = new PayKit(stripe());\nexport const endpoints = createEndpointHandlers(paykit);\n"},{"path":"shared/routers/nextjs/catch-all.ts","type":"registry:page","target":"app/api/paykit/[...endpoint]/route.ts","content":"import { endpoints } from '@/lib/paykit';\nimport type {\n  EndpointArgs,\n  EndpointHandler,\n  EndpointPath,\n} from '@paykit-sdk/core';\nimport { NextResponse, NextRequest } from 'next/server';\n\nexport async function POST(\n  request: NextRequest,\n  { params }: { params: Promise<{ endpoint: string[] }> },\n) {\n  const { endpoint: endpointArray } = await params;\n\n  const endpoint = ('/' + endpointArray.join('/')) as EndpointPath;\n\n  const handler = endpoints[endpoint] as EndpointHandler<\n    typeof endpoint\n  >;\n\n  if (!handler) {\n    return NextResponse.json(\n      { message: 'Endpoint not found' },\n      { status: 404 },\n    );\n  }\n\n  const body = await request.json();\n\n  const { args } = body as { args: EndpointArgs<typeof endpoint> };\n\n  try {\n    const result = await handler(...args);\n    return NextResponse.json({ result });\n  } catch (error) {\n    console.error('PayKit API Error:', error);\n    const message =\n      error instanceof Error\n        ? error.message\n        : 'Internal server error';\n    return NextResponse.json({ message }, { status: 500 });\n  }\n}\n"},{"path":"shared/routers/nextjs/webhook.ts","type":"registry:page","target":"app/api/paykit/webhooks/route.ts","content":"import { paykit } from '@/lib/paykit';\nimport type { NextRequest } from 'next/server';\nimport { NextResponse } from 'next/server';\n\nexport async function POST(request: NextRequest) {\n  const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET;\n\n  if (!webhookSecret) {\n    return NextResponse.json(\n      { error: 'Webhook secret not configured' },\n      { status: 500 },\n    );\n  }\n\n  const webhook = paykit.webhooks\n    .setup({ webhookSecret })\n    .on('customer.created', async event => {\n      console.log('Customer created:', event.data);\n    })\n    .on('subscription.created', async event => {\n      console.log('Subscription created:', event.data);\n    })\n    .on('payment.created', async event => {\n      console.log('Payment created:', event.data);\n    })\n    .on('refund.created', async event => {\n      console.log('Refund created:', event.data);\n    })\n    .on('invoice.generated', async event => {\n      console.log('Invoice generated:', event.data);\n    });\n\n  const body = await request.text();\n  const headers = request.headers;\n  const url = request.url;\n\n  try {\n    await webhook.handle({ body, headers, fullUrl: url });\n    return NextResponse.json({ success: true });\n  } catch (error) {\n    console.log('Webhook Error', error);\n    return NextResponse.json({ success: false });\n  }\n}\n"}],"envVars":{"STRIPE_SECRET_KEY":"sk_test_...","STRIPE_WEBHOOK_SECRET":"whsec_..."},"docs":"Get your Stripe Secret Key from https://dashboard.stripe.com/apikeys \n Create a webhook endpoint at https://dashboard.stripe.com/webhooks to get your webhook secret.","meta":{"backend":"nextjs","provider":"stripe","orm":"none","database":"none","auth":"none"}},{"name":"stripe-hono","type":"registry:block","description":"Stripe payment integration for Hono backend with unified routes and webhook handling","dependencies":["@paykit-sdk/core","@paykit-sdk/stripe","hono"],"devDependencies":[],"registryDependencies":[],"files":[{"path":"providers/stripe.ts","type":"registry:lib","target":"src/lib/paykit.ts","content":"import { PayKit, createEndpointHandlers } from '@paykit-sdk/core';\nimport { stripe } from '@paykit-sdk/stripe';\n\nexport const paykit = new PayKit(stripe());\nexport const endpoints = createEndpointHandlers(paykit);\n"},{"path":"shared/routers/hono.ts","type":"registry:page","target":"src/routes/paykit.ts","content":"import { endpoints, paykit } from '@/lib/paykit';\nimport type {\n  EndpointArgs,\n  EndpointHandler,\n  EndpointPath,\n} from '@paykit-sdk/core';\nimport { Hono } from 'hono';\n\nexport const paykitRouter = new Hono();\n\npaykitRouter.post('/*', async c => {\n  const path = c.req.path as EndpointPath;\n\n  const handler = endpoints[path] as EndpointHandler<typeof path>;\n\n  if (!handler) {\n    return c.json({ message: 'Endpoint not found' }, 404);\n  }\n\n  const body = await c.req.json();\n  const { args } = body as { args: EndpointArgs<typeof path> };\n\n  try {\n    const result = await handler(...args);\n    return c.json({ result });\n  } catch (error) {\n    console.error('PayKit API Error:', error);\n    const message =\n      error instanceof Error\n        ? error.message\n        : 'Internal server error';\n    return c.json({ message }, 500);\n  }\n});\n\n// Webhook handler\npaykitRouter.post('/webhooks', async c => {\n  const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET;\n\n  if (!webhookSecret) {\n    return c.json({ error: 'Webhook secret not configured' }, 500);\n  }\n\n  const webhook = paykit.webhooks\n    .setup({ webhookSecret })\n    .on('customer.created', async event => {\n      console.log('Customer created:', event.data);\n    })\n    .on('subscription.created', async event => {\n      console.log('Subscription created:', event.data);\n    })\n    .on('payment.created', async event => {\n      console.log('Payment created:', event.data);\n    })\n    .on('refund.created', async event => {\n      console.log('Refund created:', event.data);\n    })\n    .on('invoice.generated', async event => {\n      console.log('Invoice generated:', event.data);\n    });\n\n  const body = await c.req.text();\n  const headers = new Headers(c.req.raw.headers);\n  const url = c.req.raw.url;\n\n  try {\n    console.log('Webhook handled');\n    await webhook.handle({ body, headers, fullUrl: url });\n    return c.json({ success: true });\n  } catch (error) {\n    console.log('Webhook Error', error);\n    return c.json({ success: false });\n  }\n});\n"}],"envVars":{"STRIPE_SECRET_KEY":"sk_test_...","STRIPE_WEBHOOK_SECRET":"whsec_..."},"docs":"Get your Stripe API keys from https://dashboard.stripe.com/apikeys \n Create a webhook endpoint at https://dashboard.stripe.com/webhooks to get your webhook secret.","meta":{"backend":"hono","provider":"stripe","orm":"none","database":"none","auth":"none"}},{"name":"stripe-express","type":"registry:block","description":"Stripe payment integration for Express backend with unified routes and webhook handling","dependencies":["@paykit-sdk/core","@paykit-sdk/stripe","express"],"devDependencies":["@types/express"],"registryDependencies":[],"files":[{"path":"providers/stripe.ts","type":"registry:lib","target":"src/lib/paykit.ts","content":"import { PayKit, createEndpointHandlers } from '@paykit-sdk/core';\nimport { stripe } from '@paykit-sdk/stripe';\n\nexport const paykit = new PayKit(stripe());\nexport const endpoints = createEndpointHandlers(paykit);\n"},{"path":"shared/routers/express.ts","type":"registry:page","target":"src/routes/paykit.ts","content":"import { endpoints, paykit } from '@/lib/paykit';\nimport type {\n  EndpointArgs,\n  EndpointHandler,\n  EndpointPath,\n} from '@paykit-sdk/core';\nimport { Router, type Request, type Response } from 'express';\n\nexport const paykitRouter = Router();\n\n// Catch-all for PayKit API endpoints\npaykitRouter.post('/*', async (req: Request, res: Response) => {\n  const path = req.path as EndpointPath;\n  const handler = endpoints[path] as EndpointHandler<typeof path>;\n\n  if (!handler) {\n    return res.status(404).json({ message: 'Endpoint not found' });\n  }\n\n  const { args } = req.body as { args: EndpointArgs<typeof path> };\n\n  try {\n    const result = await handler(...args);\n    return res.json({ result });\n  } catch (error) {\n    console.error('PayKit API Error:', error);\n    const message =\n      error instanceof Error\n        ? error.message\n        : 'Internal server error';\n    return res.status(500).json({ message });\n  }\n});\n\n// Webhook handler\npaykitRouter.post(\n  '/webhooks',\n  async (req: Request, res: Response) => {\n    const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET;\n\n    if (!webhookSecret) {\n      return res\n        .status(500)\n        .json({ error: 'Webhook secret not configured' });\n    }\n\n    const webhook = paykit.webhooks\n      .setup({ webhookSecret })\n      .on('customer.created', async event => {\n        console.log('Customer created:', event.data);\n      })\n      .on('subscription.created', async event => {\n        console.log('Subscription created:', event.data);\n      })\n      .on('payment.created', async event => {\n        console.log('Payment created:', event.data);\n      })\n      .on('refund.created', async event => {\n        console.log('Refund created:', event.data);\n      })\n      .on('invoice.generated', async event => {\n        console.log('Invoice generated:', event.data);\n      });\n\n    // Express stores raw body in req.body when using express.raw()\n    const body =\n      typeof req.body === 'string'\n        ? req.body\n        : JSON.stringify(req.body);\n    const headers = new Headers(\n      Object.entries(req.headers) as [string, string][],\n    );\n    const fullUrl = `${req.protocol}://${req.get('host')}${req.originalUrl}`;\n\n    try {\n      console.log('Webhook handled');\n      await webhook.handle({ body, headers, fullUrl });\n      return res.json({ success: true });\n    } catch (error) {\n      console.log('Webhook Error', error);\n      return res.json({ success: false });\n    }\n  },\n);\n\n/**\n * MAIN APP ROUTER INTEGRATION:\n * import express from 'express';\n * import { paykitRouter } from './router';\n *\n * const app = express();\n *\n * ⚠️ IMPORTANT: Middleware setup\n * app.use(express.json());\n * app.use('/paykit/webhooks',express.raw({ type: 'application/json' }));\n *\n * // Your existing routes\n * app.get('/', (req, res) => res.send('Hello World'));\n *\n * // PayKit routes\n * app.use('/paykit', paykitRouter);\n *\n * app.listen(3000, () => {\n *   console.log('Server running on port 3000');\n * });\n */\n"}],"envVars":{"STRIPE_SECRET_KEY":"sk_test_...","STRIPE_WEBHOOK_SECRET":"whsec_..."},"docs":"Get your Stripe API keys from https://dashboard.stripe.com/apikeys\nCreate a webhook endpoint at https://dashboard.stripe.com/webhooks to get your webhook secret\nMake sure to read the integration guide completely in `src/routes/paykit.ts` file for the proper setup.","meta":{"backend":"express","provider":"stripe","orm":"none","database":"none","auth":"none"}},{"name":"stripe-nextjs-hooks","type":"registry:block","description":"Stripe payment integration for Next.js App Router with React hooks","dependencies":["@paykit-sdk/react"],"devDependencies":[],"registryDependencies":["https://usepaykit.dev/r/stripe-nextjs"],"files":[{"path":"shared/hooks/paykit-wrapper.tsx","type":"registry:component","content":"'use client';\n\nimport * as React from 'react';\nimport { PaykitProvider } from '@paykit-sdk/react';\n\nexport const PaykitWrapper = ({\n  children,\n}: React.PropsWithChildren) => {\n  return (\n    <PaykitProvider\n      headers={{ xApiKey: '1234567890' }}\n      apiUrl=\"/api/paykit\"\n    >\n      {children}\n    </PaykitProvider>\n  );\n};\n"},{"path":"shared/hooks/customer-manager.tsx","type":"registry:component","content":"'use client';\n\nimport * as React from 'react';\nimport {\n  useCustomer,\n  useSubscription,\n  useRefund,\n} from '@paykit-sdk/react';\n\nexport const CustomerManager = () => {\n  const { create: createCustomer } = useCustomer();\n  const { create: createSubscription } = useSubscription();\n  const { cancel: cancelSubscription } = useSubscription();\n  const { create: createRefund } = useRefund();\n\n  const [customerId, setCustomerId] = React.useState<string>();\n  const [subscriptionId, setSubscriptionId] =\n    React.useState<string>();\n  const [paymentId, setPaymentId] = React.useState<string>();\n\n  const handleCreateCustomer = async () => {\n    const [data, error] = await createCustomer.run({\n      email: 'customer@example.com',\n      phone: '+1234567890',\n      name: 'John Doe',\n      metadata: { source: 'web_app' },\n    });\n\n    if (error) {\n      console.error('Failed to create customer:', error);\n      return;\n    }\n\n    setCustomerId(data.id);\n  };\n\n  // Create subscription\n  const handleCreateSubscription = async () => {\n    if (!customerId) return;\n\n    const [data, error] = await createSubscription.run({\n      customer: customerId,\n      item_id: 'price_...',\n      amount: 2999,\n      currency: 'USD',\n      billing_interval: 'month',\n      metadata: { plan: 'pro' },\n      quantity: 1,\n    });\n\n    if (error) {\n      console.error('Failed to create subscription:', error);\n      return;\n    }\n\n    setSubscriptionId(data.id);\n  };\n\n  // Cancel subscription\n  const handleCancelSubscription = async () => {\n    if (!subscriptionId) return;\n\n    const [, error] = await cancelSubscription.run(subscriptionId);\n\n    if (error) {\n      console.error('Failed to cancel subscription:', error);\n      return;\n    }\n\n    console.log('Subscription cancelled');\n  };\n\n  // Create refund\n  const handleCreateRefund = async () => {\n    if (!paymentId) return;\n\n    const [data, error] = await createRefund.run({\n      payment_id: paymentId,\n      amount: 1000, // $10.00\n      reason: 'customer_request',\n      metadata: null,\n    });\n\n    if (error) {\n      console.error('Failed to create refund:', error);\n      return;\n    }\n\n    console.log(`Refund created: ${data.id}`);\n  };\n\n  return (\n    <div className=\"bg-background flex flex-col gap-4 rounded-lg p-4\">\n      <h2 className=\"text-foreground text-2xl font-bold\">\n        Customer Manager\n      </h2>\n\n      {/* Customer Section */}\n      <section className=\"flex flex-col gap-2\">\n        <h3 className=\"text-foreground text-lg font-medium\">\n          Customer\n        </h3>\n        <button\n          onClick={handleCreateCustomer}\n          disabled={createCustomer.loading}\n        >\n          {createCustomer.loading ? 'Creating...' : 'Create Customer'}\n        </button>\n        {customerId && <p>Customer ID: {customerId}</p>}\n      </section>\n\n      {/* Subscription Section */}\n      <section className=\"flex flex-col gap-2\">\n        <h3 className=\"text-foreground text-lg font-medium\">\n          Subscription\n        </h3>\n        <button\n          onClick={handleCreateSubscription}\n          disabled={!customerId || createSubscription.loading}\n        >\n          {createSubscription.loading\n            ? 'Creating...'\n            : 'Create Subscription'}\n        </button>\n        <button\n          onClick={handleCancelSubscription}\n          disabled={!subscriptionId || cancelSubscription.loading}\n        >\n          {cancelSubscription.loading\n            ? 'Cancelling...'\n            : 'Cancel Subscription'}\n        </button>\n        {subscriptionId && <p>Subscription ID: {subscriptionId}</p>}\n      </section>\n\n      {/* Refund Section */}\n      <section className=\"flex flex-col gap-2\">\n        <h3 className=\"text-foreground text-lg font-medium\">\n          Refund\n        </h3>\n        <input\n          type=\"text\"\n          placeholder=\"Enter Payment ID\"\n          value={paymentId}\n          onChange={e =>\n            setPaymentId(\n              (e.target as HTMLInputElement).value as string,\n            )\n          }\n          className=\"bg-background border-input rounded-md border p-2\"\n        />\n\n        <button\n          onClick={handleCreateRefund}\n          disabled={!paymentId || createRefund.loading}\n        >\n          {createRefund.loading\n            ? 'Processing...'\n            : 'Create $10 Refund'}\n        </button>\n      </section>\n    </div>\n  );\n};\n"},{"path":"shared/hooks/checkout-form.tsx","type":"registry:component","content":"'use client';\n\nimport * as React from 'react';\nimport { useCheckout } from '@paykit-sdk/react';\n\nexport const CheckoutForm = () => {\n  const { create } = useCheckout();\n  const [checkoutUrl, setCheckoutUrl] = React.useState<string | null>(\n    null,\n  );\n\n  const handleCreateCheckout = async () => {\n    const [data, error] = await create.run({\n      session_type: 'one_time',\n      item_id: 'price_123',\n      quantity: 1,\n      customer: 'cus_z123', // or { email: 'odii@gmail.com' }\n      metadata: { source: 'web_app' },\n      cancel_url: 'http://localhost:3000/dashboard',\n      success_url: 'http://localhost:3000/success',\n    });\n\n    if (error) {\n      console.error('Checkout creation failed:', error);\n      return;\n    }\n\n    setCheckoutUrl(data.payment_url);\n  };\n\n  return (\n    <div className=\"bg-background flex flex-col gap-4\">\n      <h2 className=\"text-foreground text-xl\">Proceed to buy</h2>\n\n      <button\n        disabled={create.loading}\n        onClick={handleCreateCheckout}\n        className=\"bg-primary text-primary-foreground rounded-md px-4 py-2\"\n      >\n        {create.loading ? 'Creating...' : 'Create $29.99 Checkout'}\n      </button>\n\n      {checkoutUrl && (\n        <div>\n          <p>Checkout created!</p>\n          <a\n            href={checkoutUrl}\n            target=\"_blank\"\n            rel=\"noopener noreferrer\"\n          >\n            Go to checkout →\n          </a>\n        </div>\n      )}\n    </div>\n  );\n};\n"}],"docs":"Add the PaykitWrapper to your Next.js layout file to wrap your app in the PaykitProvider.","meta":{"backend":"nextjs","provider":"stripe","orm":"none","database":"none","auth":"none"}},{"name":"stripe-nextjs-prisma","type":"registry:block","description":"Stripe payment integration for Next.js App Router with Prisma ORM","dependencies":["@prisma/client"],"devDependencies":["prisma"],"registryDependencies":["https://usepaykit.dev/r/stripe-nextjs"],"files":[{"path":"shared/schema/prisma.prisma","type":"registry:file","target":"prisma/schema-payments.prisma","content":"model Customer {\n  id        String   @id @default(cuid())\n  email     String   @unique\n  name      String\n  phone     String\n  metadata  Json?\n  createdAt DateTime @default(now())\n  updatedAt DateTime @updatedAt\n\n  payments      Payment[]\n  subscriptions Subscription[]\n  invoices      Invoice[]\n}\n\nmodel Payment {\n  id         String        @id\n  amount     Int\n  currency   String\n  status     PaymentStatus\n  itemId  String?       @map(\"item_id\")\n  metadata   Json\n  createdAt  DateTime      @default(now())\n  updatedAt  DateTime      @updatedAt\n\n  customerId String?   @map(\"customer_id\")\n  customer   Customer? @relation(fields: [customerId], references: [id], onDelete: Cascade)\n\n  // Guest checkout for when the customer is not yet determined\n  customerEmail String? @map(\"customer_email\")\n\n  refunds    Refund[]\n\n  paymentUrl String? @map(\"payment_url\")\n  requiresAction Boolean? @map(\"requires_action\")\n\n  @@index([customerId])\n  @@index([status])\n  @@index([customerEmail])\n}\n\nenum PaymentStatus {\n  pending\n  processing\n  requires_action\n  requires_capture\n  succeeded\n  canceled\n  failed\n}\n\nmodel Subscription {\n  id                  String               @id\n  amount              Int\n  currency            String\n  status              SubscriptionStatus\n  itemId              String               @map(\"item_id\")\n  billingInterval     String               @map(\"billing_interval\")\n  currentPeriodStart  DateTime             @map(\"current_period_start\")\n  currentPeriodEnd    DateTime             @map(\"current_period_end\")\n  metadata            Json?\n  customFields        Json?                @map(\"custom_fields\")\n  createdAt           DateTime             @default(now())\n  updatedAt           DateTime             @updatedAt\n\n  customerId String?   @map(\"customer_id\")\n  customer   Customer? @relation(fields: [customerId], references: [id], onDelete: Cascade)\n\n  // Guest checkout for when the customer is not yet determined\n  customerEmail String? @map(\"customer_email\")\n\n  invoices   Invoice[]\n\n  @@index([customerId])\n  @@index([status])\n  @@index([customerEmail])\n}\n\nenum SubscriptionStatus {\n  active\n  past_due\n  canceled\n  expired\n  pending\n}\n\nmodel Refund {\n  id        String   @id\n  amount    Int\n  currency  String\n  reason    String?\n  metadata  Json?\n  createdAt DateTime @default(now())\n\n  paymentId String  @map(\"payment_id\")\n  payment   Payment @relation(fields: [paymentId], references: [id], onDelete: Cascade)\n\n  @@index([paymentId])\n}\n\nmodel Invoice {\n  id             String        @id\n  subscriptionId String?       @map(\"subscription_id\")\n  billingMode    String        @map(\"billing_mode\")\n  amountPaid     Int           @map(\"amount_paid\")\n  currency       String\n  status         InvoiceStatus\n  paidAt         DateTime?     @map(\"paid_at\")\n  lineItems      Json?         @map(\"line_items\")\n  metadata       Json?\n  customFields   Json?         @map(\"custom_fields\")\n  createdAt      DateTime      @default(now())\n  updatedAt      DateTime      @updatedAt\n\n  customerId String?   @map(\"customer_id\")\n  customer   Customer? @relation(fields: [customerId], references: [id], onDelete: Cascade)\n\n  customerEmail String? @map(\"customer_email\")\n  subscription Subscription? @relation(fields: [subscriptionId], references: [id], onDelete: SetNull)\n\n  @@index([customerId])\n  @@index([subscriptionId])\n  @@index([status])\n  @@index([customerEmail])\n}\n\nenum InvoiceStatus {\n  paid\n  open\n}"}],"docs":"Move the content from prisma/schema-payments.prisma to your main schema.prisma file. \n Run 'npx prisma migrate dev' to create the tables.","meta":{"backend":"nextjs","provider":"stripe","orm":"prisma","database":"postgres","auth":"none"}},{"name":"stripe-nextjs-drizzle","type":"registry:block","description":"Stripe integration for Next.js with Drizzle ORM schemas for payments and subscriptions","dependencies":["drizzle-orm"],"devDependencies":["drizzle-kit"],"registryDependencies":["https://usepaykit.dev/r/stripe-nextjs"],"files":[{"type":"registry:file","target":"src/db/schema/payments.ts","path":"shared/schema/drizzle.ts","content":"import {\n  pgTable,\n  text,\n  timestamp,\n  integer,\n  json,\n  pgEnum,\n  index,\n  boolean,\n} from 'drizzle-orm/pg-core';\n\n// Enums\nexport const paymentStatusEnum = pgEnum('payment_status', [\n  'pending',\n  'processing',\n  'requires_action',\n  'requires_capture',\n  'succeeded',\n  'canceled',\n  'failed',\n]);\n\nexport const subscriptionStatusEnum = pgEnum('subscription_status', [\n  'active',\n  'past_due',\n  'canceled',\n  'expired',\n  'trialing',\n  'pending',\n]);\n\nexport const invoiceStatusEnum = pgEnum('invoice_status', [\n  'paid',\n  'open',\n]);\n\n// Tables\nexport const customers = pgTable('customers', {\n  id: text('id').primaryKey(),\n  email: text('email').notNull().unique(),\n  name: text('name').notNull(),\n  phone: text('phone'),\n  metadata: json('metadata'),\n  createdAt: timestamp('created_at').defaultNow().notNull(),\n  updatedAt: timestamp('updated_at').defaultNow().notNull(),\n});\n\nexport const payments = pgTable(\n  'payments',\n  {\n    id: text('id').primaryKey(),\n    amount: integer('amount').notNull(),\n    currency: text('currency').notNull(),\n    status: paymentStatusEnum('status').notNull(),\n    itemId: text('item_id'),\n    metadata: json('metadata').notNull(),\n    createdAt: timestamp('created_at').defaultNow().notNull(),\n    updatedAt: timestamp('updated_at').defaultNow().notNull(),\n\n    // Optional customer relationship\n    customerId: text('customer_id').references(() => customers.id, {\n      onDelete: 'cascade',\n    }),\n\n    // Guest checkout for when the customer is not yet determined\n    customerEmail: text('customer_email'),\n\n    paymentUrl: text('payment_url'),\n    requiresAction: boolean('requires_action').default(false),\n  },\n  table => ({\n    customerIdIdx: index('payments_customer_id_idx').on(\n      table.customerId,\n    ),\n    statusIdx: index('payments_status_idx').on(table.status),\n    customerEmailIdx: index('payments_customer_email_idx').on(\n      table.customerEmail,\n    ),\n  }),\n);\n\nexport const subscriptions = pgTable(\n  'subscriptions',\n  {\n    id: text('id').primaryKey(),\n    amount: integer('amount').notNull(),\n    currency: text('currency').notNull(),\n    status: subscriptionStatusEnum('status').notNull(),\n    itemId: text('item_id').notNull(),\n    billingInterval: text('billing_interval').notNull(),\n    currentPeriodStart: timestamp('current_period_start').notNull(),\n    currentPeriodEnd: timestamp('current_period_end').notNull(),\n    metadata: json('metadata'),\n    customFields: json('custom_fields'),\n    createdAt: timestamp('created_at').defaultNow().notNull(),\n    updatedAt: timestamp('updated_at').defaultNow().notNull(),\n\n    // Optional customer relationship\n    customerId: text('customer_id').references(() => customers.id, {\n      onDelete: 'cascade',\n    }),\n\n    // Guest checkout for when the customer is not yet determined\n    customerEmail: text('customer_email'),\n  },\n  table => ({\n    customerIdIdx: index('subscriptions_customer_id_idx').on(\n      table.customerId,\n    ),\n    statusIdx: index('subscriptions_status_idx').on(table.status),\n    customerEmailIdx: index('subscriptions_customer_email_idx').on(\n      table.customerEmail,\n    ),\n  }),\n);\n\nexport const refunds = pgTable(\n  'refunds',\n  {\n    id: text('id').primaryKey(),\n    amount: integer('amount').notNull(),\n    currency: text('currency').notNull(),\n    reason: text('reason'),\n    metadata: json('metadata'),\n    createdAt: timestamp('created_at').defaultNow().notNull(),\n\n    paymentId: text('payment_id')\n      .notNull()\n      .references(() => payments.id, { onDelete: 'cascade' }),\n  },\n  table => ({\n    paymentIdIdx: index('refunds_payment_id_idx').on(table.paymentId),\n  }),\n);\n\nexport const invoices = pgTable(\n  'invoices',\n  {\n    id: text('id').primaryKey(),\n    subscriptionId: text('subscription_id').references(\n      () => subscriptions.id,\n      {\n        onDelete: 'set null',\n      },\n    ),\n    billingMode: text('billing_mode').notNull(),\n    amountPaid: integer('amount_paid').notNull(),\n    currency: text('currency').notNull(),\n    status: invoiceStatusEnum('status').notNull(),\n    paidAt: timestamp('paid_at'),\n    lineItems: json('line_items'),\n    metadata: json('metadata'),\n    customFields: json('custom_fields'),\n    createdAt: timestamp('created_at').defaultNow().notNull(),\n    updatedAt: timestamp('updated_at').defaultNow().notNull(),\n\n    customerId: text('customer_id').references(() => customers.id, {\n      onDelete: 'cascade',\n    }),\n\n    // Guest checkout for when the customer is not yet determined\n    customerEmail: text('customer_email'),\n  },\n  table => ({\n    customerIdIdx: index('invoices_customer_id_idx').on(\n      table.customerId,\n    ),\n    subscriptionIdIdx: index('invoices_subscription_id_idx').on(\n      table.subscriptionId,\n    ),\n    statusIdx: index('invoices_status_idx').on(table.status),\n    customerEmailIdx: index('invoices_customer_email_idx').on(\n      table.customerEmail,\n    ),\n  }),\n);\n\nexport type Invoice = typeof invoices.$inferSelect;\nexport type Customer = typeof customers.$inferSelect;\nexport type Payment = typeof payments.$inferSelect;\nexport type Subscription = typeof subscriptions.$inferSelect;\nexport type Refund = typeof refunds.$inferSelect;\n"}],"docs":"Copy the content from src/db/schema/payments.ts to your own schema.ts file. \n Run 'drizzle-kit push' to sync with your database.","meta":{"backend":"nextjs","provider":"stripe","orm":"drizzle","database":"postgres","auth":"none"}},{"name":"stripe-nextjs-typeorm","type":"registry:block","description":"Stripe integration for Next.js with TypeORM schemas for payments and subscriptions","dependencies":["typeorm"],"devDependencies":["typeorm"],"registryDependencies":["https://usepaykit.dev/r/stripe-nextjs"],"files":[{"path":"shared/schema/typeorm.ts","type":"registry:file","target":"src/db/schema/payments.ts","content":"import {\n    Entity,\n    PrimaryColumn,\n    Column,\n    CreateDateColumn,\n    UpdateDateColumn,\n    ManyToOne,\n    JoinColumn,\n    Index,\n  } from 'typeorm';\n  \n  // Enums\n  export enum PaymentStatus {\n    PENDING = 'pending',\n    PROCESSING = 'processing',\n    REQUIRES_ACTION = 'requires_action',\n    REQUIRES_CAPTURE = 'requires_capture',\n    SUCCEEDED = 'succeeded',\n    CANCELED = 'canceled',\n    FAILED = 'failed',\n  }\n  \n  export enum SubscriptionStatus {\n    ACTIVE = 'active',\n    PAST_DUE = 'past_due',\n    CANCELED = 'canceled',\n    EXPIRED = 'expired',\n    TRIALING = 'trialing',\n    PENDING = 'pending',\n  }\n  \n  export enum InvoiceStatus {\n    PAID = 'paid',\n    OPEN = 'open',\n  }\n  \n  // Entities\n  @Entity('customers')\n  export class Customer {\n    @PrimaryColumn({ type: 'text' })\n    id!: string;\n  \n  @Column({ type: 'text', unique: true })\n  @Index()\n  email!: string;\n\n  @Column({ type: 'text' })\n  name!: string;\n\n  @Column({ type: 'text' })\n  phone!: string;\n\n  @Column({ type: 'jsonb', nullable: true })\n  metadata?: Record<string, any>;\n\n  @CreateDateColumn({ type: 'timestamp', name: 'created_at' })\n  createdAt!: Date;\n\n  @UpdateDateColumn({ type: 'timestamp', name: 'updated_at' })\n  updatedAt!: Date;\n}\n  \n  @Entity('payments')\n  export class Payment {\n    @PrimaryColumn({ type: 'text' })\n    id!: string;\n  \n    @Column({ type: 'integer' })\n    amount!: number;\n  \n    @Column({ type: 'text' })\n    currency!: string;\n  \n    @Column({\n      type: 'enum',\n      enum: PaymentStatus,\n    })\n    @Index()\n    status!: PaymentStatus;\n  \n    @Column({ type: 'text', nullable: true, name: 'item_id' })\n    itemId?: string;\n  \n    @Column({ type: 'jsonb' })\n    metadata!: Record<string, any>;\n  \n    @Column({ type: 'text', nullable: true, name: 'customer_id' })\n    @Index()\n    customerId?: string;\n  \n    @ManyToOne(() => Customer, { onDelete: 'CASCADE' })\n    @JoinColumn({ name: 'customer_id' })\n    customer?: Customer;\n  \n    @Column({ type: 'text', nullable: true, name: 'customer_email' })\n    @Index()\n    customerEmail?: string;\n  \n    @Column({ type: 'text', nullable: true, name: 'payment_url' })\n    paymentUrl?: string;\n\n    @Column({ type: 'boolean', nullable: true, name: 'requires_action' })\n    requiresAction?: boolean;\n\n    @CreateDateColumn({ type: 'timestamp', name: 'created_at' })\n    createdAt!: Date;\n  \n    @UpdateDateColumn({ type: 'timestamp', name: 'updated_at' })\n    updatedAt!: Date;\n  }\n  \n @Entity('subscriptions')\n export class Subscription {\n  @PrimaryColumn({ type: 'text' })\n  id!: string;\n  \n    @Column({ type: 'integer' })\n    amount!: number;\n  \n    @Column({ type: 'text' })\n    currency!: string;\n  \n    @Column({\n      type: 'enum',\n      enum: SubscriptionStatus,\n    })\n    @Index()\n    status!: SubscriptionStatus;\n  \n    @Column({ type: 'text', name: 'item_id' })\n    itemId!: string;\n  \n    @Column({ type: 'text', name: 'billing_interval' })\n    billingInterval!: string;\n  \n    @Column({ type: 'timestamp', name: 'current_period_start' })\n    currentPeriodStart!: Date;\n  \n    @Column({ type: 'timestamp', name: 'current_period_end' })\n    currentPeriodEnd!: Date;\n  \n    @Column({ type: 'jsonb', nullable: true })\n    metadata?: Record<string, any>;\n  \n    @Column({ type: 'jsonb', nullable: true, name: 'custom_fields' })\n    customFields?: Record<string, any>;\n  \n    @Column({ type: 'text', nullable: true, name: 'customer_id' })\n    @Index()\n    customerId?: string;\n  \n    @ManyToOne(() => Customer, { onDelete: 'CASCADE' })\n    @JoinColumn({ name: 'customer_id' })\n    customer?: Customer;\n  \n    @Column({ type: 'text', nullable: true, name: 'customer_email' })\n    @Index()\n    customerEmail?: string;\n  \n  @CreateDateColumn({ type: 'timestamp', name: 'created_at' })\n  createdAt!: Date;\n\n  @UpdateDateColumn({ type: 'timestamp', name: 'updated_at' })\n  updatedAt!: Date;\n}\n  \n  @Entity('refunds')\n  export class Refund {\n    @PrimaryColumn({ type: 'text' })\n    id!: string;\n  \n    @Column({ type: 'integer' })\n    amount!: number;\n  \n    @Column({ type: 'text' })\n    currency!: string;\n  \n    @Column({ type: 'text', nullable: true })\n    reason?: string;\n  \n    @Column({ type: 'jsonb', nullable: true })\n    metadata?: Record<string, any>;\n  \n    @Column({ type: 'text', name: 'payment_id' })\n    @Index()\n    paymentId!: string;\n  \n    @ManyToOne(() => Payment, { onDelete: 'CASCADE' })\n    @JoinColumn({ name: 'payment_id' })\n    payment!: Payment;\n  \n    @CreateDateColumn({ type: 'timestamp', name: 'created_at' })\n    createdAt!: Date;\n  }\n  \n  @Entity('invoices')\n  export class Invoice {\n    @PrimaryColumn({ type: 'text' })\n    id!: string;\n  \n    @Column({ type: 'text', nullable: true, name: 'subscription_id' })\n    @Index()\n    subscriptionId?: string;\n  \n    @ManyToOne(() => Subscription, { onDelete: 'SET NULL' })\n    @JoinColumn({ name: 'subscription_id' })\n    subscription?: Subscription;\n  \n    @Column({ type: 'text', name: 'billing_mode' })\n    billingMode!: string;\n  \n  @Column({ type: 'integer', name: 'amount_paid' })\n  amountPaid!: number;\n\n  @Column({ type: 'text' })\n  currency!: string;\n  \n    @Column({\n      type: 'enum',\n      enum: InvoiceStatus,\n    })\n    @Index()\n    status!: InvoiceStatus;\n  \n    @Column({ type: 'timestamp', nullable: true, name: 'paid_at' })\n    paidAt?: Date;\n  \n    @Column({ type: 'jsonb', nullable: true, name: 'line_items' })\n    lineItems?: Record<string, any>;\n  \n  @Column({ type: 'jsonb', nullable: true })\n  metadata?: Record<string, any>;\n\n  @Column({ type: 'jsonb', nullable: true, name: 'custom_fields' })\n  customFields?: Record<string, any>;\n  \n    @Column({ type: 'text', nullable: true, name: 'customer_id' })\n    @Index()\n    customerId?: string;\n  \n    @ManyToOne(() => Customer, { onDelete: 'CASCADE' })\n    @JoinColumn({ name: 'customer_id' })\n    customer?: Customer;\n  \n    @Column({ type: 'text', nullable: true, name: 'customer_email' })\n    @Index()\n    customerEmail?: string;\n  \n    @CreateDateColumn({ type: 'timestamp', name: 'created_at' })\n    createdAt!: Date;\n  \n    @UpdateDateColumn({ type: 'timestamp', name: 'updated_at' })\n    updatedAt!: Date;\n  }"}],"docs":"Copy the content from src/db/schema/payments.ts to your own schema.ts file. \n Run 'npx typeorm migration:generate' to create the migrations.","meta":{"backend":"nextjs","provider":"stripe","orm":"typeorm","database":"postgres","auth":"none"}},{"name":"stripe-nextjs-mongoose","type":"registry:block","description":"Stripe integration for Next.js with Mongoose schemas for payments and subscriptions","dependencies":["mongoose"],"devDependencies":["mongoose"],"registryDependencies":["https://usepaykit.dev/r/stripe-nextjs"],"files":[{"path":"shared/schema/mongoose.ts","type":"registry:file","target":"models/payments.ts","content":"import { Schema, model, Document, Types } from 'mongoose';\n\n// Enums\nexport enum PaymentStatus {\n  PENDING = 'pending',\n  PROCESSING = 'processing',\n  REQUIRES_ACTION = 'requires_action',\n  REQUIRES_CAPTURE = 'requires_capture',\n  SUCCEEDED = 'succeeded',\n  CANCELED = 'canceled',\n  FAILED = 'failed',\n}\n\nexport enum SubscriptionStatus {\n  ACTIVE = 'active',\n  PAST_DUE = 'past_due',\n  CANCELED = 'canceled',\n  EXPIRED = 'expired',\n  TRIALING = 'trialing',\n  PENDING = 'pending',\n}\n\nexport enum InvoiceStatus {\n  PAID = 'paid',\n  OPEN = 'open',\n}\n\n// Interfaces\nexport interface ICustomer extends Document {\n  _id: string;\n  email: string;\n  name: string;\n  phone: string | null;\n  metadata?: Record<string, any>;\n  createdAt: Date;\n  updatedAt: Date;\n}\n\nexport interface IPayment extends Document {\n  _id: string;\n  amount: number;\n  currency: string;\n  status: PaymentStatus;\n  itemId?: string;\n  metadata: Record<string, any>;\n  customerId?: Types.ObjectId | ICustomer;\n  customerEmail?: string;\n  paymentUrl?: string;\n  requiresAction?: boolean;\n  createdAt: Date;\n  updatedAt: Date;\n}\n\nexport interface ISubscription extends Document {\n  _id: string;\n  amount: number;\n  currency: string;\n  status: SubscriptionStatus;\n  itemId: string;\n  billingInterval: string;\n  currentPeriodStart: Date;\n  currentPeriodEnd: Date;\n  metadata?: Record<string, any>;\n  customFields?: Record<string, any>;\n  customerId?: Types.ObjectId | ICustomer;\n  customerEmail?: string;\n  createdAt: Date;\n  updatedAt: Date;\n}\n\nexport interface IRefund extends Document {\n  _id: string;\n  amount: number;\n  currency: string;\n  reason?: string;\n  metadata?: Record<string, any>;\n  paymentId: Types.ObjectId | IPayment;\n  createdAt: Date;\n}\n\nexport interface IInvoice extends Document {\n  _id: string;\n  subscriptionId?: Types.ObjectId | ISubscription;\n  billingMode: string;\n  amountPaid: number;\n  currency: string;\n  status: InvoiceStatus;\n  paidAt?: Date;\n  lineItems?: Record<string, any>;\n  metadata?: Record<string, any>;\n  customFields?: Record<string, any>;\n  customerId?: Types.ObjectId | ICustomer;\n  customerEmail?: string;\n  createdAt: Date;\n  updatedAt: Date;\n}\n\n// Schemas\nconst CustomerSchema = new Schema<ICustomer>(\n  {\n    _id: { type: String, required: true },\n    email: {\n      type: String,\n      required: true,\n      unique: true,\n      index: true,\n    },\n    name: { type: String, required: true },\n    phone: { type: String, required: false, default: null },\n    metadata: { type: Schema.Types.Mixed },\n  },\n  {\n    timestamps: true,\n    _id: false,\n  },\n);\n\nconst PaymentSchema = new Schema<IPayment>(\n  {\n    _id: { type: String, required: true },\n    amount: { type: Number, required: true },\n    currency: { type: String, required: true },\n    status: {\n      type: String,\n      enum: Object.values(PaymentStatus),\n      required: true,\n      index: true,\n    },\n    itemId: { type: String, index: true },\n    metadata: { type: Schema.Types.Mixed, required: true },\n    customerId: { type: String, ref: 'Customer', index: true },\n    customerEmail: { type: String, index: true },\n    paymentUrl: { type: String },\n    requiresAction: { type: Boolean, default: false },\n  },\n  {\n    timestamps: true,\n    _id: false,\n  },\n);\n\nconst SubscriptionSchema = new Schema<ISubscription>(\n  {\n    _id: { type: String, required: true },\n    amount: { type: Number, required: true },\n    currency: { type: String, required: true },\n    status: {\n      type: String,\n      enum: Object.values(SubscriptionStatus),\n      required: true,\n      index: true,\n    },\n    itemId: { type: String, required: true },\n    billingInterval: { type: String, required: true },\n    currentPeriodStart: { type: Date, required: true },\n    currentPeriodEnd: { type: Date, required: true },\n    metadata: { type: Schema.Types.Mixed },\n    customFields: { type: Schema.Types.Mixed },\n    customerId: { type: String, ref: 'Customer', index: true },\n    customerEmail: { type: String, index: true },\n  },\n  {\n    timestamps: true,\n    _id: false,\n  },\n);\n\nconst RefundSchema = new Schema<IRefund>(\n  {\n    _id: { type: String, required: true },\n    amount: { type: Number, required: true },\n    currency: { type: String, required: true },\n    reason: { type: String },\n    metadata: { type: Schema.Types.Mixed },\n    paymentId: {\n      type: String,\n      ref: 'Payment',\n      required: true,\n      index: true,\n    },\n    createdAt: { type: Date, default: Date.now },\n  },\n  {\n    _id: false,\n  },\n);\n\nconst InvoiceSchema = new Schema<IInvoice>(\n  {\n    _id: { type: String, required: true },\n    subscriptionId: {\n      type: String,\n      ref: 'Subscription',\n      index: true,\n    },\n    billingMode: { type: String, required: true },\n    amountPaid: { type: Number, required: true },\n    currency: { type: String, required: true },\n    status: {\n      type: String,\n      enum: Object.values(InvoiceStatus),\n      required: true,\n      index: true,\n    },\n    paidAt: { type: Date },\n    lineItems: { type: Schema.Types.Mixed },\n    metadata: { type: Schema.Types.Mixed },\n    customFields: { type: Schema.Types.Mixed },\n    customerId: { type: String, ref: 'Customer', index: true },\n    customerEmail: { type: String, index: true },\n  },\n  {\n    timestamps: true,\n    _id: false,\n  },\n);\n\n// Models\nexport const Customer = model<ICustomer>('Customer', CustomerSchema);\nexport const Payment = model<IPayment>('Payment', PaymentSchema);\nexport const Subscription = model<ISubscription>(\n  'Subscription',\n  SubscriptionSchema,\n);\nexport const Refund = model<IRefund>('Refund', RefundSchema);\nexport const Invoice = model<IInvoice>('Invoice', InvoiceSchema);\n"}],"docs":"Copy the content from models/payments.ts to your own models/payments.ts file.","meta":{"backend":"nextjs","provider":"stripe","orm":"mongoose","database":"mongodb","auth":"none"}},{"name":"stripe-nextjs-sequelize","type":"registry:block","description":"Stripe integration for Next.js with Sequelize schemas for payments and subscriptions","dependencies":["sequelize"],"devDependencies":["sequelize"],"registryDependencies":["https://usepaykit.dev/r/stripe-nextjs"],"files":[{"path":"shared/schema/sequelize.ts","type":"registry:file","target":"src/db/schema/payments.ts","content":"import { DataTypes, Model, Sequelize } from 'sequelize';\n\n// Initialize Sequelize (user will provide their connection)\nexport const initializeSequelize = (sequelize: Sequelize) => {\n  // Customer Model\n  class Customer extends Model {\n    declare id: string;\n    declare email: string;\n    declare name: string;\n    declare phone: string | null;\n    declare metadata?: Record<string, any>;\n    declare createdAt: Date;\n    declare updatedAt: Date;\n  }\n\n  Customer.init(\n    {\n      id: {\n        type: DataTypes.STRING,\n        primaryKey: true,\n      },\n      email: {\n        type: DataTypes.STRING,\n        allowNull: false,\n        unique: true,\n      },\n      name: {\n        type: DataTypes.STRING,\n        allowNull: false,\n      },\n      phone: {\n        type: DataTypes.STRING,\n        allowNull: true,\n      },\n      metadata: {\n        type: DataTypes.JSONB,\n        allowNull: true,\n      },\n    },\n    {\n      sequelize,\n      tableName: 'customers',\n      timestamps: true,\n      underscored: true,\n      indexes: [{ fields: ['email'] }],\n    },\n  );\n\n  // Payment Model\n  class Payment extends Model {\n    declare id: string;\n    declare amount: number;\n    declare currency: string;\n    declare status: string;\n    declare itemId?: string;\n    declare metadata: Record<string, any>;\n    declare customerId?: string;\n    declare customerEmail?: string;\n    declare paymentUrl?: string;\n    declare requiresAction?: boolean;\n    declare createdAt: Date;\n    declare updatedAt: Date;\n  }\n\n  Payment.init(\n    {\n      id: {\n        type: DataTypes.STRING,\n        primaryKey: true,\n      },\n      amount: {\n        type: DataTypes.INTEGER,\n        allowNull: false,\n      },\n      currency: {\n        type: DataTypes.STRING,\n        allowNull: false,\n      },\n      status: {\n        type: DataTypes.ENUM(\n          'pending',\n          'processing',\n          'requires_action',\n          'requires_capture',\n          'succeeded',\n          'canceled',\n          'failed',\n        ),\n        allowNull: false,\n      },\n      itemId: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'item_id',\n      },\n      metadata: {\n        type: DataTypes.JSONB,\n        allowNull: false,\n      },\n      customerId: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'customer_id',\n        references: {\n          model: 'customers',\n          key: 'id',\n        },\n        onDelete: 'CASCADE',\n      },\n      customerEmail: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'customer_email',\n      },\n      paymentUrl: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'payment_url',\n      },\n      requiresAction: {\n        type: DataTypes.BOOLEAN,\n        allowNull: true,\n        field: 'requires_action',\n        defaultValue: false,\n      },\n    },\n    {\n      sequelize,\n      tableName: 'payments',\n      timestamps: true,\n      underscored: true,\n      indexes: [\n        { fields: ['customer_id'] },\n        { fields: ['status'] },\n        { fields: ['customer_email'] },\n      ],\n    },\n  );\n\n  // Subscription Model\n  class Subscription extends Model {\n    declare id: string;\n    declare amount: number;\n    declare currency: string;\n    declare status: string;\n    declare itemId: string;\n    declare billingInterval: string;\n    declare currentPeriodStart: Date;\n    declare currentPeriodEnd: Date;\n    declare metadata?: Record<string, any>;\n    declare customFields?: Record<string, any>;\n    declare customerId?: string;\n    declare customerEmail?: string;\n    declare createdAt: Date;\n    declare updatedAt: Date;\n  }\n\n  Subscription.init(\n    {\n      id: {\n        type: DataTypes.STRING,\n        primaryKey: true,\n      },\n      amount: {\n        type: DataTypes.INTEGER,\n        allowNull: false,\n      },\n      currency: {\n        type: DataTypes.STRING,\n        allowNull: false,\n      },\n      status: {\n        type: DataTypes.ENUM(\n          'active',\n          'past_due',\n          'canceled',\n          'expired',\n          'trialing',\n          'pending',\n        ),\n        allowNull: false,\n      },\n      itemId: {\n        type: DataTypes.STRING,\n        allowNull: false,\n        field: 'item_id',\n      },\n      billingInterval: {\n        type: DataTypes.STRING,\n        allowNull: false,\n        field: 'billing_interval',\n      },\n      currentPeriodStart: {\n        type: DataTypes.DATE,\n        allowNull: false,\n        field: 'current_period_start',\n      },\n      currentPeriodEnd: {\n        type: DataTypes.DATE,\n        allowNull: false,\n        field: 'current_period_end',\n      },\n      metadata: {\n        type: DataTypes.JSONB,\n        allowNull: true,\n      },\n      customFields: {\n        type: DataTypes.JSONB,\n        allowNull: true,\n        field: 'custom_fields',\n      },\n      customerId: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'customer_id',\n        references: {\n          model: 'customers',\n          key: 'id',\n        },\n        onDelete: 'CASCADE',\n      },\n      customerEmail: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'customer_email',\n      },\n    },\n    {\n      sequelize,\n      tableName: 'subscriptions',\n      timestamps: true,\n      underscored: true,\n      indexes: [\n        { fields: ['customer_id'] },\n        { fields: ['status'] },\n        { fields: ['customer_email'] },\n      ],\n    },\n  );\n\n  // Refund Model\n  class Refund extends Model {\n    declare id: string;\n    declare amount: number;\n    declare currency: string;\n    declare reason?: string;\n    declare metadata?: Record<string, any>;\n    declare paymentId: string;\n    declare createdAt: Date;\n  }\n\n  Refund.init(\n    {\n      id: {\n        type: DataTypes.STRING,\n        primaryKey: true,\n      },\n      amount: {\n        type: DataTypes.INTEGER,\n        allowNull: false,\n      },\n      currency: {\n        type: DataTypes.STRING,\n        allowNull: false,\n      },\n      reason: {\n        type: DataTypes.STRING,\n        allowNull: true,\n      },\n      metadata: {\n        type: DataTypes.JSONB,\n        allowNull: true,\n      },\n      paymentId: {\n        type: DataTypes.STRING,\n        allowNull: false,\n        field: 'payment_id',\n        references: {\n          model: 'payments',\n          key: 'id',\n        },\n        onDelete: 'CASCADE',\n      },\n    },\n    {\n      sequelize,\n      tableName: 'refunds',\n      timestamps: false,\n      underscored: true,\n      indexes: [{ fields: ['payment_id'] }],\n    },\n  );\n\n  // Invoice Model\n  class Invoice extends Model {\n    declare id: string;\n    declare subscriptionId?: string;\n    declare billingMode: string;\n    declare amountPaid: number;\n    declare currency: string;\n    declare status: string;\n    declare paidAt?: Date;\n    declare lineItems?: Record<string, any>;\n    declare metadata?: Record<string, any>;\n    declare customFields?: Record<string, any>;\n    declare customerId?: string;\n    declare customerEmail?: string;\n    declare createdAt: Date;\n    declare updatedAt: Date;\n  }\n\n  Invoice.init(\n    {\n      id: {\n        type: DataTypes.STRING,\n        primaryKey: true,\n      },\n      subscriptionId: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'subscription_id',\n        references: {\n          model: 'subscriptions',\n          key: 'id',\n        },\n        onDelete: 'SET NULL',\n      },\n      billingMode: {\n        type: DataTypes.STRING,\n        allowNull: false,\n        field: 'billing_mode',\n      },\n      amountPaid: {\n        type: DataTypes.INTEGER,\n        allowNull: false,\n        field: 'amount_paid',\n      },\n      currency: {\n        type: DataTypes.STRING,\n        allowNull: false,\n      },\n      status: {\n        type: DataTypes.ENUM('paid', 'open'),\n        allowNull: false,\n      },\n      paidAt: {\n        type: DataTypes.DATE,\n        allowNull: true,\n        field: 'paid_at',\n      },\n      lineItems: {\n        type: DataTypes.JSONB,\n        allowNull: true,\n        field: 'line_items',\n      },\n      metadata: {\n        type: DataTypes.JSONB,\n        allowNull: true,\n      },\n      customFields: {\n        type: DataTypes.JSONB,\n        allowNull: true,\n        field: 'custom_fields',\n      },\n      customerId: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'customer_id',\n        references: {\n          model: 'customers',\n          key: 'id',\n        },\n        onDelete: 'CASCADE',\n      },\n      customerEmail: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'customer_email',\n      },\n    },\n    {\n      sequelize,\n      tableName: 'invoices',\n      timestamps: true,\n      underscored: true,\n      indexes: [\n        { fields: ['customer_id'] },\n        { fields: ['subscription_id'] },\n        { fields: ['status'] },\n        { fields: ['customer_email'] },\n      ],\n    },\n  );\n\n  // Define associations\n  Customer.hasMany(Payment, {\n    foreignKey: 'customerId',\n    onDelete: 'CASCADE',\n  });\n  Payment.belongsTo(Customer, { foreignKey: 'customerId' });\n\n  Customer.hasMany(Subscription, {\n    foreignKey: 'customerId',\n    onDelete: 'CASCADE',\n  });\n  Subscription.belongsTo(Customer, { foreignKey: 'customerId' });\n\n  Payment.hasMany(Refund, {\n    foreignKey: 'paymentId',\n    onDelete: 'CASCADE',\n  });\n  Refund.belongsTo(Payment, { foreignKey: 'paymentId' });\n\n  Customer.hasMany(Invoice, {\n    foreignKey: 'customerId',\n    onDelete: 'CASCADE',\n  });\n  Invoice.belongsTo(Customer, { foreignKey: 'customerId' });\n\n  Subscription.hasMany(Invoice, {\n    foreignKey: 'subscriptionId',\n    onDelete: 'SET NULL',\n  });\n  Invoice.belongsTo(Subscription, { foreignKey: 'subscriptionId' });\n\n  return {\n    Customer,\n    Payment,\n    Subscription,\n    Refund,\n    Invoice,\n  };\n};\n\n// Export types\nexport type CustomerModel = ReturnType<\n  typeof initializeSequelize\n>['Customer'];\nexport type PaymentModel = ReturnType<\n  typeof initializeSequelize\n>['Payment'];\nexport type SubscriptionModel = ReturnType<\n  typeof initializeSequelize\n>['Subscription'];\nexport type RefundModel = ReturnType<\n  typeof initializeSequelize\n>['Refund'];\nexport type InvoiceModel = ReturnType<\n  typeof initializeSequelize\n>['Invoice'];\n"}],"docs":"Copy the content from src/db/schema/payments.ts to your own schema folder.","meta":{"backend":"nextjs","provider":"stripe","orm":"sequelize","database":"mysql","auth":"none"}},{"name":"stripe-hono-prisma","type":"registry:block","description":"Stripe integration for Hono with Prisma ORM schemas for payments and subscriptions","dependencies":["prisma"],"devDependencies":["prisma"],"registryDependencies":["https://usepaykit.dev/r/stripe-hono"],"files":[{"type":"registry:file","target":"prisma/schema-payments.prisma","path":"shared/schema/prisma.prisma","content":"model Customer {\n  id        String   @id @default(cuid())\n  email     String   @unique\n  name      String\n  phone     String\n  metadata  Json?\n  createdAt DateTime @default(now())\n  updatedAt DateTime @updatedAt\n\n  payments      Payment[]\n  subscriptions Subscription[]\n  invoices      Invoice[]\n}\n\nmodel Payment {\n  id         String        @id\n  amount     Int\n  currency   String\n  status     PaymentStatus\n  itemId  String?       @map(\"item_id\")\n  metadata   Json\n  createdAt  DateTime      @default(now())\n  updatedAt  DateTime      @updatedAt\n\n  customerId String?   @map(\"customer_id\")\n  customer   Customer? @relation(fields: [customerId], references: [id], onDelete: Cascade)\n\n  // Guest checkout for when the customer is not yet determined\n  customerEmail String? @map(\"customer_email\")\n\n  refunds    Refund[]\n\n  paymentUrl String? @map(\"payment_url\")\n  requiresAction Boolean? @map(\"requires_action\")\n\n  @@index([customerId])\n  @@index([status])\n  @@index([customerEmail])\n}\n\nenum PaymentStatus {\n  pending\n  processing\n  requires_action\n  requires_capture\n  succeeded\n  canceled\n  failed\n}\n\nmodel Subscription {\n  id                  String               @id\n  amount              Int\n  currency            String\n  status              SubscriptionStatus\n  itemId              String               @map(\"item_id\")\n  billingInterval     String               @map(\"billing_interval\")\n  currentPeriodStart  DateTime             @map(\"current_period_start\")\n  currentPeriodEnd    DateTime             @map(\"current_period_end\")\n  metadata            Json?\n  customFields        Json?                @map(\"custom_fields\")\n  createdAt           DateTime             @default(now())\n  updatedAt           DateTime             @updatedAt\n\n  customerId String?   @map(\"customer_id\")\n  customer   Customer? @relation(fields: [customerId], references: [id], onDelete: Cascade)\n\n  // Guest checkout for when the customer is not yet determined\n  customerEmail String? @map(\"customer_email\")\n\n  invoices   Invoice[]\n\n  @@index([customerId])\n  @@index([status])\n  @@index([customerEmail])\n}\n\nenum SubscriptionStatus {\n  active\n  past_due\n  canceled\n  expired\n  pending\n}\n\nmodel Refund {\n  id        String   @id\n  amount    Int\n  currency  String\n  reason    String?\n  metadata  Json?\n  createdAt DateTime @default(now())\n\n  paymentId String  @map(\"payment_id\")\n  payment   Payment @relation(fields: [paymentId], references: [id], onDelete: Cascade)\n\n  @@index([paymentId])\n}\n\nmodel Invoice {\n  id             String        @id\n  subscriptionId String?       @map(\"subscription_id\")\n  billingMode    String        @map(\"billing_mode\")\n  amountPaid     Int           @map(\"amount_paid\")\n  currency       String\n  status         InvoiceStatus\n  paidAt         DateTime?     @map(\"paid_at\")\n  lineItems      Json?         @map(\"line_items\")\n  metadata       Json?\n  customFields   Json?         @map(\"custom_fields\")\n  createdAt      DateTime      @default(now())\n  updatedAt      DateTime      @updatedAt\n\n  customerId String?   @map(\"customer_id\")\n  customer   Customer? @relation(fields: [customerId], references: [id], onDelete: Cascade)\n\n  customerEmail String? @map(\"customer_email\")\n  subscription Subscription? @relation(fields: [subscriptionId], references: [id], onDelete: SetNull)\n\n  @@index([customerId])\n  @@index([subscriptionId])\n  @@index([status])\n  @@index([customerEmail])\n}\n\nenum InvoiceStatus {\n  paid\n  open\n}"}],"docs":"Copy the content from prisma/schema-payments.prisma to your own schema.prisma file.\nRun 'prisma migrate dev' to create the tables.","meta":{"backend":"hono","provider":"stripe","orm":"prisma","database":"sqlite","auth":"none"}},{"name":"stripe-hono-drizzle","type":"registry:block","description":"Stripe integration for Hono with Drizzle ORM schemas for payments and subscriptions","dependencies":["drizzle-orm"],"devDependencies":["drizzle-kit"],"registryDependencies":["https://usepaykit.dev/r/stripe-hono"],"files":[{"type":"registry:file","target":"src/db/schema/payments.ts","path":"shared/schema/drizzle.ts","content":"import {\n  pgTable,\n  text,\n  timestamp,\n  integer,\n  json,\n  pgEnum,\n  index,\n  boolean,\n} from 'drizzle-orm/pg-core';\n\n// Enums\nexport const paymentStatusEnum = pgEnum('payment_status', [\n  'pending',\n  'processing',\n  'requires_action',\n  'requires_capture',\n  'succeeded',\n  'canceled',\n  'failed',\n]);\n\nexport const subscriptionStatusEnum = pgEnum('subscription_status', [\n  'active',\n  'past_due',\n  'canceled',\n  'expired',\n  'trialing',\n  'pending',\n]);\n\nexport const invoiceStatusEnum = pgEnum('invoice_status', [\n  'paid',\n  'open',\n]);\n\n// Tables\nexport const customers = pgTable('customers', {\n  id: text('id').primaryKey(),\n  email: text('email').notNull().unique(),\n  name: text('name').notNull(),\n  phone: text('phone'),\n  metadata: json('metadata'),\n  createdAt: timestamp('created_at').defaultNow().notNull(),\n  updatedAt: timestamp('updated_at').defaultNow().notNull(),\n});\n\nexport const payments = pgTable(\n  'payments',\n  {\n    id: text('id').primaryKey(),\n    amount: integer('amount').notNull(),\n    currency: text('currency').notNull(),\n    status: paymentStatusEnum('status').notNull(),\n    itemId: text('item_id'),\n    metadata: json('metadata').notNull(),\n    createdAt: timestamp('created_at').defaultNow().notNull(),\n    updatedAt: timestamp('updated_at').defaultNow().notNull(),\n\n    // Optional customer relationship\n    customerId: text('customer_id').references(() => customers.id, {\n      onDelete: 'cascade',\n    }),\n\n    // Guest checkout for when the customer is not yet determined\n    customerEmail: text('customer_email'),\n\n    paymentUrl: text('payment_url'),\n    requiresAction: boolean('requires_action').default(false),\n  },\n  table => ({\n    customerIdIdx: index('payments_customer_id_idx').on(\n      table.customerId,\n    ),\n    statusIdx: index('payments_status_idx').on(table.status),\n    customerEmailIdx: index('payments_customer_email_idx').on(\n      table.customerEmail,\n    ),\n  }),\n);\n\nexport const subscriptions = pgTable(\n  'subscriptions',\n  {\n    id: text('id').primaryKey(),\n    amount: integer('amount').notNull(),\n    currency: text('currency').notNull(),\n    status: subscriptionStatusEnum('status').notNull(),\n    itemId: text('item_id').notNull(),\n    billingInterval: text('billing_interval').notNull(),\n    currentPeriodStart: timestamp('current_period_start').notNull(),\n    currentPeriodEnd: timestamp('current_period_end').notNull(),\n    metadata: json('metadata'),\n    customFields: json('custom_fields'),\n    createdAt: timestamp('created_at').defaultNow().notNull(),\n    updatedAt: timestamp('updated_at').defaultNow().notNull(),\n\n    // Optional customer relationship\n    customerId: text('customer_id').references(() => customers.id, {\n      onDelete: 'cascade',\n    }),\n\n    // Guest checkout for when the customer is not yet determined\n    customerEmail: text('customer_email'),\n  },\n  table => ({\n    customerIdIdx: index('subscriptions_customer_id_idx').on(\n      table.customerId,\n    ),\n    statusIdx: index('subscriptions_status_idx').on(table.status),\n    customerEmailIdx: index('subscriptions_customer_email_idx').on(\n      table.customerEmail,\n    ),\n  }),\n);\n\nexport const refunds = pgTable(\n  'refunds',\n  {\n    id: text('id').primaryKey(),\n    amount: integer('amount').notNull(),\n    currency: text('currency').notNull(),\n    reason: text('reason'),\n    metadata: json('metadata'),\n    createdAt: timestamp('created_at').defaultNow().notNull(),\n\n    paymentId: text('payment_id')\n      .notNull()\n      .references(() => payments.id, { onDelete: 'cascade' }),\n  },\n  table => ({\n    paymentIdIdx: index('refunds_payment_id_idx').on(table.paymentId),\n  }),\n);\n\nexport const invoices = pgTable(\n  'invoices',\n  {\n    id: text('id').primaryKey(),\n    subscriptionId: text('subscription_id').references(\n      () => subscriptions.id,\n      {\n        onDelete: 'set null',\n      },\n    ),\n    billingMode: text('billing_mode').notNull(),\n    amountPaid: integer('amount_paid').notNull(),\n    currency: text('currency').notNull(),\n    status: invoiceStatusEnum('status').notNull(),\n    paidAt: timestamp('paid_at'),\n    lineItems: json('line_items'),\n    metadata: json('metadata'),\n    customFields: json('custom_fields'),\n    createdAt: timestamp('created_at').defaultNow().notNull(),\n    updatedAt: timestamp('updated_at').defaultNow().notNull(),\n\n    customerId: text('customer_id').references(() => customers.id, {\n      onDelete: 'cascade',\n    }),\n\n    // Guest checkout for when the customer is not yet determined\n    customerEmail: text('customer_email'),\n  },\n  table => ({\n    customerIdIdx: index('invoices_customer_id_idx').on(\n      table.customerId,\n    ),\n    subscriptionIdIdx: index('invoices_subscription_id_idx').on(\n      table.subscriptionId,\n    ),\n    statusIdx: index('invoices_status_idx').on(table.status),\n    customerEmailIdx: index('invoices_customer_email_idx').on(\n      table.customerEmail,\n    ),\n  }),\n);\n\nexport type Invoice = typeof invoices.$inferSelect;\nexport type Customer = typeof customers.$inferSelect;\nexport type Payment = typeof payments.$inferSelect;\nexport type Subscription = typeof subscriptions.$inferSelect;\nexport type Refund = typeof refunds.$inferSelect;\n"}],"docs":"Copy the content from src/db/schema/payments.ts to your own schema.ts file. \n Run 'drizzle-kit push' to sync with your database.","meta":{"backend":"hono","provider":"stripe","orm":"drizzle","database":"postgres","auth":"none"}},{"name":"stripe-hono-sequelize","type":"registry:block","description":"Stripe integration for Hono with Sequelize schemas for payments and subscriptions","dependencies":["sequelize"],"devDependencies":["sequelize"],"registryDependencies":["https://usepaykit.dev/r/stripe-hono"],"files":[{"type":"registry:file","target":"src/db/schema/payments.ts","path":"shared/schema/sequelize.ts","content":"import { DataTypes, Model, Sequelize } from 'sequelize';\n\n// Initialize Sequelize (user will provide their connection)\nexport const initializeSequelize = (sequelize: Sequelize) => {\n  // Customer Model\n  class Customer extends Model {\n    declare id: string;\n    declare email: string;\n    declare name: string;\n    declare phone: string | null;\n    declare metadata?: Record<string, any>;\n    declare createdAt: Date;\n    declare updatedAt: Date;\n  }\n\n  Customer.init(\n    {\n      id: {\n        type: DataTypes.STRING,\n        primaryKey: true,\n      },\n      email: {\n        type: DataTypes.STRING,\n        allowNull: false,\n        unique: true,\n      },\n      name: {\n        type: DataTypes.STRING,\n        allowNull: false,\n      },\n      phone: {\n        type: DataTypes.STRING,\n        allowNull: true,\n      },\n      metadata: {\n        type: DataTypes.JSONB,\n        allowNull: true,\n      },\n    },\n    {\n      sequelize,\n      tableName: 'customers',\n      timestamps: true,\n      underscored: true,\n      indexes: [{ fields: ['email'] }],\n    },\n  );\n\n  // Payment Model\n  class Payment extends Model {\n    declare id: string;\n    declare amount: number;\n    declare currency: string;\n    declare status: string;\n    declare itemId?: string;\n    declare metadata: Record<string, any>;\n    declare customerId?: string;\n    declare customerEmail?: string;\n    declare paymentUrl?: string;\n    declare requiresAction?: boolean;\n    declare createdAt: Date;\n    declare updatedAt: Date;\n  }\n\n  Payment.init(\n    {\n      id: {\n        type: DataTypes.STRING,\n        primaryKey: true,\n      },\n      amount: {\n        type: DataTypes.INTEGER,\n        allowNull: false,\n      },\n      currency: {\n        type: DataTypes.STRING,\n        allowNull: false,\n      },\n      status: {\n        type: DataTypes.ENUM(\n          'pending',\n          'processing',\n          'requires_action',\n          'requires_capture',\n          'succeeded',\n          'canceled',\n          'failed',\n        ),\n        allowNull: false,\n      },\n      itemId: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'item_id',\n      },\n      metadata: {\n        type: DataTypes.JSONB,\n        allowNull: false,\n      },\n      customerId: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'customer_id',\n        references: {\n          model: 'customers',\n          key: 'id',\n        },\n        onDelete: 'CASCADE',\n      },\n      customerEmail: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'customer_email',\n      },\n      paymentUrl: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'payment_url',\n      },\n      requiresAction: {\n        type: DataTypes.BOOLEAN,\n        allowNull: true,\n        field: 'requires_action',\n        defaultValue: false,\n      },\n    },\n    {\n      sequelize,\n      tableName: 'payments',\n      timestamps: true,\n      underscored: true,\n      indexes: [\n        { fields: ['customer_id'] },\n        { fields: ['status'] },\n        { fields: ['customer_email'] },\n      ],\n    },\n  );\n\n  // Subscription Model\n  class Subscription extends Model {\n    declare id: string;\n    declare amount: number;\n    declare currency: string;\n    declare status: string;\n    declare itemId: string;\n    declare billingInterval: string;\n    declare currentPeriodStart: Date;\n    declare currentPeriodEnd: Date;\n    declare metadata?: Record<string, any>;\n    declare customFields?: Record<string, any>;\n    declare customerId?: string;\n    declare customerEmail?: string;\n    declare createdAt: Date;\n    declare updatedAt: Date;\n  }\n\n  Subscription.init(\n    {\n      id: {\n        type: DataTypes.STRING,\n        primaryKey: true,\n      },\n      amount: {\n        type: DataTypes.INTEGER,\n        allowNull: false,\n      },\n      currency: {\n        type: DataTypes.STRING,\n        allowNull: false,\n      },\n      status: {\n        type: DataTypes.ENUM(\n          'active',\n          'past_due',\n          'canceled',\n          'expired',\n          'trialing',\n          'pending',\n        ),\n        allowNull: false,\n      },\n      itemId: {\n        type: DataTypes.STRING,\n        allowNull: false,\n        field: 'item_id',\n      },\n      billingInterval: {\n        type: DataTypes.STRING,\n        allowNull: false,\n        field: 'billing_interval',\n      },\n      currentPeriodStart: {\n        type: DataTypes.DATE,\n        allowNull: false,\n        field: 'current_period_start',\n      },\n      currentPeriodEnd: {\n        type: DataTypes.DATE,\n        allowNull: false,\n        field: 'current_period_end',\n      },\n      metadata: {\n        type: DataTypes.JSONB,\n        allowNull: true,\n      },\n      customFields: {\n        type: DataTypes.JSONB,\n        allowNull: true,\n        field: 'custom_fields',\n      },\n      customerId: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'customer_id',\n        references: {\n          model: 'customers',\n          key: 'id',\n        },\n        onDelete: 'CASCADE',\n      },\n      customerEmail: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'customer_email',\n      },\n    },\n    {\n      sequelize,\n      tableName: 'subscriptions',\n      timestamps: true,\n      underscored: true,\n      indexes: [\n        { fields: ['customer_id'] },\n        { fields: ['status'] },\n        { fields: ['customer_email'] },\n      ],\n    },\n  );\n\n  // Refund Model\n  class Refund extends Model {\n    declare id: string;\n    declare amount: number;\n    declare currency: string;\n    declare reason?: string;\n    declare metadata?: Record<string, any>;\n    declare paymentId: string;\n    declare createdAt: Date;\n  }\n\n  Refund.init(\n    {\n      id: {\n        type: DataTypes.STRING,\n        primaryKey: true,\n      },\n      amount: {\n        type: DataTypes.INTEGER,\n        allowNull: false,\n      },\n      currency: {\n        type: DataTypes.STRING,\n        allowNull: false,\n      },\n      reason: {\n        type: DataTypes.STRING,\n        allowNull: true,\n      },\n      metadata: {\n        type: DataTypes.JSONB,\n        allowNull: true,\n      },\n      paymentId: {\n        type: DataTypes.STRING,\n        allowNull: false,\n        field: 'payment_id',\n        references: {\n          model: 'payments',\n          key: 'id',\n        },\n        onDelete: 'CASCADE',\n      },\n    },\n    {\n      sequelize,\n      tableName: 'refunds',\n      timestamps: false,\n      underscored: true,\n      indexes: [{ fields: ['payment_id'] }],\n    },\n  );\n\n  // Invoice Model\n  class Invoice extends Model {\n    declare id: string;\n    declare subscriptionId?: string;\n    declare billingMode: string;\n    declare amountPaid: number;\n    declare currency: string;\n    declare status: string;\n    declare paidAt?: Date;\n    declare lineItems?: Record<string, any>;\n    declare metadata?: Record<string, any>;\n    declare customFields?: Record<string, any>;\n    declare customerId?: string;\n    declare customerEmail?: string;\n    declare createdAt: Date;\n    declare updatedAt: Date;\n  }\n\n  Invoice.init(\n    {\n      id: {\n        type: DataTypes.STRING,\n        primaryKey: true,\n      },\n      subscriptionId: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'subscription_id',\n        references: {\n          model: 'subscriptions',\n          key: 'id',\n        },\n        onDelete: 'SET NULL',\n      },\n      billingMode: {\n        type: DataTypes.STRING,\n        allowNull: false,\n        field: 'billing_mode',\n      },\n      amountPaid: {\n        type: DataTypes.INTEGER,\n        allowNull: false,\n        field: 'amount_paid',\n      },\n      currency: {\n        type: DataTypes.STRING,\n        allowNull: false,\n      },\n      status: {\n        type: DataTypes.ENUM('paid', 'open'),\n        allowNull: false,\n      },\n      paidAt: {\n        type: DataTypes.DATE,\n        allowNull: true,\n        field: 'paid_at',\n      },\n      lineItems: {\n        type: DataTypes.JSONB,\n        allowNull: true,\n        field: 'line_items',\n      },\n      metadata: {\n        type: DataTypes.JSONB,\n        allowNull: true,\n      },\n      customFields: {\n        type: DataTypes.JSONB,\n        allowNull: true,\n        field: 'custom_fields',\n      },\n      customerId: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'customer_id',\n        references: {\n          model: 'customers',\n          key: 'id',\n        },\n        onDelete: 'CASCADE',\n      },\n      customerEmail: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'customer_email',\n      },\n    },\n    {\n      sequelize,\n      tableName: 'invoices',\n      timestamps: true,\n      underscored: true,\n      indexes: [\n        { fields: ['customer_id'] },\n        { fields: ['subscription_id'] },\n        { fields: ['status'] },\n        { fields: ['customer_email'] },\n      ],\n    },\n  );\n\n  // Define associations\n  Customer.hasMany(Payment, {\n    foreignKey: 'customerId',\n    onDelete: 'CASCADE',\n  });\n  Payment.belongsTo(Customer, { foreignKey: 'customerId' });\n\n  Customer.hasMany(Subscription, {\n    foreignKey: 'customerId',\n    onDelete: 'CASCADE',\n  });\n  Subscription.belongsTo(Customer, { foreignKey: 'customerId' });\n\n  Payment.hasMany(Refund, {\n    foreignKey: 'paymentId',\n    onDelete: 'CASCADE',\n  });\n  Refund.belongsTo(Payment, { foreignKey: 'paymentId' });\n\n  Customer.hasMany(Invoice, {\n    foreignKey: 'customerId',\n    onDelete: 'CASCADE',\n  });\n  Invoice.belongsTo(Customer, { foreignKey: 'customerId' });\n\n  Subscription.hasMany(Invoice, {\n    foreignKey: 'subscriptionId',\n    onDelete: 'SET NULL',\n  });\n  Invoice.belongsTo(Subscription, { foreignKey: 'subscriptionId' });\n\n  return {\n    Customer,\n    Payment,\n    Subscription,\n    Refund,\n    Invoice,\n  };\n};\n\n// Export types\nexport type CustomerModel = ReturnType<\n  typeof initializeSequelize\n>['Customer'];\nexport type PaymentModel = ReturnType<\n  typeof initializeSequelize\n>['Payment'];\nexport type SubscriptionModel = ReturnType<\n  typeof initializeSequelize\n>['Subscription'];\nexport type RefundModel = ReturnType<\n  typeof initializeSequelize\n>['Refund'];\nexport type InvoiceModel = ReturnType<\n  typeof initializeSequelize\n>['Invoice'];\n"}],"docs":"Copy the content from src/db/schema/payments.ts to your own schema.ts file. \n Run 'sequelize migration:generate' to create the migrations.","meta":{"backend":"hono","provider":"stripe","orm":"sequelize","database":"sqlite","auth":"none"}},{"name":"stripe-hono-mongoose","type":"registry:block","description":"Stripe integration for Hono with Mongoose schemas for payments and subscriptions","dependencies":["mongoose"],"devDependencies":["mongoose"],"registryDependencies":["https://usepaykit.dev/r/stripe-hono"],"files":[{"type":"registry:file","target":"models/payments.ts","path":"shared/schema/mongoose.ts","content":"import { Schema, model, Document, Types } from 'mongoose';\n\n// Enums\nexport enum PaymentStatus {\n  PENDING = 'pending',\n  PROCESSING = 'processing',\n  REQUIRES_ACTION = 'requires_action',\n  REQUIRES_CAPTURE = 'requires_capture',\n  SUCCEEDED = 'succeeded',\n  CANCELED = 'canceled',\n  FAILED = 'failed',\n}\n\nexport enum SubscriptionStatus {\n  ACTIVE = 'active',\n  PAST_DUE = 'past_due',\n  CANCELED = 'canceled',\n  EXPIRED = 'expired',\n  TRIALING = 'trialing',\n  PENDING = 'pending',\n}\n\nexport enum InvoiceStatus {\n  PAID = 'paid',\n  OPEN = 'open',\n}\n\n// Interfaces\nexport interface ICustomer extends Document {\n  _id: string;\n  email: string;\n  name: string;\n  phone: string | null;\n  metadata?: Record<string, any>;\n  createdAt: Date;\n  updatedAt: Date;\n}\n\nexport interface IPayment extends Document {\n  _id: string;\n  amount: number;\n  currency: string;\n  status: PaymentStatus;\n  itemId?: string;\n  metadata: Record<string, any>;\n  customerId?: Types.ObjectId | ICustomer;\n  customerEmail?: string;\n  paymentUrl?: string;\n  requiresAction?: boolean;\n  createdAt: Date;\n  updatedAt: Date;\n}\n\nexport interface ISubscription extends Document {\n  _id: string;\n  amount: number;\n  currency: string;\n  status: SubscriptionStatus;\n  itemId: string;\n  billingInterval: string;\n  currentPeriodStart: Date;\n  currentPeriodEnd: Date;\n  metadata?: Record<string, any>;\n  customFields?: Record<string, any>;\n  customerId?: Types.ObjectId | ICustomer;\n  customerEmail?: string;\n  createdAt: Date;\n  updatedAt: Date;\n}\n\nexport interface IRefund extends Document {\n  _id: string;\n  amount: number;\n  currency: string;\n  reason?: string;\n  metadata?: Record<string, any>;\n  paymentId: Types.ObjectId | IPayment;\n  createdAt: Date;\n}\n\nexport interface IInvoice extends Document {\n  _id: string;\n  subscriptionId?: Types.ObjectId | ISubscription;\n  billingMode: string;\n  amountPaid: number;\n  currency: string;\n  status: InvoiceStatus;\n  paidAt?: Date;\n  lineItems?: Record<string, any>;\n  metadata?: Record<string, any>;\n  customFields?: Record<string, any>;\n  customerId?: Types.ObjectId | ICustomer;\n  customerEmail?: string;\n  createdAt: Date;\n  updatedAt: Date;\n}\n\n// Schemas\nconst CustomerSchema = new Schema<ICustomer>(\n  {\n    _id: { type: String, required: true },\n    email: {\n      type: String,\n      required: true,\n      unique: true,\n      index: true,\n    },\n    name: { type: String, required: true },\n    phone: { type: String, required: false, default: null },\n    metadata: { type: Schema.Types.Mixed },\n  },\n  {\n    timestamps: true,\n    _id: false,\n  },\n);\n\nconst PaymentSchema = new Schema<IPayment>(\n  {\n    _id: { type: String, required: true },\n    amount: { type: Number, required: true },\n    currency: { type: String, required: true },\n    status: {\n      type: String,\n      enum: Object.values(PaymentStatus),\n      required: true,\n      index: true,\n    },\n    itemId: { type: String, index: true },\n    metadata: { type: Schema.Types.Mixed, required: true },\n    customerId: { type: String, ref: 'Customer', index: true },\n    customerEmail: { type: String, index: true },\n    paymentUrl: { type: String },\n    requiresAction: { type: Boolean, default: false },\n  },\n  {\n    timestamps: true,\n    _id: false,\n  },\n);\n\nconst SubscriptionSchema = new Schema<ISubscription>(\n  {\n    _id: { type: String, required: true },\n    amount: { type: Number, required: true },\n    currency: { type: String, required: true },\n    status: {\n      type: String,\n      enum: Object.values(SubscriptionStatus),\n      required: true,\n      index: true,\n    },\n    itemId: { type: String, required: true },\n    billingInterval: { type: String, required: true },\n    currentPeriodStart: { type: Date, required: true },\n    currentPeriodEnd: { type: Date, required: true },\n    metadata: { type: Schema.Types.Mixed },\n    customFields: { type: Schema.Types.Mixed },\n    customerId: { type: String, ref: 'Customer', index: true },\n    customerEmail: { type: String, index: true },\n  },\n  {\n    timestamps: true,\n    _id: false,\n  },\n);\n\nconst RefundSchema = new Schema<IRefund>(\n  {\n    _id: { type: String, required: true },\n    amount: { type: Number, required: true },\n    currency: { type: String, required: true },\n    reason: { type: String },\n    metadata: { type: Schema.Types.Mixed },\n    paymentId: {\n      type: String,\n      ref: 'Payment',\n      required: true,\n      index: true,\n    },\n    createdAt: { type: Date, default: Date.now },\n  },\n  {\n    _id: false,\n  },\n);\n\nconst InvoiceSchema = new Schema<IInvoice>(\n  {\n    _id: { type: String, required: true },\n    subscriptionId: {\n      type: String,\n      ref: 'Subscription',\n      index: true,\n    },\n    billingMode: { type: String, required: true },\n    amountPaid: { type: Number, required: true },\n    currency: { type: String, required: true },\n    status: {\n      type: String,\n      enum: Object.values(InvoiceStatus),\n      required: true,\n      index: true,\n    },\n    paidAt: { type: Date },\n    lineItems: { type: Schema.Types.Mixed },\n    metadata: { type: Schema.Types.Mixed },\n    customFields: { type: Schema.Types.Mixed },\n    customerId: { type: String, ref: 'Customer', index: true },\n    customerEmail: { type: String, index: true },\n  },\n  {\n    timestamps: true,\n    _id: false,\n  },\n);\n\n// Models\nexport const Customer = model<ICustomer>('Customer', CustomerSchema);\nexport const Payment = model<IPayment>('Payment', PaymentSchema);\nexport const Subscription = model<ISubscription>(\n  'Subscription',\n  SubscriptionSchema,\n);\nexport const Refund = model<IRefund>('Refund', RefundSchema);\nexport const Invoice = model<IInvoice>('Invoice', InvoiceSchema);\n"}],"docs":"Copy the content from models/payments.ts to your own models/payments.ts file.","meta":{"backend":"hono","provider":"stripe","orm":"mongoose","database":"mongodb","auth":"none"}},{"name":"stripe-hono-typeorm","type":"registry:block","description":"Stripe integration for Hono with TypeORM schemas for payments and subscriptions","dependencies":["typeorm"],"devDependencies":["typeorm"],"registryDependencies":["https://usepaykit.dev/r/stripe-hono"],"files":[{"type":"registry:file","target":"src/db/schema/payments.ts","path":"shared/schema/typeorm.ts","content":"import {\n    Entity,\n    PrimaryColumn,\n    Column,\n    CreateDateColumn,\n    UpdateDateColumn,\n    ManyToOne,\n    JoinColumn,\n    Index,\n  } from 'typeorm';\n  \n  // Enums\n  export enum PaymentStatus {\n    PENDING = 'pending',\n    PROCESSING = 'processing',\n    REQUIRES_ACTION = 'requires_action',\n    REQUIRES_CAPTURE = 'requires_capture',\n    SUCCEEDED = 'succeeded',\n    CANCELED = 'canceled',\n    FAILED = 'failed',\n  }\n  \n  export enum SubscriptionStatus {\n    ACTIVE = 'active',\n    PAST_DUE = 'past_due',\n    CANCELED = 'canceled',\n    EXPIRED = 'expired',\n    TRIALING = 'trialing',\n    PENDING = 'pending',\n  }\n  \n  export enum InvoiceStatus {\n    PAID = 'paid',\n    OPEN = 'open',\n  }\n  \n  // Entities\n  @Entity('customers')\n  export class Customer {\n    @PrimaryColumn({ type: 'text' })\n    id!: string;\n  \n  @Column({ type: 'text', unique: true })\n  @Index()\n  email!: string;\n\n  @Column({ type: 'text' })\n  name!: string;\n\n  @Column({ type: 'text' })\n  phone!: string;\n\n  @Column({ type: 'jsonb', nullable: true })\n  metadata?: Record<string, any>;\n\n  @CreateDateColumn({ type: 'timestamp', name: 'created_at' })\n  createdAt!: Date;\n\n  @UpdateDateColumn({ type: 'timestamp', name: 'updated_at' })\n  updatedAt!: Date;\n}\n  \n  @Entity('payments')\n  export class Payment {\n    @PrimaryColumn({ type: 'text' })\n    id!: string;\n  \n    @Column({ type: 'integer' })\n    amount!: number;\n  \n    @Column({ type: 'text' })\n    currency!: string;\n  \n    @Column({\n      type: 'enum',\n      enum: PaymentStatus,\n    })\n    @Index()\n    status!: PaymentStatus;\n  \n    @Column({ type: 'text', nullable: true, name: 'item_id' })\n    itemId?: string;\n  \n    @Column({ type: 'jsonb' })\n    metadata!: Record<string, any>;\n  \n    @Column({ type: 'text', nullable: true, name: 'customer_id' })\n    @Index()\n    customerId?: string;\n  \n    @ManyToOne(() => Customer, { onDelete: 'CASCADE' })\n    @JoinColumn({ name: 'customer_id' })\n    customer?: Customer;\n  \n    @Column({ type: 'text', nullable: true, name: 'customer_email' })\n    @Index()\n    customerEmail?: string;\n  \n    @Column({ type: 'text', nullable: true, name: 'payment_url' })\n    paymentUrl?: string;\n\n    @Column({ type: 'boolean', nullable: true, name: 'requires_action' })\n    requiresAction?: boolean;\n\n    @CreateDateColumn({ type: 'timestamp', name: 'created_at' })\n    createdAt!: Date;\n  \n    @UpdateDateColumn({ type: 'timestamp', name: 'updated_at' })\n    updatedAt!: Date;\n  }\n  \n @Entity('subscriptions')\n export class Subscription {\n  @PrimaryColumn({ type: 'text' })\n  id!: string;\n  \n    @Column({ type: 'integer' })\n    amount!: number;\n  \n    @Column({ type: 'text' })\n    currency!: string;\n  \n    @Column({\n      type: 'enum',\n      enum: SubscriptionStatus,\n    })\n    @Index()\n    status!: SubscriptionStatus;\n  \n    @Column({ type: 'text', name: 'item_id' })\n    itemId!: string;\n  \n    @Column({ type: 'text', name: 'billing_interval' })\n    billingInterval!: string;\n  \n    @Column({ type: 'timestamp', name: 'current_period_start' })\n    currentPeriodStart!: Date;\n  \n    @Column({ type: 'timestamp', name: 'current_period_end' })\n    currentPeriodEnd!: Date;\n  \n    @Column({ type: 'jsonb', nullable: true })\n    metadata?: Record<string, any>;\n  \n    @Column({ type: 'jsonb', nullable: true, name: 'custom_fields' })\n    customFields?: Record<string, any>;\n  \n    @Column({ type: 'text', nullable: true, name: 'customer_id' })\n    @Index()\n    customerId?: string;\n  \n    @ManyToOne(() => Customer, { onDelete: 'CASCADE' })\n    @JoinColumn({ name: 'customer_id' })\n    customer?: Customer;\n  \n    @Column({ type: 'text', nullable: true, name: 'customer_email' })\n    @Index()\n    customerEmail?: string;\n  \n  @CreateDateColumn({ type: 'timestamp', name: 'created_at' })\n  createdAt!: Date;\n\n  @UpdateDateColumn({ type: 'timestamp', name: 'updated_at' })\n  updatedAt!: Date;\n}\n  \n  @Entity('refunds')\n  export class Refund {\n    @PrimaryColumn({ type: 'text' })\n    id!: string;\n  \n    @Column({ type: 'integer' })\n    amount!: number;\n  \n    @Column({ type: 'text' })\n    currency!: string;\n  \n    @Column({ type: 'text', nullable: true })\n    reason?: string;\n  \n    @Column({ type: 'jsonb', nullable: true })\n    metadata?: Record<string, any>;\n  \n    @Column({ type: 'text', name: 'payment_id' })\n    @Index()\n    paymentId!: string;\n  \n    @ManyToOne(() => Payment, { onDelete: 'CASCADE' })\n    @JoinColumn({ name: 'payment_id' })\n    payment!: Payment;\n  \n    @CreateDateColumn({ type: 'timestamp', name: 'created_at' })\n    createdAt!: Date;\n  }\n  \n  @Entity('invoices')\n  export class Invoice {\n    @PrimaryColumn({ type: 'text' })\n    id!: string;\n  \n    @Column({ type: 'text', nullable: true, name: 'subscription_id' })\n    @Index()\n    subscriptionId?: string;\n  \n    @ManyToOne(() => Subscription, { onDelete: 'SET NULL' })\n    @JoinColumn({ name: 'subscription_id' })\n    subscription?: Subscription;\n  \n    @Column({ type: 'text', name: 'billing_mode' })\n    billingMode!: string;\n  \n  @Column({ type: 'integer', name: 'amount_paid' })\n  amountPaid!: number;\n\n  @Column({ type: 'text' })\n  currency!: string;\n  \n    @Column({\n      type: 'enum',\n      enum: InvoiceStatus,\n    })\n    @Index()\n    status!: InvoiceStatus;\n  \n    @Column({ type: 'timestamp', nullable: true, name: 'paid_at' })\n    paidAt?: Date;\n  \n    @Column({ type: 'jsonb', nullable: true, name: 'line_items' })\n    lineItems?: Record<string, any>;\n  \n  @Column({ type: 'jsonb', nullable: true })\n  metadata?: Record<string, any>;\n\n  @Column({ type: 'jsonb', nullable: true, name: 'custom_fields' })\n  customFields?: Record<string, any>;\n  \n    @Column({ type: 'text', nullable: true, name: 'customer_id' })\n    @Index()\n    customerId?: string;\n  \n    @ManyToOne(() => Customer, { onDelete: 'CASCADE' })\n    @JoinColumn({ name: 'customer_id' })\n    customer?: Customer;\n  \n    @Column({ type: 'text', nullable: true, name: 'customer_email' })\n    @Index()\n    customerEmail?: string;\n  \n    @CreateDateColumn({ type: 'timestamp', name: 'created_at' })\n    createdAt!: Date;\n  \n    @UpdateDateColumn({ type: 'timestamp', name: 'updated_at' })\n    updatedAt!: Date;\n  }"}],"docs":"Copy the content from src/db/schema/payments.ts to your own schema.ts file. \n Run 'npx typeorm migration:generate' to create the migrations.","meta":{"backend":"hono","provider":"stripe","orm":"typeorm","database":"postgres","auth":"none"}},{"name":"stripe-express-prisma","type":"registry:block","description":"Stripe integration for Express with Prisma ORM schemas for payments and subscriptions","dependencies":["prisma"],"devDependencies":["prisma"],"registryDependencies":["https://usepaykit.dev/r/stripe-express"],"files":[{"type":"registry:file","target":"prisma/schema-payments.prisma","path":"shared/schema/prisma.prisma","content":"model Customer {\n  id        String   @id @default(cuid())\n  email     String   @unique\n  name      String\n  phone     String\n  metadata  Json?\n  createdAt DateTime @default(now())\n  updatedAt DateTime @updatedAt\n\n  payments      Payment[]\n  subscriptions Subscription[]\n  invoices      Invoice[]\n}\n\nmodel Payment {\n  id         String        @id\n  amount     Int\n  currency   String\n  status     PaymentStatus\n  itemId  String?       @map(\"item_id\")\n  metadata   Json\n  createdAt  DateTime      @default(now())\n  updatedAt  DateTime      @updatedAt\n\n  customerId String?   @map(\"customer_id\")\n  customer   Customer? @relation(fields: [customerId], references: [id], onDelete: Cascade)\n\n  // Guest checkout for when the customer is not yet determined\n  customerEmail String? @map(\"customer_email\")\n\n  refunds    Refund[]\n\n  paymentUrl String? @map(\"payment_url\")\n  requiresAction Boolean? @map(\"requires_action\")\n\n  @@index([customerId])\n  @@index([status])\n  @@index([customerEmail])\n}\n\nenum PaymentStatus {\n  pending\n  processing\n  requires_action\n  requires_capture\n  succeeded\n  canceled\n  failed\n}\n\nmodel Subscription {\n  id                  String               @id\n  amount              Int\n  currency            String\n  status              SubscriptionStatus\n  itemId              String               @map(\"item_id\")\n  billingInterval     String               @map(\"billing_interval\")\n  currentPeriodStart  DateTime             @map(\"current_period_start\")\n  currentPeriodEnd    DateTime             @map(\"current_period_end\")\n  metadata            Json?\n  customFields        Json?                @map(\"custom_fields\")\n  createdAt           DateTime             @default(now())\n  updatedAt           DateTime             @updatedAt\n\n  customerId String?   @map(\"customer_id\")\n  customer   Customer? @relation(fields: [customerId], references: [id], onDelete: Cascade)\n\n  // Guest checkout for when the customer is not yet determined\n  customerEmail String? @map(\"customer_email\")\n\n  invoices   Invoice[]\n\n  @@index([customerId])\n  @@index([status])\n  @@index([customerEmail])\n}\n\nenum SubscriptionStatus {\n  active\n  past_due\n  canceled\n  expired\n  pending\n}\n\nmodel Refund {\n  id        String   @id\n  amount    Int\n  currency  String\n  reason    String?\n  metadata  Json?\n  createdAt DateTime @default(now())\n\n  paymentId String  @map(\"payment_id\")\n  payment   Payment @relation(fields: [paymentId], references: [id], onDelete: Cascade)\n\n  @@index([paymentId])\n}\n\nmodel Invoice {\n  id             String        @id\n  subscriptionId String?       @map(\"subscription_id\")\n  billingMode    String        @map(\"billing_mode\")\n  amountPaid     Int           @map(\"amount_paid\")\n  currency       String\n  status         InvoiceStatus\n  paidAt         DateTime?     @map(\"paid_at\")\n  lineItems      Json?         @map(\"line_items\")\n  metadata       Json?\n  customFields   Json?         @map(\"custom_fields\")\n  createdAt      DateTime      @default(now())\n  updatedAt      DateTime      @updatedAt\n\n  customerId String?   @map(\"customer_id\")\n  customer   Customer? @relation(fields: [customerId], references: [id], onDelete: Cascade)\n\n  customerEmail String? @map(\"customer_email\")\n  subscription Subscription? @relation(fields: [subscriptionId], references: [id], onDelete: SetNull)\n\n  @@index([customerId])\n  @@index([subscriptionId])\n  @@index([status])\n  @@index([customerEmail])\n}\n\nenum InvoiceStatus {\n  paid\n  open\n}"}],"docs":"Copy the content from prisma/schema-payments.prisma to your own schema.prisma file.\nRun 'prisma migrate dev' to create the tables.","meta":{"backend":"express","provider":"stripe","orm":"prisma","database":"postgres","auth":"none"}},{"name":"stripe-express-drizzle","type":"registry:block","description":"Stripe integration for Express with Drizzle ORM schemas for payments and subscriptions","dependencies":["drizzle-orm"],"devDependencies":["drizzle-kit"],"registryDependencies":["https://usepaykit.dev/r/stripe-express"],"files":[{"type":"registry:file","target":"src/db/schema/payments.ts","path":"shared/schema/drizzle.ts","content":"import {\n  pgTable,\n  text,\n  timestamp,\n  integer,\n  json,\n  pgEnum,\n  index,\n  boolean,\n} from 'drizzle-orm/pg-core';\n\n// Enums\nexport const paymentStatusEnum = pgEnum('payment_status', [\n  'pending',\n  'processing',\n  'requires_action',\n  'requires_capture',\n  'succeeded',\n  'canceled',\n  'failed',\n]);\n\nexport const subscriptionStatusEnum = pgEnum('subscription_status', [\n  'active',\n  'past_due',\n  'canceled',\n  'expired',\n  'trialing',\n  'pending',\n]);\n\nexport const invoiceStatusEnum = pgEnum('invoice_status', [\n  'paid',\n  'open',\n]);\n\n// Tables\nexport const customers = pgTable('customers', {\n  id: text('id').primaryKey(),\n  email: text('email').notNull().unique(),\n  name: text('name').notNull(),\n  phone: text('phone'),\n  metadata: json('metadata'),\n  createdAt: timestamp('created_at').defaultNow().notNull(),\n  updatedAt: timestamp('updated_at').defaultNow().notNull(),\n});\n\nexport const payments = pgTable(\n  'payments',\n  {\n    id: text('id').primaryKey(),\n    amount: integer('amount').notNull(),\n    currency: text('currency').notNull(),\n    status: paymentStatusEnum('status').notNull(),\n    itemId: text('item_id'),\n    metadata: json('metadata').notNull(),\n    createdAt: timestamp('created_at').defaultNow().notNull(),\n    updatedAt: timestamp('updated_at').defaultNow().notNull(),\n\n    // Optional customer relationship\n    customerId: text('customer_id').references(() => customers.id, {\n      onDelete: 'cascade',\n    }),\n\n    // Guest checkout for when the customer is not yet determined\n    customerEmail: text('customer_email'),\n\n    paymentUrl: text('payment_url'),\n    requiresAction: boolean('requires_action').default(false),\n  },\n  table => ({\n    customerIdIdx: index('payments_customer_id_idx').on(\n      table.customerId,\n    ),\n    statusIdx: index('payments_status_idx').on(table.status),\n    customerEmailIdx: index('payments_customer_email_idx').on(\n      table.customerEmail,\n    ),\n  }),\n);\n\nexport const subscriptions = pgTable(\n  'subscriptions',\n  {\n    id: text('id').primaryKey(),\n    amount: integer('amount').notNull(),\n    currency: text('currency').notNull(),\n    status: subscriptionStatusEnum('status').notNull(),\n    itemId: text('item_id').notNull(),\n    billingInterval: text('billing_interval').notNull(),\n    currentPeriodStart: timestamp('current_period_start').notNull(),\n    currentPeriodEnd: timestamp('current_period_end').notNull(),\n    metadata: json('metadata'),\n    customFields: json('custom_fields'),\n    createdAt: timestamp('created_at').defaultNow().notNull(),\n    updatedAt: timestamp('updated_at').defaultNow().notNull(),\n\n    // Optional customer relationship\n    customerId: text('customer_id').references(() => customers.id, {\n      onDelete: 'cascade',\n    }),\n\n    // Guest checkout for when the customer is not yet determined\n    customerEmail: text('customer_email'),\n  },\n  table => ({\n    customerIdIdx: index('subscriptions_customer_id_idx').on(\n      table.customerId,\n    ),\n    statusIdx: index('subscriptions_status_idx').on(table.status),\n    customerEmailIdx: index('subscriptions_customer_email_idx').on(\n      table.customerEmail,\n    ),\n  }),\n);\n\nexport const refunds = pgTable(\n  'refunds',\n  {\n    id: text('id').primaryKey(),\n    amount: integer('amount').notNull(),\n    currency: text('currency').notNull(),\n    reason: text('reason'),\n    metadata: json('metadata'),\n    createdAt: timestamp('created_at').defaultNow().notNull(),\n\n    paymentId: text('payment_id')\n      .notNull()\n      .references(() => payments.id, { onDelete: 'cascade' }),\n  },\n  table => ({\n    paymentIdIdx: index('refunds_payment_id_idx').on(table.paymentId),\n  }),\n);\n\nexport const invoices = pgTable(\n  'invoices',\n  {\n    id: text('id').primaryKey(),\n    subscriptionId: text('subscription_id').references(\n      () => subscriptions.id,\n      {\n        onDelete: 'set null',\n      },\n    ),\n    billingMode: text('billing_mode').notNull(),\n    amountPaid: integer('amount_paid').notNull(),\n    currency: text('currency').notNull(),\n    status: invoiceStatusEnum('status').notNull(),\n    paidAt: timestamp('paid_at'),\n    lineItems: json('line_items'),\n    metadata: json('metadata'),\n    customFields: json('custom_fields'),\n    createdAt: timestamp('created_at').defaultNow().notNull(),\n    updatedAt: timestamp('updated_at').defaultNow().notNull(),\n\n    customerId: text('customer_id').references(() => customers.id, {\n      onDelete: 'cascade',\n    }),\n\n    // Guest checkout for when the customer is not yet determined\n    customerEmail: text('customer_email'),\n  },\n  table => ({\n    customerIdIdx: index('invoices_customer_id_idx').on(\n      table.customerId,\n    ),\n    subscriptionIdIdx: index('invoices_subscription_id_idx').on(\n      table.subscriptionId,\n    ),\n    statusIdx: index('invoices_status_idx').on(table.status),\n    customerEmailIdx: index('invoices_customer_email_idx').on(\n      table.customerEmail,\n    ),\n  }),\n);\n\nexport type Invoice = typeof invoices.$inferSelect;\nexport type Customer = typeof customers.$inferSelect;\nexport type Payment = typeof payments.$inferSelect;\nexport type Subscription = typeof subscriptions.$inferSelect;\nexport type Refund = typeof refunds.$inferSelect;\n"}],"docs":"Copy the content from src/db/schema/payments.ts to your own schema.ts file. \n Run 'drizzle-kit push' to sync with your database.","meta":{"backend":"express","provider":"stripe","orm":"drizzle","database":"postgres","auth":"none"}},{"name":"stripe-express-sequelize","type":"registry:block","description":"Stripe integration for Express with Sequelize schemas for payments and subscriptions","dependencies":["sequelize"],"devDependencies":["sequelize"],"registryDependencies":["https://usepaykit.dev/r/stripe-express"],"files":[{"type":"registry:file","target":"src/db/schema/payments.ts","path":"shared/schema/sequelize.ts","content":"import { DataTypes, Model, Sequelize } from 'sequelize';\n\n// Initialize Sequelize (user will provide their connection)\nexport const initializeSequelize = (sequelize: Sequelize) => {\n  // Customer Model\n  class Customer extends Model {\n    declare id: string;\n    declare email: string;\n    declare name: string;\n    declare phone: string | null;\n    declare metadata?: Record<string, any>;\n    declare createdAt: Date;\n    declare updatedAt: Date;\n  }\n\n  Customer.init(\n    {\n      id: {\n        type: DataTypes.STRING,\n        primaryKey: true,\n      },\n      email: {\n        type: DataTypes.STRING,\n        allowNull: false,\n        unique: true,\n      },\n      name: {\n        type: DataTypes.STRING,\n        allowNull: false,\n      },\n      phone: {\n        type: DataTypes.STRING,\n        allowNull: true,\n      },\n      metadata: {\n        type: DataTypes.JSONB,\n        allowNull: true,\n      },\n    },\n    {\n      sequelize,\n      tableName: 'customers',\n      timestamps: true,\n      underscored: true,\n      indexes: [{ fields: ['email'] }],\n    },\n  );\n\n  // Payment Model\n  class Payment extends Model {\n    declare id: string;\n    declare amount: number;\n    declare currency: string;\n    declare status: string;\n    declare itemId?: string;\n    declare metadata: Record<string, any>;\n    declare customerId?: string;\n    declare customerEmail?: string;\n    declare paymentUrl?: string;\n    declare requiresAction?: boolean;\n    declare createdAt: Date;\n    declare updatedAt: Date;\n  }\n\n  Payment.init(\n    {\n      id: {\n        type: DataTypes.STRING,\n        primaryKey: true,\n      },\n      amount: {\n        type: DataTypes.INTEGER,\n        allowNull: false,\n      },\n      currency: {\n        type: DataTypes.STRING,\n        allowNull: false,\n      },\n      status: {\n        type: DataTypes.ENUM(\n          'pending',\n          'processing',\n          'requires_action',\n          'requires_capture',\n          'succeeded',\n          'canceled',\n          'failed',\n        ),\n        allowNull: false,\n      },\n      itemId: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'item_id',\n      },\n      metadata: {\n        type: DataTypes.JSONB,\n        allowNull: false,\n      },\n      customerId: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'customer_id',\n        references: {\n          model: 'customers',\n          key: 'id',\n        },\n        onDelete: 'CASCADE',\n      },\n      customerEmail: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'customer_email',\n      },\n      paymentUrl: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'payment_url',\n      },\n      requiresAction: {\n        type: DataTypes.BOOLEAN,\n        allowNull: true,\n        field: 'requires_action',\n        defaultValue: false,\n      },\n    },\n    {\n      sequelize,\n      tableName: 'payments',\n      timestamps: true,\n      underscored: true,\n      indexes: [\n        { fields: ['customer_id'] },\n        { fields: ['status'] },\n        { fields: ['customer_email'] },\n      ],\n    },\n  );\n\n  // Subscription Model\n  class Subscription extends Model {\n    declare id: string;\n    declare amount: number;\n    declare currency: string;\n    declare status: string;\n    declare itemId: string;\n    declare billingInterval: string;\n    declare currentPeriodStart: Date;\n    declare currentPeriodEnd: Date;\n    declare metadata?: Record<string, any>;\n    declare customFields?: Record<string, any>;\n    declare customerId?: string;\n    declare customerEmail?: string;\n    declare createdAt: Date;\n    declare updatedAt: Date;\n  }\n\n  Subscription.init(\n    {\n      id: {\n        type: DataTypes.STRING,\n        primaryKey: true,\n      },\n      amount: {\n        type: DataTypes.INTEGER,\n        allowNull: false,\n      },\n      currency: {\n        type: DataTypes.STRING,\n        allowNull: false,\n      },\n      status: {\n        type: DataTypes.ENUM(\n          'active',\n          'past_due',\n          'canceled',\n          'expired',\n          'trialing',\n          'pending',\n        ),\n        allowNull: false,\n      },\n      itemId: {\n        type: DataTypes.STRING,\n        allowNull: false,\n        field: 'item_id',\n      },\n      billingInterval: {\n        type: DataTypes.STRING,\n        allowNull: false,\n        field: 'billing_interval',\n      },\n      currentPeriodStart: {\n        type: DataTypes.DATE,\n        allowNull: false,\n        field: 'current_period_start',\n      },\n      currentPeriodEnd: {\n        type: DataTypes.DATE,\n        allowNull: false,\n        field: 'current_period_end',\n      },\n      metadata: {\n        type: DataTypes.JSONB,\n        allowNull: true,\n      },\n      customFields: {\n        type: DataTypes.JSONB,\n        allowNull: true,\n        field: 'custom_fields',\n      },\n      customerId: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'customer_id',\n        references: {\n          model: 'customers',\n          key: 'id',\n        },\n        onDelete: 'CASCADE',\n      },\n      customerEmail: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'customer_email',\n      },\n    },\n    {\n      sequelize,\n      tableName: 'subscriptions',\n      timestamps: true,\n      underscored: true,\n      indexes: [\n        { fields: ['customer_id'] },\n        { fields: ['status'] },\n        { fields: ['customer_email'] },\n      ],\n    },\n  );\n\n  // Refund Model\n  class Refund extends Model {\n    declare id: string;\n    declare amount: number;\n    declare currency: string;\n    declare reason?: string;\n    declare metadata?: Record<string, any>;\n    declare paymentId: string;\n    declare createdAt: Date;\n  }\n\n  Refund.init(\n    {\n      id: {\n        type: DataTypes.STRING,\n        primaryKey: true,\n      },\n      amount: {\n        type: DataTypes.INTEGER,\n        allowNull: false,\n      },\n      currency: {\n        type: DataTypes.STRING,\n        allowNull: false,\n      },\n      reason: {\n        type: DataTypes.STRING,\n        allowNull: true,\n      },\n      metadata: {\n        type: DataTypes.JSONB,\n        allowNull: true,\n      },\n      paymentId: {\n        type: DataTypes.STRING,\n        allowNull: false,\n        field: 'payment_id',\n        references: {\n          model: 'payments',\n          key: 'id',\n        },\n        onDelete: 'CASCADE',\n      },\n    },\n    {\n      sequelize,\n      tableName: 'refunds',\n      timestamps: false,\n      underscored: true,\n      indexes: [{ fields: ['payment_id'] }],\n    },\n  );\n\n  // Invoice Model\n  class Invoice extends Model {\n    declare id: string;\n    declare subscriptionId?: string;\n    declare billingMode: string;\n    declare amountPaid: number;\n    declare currency: string;\n    declare status: string;\n    declare paidAt?: Date;\n    declare lineItems?: Record<string, any>;\n    declare metadata?: Record<string, any>;\n    declare customFields?: Record<string, any>;\n    declare customerId?: string;\n    declare customerEmail?: string;\n    declare createdAt: Date;\n    declare updatedAt: Date;\n  }\n\n  Invoice.init(\n    {\n      id: {\n        type: DataTypes.STRING,\n        primaryKey: true,\n      },\n      subscriptionId: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'subscription_id',\n        references: {\n          model: 'subscriptions',\n          key: 'id',\n        },\n        onDelete: 'SET NULL',\n      },\n      billingMode: {\n        type: DataTypes.STRING,\n        allowNull: false,\n        field: 'billing_mode',\n      },\n      amountPaid: {\n        type: DataTypes.INTEGER,\n        allowNull: false,\n        field: 'amount_paid',\n      },\n      currency: {\n        type: DataTypes.STRING,\n        allowNull: false,\n      },\n      status: {\n        type: DataTypes.ENUM('paid', 'open'),\n        allowNull: false,\n      },\n      paidAt: {\n        type: DataTypes.DATE,\n        allowNull: true,\n        field: 'paid_at',\n      },\n      lineItems: {\n        type: DataTypes.JSONB,\n        allowNull: true,\n        field: 'line_items',\n      },\n      metadata: {\n        type: DataTypes.JSONB,\n        allowNull: true,\n      },\n      customFields: {\n        type: DataTypes.JSONB,\n        allowNull: true,\n        field: 'custom_fields',\n      },\n      customerId: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'customer_id',\n        references: {\n          model: 'customers',\n          key: 'id',\n        },\n        onDelete: 'CASCADE',\n      },\n      customerEmail: {\n        type: DataTypes.STRING,\n        allowNull: true,\n        field: 'customer_email',\n      },\n    },\n    {\n      sequelize,\n      tableName: 'invoices',\n      timestamps: true,\n      underscored: true,\n      indexes: [\n        { fields: ['customer_id'] },\n        { fields: ['subscription_id'] },\n        { fields: ['status'] },\n        { fields: ['customer_email'] },\n      ],\n    },\n  );\n\n  // Define associations\n  Customer.hasMany(Payment, {\n    foreignKey: 'customerId',\n    onDelete: 'CASCADE',\n  });\n  Payment.belongsTo(Customer, { foreignKey: 'customerId' });\n\n  Customer.hasMany(Subscription, {\n    foreignKey: 'customerId',\n    onDelete: 'CASCADE',\n  });\n  Subscription.belongsTo(Customer, { foreignKey: 'customerId' });\n\n  Payment.hasMany(Refund, {\n    foreignKey: 'paymentId',\n    onDelete: 'CASCADE',\n  });\n  Refund.belongsTo(Payment, { foreignKey: 'paymentId' });\n\n  Customer.hasMany(Invoice, {\n    foreignKey: 'customerId',\n    onDelete: 'CASCADE',\n  });\n  Invoice.belongsTo(Customer, { foreignKey: 'customerId' });\n\n  Subscription.hasMany(Invoice, {\n    foreignKey: 'subscriptionId',\n    onDelete: 'SET NULL',\n  });\n  Invoice.belongsTo(Subscription, { foreignKey: 'subscriptionId' });\n\n  return {\n    Customer,\n    Payment,\n    Subscription,\n    Refund,\n    Invoice,\n  };\n};\n\n// Export types\nexport type CustomerModel = ReturnType<\n  typeof initializeSequelize\n>['Customer'];\nexport type PaymentModel = ReturnType<\n  typeof initializeSequelize\n>['Payment'];\nexport type SubscriptionModel = ReturnType<\n  typeof initializeSequelize\n>['Subscription'];\nexport type RefundModel = ReturnType<\n  typeof initializeSequelize\n>['Refund'];\nexport type InvoiceModel = ReturnType<\n  typeof initializeSequelize\n>['Invoice'];\n"}],"docs":"Copy the content from src/db/schema/payments.ts to your own schema.ts file. \n Run 'sequelize migration:generate' to create the migrations.","meta":{"backend":"express","provider":"stripe","orm":"sequelize","database":"mysql","auth":"none"}},{"name":"stripe-express-mongoose","type":"registry:block","description":"Stripe integration for Express with Mongoose schemas for payments and subscriptions","dependencies":["mongoose"],"devDependencies":["mongoose"],"registryDependencies":["https://usepaykit.dev/r/stripe-express"],"files":[{"type":"registry:file","target":"models/payments.ts","path":"shared/schema/mongoose.ts","content":"import { Schema, model, Document, Types } from 'mongoose';\n\n// Enums\nexport enum PaymentStatus {\n  PENDING = 'pending',\n  PROCESSING = 'processing',\n  REQUIRES_ACTION = 'requires_action',\n  REQUIRES_CAPTURE = 'requires_capture',\n  SUCCEEDED = 'succeeded',\n  CANCELED = 'canceled',\n  FAILED = 'failed',\n}\n\nexport enum SubscriptionStatus {\n  ACTIVE = 'active',\n  PAST_DUE = 'past_due',\n  CANCELED = 'canceled',\n  EXPIRED = 'expired',\n  TRIALING = 'trialing',\n  PENDING = 'pending',\n}\n\nexport enum InvoiceStatus {\n  PAID = 'paid',\n  OPEN = 'open',\n}\n\n// Interfaces\nexport interface ICustomer extends Document {\n  _id: string;\n  email: string;\n  name: string;\n  phone: string | null;\n  metadata?: Record<string, any>;\n  createdAt: Date;\n  updatedAt: Date;\n}\n\nexport interface IPayment extends Document {\n  _id: string;\n  amount: number;\n  currency: string;\n  status: PaymentStatus;\n  itemId?: string;\n  metadata: Record<string, any>;\n  customerId?: Types.ObjectId | ICustomer;\n  customerEmail?: string;\n  paymentUrl?: string;\n  requiresAction?: boolean;\n  createdAt: Date;\n  updatedAt: Date;\n}\n\nexport interface ISubscription extends Document {\n  _id: string;\n  amount: number;\n  currency: string;\n  status: SubscriptionStatus;\n  itemId: string;\n  billingInterval: string;\n  currentPeriodStart: Date;\n  currentPeriodEnd: Date;\n  metadata?: Record<string, any>;\n  customFields?: Record<string, any>;\n  customerId?: Types.ObjectId | ICustomer;\n  customerEmail?: string;\n  createdAt: Date;\n  updatedAt: Date;\n}\n\nexport interface IRefund extends Document {\n  _id: string;\n  amount: number;\n  currency: string;\n  reason?: string;\n  metadata?: Record<string, any>;\n  paymentId: Types.ObjectId | IPayment;\n  createdAt: Date;\n}\n\nexport interface IInvoice extends Document {\n  _id: string;\n  subscriptionId?: Types.ObjectId | ISubscription;\n  billingMode: string;\n  amountPaid: number;\n  currency: string;\n  status: InvoiceStatus;\n  paidAt?: Date;\n  lineItems?: Record<string, any>;\n  metadata?: Record<string, any>;\n  customFields?: Record<string, any>;\n  customerId?: Types.ObjectId | ICustomer;\n  customerEmail?: string;\n  createdAt: Date;\n  updatedAt: Date;\n}\n\n// Schemas\nconst CustomerSchema = new Schema<ICustomer>(\n  {\n    _id: { type: String, required: true },\n    email: {\n      type: String,\n      required: true,\n      unique: true,\n      index: true,\n    },\n    name: { type: String, required: true },\n    phone: { type: String, required: false, default: null },\n    metadata: { type: Schema.Types.Mixed },\n  },\n  {\n    timestamps: true,\n    _id: false,\n  },\n);\n\nconst PaymentSchema = new Schema<IPayment>(\n  {\n    _id: { type: String, required: true },\n    amount: { type: Number, required: true },\n    currency: { type: String, required: true },\n    status: {\n      type: String,\n      enum: Object.values(PaymentStatus),\n      required: true,\n      index: true,\n    },\n    itemId: { type: String, index: true },\n    metadata: { type: Schema.Types.Mixed, required: true },\n    customerId: { type: String, ref: 'Customer', index: true },\n    customerEmail: { type: String, index: true },\n    paymentUrl: { type: String },\n    requiresAction: { type: Boolean, default: false },\n  },\n  {\n    timestamps: true,\n    _id: false,\n  },\n);\n\nconst SubscriptionSchema = new Schema<ISubscription>(\n  {\n    _id: { type: String, required: true },\n    amount: { type: Number, required: true },\n    currency: { type: String, required: true },\n    status: {\n      type: String,\n      enum: Object.values(SubscriptionStatus),\n      required: true,\n      index: true,\n    },\n    itemId: { type: String, required: true },\n    billingInterval: { type: String, required: true },\n    currentPeriodStart: { type: Date, required: true },\n    currentPeriodEnd: { type: Date, required: true },\n    metadata: { type: Schema.Types.Mixed },\n    customFields: { type: Schema.Types.Mixed },\n    customerId: { type: String, ref: 'Customer', index: true },\n    customerEmail: { type: String, index: true },\n  },\n  {\n    timestamps: true,\n    _id: false,\n  },\n);\n\nconst RefundSchema = new Schema<IRefund>(\n  {\n    _id: { type: String, required: true },\n    amount: { type: Number, required: true },\n    currency: { type: String, required: true },\n    reason: { type: String },\n    metadata: { type: Schema.Types.Mixed },\n    paymentId: {\n      type: String,\n      ref: 'Payment',\n      required: true,\n      index: true,\n    },\n    createdAt: { type: Date, default: Date.now },\n  },\n  {\n    _id: false,\n  },\n);\n\nconst InvoiceSchema = new Schema<IInvoice>(\n  {\n    _id: { type: String, required: true },\n    subscriptionId: {\n      type: String,\n      ref: 'Subscription',\n      index: true,\n    },\n    billingMode: { type: String, required: true },\n    amountPaid: { type: Number, required: true },\n    currency: { type: String, required: true },\n    status: {\n      type: String,\n      enum: Object.values(InvoiceStatus),\n      required: true,\n      index: true,\n    },\n    paidAt: { type: Date },\n    lineItems: { type: Schema.Types.Mixed },\n    metadata: { type: Schema.Types.Mixed },\n    customFields: { type: Schema.Types.Mixed },\n    customerId: { type: String, ref: 'Customer', index: true },\n    customerEmail: { type: String, index: true },\n  },\n  {\n    timestamps: true,\n    _id: false,\n  },\n);\n\n// Models\nexport const Customer = model<ICustomer>('Customer', CustomerSchema);\nexport const Payment = model<IPayment>('Payment', PaymentSchema);\nexport const Subscription = model<ISubscription>(\n  'Subscription',\n  SubscriptionSchema,\n);\nexport const Refund = model<IRefund>('Refund', RefundSchema);\nexport const Invoice = model<IInvoice>('Invoice', InvoiceSchema);\n"}],"docs":"Copy the content from models/payments.ts to your own models/payments.ts file.","meta":{"backend":"express","provider":"stripe","orm":"mongoose","database":"mongodb","auth":"none"}},{"name":"stripe-express-typeorm","type":"registry:block","description":"Stripe integration for Express with TypeORM schemas for payments and subscriptions","dependencies":["typeorm"],"devDependencies":["typeorm"],"registryDependencies":["https://usepaykit.dev/r/stripe-express"],"files":[{"type":"registry:file","target":"src/db/schema/payments.ts","path":"shared/schema/typeorm.ts","content":"import {\n    Entity,\n    PrimaryColumn,\n    Column,\n    CreateDateColumn,\n    UpdateDateColumn,\n    ManyToOne,\n    JoinColumn,\n    Index,\n  } from 'typeorm';\n  \n  // Enums\n  export enum PaymentStatus {\n    PENDING = 'pending',\n    PROCESSING = 'processing',\n    REQUIRES_ACTION = 'requires_action',\n    REQUIRES_CAPTURE = 'requires_capture',\n    SUCCEEDED = 'succeeded',\n    CANCELED = 'canceled',\n    FAILED = 'failed',\n  }\n  \n  export enum SubscriptionStatus {\n    ACTIVE = 'active',\n    PAST_DUE = 'past_due',\n    CANCELED = 'canceled',\n    EXPIRED = 'expired',\n    TRIALING = 'trialing',\n    PENDING = 'pending',\n  }\n  \n  export enum InvoiceStatus {\n    PAID = 'paid',\n    OPEN = 'open',\n  }\n  \n  // Entities\n  @Entity('customers')\n  export class Customer {\n    @PrimaryColumn({ type: 'text' })\n    id!: string;\n  \n  @Column({ type: 'text', unique: true })\n  @Index()\n  email!: string;\n\n  @Column({ type: 'text' })\n  name!: string;\n\n  @Column({ type: 'text' })\n  phone!: string;\n\n  @Column({ type: 'jsonb', nullable: true })\n  metadata?: Record<string, any>;\n\n  @CreateDateColumn({ type: 'timestamp', name: 'created_at' })\n  createdAt!: Date;\n\n  @UpdateDateColumn({ type: 'timestamp', name: 'updated_at' })\n  updatedAt!: Date;\n}\n  \n  @Entity('payments')\n  export class Payment {\n    @PrimaryColumn({ type: 'text' })\n    id!: string;\n  \n    @Column({ type: 'integer' })\n    amount!: number;\n  \n    @Column({ type: 'text' })\n    currency!: string;\n  \n    @Column({\n      type: 'enum',\n      enum: PaymentStatus,\n    })\n    @Index()\n    status!: PaymentStatus;\n  \n    @Column({ type: 'text', nullable: true, name: 'item_id' })\n    itemId?: string;\n  \n    @Column({ type: 'jsonb' })\n    metadata!: Record<string, any>;\n  \n    @Column({ type: 'text', nullable: true, name: 'customer_id' })\n    @Index()\n    customerId?: string;\n  \n    @ManyToOne(() => Customer, { onDelete: 'CASCADE' })\n    @JoinColumn({ name: 'customer_id' })\n    customer?: Customer;\n  \n    @Column({ type: 'text', nullable: true, name: 'customer_email' })\n    @Index()\n    customerEmail?: string;\n  \n    @Column({ type: 'text', nullable: true, name: 'payment_url' })\n    paymentUrl?: string;\n\n    @Column({ type: 'boolean', nullable: true, name: 'requires_action' })\n    requiresAction?: boolean;\n\n    @CreateDateColumn({ type: 'timestamp', name: 'created_at' })\n    createdAt!: Date;\n  \n    @UpdateDateColumn({ type: 'timestamp', name: 'updated_at' })\n    updatedAt!: Date;\n  }\n  \n @Entity('subscriptions')\n export class Subscription {\n  @PrimaryColumn({ type: 'text' })\n  id!: string;\n  \n    @Column({ type: 'integer' })\n    amount!: number;\n  \n    @Column({ type: 'text' })\n    currency!: string;\n  \n    @Column({\n      type: 'enum',\n      enum: SubscriptionStatus,\n    })\n    @Index()\n    status!: SubscriptionStatus;\n  \n    @Column({ type: 'text', name: 'item_id' })\n    itemId!: string;\n  \n    @Column({ type: 'text', name: 'billing_interval' })\n    billingInterval!: string;\n  \n    @Column({ type: 'timestamp', name: 'current_period_start' })\n    currentPeriodStart!: Date;\n  \n    @Column({ type: 'timestamp', name: 'current_period_end' })\n    currentPeriodEnd!: Date;\n  \n    @Column({ type: 'jsonb', nullable: true })\n    metadata?: Record<string, any>;\n  \n    @Column({ type: 'jsonb', nullable: true, name: 'custom_fields' })\n    customFields?: Record<string, any>;\n  \n    @Column({ type: 'text', nullable: true, name: 'customer_id' })\n    @Index()\n    customerId?: string;\n  \n    @ManyToOne(() => Customer, { onDelete: 'CASCADE' })\n    @JoinColumn({ name: 'customer_id' })\n    customer?: Customer;\n  \n    @Column({ type: 'text', nullable: true, name: 'customer_email' })\n    @Index()\n    customerEmail?: string;\n  \n  @CreateDateColumn({ type: 'timestamp', name: 'created_at' })\n  createdAt!: Date;\n\n  @UpdateDateColumn({ type: 'timestamp', name: 'updated_at' })\n  updatedAt!: Date;\n}\n  \n  @Entity('refunds')\n  export class Refund {\n    @PrimaryColumn({ type: 'text' })\n    id!: string;\n  \n    @Column({ type: 'integer' })\n    amount!: number;\n  \n    @Column({ type: 'text' })\n    currency!: string;\n  \n    @Column({ type: 'text', nullable: true })\n    reason?: string;\n  \n    @Column({ type: 'jsonb', nullable: true })\n    metadata?: Record<string, any>;\n  \n    @Column({ type: 'text', name: 'payment_id' })\n    @Index()\n    paymentId!: string;\n  \n    @ManyToOne(() => Payment, { onDelete: 'CASCADE' })\n    @JoinColumn({ name: 'payment_id' })\n    payment!: Payment;\n  \n    @CreateDateColumn({ type: 'timestamp', name: 'created_at' })\n    createdAt!: Date;\n  }\n  \n  @Entity('invoices')\n  export class Invoice {\n    @PrimaryColumn({ type: 'text' })\n    id!: string;\n  \n    @Column({ type: 'text', nullable: true, name: 'subscription_id' })\n    @Index()\n    subscriptionId?: string;\n  \n    @ManyToOne(() => Subscription, { onDelete: 'SET NULL' })\n    @JoinColumn({ name: 'subscription_id' })\n    subscription?: Subscription;\n  \n    @Column({ type: 'text', name: 'billing_mode' })\n    billingMode!: string;\n  \n  @Column({ type: 'integer', name: 'amount_paid' })\n  amountPaid!: number;\n\n  @Column({ type: 'text' })\n  currency!: string;\n  \n    @Column({\n      type: 'enum',\n      enum: InvoiceStatus,\n    })\n    @Index()\n    status!: InvoiceStatus;\n  \n    @Column({ type: 'timestamp', nullable: true, name: 'paid_at' })\n    paidAt?: Date;\n  \n    @Column({ type: 'jsonb', nullable: true, name: 'line_items' })\n    lineItems?: Record<string, any>;\n  \n  @Column({ type: 'jsonb', nullable: true })\n  metadata?: Record<string, any>;\n\n  @Column({ type: 'jsonb', nullable: true, name: 'custom_fields' })\n  customFields?: Record<string, any>;\n  \n    @Column({ type: 'text', nullable: true, name: 'customer_id' })\n    @Index()\n    customerId?: string;\n  \n    @ManyToOne(() => Customer, { onDelete: 'CASCADE' })\n    @JoinColumn({ name: 'customer_id' })\n    customer?: Customer;\n  \n    @Column({ type: 'text', nullable: true, name: 'customer_email' })\n    @Index()\n    customerEmail?: string;\n  \n    @CreateDateColumn({ type: 'timestamp', name: 'created_at' })\n    createdAt!: Date;\n  \n    @UpdateDateColumn({ type: 'timestamp', name: 'updated_at' })\n    updatedAt!: Date;\n  }"}],"docs":"Copy the content from src/db/schema/payments.ts to your own schema.ts file. \n Run 'npx typeorm migration:generate' to create the migrations.","meta":{"backend":"express","provider":"stripe","orm":"typeorm","database":"mysql","auth":"none"}},{"name":"paystack-nextjs","type":"registry:block","description":"Paystack payment integration for Next.js App Router with type-safe API routes and webhook handling","dependencies":["@paykit-sdk/core","@paykit-sdk/paystack"],"devDependencies":[],"registryDependencies":[],"files":[{"path":"providers/paystack.ts","type":"registry:lib","target":"lib/paykit.ts","content":"import { PayKit, createEndpointHandlers } from '@paykit-sdk/core';\nimport { paystack } from '@paykit-sdk/paystack';\n\nexport const paykit = new PayKit(paystack());\nexport const endpoints = createEndpointHandlers(paykit);\n"},{"path":"shared/routers/nextjs/catch-all.ts","type":"registry:page","target":"app/api/paykit/[...endpoint]/route.ts","content":"import { endpoints } from '@/lib/paykit';\nimport type {\n  EndpointArgs,\n  EndpointHandler,\n  EndpointPath,\n} from '@paykit-sdk/core';\nimport { NextResponse, NextRequest } from 'next/server';\n\nexport async function POST(\n  request: NextRequest,\n  { params }: { params: Promise<{ endpoint: string[] }> },\n) {\n  const { endpoint: endpointArray } = await params;\n\n  const endpoint = ('/' + endpointArray.join('/')) as EndpointPath;\n\n  const handler = endpoints[endpoint] as EndpointHandler<\n    typeof endpoint\n  >;\n\n  if (!handler) {\n    return NextResponse.json(\n      { message: 'Endpoint not found' },\n      { status: 404 },\n    );\n  }\n\n  const body = await request.json();\n\n  const { args } = body as { args: EndpointArgs<typeof endpoint> };\n\n  try {\n    const result = await handler(...args);\n    return NextResponse.json({ result });\n  } catch (error) {\n    console.error('PayKit API Error:', error);\n    const message =\n      error instanceof Error\n        ? error.message\n        : 'Internal server error';\n    return NextResponse.json({ message }, { status: 500 });\n  }\n}\n"},{"path":"shared/routers/nextjs/webhook.ts","type":"registry:page","target":"app/api/paykit/webhooks/route.ts","content":"import { paykit } from '@/lib/paykit';\nimport type { NextRequest } from 'next/server';\nimport { NextResponse } from 'next/server';\n\nexport async function POST(request: NextRequest) {\n  const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET;\n\n  if (!webhookSecret) {\n    return NextResponse.json(\n      { error: 'Webhook secret not configured' },\n      { status: 500 },\n    );\n  }\n\n  const webhook = paykit.webhooks\n    .setup({ webhookSecret })\n    .on('customer.created', async event => {\n      console.log('Customer created:', event.data);\n    })\n    .on('subscription.created', async event => {\n      console.log('Subscription created:', event.data);\n    })\n    .on('payment.created', async event => {\n      console.log('Payment created:', event.data);\n    })\n    .on('refund.created', async event => {\n      console.log('Refund created:', event.data);\n    })\n    .on('invoice.generated', async event => {\n      console.log('Invoice generated:', event.data);\n    });\n\n  const body = await request.text();\n  const headers = request.headers;\n  const url = request.url;\n\n  try {\n    await webhook.handle({ body, headers, fullUrl: url });\n    return NextResponse.json({ success: true });\n  } catch (error) {\n    console.log('Webhook Error', error);\n    return NextResponse.json({ success: false });\n  }\n}\n"}],"envVars":{"PAYSTACK_SECRET_KEY":"sk_test_...","PAYSTACK_WEBHOOK_SECRET":"whsec_..."},"docs":"Get your Paystack Secret Key from https://dashboard.paystack.com/#/settings/developer \n Create a webhook endpoint in your Paystack dashboard to get your webhook secret.","meta":{"backend":"nextjs","provider":"paystack","orm":"none","database":"none","auth":"none"}},{"name":"paystack-hono","type":"registry:block","description":"Paystack payment integration for Hono backend with unified routes and webhook handling","dependencies":["@paykit-sdk/core","@paykit-sdk/paystack","hono"],"devDependencies":[],"registryDependencies":[],"files":[{"path":"providers/paystack.ts","type":"registry:lib","target":"lib/paykit.ts","content":"import { PayKit, createEndpointHandlers } from '@paykit-sdk/core';\nimport { paystack } from '@paykit-sdk/paystack';\n\nexport const paykit = new PayKit(paystack());\nexport const endpoints = createEndpointHandlers(paykit);\n"},{"path":"shared/routers/hono/catch-all.ts","type":"registry:page","target":"src/routes/paykit.ts","content":""},{"path":"shared/routers/hono/webhook.ts","type":"registry:page","target":"src/routes/paykit-webhooks.ts","content":""}],"envVars":{"PAYSTACK_SECRET_KEY":"sk_test_...","PAYSTACK_WEBHOOK_SECRET":"whsec_..."},"docs":"Get your Paystack Secret Key from https://dashboard.paystack.com/#/settings/developer \n Create a webhook endpoint in your Paystack dashboard to get your webhook secret.","meta":{"backend":"hono","provider":"paystack","orm":"none","database":"none","auth":"none"}}]}