Some database adapters don't support transactions, causing payment
updates to fail completely. This change adds graceful fallback to
direct updates when transactions are unavailable.
Changes:
- Try to use transactions if supported
- Fall back to direct update if beginTransaction() fails or returns null
- Add debug logging to track which path is used
- Maintain backward compatibility with transaction-supporting databases
This fixes the "Failed to begin transaction" error in production.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Removed the testmode parameter as it was causing issues. Mollie will
automatically determine test/live mode based on the API key used.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changed from mode: 'test' | 'live' to testmode: boolean as per Mollie
API requirements. The testmode parameter is set to true when the API
key starts with 'test_', false otherwise.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Automatically set Mollie payment mode to 'test' or 'live' based on
the API key prefix (test_ or live_). This ensures payments are
created in the correct mode and helps prevent configuration errors.
Changes:
- Add getMollieMode() helper to detect mode from API key
- Include mode parameter in payment creation
- Use type assertion for Mollie client compatibility
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Previously, error objects were passed directly to the logger without
proper serialization, resulting in empty error messages like "Error:"
with no details. This made debugging production issues impossible.
Changes:
- Extract error message and stack trace before logging
- Format errors consistently across all providers
- Add stack trace logging for better debugging
- Update test provider error handling
This fixes the issue where webhook and payment update errors showed
no useful information in production logs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add fallback for Mollie API responses that may not have toPlainObject method
depending on client version or response type.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add redirectUrl field to payments collection for custom redirect destinations
- Update Mollie provider to use payment.redirectUrl with config fallback
- Update Stripe provider to pass redirectUrl as return_url
- Update test provider to redirect to payment-specific URL on success
- Fix production URL detection to check NEXT_PUBLIC_SERVER_URL first
- Update README with redirectUrl documentation and examples
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The test provider was using an in-memory Map to store payment sessions,
which caused "Payment session not found" errors in several scenarios:
1. Next.js hot reload clearing the memory
2. Different execution contexts (API routes vs Payload admin)
3. Server restarts losing all sessions
This fix updates all three test provider endpoints (UI, process, status)
to fetch payment data from the database when not found in memory:
- Tries in-memory session first (fast path)
- Falls back to database query by providerId
- Creates and caches session from database payment
- Handles both string and object collection configurations
This makes the built-in test UI work reliably out of the box, without
requiring users to implement custom session management.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
In v0.1.19, the fix for customUiRoute made it always use the default
route '/test-payment' even when customUiRoute was not specified. This
caused 404 errors because users were unaware of this default behavior.
The plugin actually provides a built-in test payment UI at
/api/payload-billing/test/payment/:id that works out of the box.
This fix ensures the correct behavior:
- When customUiRoute IS specified: Use the custom route
- When customUiRoute is NOT specified: Use the built-in UI route
This allows the testProvider to work out of the box without requiring
users to implement a custom test payment page, while still supporting
custom implementations when needed.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The test provider's customUiRoute parameter was being ignored when
generating checkout URLs. The checkout URL was always using the
hardcoded API endpoint instead of the configured custom UI route.
This fix ensures that when customUiRoute is configured, the generated
checkoutUrl will use the custom route (e.g., /test-payment/:id)
instead of the default API route.
Fixes issue where test provider checkout URLs returned 404 errors
because they pointed to /api/payload-billing/test/payment/:id instead
of the configured custom UI route.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Use Symbol.for() instead of Symbol() for plugin singleton storage to ensure
plugin state persists across different module loading contexts (admin panel,
API routes, server components).
This fixes the "Billing plugin not initialized" error that occurred when
calling payload.create() from Next.js API routes, server components, or
server actions.
Changes:
- Plugin singleton now uses Symbol.for('@xtr-dev/payload-billing')
- Provider singletons (stripe, mollie, test) use global symbols
- Enhanced error message with troubleshooting guidance
Fixes#1🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add checkoutUrl field to Payment type and collection
- Mollie provider now sets checkoutUrl from _links.checkout.href
- Test provider sets checkoutUrl to interactive payment UI
- Stripe provider doesn't use checkoutUrl (uses client_secret instead)
- Update README with checkoutUrl examples and clarifications
- Make it easier to redirect users to payment pages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Revise features list for precision and enhanced readability
- Expand and reorganize table of contents for better navigation
- Add detailed configurations and examples for Stripe, Mollie, and test providers
- Include new sections like customer management, payment flows, and webhook setup
- Refine descriptions of automatic behaviors and status synchronization
- Fix minor grammar inconsistencies and improve overall formatting
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace @/ path aliases with relative imports in invoices collection
- This fixes the 'Cannot find package @/plugin' error in published package
- Path aliases don't resolve correctly in the transpiled dist folder
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove misleading 'Complete payment tracking and history' claim
- Consolidate similar features
- Focus on core capabilities
- Make features list more concise and accurate
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Core Plugin Enhancements:
- Add afterChange hook to payments collection to auto-update linked invoice status to 'paid' when payment succeeds
- Add afterChange hook to invoices collection for bidirectional payment-invoice relationship management
- Add invoice status sync when manually marked as paid
- Update plugin config types to support collection extension options
Demo Application Features:
- Add professional invoice view page with print-friendly layout (/invoice/[id])
- Add custom message field to payment creation form
- Add invoice API endpoint to fetch complete invoice data with customer info
- Add payment API endpoint to retrieve payment with invoice relationship
- Update payment success page with "View Invoice" button
- Implement beforeChange hook to copy custom message from payment metadata to invoice
- Remove customer collection dependency - use direct customerInfo fields instead
Documentation:
- Update README with automatic status synchronization section
- Add collection extension examples to demo README
- Document new features: bidirectional relationships, status sync, invoice view
Technical Improvements:
- Fix total calculation in invoice API (use 'amount' field instead of 'total')
- Add proper TypeScript types with CollectionSlug casting
- Implement Next.js 15 async params pattern in API routes
- Add customer name/email/company fields to payment creation form
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Custom test payment UI with modern Tailwind CSS design
- Payment method selection (iDEAL, Credit Card, PayPal, Apple Pay, Bank Transfer)
- Test scenario selection (6 scenarios: success, delayed, cancelled, declined, expired, pending)
- Real-time payment status polling
- Success and failure result pages with payment details
- Interactive demo homepage at root path
- Sample data seeding (customers, invoices)
- Customers collection with auto-sync to invoices
- Comprehensive documentation (README.md, DEMO_GUIDE.md)
- Proper cursor styles for all interactive elements
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add detailed usage examples section with practical code samples for:
- Creating payments with different providers
- Creating invoices with embedded and relationship-based customer data
- Creating refunds
- Querying payments and invoices
- Updating payment status
- Using the test provider for local development
- REST API examples with cURL commands
Also add table of contents for easier navigation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Move Stripe provider webhook warning to onInit where payload is available
- Fix client-side logging in test provider UI generation
- Replace server-side logger calls with browser-compatible console in generated HTML
- Maintain proper logging context separation between server and client code
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add logger utility adapted from payload-mailing pattern
- Use PAYLOAD_BILLING_LOG_LEVEL environment variable for configuration
- Replace console.* calls with contextual loggers across providers
- Update webhook utilities to support proper logging
- Export logging utilities for external use
- Maintain fallback console logging for compatibility
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Updated InitPayment type to return Promise<Partial<Payment>> | Partial<Payment>
- Modified initProviderPayment hook to handle both async and sync returns using Promise.resolve()
- Enables payment providers to use either async or synchronous initPayment implementations
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Database Error Handling:
- Add comprehensive error handling utility `updatePaymentInDatabase()`
- Ensure consistent session status updates across all error scenarios
- Prevent inconsistent states with proper error propagation and logging
- Add structured error responses with detailed error messages
Type Safety Improvements:
- Remove all unsafe `as any` casts except for necessary PayloadCMS collection constraints
- Add proper TypeScript interfaces and validation functions
- Fix type compatibility issues with TestModeIndicators using nullish coalescing
- Enhance error type checking with proper instanceof checks
Utility Functions:
- Abstract common collection name extraction pattern into `getPaymentsCollectionName()`
- Centralize database operation patterns for consistency
- Add structured error handling with success/error result patterns
- Improve logging with proper error message extraction
Code Quality:
- Replace ad-hoc error handling with consistent, reusable patterns
- Add proper error propagation throughout the payment processing flow
- Ensure all database errors are caught and handled gracefully
- Maintain session consistency even when database operations fail
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add proper request schema validation for ProcessPaymentRequest interface
- Validate paymentId format and ensure it follows test_pay_ pattern
- Validate scenarioId and method parameters with type safety
- Replace unsafe 'as any' casting with proper validation functions
- Add consistent JSON error responses with appropriate HTTP status codes
- Improve error messages for better debugging and API usability
Security improvements:
- Prevent injection attacks through input validation
- Ensure all API endpoints validate their inputs properly
- Add format validation for payment IDs to prevent invalid requests
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add GET /api/payload-billing/test/config endpoint to retrieve test provider configuration including scenarios, payment methods, and test mode indicators.
This allows custom UIs to dynamically sync with plugin configuration instead of hardcoding values.
- Add TestProviderConfigResponse interface
- Export new type in provider index and main index
- Endpoint returns enabled status, scenarios, methods, test mode indicators, default delay, and custom UI route
Resolves#22
Co-authored-by: Bas <bvdaakster@users.noreply.github.com>
- Remove .js extensions from all TypeScript imports throughout codebase
- Update dev config to use testProvider instead of mollieProvider for testing
- Fix module resolution issues preventing development server startup
- Enable proper testing of billing plugin functionality with test provider
This resolves the "Module not found: Can't resolve" errors that were
preventing the development server from starting with Next.js/Turbopack.
All TypeScript imports now use extension-less imports as required.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Critical fixes:
- Fix template literal bug in paymentId that prevented payment processing
- Enhance error handling to update both session and database on failures
- Consolidate duplicate type definitions to single source of truth
Technical details:
- Template literal interpolation now properly provides actual session IDs
- Promise rejections in setTimeout now update payment records in database
- Removed duplicate AdvancedTestProviderConfig, now re-exports TestProviderConfig
- Enhanced error handling with comprehensive database state consistency
Prevents payment processing failures and data inconsistency issues.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add comprehensive test provider with configurable payment outcomes (paid, failed, cancelled, expired, pending)
- Support multiple payment methods (iDEAL, Credit Card, PayPal, Apple Pay, Bank Transfer)
- Interactive test payment UI with responsive design and real-time processing simulation
- Test mode indicators including warning banners, badges, and console warnings
- React components for admin UI integration (TestModeWarningBanner, TestModeBadge, TestPaymentControls)
- API endpoints for test payment processing and status polling
- Configurable scenarios with custom delays and outcomes
- Production safety mechanisms and clear test mode indicators
- Complete documentation and usage examples
Implements GitHub issue #20 for advanced test provider functionality.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add npm version badge showing current package version
- Badge links to npm package page
- Positioned prominently after the title
- Uses badge.fury.io for reliable version display
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Delete `.github/claude-config.json` and `.github/CLAUDE_PR_ASSISTANT.md`
- Clean up repository by removing unused Claude-related files
- Bump package version to `0.1.7` for metadata update