Overview
The Stripe Invoice Sync Flow enables Tirdad 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 Tirdad invoices to Stripe
- Collection Methods: Support for
charge_automaticallyandsend_invoicemethods - 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
tirdad_payment_idandtirdad_invoice_idfor 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_automaticallycollection 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.paidandpayment_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_invoicecollection method - Due Date: Sets the invoice due date from Tirdad 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.paidandpayment_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 Tirdad
- Reconciliation: Uses
tirdad_invoice_idfrom 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
tirdad_invoice_idfrom invoice metadata
Tirdad Payment Methods
1. Checkout Link (Tirdad Hosted)
Flow: Webhook Handler:checkout.session.completed
- Trigger: Customer completes payment via Stripe Checkout
- Action: Updates payment status to
SUCCEEDED - Reconciliation: Uses
tirdad_payment_idfrom PaymentIntent metadata - Note: We get the invoice ID from the PaymentIntent and don’t listen to failure webhooks
2. Charge Card (Tirdad Direct)
Flow: No Webhook Processing:- Reason: Payment is processed synchronously
- Action: Immediate status update in Tirdad
- 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 | tirdad_payment_id from session metadata |
payment_intent.succeeded | Checkout payment succeeded | Update payment status | tirdad_payment_id from PaymentIntent metadata |
payment_intent.payment_failed | Direct charge failed | Update payment status | tirdad_payment_id from PaymentIntent metadata |
invoice_payment.paid | Invoice payment succeeded | Create/update payment record | tirdad_invoice_id from invoice metadata |
Metadata Requirements
Critical: Never deletetirdad_payment_id or tirdad_invoice_id from Stripe metadata. These are essential for payment reconciliation.
Required Metadata Fields:
tirdad_payment_id: Links Stripe payment to Tirdad payment recordtirdad_invoice_id: Links Stripe invoice to Tirdad invoice recordtirdad_customer_id: Links Stripe customer to Tirdad customer record
Payment Reconciliation
Reconciliation Process
- Webhook Received: Stripe sends webhook with payment event
- Metadata Extraction: Extract
tirdad_payment_idortirdad_invoice_id - Record Lookup: Find corresponding Tirdad 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
- Tirdad: Syncs partial payment amounts
- Reconciliation: Tracks cumulative payment amounts
2. Refunds
- Stripe: Process refunds through Stripe dashboard
- Tirdad: Manual reconciliation required
3. Failed Payments
- Retry Logic: Handled by Stripe’s retry mechanism
- Webhook:
payment_intent.payment_failedfor direct charges only - Tirdad: 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.completedpayment_intent.succeededpayment_intent.payment_failedinvoice_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