Replace manualProviders.ts with a paymentProviders.ts registry (automatic vs manual settlement) and move all seat counting into capacity.ts as the single source of truth: only paid/checked-in tickets and pending_approval payments hold a seat, so abandoned checkouts never block sales. Admins can now knowingly approve a payment over capacity (allowOverCapacity), with the booking and admin UIs updated to match. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
38 lines
1.5 KiB
TypeScript
38 lines
1.5 KiB
TypeScript
// Payment provider registry.
|
|
//
|
|
// Every provider is either:
|
|
// - 'automatic': the gateway itself confirms the payment (webhook/invoice
|
|
// settlement) and the booking is auto-approved on success. No admin involved.
|
|
// Currently Lightning; future online gateways (e.g. Stripe) go here.
|
|
// - 'manual': a human must verify the money arrived (TPago, bank transfer,
|
|
// card handled offline, cash at the door). These are never auto-confirmed
|
|
// and never auto-failed; an admin settles them by hand. Bank transfer and
|
|
// TPago additionally expose an online "I've paid" step that moves the
|
|
// payment to 'pending_approval'.
|
|
//
|
|
// Capacity note (see lib/capacity.ts): only paid/checked-in tickets and
|
|
// 'pending_approval' payments hold a seat. A bare 'pending' payment — of either
|
|
// kind — holds no seat, so an abandoned checkout can never block sales.
|
|
|
|
export type PaymentProviderKind = 'automatic' | 'manual';
|
|
|
|
export const PAYMENT_PROVIDERS: Record<string, { kind: PaymentProviderKind }> = {
|
|
lightning: { kind: 'automatic' },
|
|
tpago: { kind: 'manual' },
|
|
bank_transfer: { kind: 'manual' },
|
|
card: { kind: 'manual' },
|
|
cash: { kind: 'manual' },
|
|
};
|
|
|
|
export const MANUAL_PAYMENT_PROVIDERS = Object.keys(PAYMENT_PROVIDERS).filter(
|
|
(p) => PAYMENT_PROVIDERS[p].kind === 'manual'
|
|
);
|
|
|
|
export function isManualProvider(provider: string): boolean {
|
|
return PAYMENT_PROVIDERS[provider]?.kind === 'manual';
|
|
}
|
|
|
|
export function isAutomaticProvider(provider: string): boolean {
|
|
return PAYMENT_PROVIDERS[provider]?.kind === 'automatic';
|
|
}
|