Paddle subscriptions
Here’s how to understand and configure Paddle Billing subscriptions in Business Class.
Paddle Billing
To set up Paddle Billing, read the Paddle developer docs and prepare the API and secret keys.
To update your credentials:
$ VISUAL="code --wait" bin/rails credentials:edit --environment=development
$ VISUAL="code --wait" bin/rails credentials:edit --environment=production
You’ll need to provide the following Paddle configuration as part of your credentials file:
paddle_billing:
environment: sandbox
api_key: yyyy
client_token: ppp
signing_secret: zzz
You can find vendor ID and API key in the Authentication section under Developer Tools in the Paddle dashboard. You’ll get the webhook secret when setting up the notifications.
Alternatively to Rails credentials, you can also set credentials using the environment variables:
ENV["PADDLE_BILLING_ENVIRONMENT"] = "sandbox"
ENV["PADDLE_BILLING_API_KEY"] = "ad3d6..."
ENV["PADDLE_BILLING_CLIENT_TOKEN"] = "test_1c..."
ENV["PADDLE_BILLING_SIGNING_SECRET"] = "pdl_ntfset_..."
For development, you need to create a sandbox environment separated from a production account. If you don’t set Paddle environment you can still test the application using the fake subscriptions.
The test environment doesn’t need any credentials set, only development (with a sandbox) and production need that.
Plans
You can create your plans under Catalog -> Products in the Paddle dashboard. One product can have several different prices. Note your product ID.
Then add them in the paddle.rb
initializer:
# Fill this in with your own plans. Only the price ID (`id`) is what we work
# with in terms of subscription management, the rest is for local UI/UX only.
PADDLE_PLANS = [
# {
# id: "pri_01h9a8t6kthzq2x4yaspbf06mh",
# name: "Plan name",
# trial_period: "1",
# price: "$19/mo"
# },
# {
# id: "pri_01h86bv3sg853ktbg29z11amcc",
# name: "Plan name",
# trial_period: "0",
# price: "$10/mo"
# }
]
You can also fetch this data with:
> Paddle::Price.list(product_id: Pay::PaddleBilling.product_id)&.data
Apart from the price ID, fill in whatever you want to show up in the UI. Prices are not fetched automatically to avoid dealing with slow requests or caches.
After you create your plans in Paddle, it will be possible to subscribe to them as part of the create new team/space/organization flow.
-
Plans with trials start with the status
trialing
and the attributetrial_ends_at
set. -
After trial is over, customer is charged and the status moves to
active
. A subscription without a trial is simply active from day 1. -
Active subscriptions can be paused and resumed both from the application or Paddle. Subscription is still considered active even if scheduled for change. At this time the subscription is on a grace period and considered pause or cancelled only after the grace period is over.
-
Paused subscriptions are determined by
pause_starts_at
and cancelled subscriptions byends_at
. -
Subscriptions on a grace period cannot be cancelled straight away, you need to cancel the scheduled change first.
-
Cancelled subscriptions cannot be resumed.
Webhooks
To configure webhooks head over to Developer Tools -> Notifications in the Paddle dashboard.
Set up a new destination with the webhook path /pay/webhooks/paddle
(replace your domain name):
https://example.org/pay/webhooks/paddle
Choose subscription.created and subscription.updated subscriptions. Note the secret key.
If you want to test webhooks locally, you can use a tool like Ngrok which will give you a public address:
$ ngrok http 3000
...
Forwarding https://406b-80-250-28-104.eu.ngrok.io -> http://localhost:3000
Then use this address and add it to the Paddle Sandbox under Developer Tools -> Notifications:
https://406b-80-250-28-104.eu.ngrok.io/pay/webhooks/paddle
Make sure it’s a primary address.
Next, remove the following condition in teams#success
:
# Webhook won't arrive so let's pretend things are well
create_fake_subscription if Rails.env.development?
And allow the host in config/environments/development.rb
by adding it to config.hosts
.
For a production environment you also have to approve your domain names.
Sync
Pay webhooks should ensure that subscriptions are always synced. Nevertheless, you can always run the following Rake task to synchronize subscriptions’s state:
$ bin/rails paddle:sync