Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.flexprice.io/llms.txt

Use this file to discover all available pages before exploring further.

Overview

This guide walks you through the complete Paddle integration workflow in Flexprice. Division of responsibilities:
  • Flexprice handles usage metering, billing logic, plan configuration, and invoice generation.
  • Paddle handles payment method collection, secure card storage, and automatic charging.
What you’ll achieve:
  • Subscriptions created in Flexprice automatically sync to Paddle as $0 subscriptions
  • Customers save their payment method via a Paddle-hosted checkout overlay
  • Every invoice Flexprice generates is automatically charged against the saved card via Paddle

Prerequisites

Before following this guide:
  1. Complete the Paddle Connection Setup — you need an active Paddle connection in your Flexprice environment.
  2. Ensure your Paddle webhook destination is configured with both required events: transaction.completed and subscription.activated.

How It Works

The integration runs in two phases: Phase 1 — Subscription & Card Setup Phase 2 — Invoice Auto-Charge

Step 1: Create a Subscription

Create a subscription in Flexprice as you normally would. Flexprice automatically creates a corresponding $0 subscription in Paddle and returns the checkout URL in the response metadata.
curl -X POST https://api.flexprice.io/v1/subscriptions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "cust_01abc",
    "plan_id": "plan_01xyz",
    "currency": "USD",
    "billing_cadence": "RECURRING",
    "billing_period": "MONTHLY",
    "billing_period_count": 1,
    "start_date": "2025-06-01T00:00:00Z"
  }'
Response (abbreviated):
{
  "id": "sub_01def456",
  "status": "active",
  "customer_id": "cust_01abc",
  "plan_id": "plan_01xyz",
  "metadata": {
    "paddle_checkout_url": "https://checkout.paddle.com/checkout/custom/...",
    "paddle_transaction_id": "txn_01abc123def"
  }
}
The same metadata fields are also included in the subscription.created webhook payload.
paddle_checkout_url and paddle_transaction_id are only present when your Flexprice environment has an active Paddle connection. If these fields are missing, verify the connection in Integrations → Paddle.

With a Trial Period

To give the customer a free trial before billing begins, pass trial_period_days:
curl -X POST https://api.flexprice.io/v1/subscriptions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "cust_01abc",
    "plan_id": "plan_01xyz",
    "currency": "USD",
    "billing_cadence": "RECURRING",
    "billing_period": "MONTHLY",
    "billing_period_count": 1,
    "start_date": "2025-06-01T00:00:00Z",
    "trial_period_days": 14
  }'
The paddle_checkout_url is still returned immediately. Prompt the customer to save their card during the trial window — if no card is on file when the trial ends and the first invoice is generated, the auto-charge will fail. For full details on trial behavior, see Trialing.

Step 2: Customer Saves Their Card

Extract paddle_checkout_url from the subscription response and share it with your customer — embed it in your app, send it via email, or redirect to it after signup. When the customer opens the URL, they see a Paddle-hosted overlay to enter and save their payment method. No card data passes through Flexprice or your servers. Once the card is saved:
  • Paddle fires a subscription.activated webhook to your Flexprice webhook endpoint.
  • Flexprice records that the payment method is on file.
  • The customer is ready to be charged automatically on the next invoice.
The customer should save their card before Flexprice raises the first invoice, or the auto-charge will fail.
subscription.activated here is a Paddle webhook event — it fires when the Paddle-side $0 subscription is activated after card capture. This is separate from the Flexprice subscription.activated event, which fires when a Flexprice subscription transitions from trialing to active.

Step 3: Invoice Auto-Charge

No action is required from you for recurring charges. When Flexprice generates an invoice on the billing cycle:
  1. The invoice is synced to Paddle as a transaction against the customer’s account.
  2. Paddle automatically charges the saved card.
  3. Paddle fires a transaction.completed webhook to Flexprice.
  4. Flexprice marks the invoice as paid and reconciles the amounts.
If Paddle applies tax on top of the invoice amount and the charged total exceeds the invoice total, Flexprice marks the invoice as overpaid. To avoid this, align your Paddle tax mode (internal vs. external) with your Flexprice pricing setup.

Customer & Address Sync

Customer sync is on-demand and Flexprice → Paddle only. Customers are synced to Paddle automatically when a subscription or invoice operation requires it. Paddle requires a customer address (at minimum: a country code) to create transactions. If a customer is missing a country, invoice sync will fail with "Paddle address ID not found". Add the country to the customer record in Flexprice before creating a subscription.

Troubleshooting

IssueCauseSolution
No paddle_checkout_url in subscription metadataNo active Paddle connection in environmentVerify connection in Integrations → Paddle
transaction.completed webhook not receivedWebhook destination not configured or wrong eventsGo to Paddle → Developers → Notifications and confirm both transaction.completed and subscription.activated are selected
Invoice not auto-chargedCustomer hasn’t saved card yet (subscription.activated not received)Share the paddle_checkout_url with the customer; wait for card save before expecting auto-charges
Invoice sync fails — “Paddle address ID not found”Customer missing country on their addressAdd country to the customer’s address in Flexprice
Invoice marked overpaidPaddle applied tax on top of the invoice amountAlign tax mode (internal vs. external) in Paddle settings with your Flexprice pricing
Checkout URL expired or invalidPaddle transaction expiredRe-create the subscription or contact Flexprice support to re-sync the Paddle subscription