import type { Config } from 'payload' // Base payment provider interface export interface PaymentProvider { cancelPayment(id: string): Promise createPayment(options: CreatePaymentOptions): Promise handleWebhook(request: Request, signature?: string): Promise name: string refundPayment(id: string, amount?: number): Promise retrievePayment(id: string): Promise } // Payment types export interface CreatePaymentOptions { amount: number cancelUrl?: string currency: string customer?: string description?: string metadata?: Record returnUrl?: string } export interface Payment { amount: number createdAt: string currency: string customer?: string description?: string id: string metadata?: Record provider: string providerData?: Record status: PaymentStatus updatedAt: string } export interface Refund { amount: number createdAt: string currency: string id: string paymentId: string providerData?: Record reason?: string status: RefundStatus } export interface WebhookEvent { data: Record id: string provider: string type: string verified: boolean } // Status enums export type PaymentStatus = | 'canceled' | 'failed' | 'partially_refunded' | 'pending' | 'processing' | 'refunded' | 'succeeded' export type RefundStatus = | 'canceled' | 'failed' | 'pending' | 'processing' | 'succeeded' // Provider configurations export interface StripeConfig { apiVersion?: string publishableKey: string secretKey: string webhookEndpointSecret: string } export interface MollieConfig { apiKey: string testMode?: boolean webhookUrl: string } export interface TestProviderConfig { autoComplete?: boolean defaultDelay?: number enabled: boolean failureRate?: number simulateFailures?: boolean } // Customer info extractor callback type export interface CustomerInfoExtractor { (customer: any): { name: string email: string phone?: string company?: string taxId?: string billingAddress?: { line1: string line2?: string city: string state?: string postalCode: string country: string } } } // Plugin configuration export interface BillingPluginConfig { admin?: { customComponents?: boolean dashboard?: boolean } collections?: { customerRelation?: boolean | string // false to disable, string for custom collection slug customers?: string invoices?: string payments?: string refunds?: string } customerInfoExtractor?: CustomerInfoExtractor // Callback to extract customer info from relationship disabled?: boolean providers?: { mollie?: MollieConfig stripe?: StripeConfig test?: TestProviderConfig } webhooks?: { basePath?: string cors?: boolean } } // Collection types export interface PaymentRecord { amount: number createdAt: string currency: string customer?: string description?: string id: string metadata?: Record provider: string providerData?: Record providerId: string status: PaymentStatus updatedAt: string } export interface CustomerRecord { address?: { city?: string country?: string line1?: string line2?: string postalCode?: string state?: string } createdAt: string email?: string id: string metadata?: Record name?: string phone?: string providerIds?: Record updatedAt: string } export interface InvoiceRecord { amount: number billingAddress?: { city: string country: string line1: string line2?: string postalCode: string state?: string } createdAt: string currency: string customer?: string // Optional relationship to customer collection customerInfo?: { company?: string email: string name: string phone?: string taxId?: string } dueDate?: string id: string items: InvoiceItem[] metadata?: Record number: string paidAt?: string status: InvoiceStatus updatedAt: string } export interface InvoiceItem { description: string quantity: number totalAmount: number unitAmount: number } export type InvoiceStatus = | 'draft' | 'open' | 'paid' | 'uncollectible' | 'void' // Plugin type export interface BillingPluginOptions extends BillingPluginConfig { disabled?: boolean } // Error types export class BillingError extends Error { constructor( message: string, public code: string, public provider?: string, public details?: Record ) { super(message) this.name = 'BillingError' } } export class PaymentProviderError extends BillingError { constructor( message: string, provider: string, code?: string, details?: Record ) { super(message, code || 'PROVIDER_ERROR', provider, details) this.name = 'PaymentProviderError' } } export class WebhookError extends BillingError { constructor( message: string, provider: string, code?: string, details?: Record ) { super(message, code || 'WEBHOOK_ERROR', provider, details) this.name = 'WebhookError' } }