mirror of
https://github.com/xtr-dev/payload-billing.git
synced 2025-12-10 10:53:23 +00:00
docs: Update CLAUDE.md to reflect current implementation
- Remove outdated payment provider and testing information - Focus on current customer data management features - Document customer info extractor pattern and usage - Include clear configuration examples - Remove references to unimplemented features 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
232
CLAUDE.md
232
CLAUDE.md
@@ -2,161 +2,165 @@
|
|||||||
|
|
||||||
## Project Overview
|
## Project Overview
|
||||||
|
|
||||||
This is a PayloadCMS plugin that provides billing and payment functionality with multiple payment provider integrations (Stripe, Mollie) and a test payment provider for local development.
|
This is a PayloadCMS plugin that provides billing and payment functionality with flexible customer data management and invoice generation capabilities.
|
||||||
|
|
||||||
## Architecture Principles
|
## Architecture Principles
|
||||||
|
|
||||||
### Core Design
|
### Core Design
|
||||||
- **Provider Abstraction**: All payment providers implement a common interface for consistency
|
|
||||||
- **TypeScript First**: Full TypeScript support with strict typing throughout
|
- **TypeScript First**: Full TypeScript support with strict typing throughout
|
||||||
- **PayloadCMS Integration**: Deep integration with Payload collections, hooks, and admin UI
|
- **PayloadCMS Integration**: Deep integration with Payload collections, hooks, and admin UI
|
||||||
- **Extensible**: Easy to add new payment providers through the common interface
|
- **Flexible Customer Data**: Support for both relationship-based and embedded customer information
|
||||||
- **Developer Experience**: Comprehensive testing tools and local development support
|
- **Callback-based Syncing**: Use customer info extractors to keep data in sync
|
||||||
|
|
||||||
### Payment Provider Interface
|
|
||||||
All payment providers must implement the `PaymentProvider` interface:
|
|
||||||
```typescript
|
|
||||||
interface PaymentProvider {
|
|
||||||
createPayment(options: CreatePaymentOptions): Promise<Payment>
|
|
||||||
retrievePayment(id: string): Promise<Payment>
|
|
||||||
cancelPayment(id: string): Promise<Payment>
|
|
||||||
refundPayment(id: string, amount?: number): Promise<Refund>
|
|
||||||
handleWebhook(request: Request, signature?: string): Promise<WebhookEvent>
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Collections Structure
|
### Collections Structure
|
||||||
- **Payments**: Core payment tracking with provider-specific data
|
- **Payments**: Core payment tracking with provider-specific data
|
||||||
- **Customers**: Customer management with billing information
|
- **Customers**: Customer management with billing information (optional)
|
||||||
- **Invoices**: Invoice generation and management
|
- **Invoices**: Invoice generation with embedded customer info and optional customer relationship
|
||||||
- **Refunds**: Refund tracking and management
|
- **Refunds**: Refund tracking and management
|
||||||
|
|
||||||
## Code Organization
|
## Code Organization
|
||||||
|
|
||||||
```
|
```
|
||||||
src/
|
src/
|
||||||
├── providers/ # Payment provider implementations
|
|
||||||
│ ├── stripe/ # Stripe integration
|
|
||||||
│ ├── mollie/ # Mollie integration
|
|
||||||
│ ├── test/ # Test provider for development
|
|
||||||
│ └── base/ # Base provider interface and utilities
|
|
||||||
├── collections/ # PayloadCMS collection configurations
|
├── collections/ # PayloadCMS collection configurations
|
||||||
├── endpoints/ # API endpoints (webhooks, etc.)
|
|
||||||
├── hooks/ # PayloadCMS lifecycle hooks
|
|
||||||
├── admin/ # Admin UI components and extensions
|
|
||||||
├── types/ # TypeScript type definitions
|
├── types/ # TypeScript type definitions
|
||||||
└── utils/ # Shared utilities and helpers
|
└── index.ts # Main plugin entry point
|
||||||
```
|
```
|
||||||
|
|
||||||
## Development Guidelines
|
## Customer Data Management
|
||||||
|
|
||||||
### Payment Provider Development
|
### Customer Info Extractor Pattern
|
||||||
1. **Implement Base Interface**: All providers must implement `PaymentProvider`
|
|
||||||
2. **Error Handling**: Use consistent error types and proper error propagation
|
|
||||||
3. **Webhook Security**: Always verify webhook signatures and implement replay protection
|
|
||||||
4. **Idempotency**: Support idempotent operations where possible
|
|
||||||
5. **Logging**: Use structured logging for debugging and monitoring
|
|
||||||
|
|
||||||
### Testing Strategy
|
The plugin uses a callback-based approach to extract customer information from customer relationships:
|
||||||
- **Unit Tests**: Test individual provider methods and utilities
|
|
||||||
- **Integration Tests**: Test provider integrations with mock APIs
|
|
||||||
- **E2E Tests**: Test complete payment flows using test provider
|
|
||||||
- **Webhook Tests**: Test webhook handling with various scenarios
|
|
||||||
|
|
||||||
### TypeScript Guidelines
|
```typescript
|
||||||
- Use strict TypeScript configuration
|
// Define how to extract customer info from your customer collection
|
||||||
- Define proper interfaces for all external API responses
|
const customerInfoExtractor: CustomerInfoExtractor = (customer) => ({
|
||||||
- Use discriminated unions for provider-specific data
|
name: customer.name,
|
||||||
- Implement proper generic types for extensibility
|
email: customer.email,
|
||||||
|
phone: customer.phone,
|
||||||
### PayloadCMS Integration
|
company: customer.company,
|
||||||
- Follow PayloadCMS plugin patterns and conventions
|
taxId: customer.taxId,
|
||||||
- Use proper collection configurations with access control
|
billingAddress: {
|
||||||
- Implement admin UI components using PayloadCMS patterns
|
line1: customer.address.line1,
|
||||||
- Utilize PayloadCMS hooks for business logic
|
line2: customer.address.line2,
|
||||||
|
city: customer.address.city,
|
||||||
### Security Considerations
|
state: customer.address.state,
|
||||||
- **Webhook Verification**: Always verify webhook signatures
|
postalCode: customer.address.postalCode,
|
||||||
- **API Key Storage**: Use environment variables for sensitive data
|
country: customer.address.country,
|
||||||
- **Access Control**: Implement proper PayloadCMS access control
|
}
|
||||||
- **Input Validation**: Validate all inputs and sanitize data
|
})
|
||||||
- **Audit Logging**: Log all payment operations for audit trails
|
|
||||||
|
|
||||||
## Environment Configuration
|
|
||||||
|
|
||||||
### Required Environment Variables
|
|
||||||
```bash
|
|
||||||
# Stripe Configuration
|
|
||||||
STRIPE_SECRET_KEY=sk_test_...
|
|
||||||
STRIPE_PUBLISHABLE_KEY=pk_test_...
|
|
||||||
STRIPE_WEBHOOK_SECRET=whsec_...
|
|
||||||
|
|
||||||
# Mollie Configuration
|
|
||||||
MOLLIE_API_KEY=test_...
|
|
||||||
MOLLIE_WEBHOOK_URL=https://yourapp.com/api/billing/webhooks/mollie
|
|
||||||
|
|
||||||
# Test Provider Configuration
|
|
||||||
NODE_ENV=development # Enables test provider
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Development Setup
|
### Invoice Customer Data Options
|
||||||
1. Use test provider for local development
|
|
||||||
2. Configure webhook forwarding tools (ngrok, etc.) for local webhook testing
|
1. **With Customer Relationship + Extractor**:
|
||||||
3. Use provider sandbox/test modes during development
|
- Customer relationship required
|
||||||
4. Implement comprehensive logging for debugging
|
- Customer info auto-populated and read-only
|
||||||
|
- Syncs automatically when customer changes
|
||||||
|
|
||||||
|
2. **With Customer Relationship (no extractor)**:
|
||||||
|
- Customer relationship optional
|
||||||
|
- Customer info manually editable
|
||||||
|
- Either relationship OR customer info required
|
||||||
|
|
||||||
|
3. **No Customer Collection**:
|
||||||
|
- Customer info fields always required and editable
|
||||||
|
- No relationship field available
|
||||||
|
|
||||||
## Plugin Configuration
|
## Plugin Configuration
|
||||||
|
|
||||||
### Basic Configuration
|
### Basic Configuration
|
||||||
```typescript
|
```typescript
|
||||||
|
import { billingPlugin, defaultCustomerInfoExtractor } from '@xtr-dev/payload-billing'
|
||||||
|
|
||||||
billingPlugin({
|
billingPlugin({
|
||||||
providers: {
|
|
||||||
// Provider configurations
|
|
||||||
},
|
|
||||||
collections: {
|
collections: {
|
||||||
// Collection name overrides
|
customers: 'customers', // Customer collection slug
|
||||||
|
invoices: 'invoices', // Invoice collection slug
|
||||||
|
payments: 'payments', // Payment collection slug
|
||||||
|
refunds: 'refunds', // Refund collection slug
|
||||||
|
customerRelation: false, // Disable customer relationship
|
||||||
|
// OR
|
||||||
|
customerRelation: 'clients', // Use custom collection slug
|
||||||
},
|
},
|
||||||
webhooks: {
|
customerInfoExtractor: defaultCustomerInfoExtractor, // For built-in customer collection
|
||||||
// Webhook configuration
|
|
||||||
},
|
|
||||||
admin: {
|
|
||||||
// Admin UI configuration
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
### Advanced Configuration
|
### Custom Customer Info Extractor
|
||||||
- Custom collection schemas
|
```typescript
|
||||||
- Provider-specific options
|
billingPlugin({
|
||||||
- Webhook endpoint customization
|
customerInfoExtractor: (customer) => ({
|
||||||
- Admin UI customization
|
name: customer.fullName,
|
||||||
|
email: customer.contactEmail,
|
||||||
|
phone: customer.phoneNumber,
|
||||||
|
company: customer.companyName,
|
||||||
|
taxId: customer.vatNumber,
|
||||||
|
billingAddress: {
|
||||||
|
line1: customer.billing.street,
|
||||||
|
line2: customer.billing.apartment,
|
||||||
|
city: customer.billing.city,
|
||||||
|
state: customer.billing.state,
|
||||||
|
postalCode: customer.billing.zip,
|
||||||
|
country: customer.billing.countryCode,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
## Error Handling Strategy
|
## Development Guidelines
|
||||||
|
|
||||||
### Provider Errors
|
### TypeScript Guidelines
|
||||||
- Map provider-specific errors to common error types
|
- Use strict TypeScript configuration
|
||||||
- Preserve original error information for debugging
|
- All customer info extractors must implement `CustomerInfoExtractor` interface
|
||||||
- Implement proper retry logic for transient failures
|
- Ensure consistent camelCase naming for all address fields
|
||||||
|
|
||||||
### Webhook Errors
|
### PayloadCMS Integration
|
||||||
- Handle duplicate webhooks gracefully
|
- Follow PayloadCMS plugin patterns and conventions
|
||||||
- Implement proper error responses for webhook failures
|
- Use proper collection configurations with access control
|
||||||
- Log webhook processing errors with context
|
- Utilize PayloadCMS hooks for data syncing and validation
|
||||||
|
|
||||||
|
### Field Validation Rules
|
||||||
|
- When using `customerInfoExtractor`: customer relationship is required, customer info auto-populated
|
||||||
|
- When not using extractor: either customer relationship OR customer info must be provided
|
||||||
|
- When no customer collection: customer info is always required
|
||||||
|
|
||||||
|
## Collections API
|
||||||
|
|
||||||
|
### Invoice Collection Features
|
||||||
|
- Automatic invoice number generation (INV-{timestamp})
|
||||||
|
- Currency validation (3-letter ISO codes)
|
||||||
|
- Automatic due date setting (30 days from creation)
|
||||||
|
- Line item total calculations
|
||||||
|
- Customer info syncing via hooks
|
||||||
|
|
||||||
|
### Customer Data Syncing
|
||||||
|
The `beforeChange` hook automatically:
|
||||||
|
1. Detects when customer relationship changes
|
||||||
|
2. Fetches customer data from the related collection
|
||||||
|
3. Extracts customer info using the provided callback
|
||||||
|
4. Updates invoice with extracted data
|
||||||
|
5. Maintains data consistency across updates
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
### Validation Errors
|
||||||
|
- Customer relationship required when using extractor
|
||||||
|
- Customer info required when not using relationship
|
||||||
|
- Proper error messages for missing required fields
|
||||||
|
|
||||||
|
### Data Extraction Errors
|
||||||
|
- Failed customer fetches are logged and throw user-friendly errors
|
||||||
|
- Invalid customer data is handled gracefully
|
||||||
|
|
||||||
## Performance Considerations
|
## Performance Considerations
|
||||||
- Implement proper caching where appropriate
|
- Customer data is only fetched when relationship changes
|
||||||
- Use database indexes for payment queries
|
- Read-only fields prevent unnecessary manual edits
|
||||||
- Optimize webhook processing for high throughput
|
- Efficient hook execution with proper change detection
|
||||||
- Consider rate limiting for API endpoints
|
|
||||||
|
|
||||||
## Monitoring and Observability
|
|
||||||
- Log all payment operations with structured data
|
|
||||||
- Track payment success/failure rates
|
|
||||||
- Monitor webhook processing times
|
|
||||||
- Implement health check endpoints
|
|
||||||
|
|
||||||
## Documentation Requirements
|
## Documentation Requirements
|
||||||
- Document all public APIs with examples
|
- Document all public APIs with examples
|
||||||
- Provide integration guides for each payment provider
|
- Provide clear customer info extractor examples
|
||||||
- Include troubleshooting guides for common issues
|
- Include configuration guides for different use cases
|
||||||
- Maintain up-to-date TypeScript documentation
|
- Maintain up-to-date TypeScript documentation
|
||||||
Reference in New Issue
Block a user