Overview
A Paddle connection in Flexprice stores encrypted credentials that allow the system to interact with your Paddle account for:- Creating customers and addresses in Paddle
- Syncing invoices to Paddle as transactions
- Processing payments via Flexprice Checkout (Paddle-hosted overlay)
- Receiving webhook notifications from Paddle
- Automatic reconciliation of payments between Paddle and Flexprice
Prerequisites
Before setting up your Paddle connection, ensure you have:- Active Paddle Billing Account - Sign up at paddle.com
- API Key - Available in your Paddle Dashboard (Developers → Authentication)
- Webhook Secret - Configured in Paddle Dashboard (Developers → Notifications)
- Client-Side Token - For Overlay checkout page
- Flexprice Environment - Valid Flexprice environment
- Default Payment Link - Set up the Flexprice checkout URL (see Step 2)
- Domain Approval - flexprice.io domain approved in Paddle (see Step 2)
Step 1: Gather Paddle Credentials
Required Credentials
| Credential | Location in Paddle Dashboard | Required | Purpose |
|---|---|---|---|
| API Key | Developers → Authentication | ✅ | API authentication |
| Webhook Secret | Developers → Notifications → [Your Endpoint] | ✅ | Webhook signature verification |
| Client-Side Token | Developers → Authentication | ✅ | Paddle.js initialization on checkout page |
| Redirect URL | Connection metadata (not Paddle) | Recommended | Success URL after payment |
Finding Your Credentials
-
API Key:
- Go to Paddle Dashboard → Developers → Authentication
- Copy your API key (use
pdl_sdbx_prefix for sandbox, live prefix for production)
-
Webhook Secret:
- Go to Paddle Dashboard → Developers → Notifications
- Create or select your webhook endpoint
- Copy the webhook secret (used for signature verification)
-
Client-Side Token:
- Go to Paddle Dashboard → Developers → Authentication
- Copy the client-side token (e.g.
test_xxxorlive_xxx) for Paddle.js

Step 2: Configure Paddle Checkout & Webhooks
Default Payment Link
Paddle requires a default payment link to create transactions. All payment links will use this domain for the payment form.- Go to Paddle Dashboard → Checkout → Checkout settings
- Set Default payment link to:
https://admin.flexprice.io/checkout - Submit your domain for approval via Request website approval if not already approved

Website Approval
Your domain must be approved before checkout works in production.- Go to Paddle Dashboard → Checkout → Request website approval
- Add and approve the flexprice.io domain (or your production domain)

Setting Up the Webhook
- Go to Paddle Dashboard → Developers → Notifications
- Click Add notification destination
- Enter your webhook URL (see format below)
- Select the required events listed below
- Copy the Webhook Secret for your connection
tenant_01K1TJDVNSN7TWY8CZY870QMNV and env_01K1TJJF0CJR410C6QVPYQTNV0 with your tenant and environment IDs. If you use a different Flexprice region, use the base URL for your region instead of https://api.cloud.flexprice.io.)
Required Webhook Events – Configure these events in your Paddle webhook endpoint:
| Event Type | Purpose |
|---|---|
transaction.completed | Track successful payment completions and reconcile invoices |
customer.created | Sync customers created in Paddle to Flexprice |
address.created | Update customer address mapping for invoice sync |

Step 3: Create Paddle Connection
Using Flexprice Dashboard
You can create a Paddle connection directly from the Flexprice dashboard:Enter credentials
Enter your API Key, Webhook Secret, and Client-Side Token (recommended). Optionally add a Redirect URL in metadata for post-payment redirects.

Customer & Address Sync
Customer sync is on-demand and primarily one-way (Flexprice → Paddle). Customers are synced when creating invoices or payment links.- Address required: Paddle needs a customer address (at least country) to create transactions. Flexprice creates the address in Paddle from customer data when syncing.
- Entity mapping: Links Flexprice customers to Paddle customer IDs via metadata and entity integration mapping.
- Paddle-origin customers:
customer.createdandaddress.createdwebhooks sync Paddle customers into Flexprice and update address mapping.
Invoice Sync & Flexprice Checkout
- Flexprice creates a Paddle transaction from invoice line items (customer + address on transaction).
- Paddle returns a checkout URL (your default link +
?_ptxn=txn_xxx). - Flexprice appends a signed
token(JWT) withclient_side_tokenandsuccess_urlso your checkout page can run Paddle.js. - Customer pays via Paddle overlay; if they click save card, Paddle stores the payment method.
transaction.completedwebhook reconciles the payment. If Paddle adds tax and the amount exceeds the invoice total, Flexprice marks the invoice as overpaid.
Security Best Practices
Credential Management
- Environment Separation: Use sandbox keys (
pdl_sdbx_) for development - Key Rotation: Regularly rotate your Paddle API keys
- Encryption: All credentials are encrypted at rest in Flexprice
Webhook Security
- HTTPS Only: Always use HTTPS for webhook endpoints
- Signature Verification: Flexprice verifies all webhook signatures
- Secret Management: Keep webhook secrets secure and rotate regularly
Troubleshooting
| Issue | Cause | Solution |
|---|---|---|
| Invoice sync fails – “Paddle address ID not found” | Customer missing country or address not synced | Add country to customer address; ensure address has valid country code |
| Connection test fails | Invalid API keys | Verify keys in Paddle Dashboard |
| Webhook not received | Incorrect webhook URL | Check URL format and endpoint |
| Checkout won’t open | Missing client_side_token or token param | Add client_side_token to connection; ensure checkout reads token from URL |
| Invoice marked overpaid | Paddle added tax on top of invoice amount | Align tax mode (internal vs external) in Paddle with your invoice pricing |
Next Steps
After setting up your Paddle connection:- Test Customer Sync: Create a test customer with address and sync an invoice
- Verify Checkout: Complete a test payment via Flexprice Checkout
- Monitor Webhooks: Ensure webhook events are being received
- Go Live: Switch to production keys when ready

