diff options
| author | Frank <[email protected]> | 2025-09-24 19:09:23 -0400 |
|---|---|---|
| committer | Frank <[email protected]> | 2025-09-24 19:09:28 -0400 |
| commit | d0377a95cf407c1c6a718a52018087885af90677 (patch) | |
| tree | 27d9d7dd0f082799ae311548d04976510dd37f9d /packages/console/core/src | |
| parent | 3b20bf6d4f744e63faa8b798ca911a93338dc4f3 (diff) | |
| download | opencode-d0377a95cf407c1c6a718a52018087885af90677.tar.gz opencode-d0377a95cf407c1c6a718a52018087885af90677.zip | |
zen: billing
Diffstat (limited to 'packages/console/core/src')
| -rw-r--r-- | packages/console/core/src/billing.ts | 64 | ||||
| -rw-r--r-- | packages/console/core/src/schema/billing.sql.ts | 1 |
2 files changed, 45 insertions, 20 deletions
diff --git a/packages/console/core/src/billing.ts b/packages/console/core/src/billing.ts index dda0c539f..4267d3b94 100644 --- a/packages/console/core/src/billing.ts +++ b/packages/console/core/src/billing.ts @@ -10,6 +10,8 @@ import { Identifier } from "./identifier" import { centsToMicroCents } from "./util/price" export namespace Billing { + export const CHARGE_NAME = "opencode credits" + export const CHARGE_FEE_NAME = "processing fee" export const CHARGE_AMOUNT = 2000 // $20 export const CHARGE_FEE = 123 // Stripe fee 4.4% + $0.30 export const CHARGE_THRESHOLD = 500 // $5 @@ -73,22 +75,39 @@ export namespace Billing { .then((rows) => rows[0]), ) const paymentID = Identifier.create("payment") - let charge + let invoice try { - charge = await Billing.stripe().paymentIntents.create( - { - amount: Billing.CHARGE_AMOUNT + Billing.CHARGE_FEE, - currency: "usd", - customer: customerID!, - payment_method: paymentMethodID!, - off_session: true, - confirm: true, - }, - { idempotencyKey: paymentID }, - ) - - if (charge.status !== "succeeded") throw new Error(charge.last_payment_error?.message) + const draft = await Billing.stripe().invoices.create({ + customer: customerID!, + auto_advance: false, + default_payment_method: paymentMethodID!, + collection_method: "charge_automatically", + currency: "usd", + }) + await Billing.stripe().invoiceItems.create({ + amount: Billing.CHARGE_AMOUNT, + currency: "usd", + customer: customerID!, + description: CHARGE_NAME, + invoice: draft.id!, + }) + await Billing.stripe().invoiceItems.create({ + amount: Billing.CHARGE_FEE, + currency: "usd", + customer: customerID!, + description: CHARGE_FEE_NAME, + invoice: draft.id!, + }) + await Billing.stripe().invoices.finalizeInvoice(draft.id!) + invoice = await Billing.stripe().invoices.pay(draft.id!, { + off_session: true, + payment_method: paymentMethodID!, + expand: ["payments"], + }) + if (invoice.status !== "paid" || invoice.payments?.data.length !== 1) + throw new Error(invoice.last_finalization_error?.message) } catch (e: any) { + console.error(e) await Database.use((tx) => tx .update(BillingTable) @@ -114,7 +133,8 @@ export namespace Billing { workspaceID: Actor.workspace(), id: paymentID, amount: centsToMicroCents(CHARGE_AMOUNT), - paymentID: charge.id, + invoiceID: invoice.id!, + paymentID: invoice.payments?.data[0].payment.payment_intent as string, customerID, }) }) @@ -155,12 +175,13 @@ export namespace Billing { const customer = await Billing.get() const session = await Billing.stripe().checkout.sessions.create({ mode: "payment", + billing_address_collection: "required", line_items: [ { price_data: { currency: "usd", product_data: { - name: "opencode credits", + name: CHARGE_NAME, }, unit_amount: CHARGE_AMOUNT, }, @@ -170,16 +191,13 @@ export namespace Billing { price_data: { currency: "usd", product_data: { - name: "processing fee", + name: CHARGE_FEE_NAME, }, unit_amount: CHARGE_FEE, }, quantity: 1, }, ], - payment_intent_data: { - setup_future_usage: "on_session", - }, ...(customer.customerID ? { customer: customer.customerID, @@ -192,6 +210,12 @@ export namespace Billing { workspaceID: Actor.workspace(), }, currency: "usd", + invoice_creation: { + enabled: true, + }, + payment_intent_data: { + setup_future_usage: "on_session", + }, payment_method_types: ["card"], payment_method_data: { allow_redisplay: "always", diff --git a/packages/console/core/src/schema/billing.sql.ts b/packages/console/core/src/schema/billing.sql.ts index f7da84ab7..302e01133 100644 --- a/packages/console/core/src/schema/billing.sql.ts +++ b/packages/console/core/src/schema/billing.sql.ts @@ -28,6 +28,7 @@ export const PaymentTable = mysqlTable( ...workspaceColumns, ...timestamps, customerID: varchar("customer_id", { length: 255 }), + invoiceID: varchar("invoice_id", { length: 255 }), paymentID: varchar("payment_id", { length: 255 }), amount: bigint("amount", { mode: "number" }).notNull(), timeRefunded: utc("time_refunded"), |
