diff options
| author | Frank <[email protected]> | 2025-10-31 14:42:18 -0400 |
|---|---|---|
| committer | Frank <[email protected]> | 2025-10-31 14:43:51 -0400 |
| commit | 021334509e8d4d9a823caf49216346afca1c36f4 (patch) | |
| tree | d4779f2fcf2a25da5e38bdd54ccf0f74fdd537f9 /packages/console/app/src | |
| parent | 4bde3f7b156729733c0286a8119825d5782d8a31 (diff) | |
| download | opencode-021334509e8d4d9a823caf49216346afca1c36f4.tar.gz opencode-021334509e8d4d9a823caf49216346afca1c36f4.zip | |
sync
Diffstat (limited to 'packages/console/app/src')
5 files changed, 51 insertions, 14 deletions
diff --git a/packages/console/app/src/routes/stripe/webhook.ts b/packages/console/app/src/routes/stripe/webhook.ts index f1fa73c91..54dc4eb23 100644 --- a/packages/console/app/src/routes/stripe/webhook.ts +++ b/packages/console/app/src/routes/stripe/webhook.ts @@ -53,7 +53,8 @@ export async function POST(input: APIEvent) { await Actor.provide("system", { workspaceID }, async () => { const customer = await Billing.get() - if (customer?.customerID && customer.customerID !== customerID) throw new Error("Customer ID mismatch") + if (customer?.customerID && customer.customerID !== customerID) + throw new Error("Customer ID mismatch") // set customer metadata if (!customer?.customerID) { @@ -69,7 +70,18 @@ export async function POST(input: APIEvent) { expand: ["payment_method"], }) const paymentMethod = paymentIntent.payment_method - if (!paymentMethod || typeof paymentMethod === "string") throw new Error("Payment method not expanded") + if (!paymentMethod || typeof paymentMethod === "string") + throw new Error("Payment method not expanded") + + const oldBillingInfo = await Database.use((tx) => + tx + .select({ + customerID: BillingTable.customerID, + }) + .from(BillingTable) + .where(eq(BillingTable.workspaceID, workspaceID)) + .then((rows) => rows[0]), + ) await Database.transaction(async (tx) => { await tx @@ -80,9 +92,16 @@ export async function POST(input: APIEvent) { paymentMethodID: paymentMethod.id, paymentMethodLast4: paymentMethod.card?.last4 ?? null, paymentMethodType: paymentMethod.type, - reload: true, - reloadError: null, - timeReloadError: null, + // enable reload if first time enabling billing + ...(oldBillingInfo?.customerID + ? {} + : { + reload: true, + reloadTrigger: Billing.CHARGE_THRESHOLD_DOLLAR, + reloadAmount: Billing.CHARGE_AMOUNT_DOLLAR, + reloadError: null, + timeReloadError: null, + }), }) .where(eq(BillingTable.workspaceID, workspaceID)) await tx.insert(PaymentTable).values({ @@ -119,7 +138,12 @@ export async function POST(input: APIEvent) { .set({ timeRefunded: new Date(body.created * 1000), }) - .where(and(eq(PaymentTable.paymentID, paymentIntentID), eq(PaymentTable.workspaceID, workspaceID))) + .where( + and( + eq(PaymentTable.paymentID, paymentIntentID), + eq(PaymentTable.workspaceID, workspaceID), + ), + ) await tx .update(BillingTable) diff --git a/packages/console/app/src/routes/workspace/[id]/billing/billing-section.tsx b/packages/console/app/src/routes/workspace/[id]/billing/billing-section.tsx index 7cbf29ad6..c0723136b 100644 --- a/packages/console/app/src/routes/workspace/[id]/billing/billing-section.tsx +++ b/packages/console/app/src/routes/workspace/[id]/billing/billing-section.tsx @@ -93,7 +93,7 @@ export function BillingSection() { </span> <span data-slot="balance-label">Current Balance</span> </div> - <Show when={balanceInfo()?.paymentMethodType}> + <Show when={balanceInfo()?.customerID}> <div data-slot="balance-right-section"> <button data-color="primary" @@ -149,7 +149,7 @@ export function BillingSection() { </div> </Show> </div> - <Show when={!balanceInfo()?.paymentMethodType}> + <Show when={!balanceInfo()?.customerID}> <button data-slot="enable-billing-button" data-color="primary" diff --git a/packages/console/app/src/routes/workspace/[id]/billing/index.tsx b/packages/console/app/src/routes/workspace/[id]/billing/index.tsx index ad432a8aa..f14dbffbf 100644 --- a/packages/console/app/src/routes/workspace/[id]/billing/index.tsx +++ b/packages/console/app/src/routes/workspace/[id]/billing/index.tsx @@ -16,7 +16,7 @@ export default function () { <div data-slot="sections"> <Show when={userInfo()?.isAdmin}> <BillingSection /> - <Show when={billingInfo()?.paymentMethodType}> + <Show when={billingInfo()?.customerID}> <ReloadSection /> <MonthlyLimitSection /> <PaymentSection /> diff --git a/packages/console/app/src/routes/workspace/[id]/billing/reload-section.module.css b/packages/console/app/src/routes/workspace/[id]/billing/reload-section.module.css index 97646269f..08fb8524b 100644 --- a/packages/console/app/src/routes/workspace/[id]/billing/reload-section.module.css +++ b/packages/console/app/src/routes/workspace/[id]/billing/reload-section.module.css @@ -1,4 +1,11 @@ .root { + [data-slot="title-row"] { + display: flex; + justify-content: space-between; + align-items: center; + gap: var(--space-4); + } + [data-slot="section-content"] { display: flex; flex-direction: column; diff --git a/packages/console/app/src/routes/workspace/[id]/billing/reload-section.tsx b/packages/console/app/src/routes/workspace/[id]/billing/reload-section.tsx index 4b55c97a9..67a74d9fe 100644 --- a/packages/console/app/src/routes/workspace/[id]/billing/reload-section.tsx +++ b/packages/console/app/src/routes/workspace/[id]/billing/reload-section.tsx @@ -26,7 +26,14 @@ const setReload = action(async (form: FormData) => { .update(BillingTable) .set({ reload: reloadValue, - ...(reloadValue ? { reloadError: null, timeReloadError: null } : {}), + ...(reloadValue + ? { + reloadTrigger: Billing.CHARGE_THRESHOLD_DOLLAR, + reloadAmount: Billing.CHARGE_AMOUNT_DOLLAR, + reloadError: null, + timeReloadError: null, + } + : {}), }) .where(eq(BillingTable.workspaceID, workspaceID)), ), @@ -51,10 +58,7 @@ export function ReloadSection() { <section class={styles.root}> <div data-slot="section-title"> <h2>Auto Reload</h2> - <p>Automatically reload your balance when it gets low.</p> - </div> - <div data-slot="section-content"> - <div data-slot="setting-row"> + <div data-slot="title-row"> <Show when={balanceInfo()?.reload} fallback={ @@ -79,6 +83,8 @@ export function ReloadSection() { </button> </form> </div> + </div> + <div data-slot="section-content"> <Show when={balanceInfo()?.reload && balanceInfo()?.reloadError}> <div data-slot="reload-error"> <p> |
