Skip to content

Paddle facts ​

Updated

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: 1 pins a request to API version 1.
  • A transaction's payments array is sorted newest first; adjustments come back only with include=adjustments.
  • A webhook delivery succeeds only on HTTP 200 within five seconds.

Account prerequisites ​

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 localhost or a test domain.
  • Sandbox and live are configured separately. (Default payment link)

Taxable categories ​

  • Each product carries a tax category, such as standard, digital-goods or saas.
  • 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_approved error. (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: 1 pins 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 ​

SandboxLive
API base URLhttps://sandbox-api.paddle.comhttps://api.paddle.com
Credentials, data, dashboardSeparateSeparate
CardsTest cards only; real cards are rejectedReal cards only; test cards do not work
Checkout domain approvalNo review requiredApproval required
RefundsApproved automatically about every 10 minutesMost need Paddle's approval
Webhook retries3 within 15 minutes60 within 3 days

(Sandbox)

Transactions and adjustments ​

  • A transaction's payments array is sorted by created_at in descending order: the most recent payment attempt comes first. (Get a transaction)
  • Related entities are returned only when requested with include; the allowed values are address, adjustments, adjustments_totals, available_payment_methods, business, customer and discount. (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-Signature header of the form ts=<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 ​

Sources ​