Phase8: Auto bill credit card
All checks were successful
Build and Push / build (push) Successful in 1m45s

This commit is contained in:
2026-05-27 22:20:13 +02:00
parent a6c3c42ec9
commit 9243beddd3
2 changed files with 30 additions and 26 deletions

View File

@@ -525,29 +525,33 @@ export async function POST(request: Request) {
// Build the billing snapshot from the org's address (already
// fetched above for the wizard's billing-address resolution).
// The snapshot is what the invoice + Stripe customer use.
const billingSnapshot: InvoiceBillingSnapshot = orgBilling
? {
companyName: orgBilling.companyName,
contactName: orgBilling.contactName ?? null,
streetAddress: orgBilling.streetAddress,
postalCode: orgBilling.postalCode,
city: orgBilling.city,
country: orgBilling.country,
vatNumber: orgBilling.vatNumber ?? null,
billingEmail: orgBilling.billingEmail,
notes: orgBilling.notes ?? null,
}
: {
companyName,
contactName: contactName,
streetAddress: billingAddress.streetAddress,
postalCode: billingAddress.postalCode,
city: billingAddress.city,
country: billingAddress.country,
vatNumber: billingAddress.vatNumber ?? null,
billingEmail: billingAddress.billingEmail,
notes: null,
};
//
// orgBilling MUST exist here: the auto-pay pre-check above
// requires a saved Stripe PaymentMethod, which can only be
// created via ensureStripeCustomerForOrg, which requires
// org_billing. If it's missing the system is in an inconsistent
// state we shouldn't paper over.
if (!orgBilling) {
console.error(
`Paid-fee onboarding path reached without org_billing for org ${user.orgId} — auto-pay pre-check should have prevented this.`
);
await deletePendingPaymentRequest(tenantRequest.id).catch(() => undefined);
return NextResponse.json(
{ error: "Billing record missing. Please re-save your billing details on /settings/billing." },
{ status: 500 }
);
}
const billingSnapshot: InvoiceBillingSnapshot = {
companyName: orgBilling.companyName,
contactName: orgBilling.contactName ?? null,
streetAddress: orgBilling.streetAddress,
postalCode: orgBilling.postalCode,
city: orgBilling.city,
country: orgBilling.country,
vatNumber: orgBilling.vatNumber ?? null,
billingEmail: orgBilling.billingEmail,
notes: orgBilling.notes ?? null,
};
// Locale for the invoice + PDF — pick from the org's country
// using the same heuristic the auto-cron uses.

View File

@@ -4203,7 +4203,7 @@ export async function getTenantRequestForSetupFlow(
[requestId]
);
return result.rows.length > 0
? rowToTenantRequest(result.rows[0])
? mapRow(result.rows[0])
: null;
}
@@ -4231,7 +4231,7 @@ export async function createTenantRequestPendingPayment(params: {
soulMd?: string;
agentsMd?: string | null;
packages: string[];
billingAddress: Record<string, unknown>;
billingAddress: BillingAddress;
billingNotes?: string;
encryptedSecrets?: Buffer | null;
isPersonal: boolean;
@@ -4267,7 +4267,7 @@ export async function createTenantRequestPendingPayment(params: {
params.isPersonal,
]
);
return rowToTenantRequest(result.rows[0]);
return mapRow(result.rows[0]);
}
/**