Paddle facts
The Paddle Billing behaviour an integration has to get exactly right: account prerequisites, API keys and versions, sandbox differences, transactions and webhooks.
As Paddle publishes it
Every statement on this page restates Paddle's public developer documentation; the source of each section is linked in it and listed under Sources.
In short
- Transactions cannot be created without a default payment link.
- API keys are bearer tokens;
Paddle-Version: 1pins a request to API version 1. - A transaction's
paymentsarray is sorted newest first; adjustments come back only withinclude=adjustments. - A webhook delivery succeeds only on HTTP 200 within five seconds.
Account prerequisites
Default payment link
No link, no transactions
Transactions cannot be created without a default payment link — manually collected transactions (invoices) included. (Default payment link)
- Setting the default payment link requires the website to be approved first (Paddle › My account › Settings › Website approval).
- In live accounts the default payment link must include Paddle.js and pass domain verification; in the sandbox it may be
localhostor a test domain. - Sandbox and live are configured separately. (Default payment link)
Taxable categories
- Each product carries a tax category, such as
standard,digital-goodsorsaas. - Categories other than the default have to be approved for the account (Paddle › Catalog › Taxable categories).
- Supplying a category the account is not approved for is refused with the
product_tax_category_not_approvederror. (Tax category not approved, Paddle Billing: what you need to know)
API keys and versions
Key format
An API key is sent as a bearer token: Authorization: Bearer <key>. Keys start with pdl_, contain live_ or sdbx_ for the environment and apikey_, and are 69 characters long. (Authentication)
Permissions and expiry
- A key can be limited to specific permissions; Paddle recommends the minimum an integration needs.
- Expiry is optional but recommended: the default is 90 days and the maximum one year from creation.
- An expired key cannot be reused. (Authentication)
Versions
Paddle-Version: 1pins a request to API version 1, the current version.- Without the header the account's default version applies; integrations are never upgraded automatically.
- Webhook destinations have their own configured version. (Versioning)
Sandbox and live
| Sandbox | Live | |
|---|---|---|
| API base URL | https://sandbox-api.paddle.com | https://api.paddle.com |
| Credentials, data, dashboard | Separate | Separate |
| Cards | Test cards only; real cards are rejected | Real cards only; test cards do not work |
| Checkout domain approval | No review required | Approval required |
| Refunds | Approved automatically about every 10 minutes | Most need Paddle's approval |
| Webhook retries | 3 within 15 minutes | 60 within 3 days |
(Sandbox)
Transactions and adjustments
- A transaction's
paymentsarray is sorted bycreated_atin descending order: the most recent payment attempt comes first. (Get a transaction) - Related entities are returned only when requested with
include; the allowed values areaddress,adjustments,adjustments_totals,available_payment_methods,business,customeranddiscount. (Get a transaction)
Adjustments need include
Adjustments — refunds and credits against a completed transaction — therefore come back only with include=adjustments. (Get a transaction)
Webhooks
Signature
- Each notification carries a
Paddle-Signatureheader of the formts=<unix timestamp>;h1=<signature>. - The signature is an HMAC-SHA256 of
<ts>:<raw body>made with the notification destination's secret key; each destination has its own key. (Signature verification)
Signature check
The receiver recomputes the signature over the unchanged raw body, compares it in constant time, and checks the timestamp against the current time; Paddle's recommended tolerance, which its SDKs enforce, is five seconds. (Signature verification)
Delivery
- A delivery succeeds only when the receiver answers HTTP 200 within five seconds, so a handler answers before doing its own processing.
- Every other outcome is retried with exponential backoff (60-second base, factor 1.1): 3 times within 15 minutes in the sandbox, 60 times within 3 days in live (20 attempts in the first hour, 47 in the first day).
- When all attempts are exhausted the notification's status becomes
failed. (Respond to webhooks)
Replay
- A notification in status
failedordeliveredcan be redelivered with the replay-notification operation. - Notifications are retained for at most 90 days. (Respond to webhooks, Replay a notification)