mirror of
https://github.com/anomalyco/opencode.git
synced 2026-02-01 22:48:16 +00:00
zen: disable reload when reload fails
This commit is contained in:
@@ -77,6 +77,8 @@ export const stripeWebhook = new stripe.WebhookEndpoint("StripeWebhookEndpoint",
|
||||
"checkout.session.expired",
|
||||
"charge.refunded",
|
||||
"invoice.payment_succeeded",
|
||||
"invoice.payment_failed",
|
||||
"invoice.payment_action_required",
|
||||
"customer.created",
|
||||
"customer.deleted",
|
||||
"customer.updated",
|
||||
|
||||
@@ -141,8 +141,6 @@ export async function POST(input: APIEvent) {
|
||||
return couponID
|
||||
})()
|
||||
|
||||
// get user
|
||||
|
||||
await Actor.provide("system", { workspaceID }, async () => {
|
||||
// look up current billing
|
||||
const billing = await Billing.get()
|
||||
@@ -422,8 +420,8 @@ export async function POST(input: APIEvent) {
|
||||
}
|
||||
if (body.type === "invoice.payment_succeeded") {
|
||||
if (
|
||||
body.data.object.billing_reason === "subscription_cycle" ||
|
||||
body.data.object.billing_reason === "subscription_create"
|
||||
body.data.object.billing_reason === "subscription_create" ||
|
||||
body.data.object.billing_reason === "subscription_cycle"
|
||||
) {
|
||||
const invoiceID = body.data.object.id as string
|
||||
const amountInCents = body.data.object.amount_paid
|
||||
@@ -476,6 +474,70 @@ export async function POST(input: APIEvent) {
|
||||
},
|
||||
}),
|
||||
)
|
||||
} else if (body.data.object.billing_reason === "manual") {
|
||||
const workspaceID = body.data.object.metadata?.workspaceID
|
||||
const amountInCents = body.data.object.metadata?.amount && parseInt(body.data.object.metadata?.amount)
|
||||
const invoiceID = body.data.object.id as string
|
||||
const customerID = body.data.object.customer as string
|
||||
|
||||
if (!workspaceID) throw new Error("Workspace ID not found")
|
||||
if (!customerID) throw new Error("Customer ID not found")
|
||||
if (!amountInCents) throw new Error("Amount not found")
|
||||
if (!invoiceID) throw new Error("Invoice ID not found")
|
||||
|
||||
await Actor.provide("system", { workspaceID }, async () => {
|
||||
// get payment id from invoice
|
||||
const invoice = await Billing.stripe().invoices.retrieve(invoiceID, {
|
||||
expand: ["payments"],
|
||||
})
|
||||
await Database.transaction(async (tx) => {
|
||||
await tx
|
||||
.update(BillingTable)
|
||||
.set({
|
||||
balance: sql`${BillingTable.balance} + ${centsToMicroCents(amountInCents)}`,
|
||||
reloadError: null,
|
||||
timeReloadError: null,
|
||||
})
|
||||
.where(eq(BillingTable.workspaceID, Actor.workspace()))
|
||||
await tx.insert(PaymentTable).values({
|
||||
workspaceID: Actor.workspace(),
|
||||
id: Identifier.create("payment"),
|
||||
amount: centsToMicroCents(amountInCents),
|
||||
invoiceID,
|
||||
paymentID: invoice.payments?.data[0].payment.payment_intent as string,
|
||||
customerID,
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
if (body.type === "invoice.payment_failed" || body.type === "invoice.payment_action_required") {
|
||||
if (body.data.object.billing_reason === "manual") {
|
||||
const workspaceID = body.data.object.metadata?.workspaceID
|
||||
const invoiceID = body.data.object.id
|
||||
|
||||
if (!workspaceID) throw new Error("Workspace ID not found")
|
||||
if (!invoiceID) throw new Error("Invoice ID not found")
|
||||
|
||||
const paymentIntent = await Billing.stripe().paymentIntents.retrieve(invoiceID);
|
||||
console.log(JSON.stringify(paymentIntent))
|
||||
const errorMessage =
|
||||
typeof paymentIntent === "object" && paymentIntent !== null
|
||||
? paymentIntent.last_payment_error?.message
|
||||
: undefined
|
||||
|
||||
await Actor.provide("system", { workspaceID }, async () => {
|
||||
await Database.use((tx) =>
|
||||
tx
|
||||
.update(BillingTable)
|
||||
.set({
|
||||
reload: false,
|
||||
reloadError: errorMessage ?? "Payment failed.",
|
||||
timeReloadError: sql`now()`,
|
||||
})
|
||||
.where(eq(BillingTable.workspaceID, Actor.workspace())),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
if (body.type === "charge.refunded") {
|
||||
|
||||
@@ -78,8 +78,6 @@ export namespace Billing {
|
||||
const customerID = billing.customerID
|
||||
const paymentMethodID = billing.paymentMethodID
|
||||
const amountInCents = (billing.reloadAmount ?? Billing.RELOAD_AMOUNT) * 100
|
||||
const paymentID = Identifier.create("payment")
|
||||
let invoice
|
||||
try {
|
||||
const draft = await Billing.stripe().invoices.create({
|
||||
customer: customerID!,
|
||||
@@ -87,6 +85,10 @@ export namespace Billing {
|
||||
default_payment_method: paymentMethodID!,
|
||||
collection_method: "charge_automatically",
|
||||
currency: "usd",
|
||||
metadata: {
|
||||
workspaceID: Actor.workspace(),
|
||||
amount: amountInCents.toString(),
|
||||
},
|
||||
})
|
||||
await Billing.stripe().invoiceItems.create({
|
||||
amount: amountInCents,
|
||||
@@ -103,19 +105,17 @@ export namespace Billing {
|
||||
description: ITEM_FEE_NAME,
|
||||
})
|
||||
await Billing.stripe().invoices.finalizeInvoice(draft.id!)
|
||||
invoice = await Billing.stripe().invoices.pay(draft.id!, {
|
||||
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)
|
||||
.set({
|
||||
reload: false,
|
||||
reloadError: e.message ?? "Payment failed.",
|
||||
timeReloadError: sql`now()`,
|
||||
})
|
||||
@@ -123,25 +123,6 @@ export namespace Billing {
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
await Database.transaction(async (tx) => {
|
||||
await tx
|
||||
.update(BillingTable)
|
||||
.set({
|
||||
balance: sql`${BillingTable.balance} + ${centsToMicroCents(amountInCents)}`,
|
||||
reloadError: null,
|
||||
timeReloadError: null,
|
||||
})
|
||||
.where(eq(BillingTable.workspaceID, Actor.workspace()))
|
||||
await tx.insert(PaymentTable).values({
|
||||
workspaceID: Actor.workspace(),
|
||||
id: paymentID,
|
||||
amount: centsToMicroCents(amountInCents),
|
||||
invoiceID: invoice.id!,
|
||||
paymentID: invoice.payments?.data[0].payment.payment_intent as string,
|
||||
customerID,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const grantCredit = async (workspaceID: string, dollarAmount: number) => {
|
||||
|
||||
Reference in New Issue
Block a user