Overview
The Stripe Invoice Sync Flow enables FlexPrice to synchronize invoices with Stripe, allowing for seamless payment processing and reconciliation across both platforms. This system handles different collection methods, webhook processing, and ensures accurate payment tracking.Key Features
- Invoice Synchronization: Automatic sync of FlexPrice invoices to Stripe
- Collection Methods: Support for
charge_automatically
andsend_invoice
methods - Payment Reconciliation: Real-time payment tracking across platforms
- Webhook Processing: Comprehensive webhook handling for all payment events
- Credit/Offline Restrictions: Disabled when invoice sync is enabled
- Metadata Tracking: Uses
flexprice_payment_id
andflexprice_invoice_id
for reconciliation
Invoice Sync Lifecycle
Collection Methods
Charge Automatically
Whencollection_method
is set to charge_automatically
:
- Invoice Creation: Creates a draft invoice in Stripe with
charge_automatically
collection method - Auto-advance: Stripe automatically creates a PaymentIntent and attempts to charge the customer’s default payment method
- Payment Processing: Stripe handles the payment attempt immediately
- Webhook Events: Listen for
invoice_payment.paid
andpayment_intent.succeeded
- Immediate payment attempt upon invoice finalization
- Uses customer’s default payment method
- Automatic retry on failure (based on Stripe settings)
- Subscription status depends of payment behavior until payment succeeds
Send Invoice
Whencollection_method
is set to send_invoice
:
- Invoice Creation: Creates a invoice in Stripe with
send_invoice
collection method - Due Date: Sets the invoice due date from FlexPrice invoice
- Send Invoice: Automatically sends the invoice to the customer via email
- Customer Action: Customer must manually pay using Stripe’s hosted invoice page
- Webhook Events: Listen for
invoice_payment.paid
andpayment_intent.succeeded
- Customer receives email with payment link
- Manual payment required by customer
- Subscription status depends on payment behavior setting
- More control over payment timing
Payment Flows
Stripe Payment Methods
1. Invoice Link (Stripe Hosted)
Flow: Webhook Handler:payment_intent.succeeded
- Trigger: Customer pays via Stripe invoice link
- Action: Creates payment record in FlexPrice
- Reconciliation: Uses
flexprice_invoice_id
from invoice metadata - Note: We don’t listen to failure webhooks, only success
2. Charge Customer (Stripe Direct)
Flow: Webhook Handler:invoice_payment.paid
- Trigger: Direct charge to customer’s payment method succeeds
- Action: Updates existing payment record
- Reconciliation: Uses
flexprice_invoice_id
from invoice metadata
FlexPrice Payment Methods
1. Checkout Link (FlexPrice Hosted)
Flow: Webhook Handler:checkout.session.completed
- Trigger: Customer completes payment via Stripe Checkout
- Action: Updates payment status to
SUCCEEDED
- Reconciliation: Uses
flexprice_payment_id
from PaymentIntent metadata - Note: We get the invoice ID from the PaymentIntent and don’t listen to failure webhooks
2. Charge Card (FlexPrice Direct)
Flow: No Webhook Processing:- Reason: Payment is processed synchronously
- Action: Immediate status update in FlexPrice
- Reconciliation: Direct API response handling
Webhook Processing
Webhook Event Types
Event Type | Trigger | Action | Reconciliation Method |
---|---|---|---|
checkout.session.completed | Payment link completed | Update payment status | flexprice_payment_id from session metadata |
payment_intent.succeeded | Checkout payment succeeded | Update payment status | flexprice_payment_id from PaymentIntent metadata |
payment_intent.payment_failed | Direct charge failed | Update payment status | flexprice_payment_id from PaymentIntent metadata |
invoice_payment.paid | Invoice payment succeeded | Create/update payment record | flexprice_invoice_id from invoice metadata |
Metadata Requirements
Critical: Never deleteflexprice_payment_id
or flexprice_invoice_id
from Stripe metadata. These are essential for payment reconciliation.
Required Metadata Fields:
flexprice_payment_id
: Links Stripe payment to FlexPrice payment recordflexprice_invoice_id
: Links Stripe invoice to FlexPrice invoice recordflexprice_customer_id
: Links Stripe customer to FlexPrice customer record
Payment Reconciliation
Reconciliation Process
- Webhook Received: Stripe sends webhook with payment event
- Metadata Extraction: Extract
flexprice_payment_id
orflexprice_invoice_id
- Record Lookup: Find corresponding FlexPrice record
- Status Update: Update payment/invoice status
- Amount Verification: Ensure payment amounts match
- Event Triggering: Send internal events for downstream processing
Restrictions and Edge Cases
When Invoice Sync is Enabled
Disabled Payment Methods:- ❌ Credit Payments: Cannot use wallet credits for payment
- ❌ Offline Payments: Cannot mark payments as offline
- ❌ Manual Payment Recording: Must use Stripe payment methods
- Invoice sync requires payment reconciliation with Stripe
- Credit and offline payments bypass Stripe’s payment tracking
- This ensures accurate financial reporting and reconciliation
Edge Cases
1. Partial Payments
- Stripe: Handles partial payments automatically
- FlexPrice: Syncs partial payment amounts
- Reconciliation: Tracks cumulative payment amounts
2. Refunds
- Stripe: Process refunds through Stripe dashboard
- FlexPrice: Manual reconciliation required
3. Failed Payments
- Retry Logic: Handled by Stripe’s retry mechanism
- Webhook:
payment_intent.payment_failed
for direct charges only - FlexPrice: Updates payment status to
FAILED
- Note: Invoice payment failures are not tracked via webhooks
Configuration
Enabling Invoice Sync
- Stripe Connection: Configure Stripe integration
- Enable Sync: Set
"invoice": {"inbound": false, "outbound": true}
- Customer Sync: Ensure customers are synced to Stripe
- Webhook Setup: Configure webhook endpoints
Webhook Endpoints
checkout.session.completed
payment_intent.succeeded
payment_intent.payment_failed
invoice_payment.paid
Error Handling
Common Errors
Error | Cause | Resolution |
---|---|---|
”Invoice not synced to Stripe” | Invoice sync disabled | Enable invoice sync or use manual payment |
”Customer not found in Stripe” | Customer not synced | Sync customer to Stripe first |
”Payment already exists” | Duplicate webhook | Skip processing (idempotent) |
“Metadata missing” | Webhook without required metadata | Log warning and skip |
Error Recovery
- Webhook Failures: Stripe retries failed webhooks
- Sync Failures: Manual retry via admin interface
Testing
Test Scenarios
- Invoice Sync: Create invoice and verify Stripe sync
- Payment Link: Generate link and complete payment
- Direct Charge: Charge customer directly
- Webhook Processing: Simulate webhook events
- Reconciliation: Verify payment amounts match
Test Data
Test Cards:4242424242424242
: Successful payment4000000000000002
: Card declined4000000000009995
: Insufficient funds