Get started
Get a step-by-step overview of how to get started with Paddle — including creating your catalog, previewing your pricing page, opening a checkout, and listening to webhooks.
Welcome! Paddle Billing is a complete digital product sales and subscription management platform, designed for modern software businesses. Our API-first platform takes care of payments, tax, localization, and subscription management for you.
This guide walks through how to get started with Paddle Billing — from creating a catalog right up to provisioning and order fulfilment.
Grab the code and test using CodePen
CodePen is a platform for building and sharing frontend code. Explore the code for this tutorial and test right away using our getting started pen.
What are we building?
By the end of this tutorial, we'll have a typical three-tier pricing page connected to Paddle Checkout.

We'll learn how to:
- Sign up for Paddle and set up an account
- Create products and prices
- Work with Paddle.js to present localized prices
- Open a checkout and take a test payment
- Create a notification destination and preview webhooks
Overview
Sign up for a sandbox account.
Create products and prices for the items you offer.
Show products from your catalog on a pricing page.
Launch a checkout from your pricing page, then take a test payment.
Preview the webhooks that occur during checkout for handling provisioning and fulfilment.
1. Sign up for Paddle
To get started with Paddle, sign up for a Paddle account. You can sign up for two kinds of account:
- Sandbox — for testing and evaluation
- Live — for selling to customers
For the best experience when testing your Paddle integration, sign up for a sandbox account. You can sign up for a live account later when you've built your integration and you're ready to start selling.
2. Set up your product catalog
Your product catalog includes subscription plans, recurring addons, one-time charges, and things like additional seats. For flexibility, there's no rigid hierarchy of products — everything you offer is a product.
Create products and related prices to start billing.
Model your pricing
A complete product in Paddle is made up of two parts:
A product entity that describes the item, like its name, description, and an image.
At least one related price entity that describes how much and how often a product is billed.
You can create as many prices for a product as you want to describe all the ways it's billed.
We'll start with a simple three-tier pricing structure, with plans for Starter
, Pro
, and Enterprise
. For each of these plans, we'll offer monthly and annual options:
Starter | Pro | Enterprise | |
---|---|---|---|
Monthly | $10.00 | $30.00 | $300.00 |
Annual | $100.00 | $300.00 | $3000.00 |
We can mirror this in Paddle, modeling this as three products with two prices for monthly and annual:
Product: Starter
- Price: Starter (monthly)
- Price: Starter (yearly)
Product: Pro
- Price: Pro (monthly)
- Price: Pro (yearly)
Product: Enterprise
- Price: Enterprise (monthly)
- Price: Enterprise (yearly)
Create products and prices
You can create products and prices using the Paddle dashboard or the API.
For the moment, we'll create products and prices for Starter
and Pro
only. Instead of letting customers sign up for an Enterprise
plan, we'll ask them to contact us.
Go to Paddle > Catalog > Products.
Click New product.
Enter details for your new product, then click Save when you're done.
Under the Prices section on the page for your product, click New price.
Enter details for your new price. Set the billing period to Monthly to create a monthly price.
Click Save when you're done.
Create another price, setting the billing period to Annually and Save.
Repeat so you have two products for Starter
and Pro
, each with a monthly and annual price.
3. Build your pricing page
Pricing pages show potential customers the subscription plans that you offer and how much they cost. They're one of the most important pages on your website, and typically play a key part in customer conversion.
Paddle includes Paddle.js, a lightweight JavaScript library for securely interacting with Paddle in your frontend. You can use Paddle.js to build pricing pages that show prospects prices that are localized for their country, displayed in their local currency with estimated taxes.
Get a client-side token
Client-side tokens let you interact with the Paddle platform in frontend code, like webpages or mobile apps. They have limited access to the data in your system, so they're safe to publish.
Go Paddle > Developer tools > Authentication
Click Generate client-side token under the Client-side tokens section.
Give your client-side token a name and description, then click Generate.
From the list of client-side tokens, click the … action menu next to the client-side token you just created, then choose Copy token from the menu.
We'll use your client-side key in the next step.
Update constants
Now we've generated a client-side token and created products and prices, let's add them to a pricing page. We'll use the getting started CodePen.
If you have a CodePen account, you can fork the CodePen to create a copy for yourself. You don't need an account to follow these steps, but your changes won't be saved.
Open the CodePen, then change the values in the CONFIG
constant at the top of the JavaScript section:
clientToken | Client-side token you copied in the last step. |
prices.starter.month | Paddle ID for the monthly price of the starter product we created previously. |
prices.starter.year | Paddle ID for the annual price for the starter product we created previously. |
prices.pro.month | Paddle ID for the monthly price for the pro product we created previously. |
prices.pro.year | Paddle ID for the annual price for the pro product we created previously. |
You can get Paddle IDs for your prices using the Paddle dashboard:
Go to Paddle > Catalog > Products, then click the product you want to get a price ID for in the list.
Click the … action menu next to a price in the list, then choose Copy price ID from the menu.
Paste the ID as a value for
month
oryear
inprices.starter
orprices.pro
.
Paddle IDs are designed to be easily recognizable. Price IDs start with
pri_
and product IDs start withpro_
. Check that you've copied Paddle IDs for prices rather than products.
Test your pricing page
If you've added a valid client-side token and passed your price IDs correctly, you should see your prices on your pricing page. These prices are fetched dynamically from Paddle.js, so any changes you make in your Paddle dashboard are reflected on your pricing page on the next call.
Select the monthly or annual toggle to change the prices that you see, then test how localized pricing works using the dropdown at the bottom.
We've included a dropdown to simulate price localization for demo purposes. In real implementations, we recommend passing an IP address to Paddle.js to automatically localize based on country or region.
First, we define variables for elements in our pricing page. We use
document.getElementById()
to assign to them to buttons and price labels in our HTML.We set
currentBillingCycle
tomonth
andcurrentCountry
toUS
. These are the defaults that we'd like to show when customers first visit our page.We call the
InitializePaddle()
function to set up and initialize Paddle. This callsPaddle.Environment.set()
to set our environment to sandbox, andPaddle.Initialize()
to authenticate using our client-side token. We also callupdatePrices()
to get prices from Paddle.js, which is a function we define later.To handle switching plan, we create a function called
updateBillingCycle()
. When someone clicks the billing toggle, we update thecurrentBillingCycle
variable, change the visual state of the buttons, and callupdatePrices()
to get prices from Paddle.js.In
updatePrices()
, we create arequest
object that includes the prices that we defined earlier and thecurrentCountry
for localization. We callPaddle.PricePreview()
with our request, then update the UI elements we defined as variables.To handle country changes, we use an event listener to update our
currentCountry
variable and callupdatePrices()
when the country is changed.
If prices don't appear on your pricing page, open the console to see any specific error messages from Paddle.js to help you troubleshoot.
Common problems
Check that:
- Your client-side token is correct. Client-side tokens for sandbox accounts start with
test_
- The Paddle IDs for price entities that you passed are correct. Price IDs start with
pri_
. - You haven't duplicated any Paddle IDs in your request to
Paddle.PricePreview()
. They must be unique.
4. Open a checkout
Paddle Checkout is where customers make purchases. For companies that offer subscriptions, it's where customers enter their details and payment information, and confirm that they'd like to sign up for a subscription with you.
You can use Paddle.js to quickly add an overlay checkout to your app or website. Overlay checkout lets you present customers with a full-page checkout overlay that's optimized for conversion.
Set a default payment link
Before we can open a checkout, we need to set a default payment link. Your default payment link is typically a page that includes your checkout, like a pricing page or billing screen in your app. Paddle uses your default payment link to generate URLs to send a way for customers to manage a payment or subscription.
For the moment, we'll set our default payment link to your website homepage or development environment URL. We can always change this later.
Go to Paddle > Checkout > Checkout settings.
Enter your website homepage under the Default payment link heading. If you don't have one, enter
https://localhost/
.Click Save when you're done.
You can turn on other payment methods on this screen, too. We'll see eligible payment methods when we open a test checkout in the next step.
Take a test payment
Now we've set our default payment link, we're ready to run through checkout and take a test purchase.
In your CodePen, click Get started for a plan to open an overlay checkout. You can take a test payment using our test card details:
Email address | An email address you own |
Country | Any valid country supported by Paddle |
ZIP code (if required) | Any valid ZIP or postal code |
Card number | 4242 4242 4242 4242 |
Name on card | Any name |
Expiration date | Any valid date in the future. |
Security code | 100 |
Each pricing card has a button with an
onClick
handler that callsopenCheckout()
, passing the plan name as a variable.We initialize Paddle as described in the previous step using our
InitializePaddle()
function.We create a function called
openCheckout()
that first checks that Paddle is initialized, then makes a call toPaddle.Checkout.open()
with an array ofitems
and object of checkoutsettings
.
If the checkout doesn't load, or you get a message saying "Something went wrong," open the console to see any specific error messages from Paddle.js to help you troubleshoot.
Common problems
Check that:
- You added a default payment link to your checkout under Paddle > Checkout > Checkout settings > Default payment link.
- Your client-side token is correct. Client-side tokens for sandbox accounts start with
test_
- The Paddle IDs for price entities that you passed are correct. Price IDs start with
pri_
. - You haven't duplicated any Paddle IDs in your items list. They must be unique.
- You're opening a checkout from a supported country.
5. Listen for webhooks
Webhooks let you know when something important happens in your Paddle account. Paddle includes webhooks for all parts of the purchase and subscription lifecycle, from new customer to cancellation.
You can use webhooks to handle provisioning and fulfilment, and to keep your app in sync with Paddle. For example, you can provision an account for a customer in your app when a subscription is created and limit access to your app if they cancel.
Create a webhook destination
To start receiving webhooks, create a notification destination. This is where you can tell Paddle which events you want to receive and where to deliver them to.
For the moment, we'll use Hookdeck Console rather than spinning up a webhook endpoint server. Hookdeck Console lets you receive webhooks in a friendly interface, with no account or setup required.
Go to Hookdeck Console, then copy the webhook endpoint URL. Keep this tab open.
In a new tab, go to Paddle > Developer Tools > Notifications.
Click New destination.
Give your destination a memorable name.
Make sure notification type is set to webhook and usage type is set to platform. These are the defaults.
Paste the webhook endpoint URL you copied from Hookdeck Console earlier.
Check the select all events box.
Click Save destination when you're done.
Take another test payment
Now we've created a notification destination, we can run through checkout again and check the events that occur.
Open your CodePen, then run through checkout again and take a test payment. As you move through checkout, you should notice webhooks in Hookdeck depending on the actions that you take.
Paddle.js also emits events during the checkout lifecycle. Events emitted by Paddle.js contain information about the items and totals on a checkout that you can use to build advanced workflows in your frontend.
As you move through checkout, Paddle automatically creates and updates entities in your system. Webhooks occur each time an entity is created and updated.
For provisioning and order fulfilment, there are some core webhooks that are useful:
transaction.created | Transactions handle capturing payment and calculating revenue in Paddle. Paddle Checkout creates a transaction, then updates it as the customer enters information and completes payment. |
customer.created | When a customer enters their email address, Paddle creates a customer for you. |
address.created | When a customer enters their country and ZIP/postal code, Paddle creates an address related to this customer. |
business.created | If a customer chooses to enter a tax/VAT number, Paddle creates a business. The option to add a tax number is presented in regions that require it, like most of Europe. |
transaction.paid | When payment goes through successfully, the transaction status changes to paid . At this point, you can be sure that a customer paid and you can start provisioning and order fulfilment. |
subscription.created | If a checkout is for recurring items, Paddle automatically creates a subscription for the customer, address, and business. Its status is active or trialing , depending on the items on the subscription. |
transaction.completed | Once payment is received and a subscription is created, Paddle continues processing a transaction to add subscription details, an invoice number, and information about fees, payouts, and earnings. |
If you don't see any webhooks in Hookdeck Console, you can check the notification destination in Paddle to see if they were sent and whether they're queued for retry.
Common problems
Check that:
- You set up a notification destination correctly. Your webhook endpoint should look like
https://hkdk.events/azz5twg6es4g41
, nothttps://console.hookdeck.com/
. - You set usage type against your notification destination to platform only or both. The simulation only option lets you work with webhook simulator, a way of sending test data.
- You checked all the events against your notification destination.
- Hookdeck accepted your webhooks by checking the logs. Go to Paddle > Notifications, then click the … action menu next to the notification destination in the list and choose View logs from menu.
Next steps
That's it. Now you've covered the basics, we recommend starting your integration or learning more about the Paddle platform.
Start building a Paddle integration
Get a jump start with our Next.js starter kit, letting you quickly create and deploy an app that includes a localized pricing page, integrated inline checkout, and screens for customers to manage their payments. Or, start by building an overlay checkout and pricing page.
Learn more about Paddle Billing
Understand the different checkout experiences that come with Paddle, learn about the payment methods you can turn on, and get an idea of how to handle customer workflows using the customer portal.
Learn about Paddle Retain
Paddle Retain powers dunning and payment recovery in Paddle Billing. Configure Paddle Retain to minimize churn and maximize lifetime revenue (LTV) by plugging into algorithms that use billions of datapoints.
- Get started
- What are we building?
- Overview
- 1. Sign up for Paddle
- 2. Set up your product catalog
- Model your pricing
- Create products and prices
- 3. Build your pricing page
- Get a client-side token
- Update constants
- Test your pricing page
- 4. Open a checkout
- Set a default payment link
- Take a test payment
- 5. Listen for webhooks
- Create a webhook destination
- Take another test payment
- Next steps
- Start building a Paddle integration
- Learn more about Paddle Billing
- Learn about Paddle Retain