Common Issues
No license is created after a test purchase#
Symptom: Payment succeeds in Paddle but the Licenses tab stays empty and the buyer sees “Preparing Your License” forever.
Cause: The webhook never reached your site, or its signature failed.
- Open License Cart → Logs. If there are no rows at all, Paddle is not sending to your site: check the destination URL in Paddle → Developer Tools → Notifications matches the Webhook URL in Settings, and that
transaction.completedis selected. - If rows show
failedwith “Webhook signature verification failed.”, the Webhook Secret is wrong. Open the notification in Paddle, copy its Secret key (not thentfset_…ID) and paste it into the matching environment’s secret field. - If rows show
skippedwith “Transaction status ‘billed’ is not completed”, wait: Paddle sends another event when the payment settles. - If rows show
successwith “0 license(s) created”, the purchased price ID is not linked to a pricing package. Create the package from License Cart so it has apaddle_price_id, or check that you bought the rightpri_….
Webhook returns HTTP 403 or 429 in Paddle’s delivery log#
Cause: Signature verification failed (403) and, after 20 failures in 10 minutes, the sender was rate-limited (429).
- Fix the secret as above.
- Wait 10 minutes for the limit to reset, then use Retry in Paddle’s notification log.
The buy button says “Payment system is loading”#
Cause: Paddle.js is not loaded because no Client-side Token is saved for the active environment, or a caching/optimisation plugin stripped the script.
- In Settings confirm the token for the active environment is filled in and saved.
- Exclude
cdn.paddle.com/paddle/v2/paddle.jsfrom script delay or minification in your optimisation plugin.
Creating a product or package fails with “Paddle Error”#
Cause: The API key for the active environment is missing or wrong, or belongs to the other environment.
- Check Active Environment and the matching API Key in Settings.
- Sandbox keys start with
pdl_sdbx_apikey_, live keys withpdl_live_apikey_.
Release ZIPs are downloadable without a license (nginx)#
Symptom: Opening https://your-site.com/wp-content/uploads/lc-releases/<file>.zip in a browser downloads the file.
Cause: nginx ignores the .htaccess License Cart writes into the folder.
- Add this to your server block and reload nginx:
location ^~ /wp-content/uploads/lc-releases/ {
deny all;
return 403;
}
- Confirm the direct URL now returns 403 while Download Latest Version in the portal still works (it uses
/wp-json/license-cart/v1/update/download).
Customers get “Activate this license on the current domain before downloading updates”#
Cause: The customer’s plugin calls update/check from a domain that is not in the key’s activations, usually after a site move or a change from http to https with a non-standard port.
- Ask the customer to deactivate and re-activate the key from their plugin’s License screen.
- If the activation limit is reached, create a replacement key or raise the limit by issuing a new manual license.
Magic login link says it has expired#
Cause: Links are single-use and valid for 30 minutes. Email scanners that pre-fetch links can consume them.
- Ask the customer to request a new link from the portal login form and open it within 30 minutes.
- Alternatively set a password for their WordPress user and let them log in at
/wp-login.php; the portal works with any logged-in session.
Customers land in wp-admin instead of the portal#
Cause: A plugin or theme redirects logins, or a filter disabled the License Cart redirect.
- Check for
license_cart_redirect_customers_from_adminin your theme or must-use plugins. - Point your login redirect plugin at the portal URL (
/my-licenses/).
“Restore failed” or “No Cloudflare backups found”#
- In Settings click Save & Test R2 Connection and read the result. The token needs Object Read & Write on the bucket.
- Confirm R2 Account ID is the 32-character account ID, not the bucket’s public hostname.
