Files
2026-10-19 14:11:28 +01:00

2.8 KiB
Executable File

Paddle subscription integration

Sandbox configuration

Keep the Paddle API key and webhook secret server-side only. Do not put either value in the macOS application or commit them to Git.

Required environment variables:

PADDLE_API_KEY=pdl_sdbx_apikey_...
PADDLE_API_URL=https://sandbox-api.paddle.com
PADDLE_WEBHOOK_SECRET=...

PADDLE_PERSONAL_PRODUCT_ID=pro_01m22q4c3vt7yvtv3h3zw1jbn0
PADDLE_PERSONAL_MONTHLY_PRICE_ID=pri_01m22q4cjx177krcpvdph7e2vy
PADDLE_PERSONAL_ANNUAL_PRICE_ID=pri_01m22q4cs9sr5gshxp6j56nvmh
PADDLE_PROFESSIONAL_PRODUCT_ID=pro_01m22q4d0s6y1557wsq9s7xw8n
PADDLE_PROFESSIONAL_MONTHLY_PRICE_ID=pri_01m22q4d6h1yvr1frawtx51gy8
PADDLE_PROFESSIONAL_ANNUAL_PRICE_ID=pri_01m22q4dcndcdbzc20txadaz52

Then run:

php artisan migrate
php artisan db:seed --class=Database\\Seeders\\PaddleCatalogSeeder
php artisan config:clear

The seeder maps the four Paddle price IDs to licensing entitlements. Personal permits one active Mac; Professional permits three.

Paddle notification destination

Configure the sandbox notification destination to POST to:

https://YOUR-HOST/api/v1/webhooks/paddle

Copy the destination endpoint secret into PADDLE_WEBHOOK_SECRET.

Subscribe to at least:

  • subscription.created
  • subscription.updated
  • subscription.activated
  • subscription.trialing
  • subscription.canceled
  • subscription.paused
  • subscription.resumed
  • subscription.past_due
  • transaction.completed
  • transaction.refunded

Entitlement behavior

  • Trialing and active subscriptions are usable.
  • A scheduled end-of-period cancellation stays usable until Paddle changes the subscription to canceled.
  • Upgrades/downgrades update the entitlement on the existing licence key.
  • Canceled or paused subscriptions revoke the licence.
  • Past-due subscriptions retain access through Paddle's current billing period rather than being revoked on the first failed payment.
  • Paddle customer details are fetched server-side when the webhook does not carry customer email/name in custom data.

Important

The API key is required only on the licensing server. Use a sandbox key with the sandbox API URL. Live Paddle products/prices have different IDs and should be configured separately when moving to production.

Hosted sandbox checkout

The licensing site exposes /buy, which initializes Paddle.js with PADDLE_CLIENT_SIDE_TOKEN and opens an overlay checkout for the four configured price IDs. Set PADDLE_ENVIRONMENT=sandbox while testing and use a test_... client-side token. The token is intentionally browser-visible; never use PADDLE_API_KEY in frontend code.

After a subscription webhook provisions a licence, the webhook controller makes a best-effort attempt to deliver pending licence keys by email. Delivery failures do not roll back the verified Paddle event; the encrypted outbox remains available for portal resend.