Join the early access program
Upgrades and downgrades in the customer portal are in early access. Read the docs to see how it works, then apply to join the waitlist. We'll reach out if you meet the program requirements.
Let customers manage their own subscription plan from the customer portal. They can move between base plans, add and remove addons, and see proration applied automatically.
This feature is powered by product collections, which describe the set of plans and addons a customer can choose from.
How it works
Product collections
A product collection groups related products into two roles:
- Base products are mutually exclusive plans. A customer can be on one base plan at a time. For example, Starter, Pro, and Advanced.
- Addon products are extras that customers can combine with their base plan. They can add or remove any number of addons at any time. For example, SSO, advanced reporting, or AI credits.
flowchart LR
subgraph base["Base products · customer picks one"]
direction TB
S[Starter]
P[Pro]
A[Advanced]
S <--> P
P <--> A
end
subgraph addons["Addon products · customer picks any number"]
direction TB
SSO[SSO]
R[Advanced reporting]
C[AI credits]
end
base -.-> addons
When you organize your products into product collections, they work the same way as before. For example, you can pass prices to Paddle.js to open a checkout as normal.
Customer portal
Once you've created a product collection, customers can open the customer portal to:
- Move up or down between base plans. For example, upgrade from Starter to Pro, or downgrade from Advanced to Pro.
- Add or remove addons against their current base plan.
- Change quantities of items on their subscription.
When upgrading and downgrading a subscription:
- Upgrades are applied immediately, and they're prorated immediately.
Portal usesproration_billing_mode: "prorated_immediately". This means that you should grant customer access to their new plan right away, and any unused time is credited to the immediate invoice. - Downgrades are applied immediately, and they're prorated on the next billing period.
Portal usesproration_billing_mode: "prorated_next_billing_period". This means that you should grant customer access to their new plan right away, and any credit is applied to the invoice for the next billing period.
Customer portal presents customers with a quantity stepper for each item in a collection. You can set a minimum and maximum quantity for an item to prevent customers from adding more or less than you want.
Overview
Set up upgrades and downgrades in the customer portal in two steps:
- Create product collections
Organize your products into collections to describe their relationship. - Generate customer portal links in your app
Build a workflow to generate authenticated links to the customer portal, so customers can easily upgrade and downgrade.
Before you begin
You'll need:
- A set of products that you've already created, with related prices created against them. Include all of the base plans and addons you want to make available in the portal.
- Access to the API, with a key that has
product.writepermission. During early access, collections can only be created using the API.
A product can only belong to one product collection at a time, so make sure the products you want to group together aren't already part of another collection.
Create a product collection
This step is API only while in early access. For general release, we'll add this to the dashboard too. Thank you for helping us test this ahead of release.
Send a POST request to the /product-collections endpoint with a unique name, the base_products customers can choose from, and any addon_products you want to offer alongside them.
A collection can contain up to 10 base products, and up to 50 addons. A product can only be in one collection at once.
If successful, Paddle returns the new product collection entity, including a procol_ ID. Copy this ID and save it for later.
/product-collections { "name": "Standard SaaS Tiers", "description": "Main pricing page for the web app", "base_products": [ { "product_id": "pro_01gsz4s0w61y0hf3htzy4h3kdt" }, { "product_id": "pro_01gsz4t5hdjse780zja8vvr7jg" }, { "product_id": "pro_01gsz4vjxdm3c8pjjj62knebfz" } ], "addon_products": [ { "product_id": "pro_01gsz91wy9k1yn7kx82aafwvea" }, { "product_id": "pro_01gsz92krfzy3hcf41cpm2n67v" } ]}{ "data": { "id": "procol_01js2gqehzccfkywgx1jk2mtsp", "name": "Standard SaaS Tiers", "description": "Main pricing page for the web app", "status": "active", "base_products": [ { "product_id": "pro_01gsz4s0w61y0hf3htzy4h3kdt" }, { "product_id": "pro_01gsz4t5hdjse780zja8vvr7jg" }, { "product_id": "pro_01gsz4vjxdm3c8pjjj62knebfz" } ], "addon_products": [ { "product_id": "pro_01gsz91wy9k1yn7kx82aafwvea" }, { "product_id": "pro_01gsz92krfzy3hcf41cpm2n67v" } ], "custom_data": null, "created_at": "2025-11-28T14:36:14.695Z", "updated_at": "2025-11-28T14:36:14.695Z" }, "meta": { "request_id": "0936d329-68b4-4c9f-b33c-d872d3ffbaf1" }}Generate customer portal links in your app
Create a customer portal session for a customer to generate an authenticated link to the customer portal so they can easily upgrade and downgrade.
Send a POST request to the /customers/{customer_id}/portal-sessions endpoint to create a customer portal session. You don't need to include a request body.
Paddle returns an authenticated link to the customer portal homepage in urls.general.overview. Return this to the customer in your app when they click a button or link to upgrade or downgrade.
/customers/{customer_id}/portal-sessions { "data": { "id": "cpls_01jcgezdnnd1t0c7wdrdher9vv", "customer_id": "ctm_01jcdaf4zgm2fxw3nc0e4fn137", "urls": { "general": { "overview": "https://customer-portal.paddle.com/cpl_01gsx07ferwf96qnjz1mrc6h0q?action=overview&token=pga_eyJhbGciOiJFZERTQSIsImtpZCI6Imp3a18wMWhkazBuOHF3OG55NTJ5cGNocGNhazA1ayIsInR5cCI6IkpXVCJ9.eyJpZCI6InBnYV8wMWpjZ2V6ZG52MmpkYTk3eHR2dHF3ZjN5bSIsInNlbGxlci1pZCI6IjEwODg5IiwidHlwZSI6InN0YW5kYXJkIiwidmVyc2lvbiI6IjEiLCJ1c2FnZSI6ImN1c3RvbWVyLXBvcnRhbC1zZXNzaW9uIiwic2NvcGUiOiJjdXN0b21lci5jaGVja291dC5jcmVhdGUgY3VzdG9tZXIuY2hlY2tvdXQucmVhZCBjdXN0b21lci5jdXN0b21lci5yZWFkIGN1c3RvbWVyLmN1c3RvbWVyLnVwZGF0ZSBjdXN0b21lci5jdXN0b21lci1hZGRyZXNzLnJlYWQgY3VzdG9tZXIuY3VzdG9tZXItcGF5bWVudC1tZXRob2QucmVhZCBjdXN0b21lci5jdXN0b21lci1wYXltZW50LW1ldGhvZC5kZWxldGUgY3VzdG9tZXIuaW52b2ljZS5yZWFkIGN1c3RvbWVyLnN1YnNjcmlwdGlvbi1jYW5jZWwuY3JlYXRlIGN1c3RvbWVyLnN1YnNjcmlwdGlvbi1wYXltZW50LnJlYWQgY3VzdG9tZXIuc3Vic2NyaXB0aW9uLXBheW1lbnQudXBkYXRlIGN1c3RvbWVyLnN1YnNjcmlwdGlvbi5yZWFkIGN1c3RvbWVyLnN1YnNjcmlwdGlvbi51cGRhdGUgY3VzdG9tZXIudHJhbnNhY3Rpb24ucmVhZCBjdXN0b21lci50cmFuc2FjdGlvbi5vcmlnaW4ucmVhZCIsImlzcyI6Imd1ZXN0YWNjZXNzLXNlcnZpY2UiLCJzdWIiOiJjdG1fMDFqY2RhZjR6Z20yZnh3M25jMGU0Zm4xMzciLCJleHAiOjE3MzE1MTA4MDEsImlhdCI6MTczMTQyNDQwMX0.Wh-U6mgB77_lqrERJPU5dql4yq523CjlYT3kHIUbYll7sSG-QmJV7jRmg9pBCFPxMlCxsBI-8pe1Nt3FucOKBg" }, "subscriptions": [] }, "created_at": "2024-11-12T15:13:21.077605273Z" }, "meta": { "request_id": "bd45eef1-a078-421b-b5d8-281a37c40f07" }}You can test the upgrade and downgrade workflow using sandbox credentials by creating a customer portal session for a customer and then opening the link in your browser.
You should handle provisioning and fulfillment as normal when a customer upgrades or downgrades a subscription, giving your customers the right level of access.