Overview
Payment links in Flexprice provide a secure, hosted checkout experience powered by Stripe. Customers click a payment URL and are redirected to Stripe’s secure checkout page to complete their payment.Key Features
- Secure Checkout: Hosted by Stripe with PCI compliance
- Multiple Payment Methods: Cards, bank transfers, digital wallets
- Mobile Optimized: Responsive checkout experience
- Real-time Updates: Webhook-driven status updates
- Invoice Integration: Automatic invoice reconciliation
- Card Saving: Optional card storage for future payments
Payment Link Lifecycle
Payment Status Flow
Status Transitions
Status Definitions
Status | Description | Triggers |
---|---|---|
INITIATED | Payment record created, Stripe session not yet created | Initial payment creation |
PENDING | Stripe checkout session created successfully | Successful Stripe API call |
PROCESSING | Payment is being processed | Temporary status during updates |
SUCCEEDED | Payment completed successfully | Stripe webhook: checkout.session.completed |
FAILED | Payment attempt failed | Stripe webhooks: checkout.session.expired , payment_intent.payment_failed |
REFUNDED | Payment was refunded | Manual refund processing |
Creating Payment Links
Prerequisites
- Stripe Connection: Active Stripe connection configured
- Customer Sync: Customer must have Stripe customer ID
- Invoice Status: Invoice must be finalized and unpaid
- Valid Amount: Payment amount must match invoice outstanding
Creating Payment Links via Dashboard
You can create payment links directly from the Flexprice dashboard:

API Request
Endpoint:POST /api/v1/payments
Headers:
Response
Payment Link Configuration
Required Fields
Field | Type | Required | Description |
---|---|---|---|
destination_type | string | ✅ | Must be "invoice" |
destination_id | string | ✅ | Valid invoice ID |
payment_method_type | string | ✅ | Must be "payment_link" |
payment_gateway | string | ✅ | Must be "stripe" |
amount | string | ✅ | Payment amount (must match invoice) |
currency | string | ✅ | Valid currency code |
process_payment | boolean | ✅ | Set to true to create Stripe session |
save_card_and_make_default | boolean | ❌ | Save card for future payments (default: false) |
Stripe Checkout Configuration
Default Checkout Settings
When creating payment links, Flexprice automatically configures Stripe Checkout with:- Payment Methods: Cards, bank transfers, digital wallets
- Currency: Matches the payment currency
- Amount: Exact payment amount
- Customer: Pre-filled with customer data
- Invoice Details: Line items from the invoice
Card Saving Configuration
Whensave_card_and_make_default
is set to true
:
- Setup Future Usage: Stripe session configured with
setup_future_usage: "off_session"
- Card Storage: Payment method automatically saved to customer
- Default Assignment: Saved card becomes the customer’s default payment method
- Future Payments: Enables subsequent card payments without re-entering details
- Card saving requires customer consent and should comply with local regulations
- Saved cards can be used for future
CARD
payment method type payments - Only one default payment method per customer is supported
Webhook Processing
Payment Completion Webhook
When a payment is completed, Stripe sends acheckout.session.completed
webhook:
Webhook Processing Flow
- Receive Webhook: Flexprice receives the webhook from Stripe
- Verify Signature: Validate webhook signature for security
- Find Payment: Locate payment record using session ID
- Check Card Saving: Read
save_card_and_make_default
from payment metadata - Set Default Card: If flag is true, set payment method as default in Stripe
- Update Status: Change payment status to
SUCCEEDED
- Reconcile Invoice: Update invoice payment status and amounts
- Trigger Events: Send payment completion events
Error Handling
Common Payment Errors
Error | Cause | Resolution |
---|---|---|
”Customer not found in Stripe” | Customer not synced | Sync customer to Stripe first |
”Invalid invoice amount” | Amount mismatch | Ensure amount matches invoice |
”Invoice already paid” | Invoice status issue | Check invoice payment status |
”Stripe session creation failed” | API error | Check Stripe connection |
Payment Failure Handling
When payments fail:- Webhook Received: Stripe sends failure webhook
- Status Updated: Payment status changed to
FAILED
- Error Logged: Failure reason recorded
- Customer Notified: Optional failure notification
- Retry Available: Customer can create new payment link
Testing Payment Links
Test Environment Setup
- Use Test Keys: Configure Stripe test mode
- Test Cards: Use Stripe’s test card numbers
- Test Webhooks: Use ngrok for local webhook testing
Test Card Numbers
Card Number | Description |
---|---|
4242424242424242 | Successful payment |
4000000000000002 | Card declined |
4000000000009995 | Insufficient funds |
4000000000009987 | Expired card |
Testing Flow
- Create Test Payment: Use test invoice and customer
- Generate Payment Link: Create payment with test data
- Complete Payment: Use test card in Stripe checkout
- Verify Webhook: Check webhook processing
- Confirm Status: Verify payment and invoice updates
Relationship with Card Payments
Enabling Future Card Payments
Payment links withsave_card_and_make_default: true
enable future card payments:
- First Payment: Customer uses payment link to pay and save card
- Card Storage: Payment method saved and set as default in Stripe
- Future Payments: Customer can use
CARD
payment method type - Seamless Experience: No redirect required for subsequent payments
Payment Method Hierarchy
Integration Strategy
Recommended Flow:- New Customers: Always use payment links for first payment
- Set Save Flag: Include
save_card_and_make_default: true
for returning customers - Future Payments: Use card payment method for faster checkout
- Fallback: Provide payment link option if card payment fails
Security Considerations
Payment Link Security
- HTTPS Required: All payment links use HTTPS
- Session Expiry: Links expire after 24 hours
- One-time Use: Each link can only be used once
- Signature Verification: All webhooks verified
Data Protection
- PCI Compliance: Stripe handles sensitive payment data
- No Card Storage: Card details never stored in Flexprice
- Encrypted Storage: All payment data encrypted at rest
- Access Controls: Role-based access to payment data
Webhook Endpoints
POST /api/v1/webhooks/stripe/{tenant_id}/{environment_id}
- Stripe webhook handler