Build a pricing page
Get a step-by-step overview of how to build a pricing page that displays localized prices, including taxes and discount calculation. Pass prices to Paddle.js when a prospect wants to subscribe.
Pricing pages show prospects the subscription plans, addons, or one-time charges that you sell 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.
You can use the Paddle API and Paddle.js to build pricing pages that show prospects prices that are relevant for their country, displayed in their local currency with estimated taxes. If you're running a sale or promo, you can calculate discounts too.
How it works
Paddle Checkout automatically shows the correct prices for a customer using geolocation to estimate where a customer is buying from. Customers see prices in their local currency, with taxes estimated for their country or region.
You can use the Paddle API to get localized prices for pricing pages or other pages on your website. This means you can show the same information on your pricing page that a customer sees when they open checkout to subscribe.
You don't need to do any calculations yourself or manipulate returned data. Paddle returns totals formatted for the country or region you're working with, including the currency symbol.
Address information
Including address information means Paddle can estimate taxes and localized pricing in the response. When working with pricing pages, you might not have captured address information yet. In this case, you can send:
customer_ip_address
Paddle fetches location using the IP address to estimate tax and localized pricing.
address
object, containingcountry_code
and (optionally)postal_code
Paddle uses the supplied country and ZIP code (where included) to estimate tax and localized pricing.
customer_id
,address_id
, andbusiness_id
Paddle uses existing customer entities to estimate tax and localized pricing. Typically used for logged-in customers who may be considering other subscriptions.
Before you begin
You'll need to create a product and a related price for the items that you'd like to include on your pricing page.
To handle signup from a pricing page, you'll need to build a checkout or page that includes Paddle.js that you can pass a list of items
to.
Get a step-by-step overview of how to build a complete checkout — including passing checkout settings. See: Build an overlay checkout or build an inline checkout
Get started
To build a pricing page:
Send a request to the pricing preview endpoint
To preview prices, include a list of items
items, with an object containing price ID and quantity for each in your request.
Unlike when working with transactions or subscriptions, you can send items with different billing periods.
You can also include:
- Customer and address information
- Discount
- Currency code
When you include address information, Paddle returns tax calculations and localized pricing.
To avoid exposing your API key and other sensitive data, do not make requests to the Paddle API directly from your frontend. Build functionality into your backend to handle requests and serve just the information you need to your frontend.
Entities in the API have an
Access-Control-Allow-Origin
header to block access from browsers.
Send a POST request to the /pricing-preview
endpoint.
Request
This example shows sending a pricing preview request using an IP address. You might do this where you don't have an address for a customer, but want to get localized prices and an estimate of taxes.
Geolocation estimates the region and country of your customer based on IP address. Taxes may change when an accurate country code or ZIP or postal code is supplied.
Include a list of items
, with an object containing price ID and quantity for each in your request.
API
List prices by making a GET request to the /prices
endpoint. Work your way through the results to find the price that you'd like to work with.
Dashboard
Head to Paddle > Catalog > Products, click on a product in the list, then click the … menu next to a price and choose Copy ID.
123456789101112131{
2 "items": [
3 {
4 "quantity": 20,
5 "price_id": "pri_01gsz8z1q1n00f12qt82y31smh"
6 },
7 {
8 "quantity": 1,
9 "price_id": "pri_01gsz98e27ak2tyhexptwc58yk"
10 }
11 ],
12 "customer_ip_address": "34.232.58.13"
13}
Response
If successful, Paddle responds with a pricing preview.
Paddle includes an address
object that includes the location information that Paddle could detect from the IP address supplied. Localized pricing and taxes are estimated for this address.
12345678910111213141516171819201{
2 "data": {
3 "customer_id": null,
4 "address_id": null,
5 "business_id": null,
6 "currency_code": "USD",
7 "address": {
8 "postal_code": "20149",
9 "country_code": "US"
10 },
11 "customer_ip_address": "34.232.58.13",
12 "discount_id": null,
13 "details": {
14 "line_items": [
15 {
16 "price": {
17 "id": "pri_01gsz8z1q1n00f12qt82y31smh",
18 "description": "Annual (per seat)",
19 "product_id": "pro_01gsz4t5hdjse780zja8vvr7jg",
20 "billing_cycle": {
Request
This example shows sending a pricing preview request that includes an address
object. You might do this where you have a country drop-down on your website, or where you gather an address in another way.
You must include address.country_code
. Including postal_code
gives you a more accurate estimate of taxes for regions that have city and state taxes.
Include a list of items
, with an object containing price ID and quantity for each in your request.
API
List prices by making a GET request to the /prices
endpoint. Work your way through the results to find the price that you'd like to work with.
Dashboard
Head to Paddle > Catalog > Products, click on a product in the list, then click the … menu next to a price and choose Copy ID.
123456789101112131415161{
2 "items": [
3 {
4 "quantity": 20,
5 "price_id": "pri_01gsz8z1q1n00f12qt82y31smh"
6 },
7 {
8 "quantity": 1,
9 "price_id": "pri_01gsz98e27ak2tyhexptwc58yk"
10 }
11 ],
12 "address": {
13 "postal_code": "10021",
14 "country_code": "US"
15 }
16}
Response
If successful, Paddle responds with a pricing preview.
Where enough address information was supplied, Paddle estimates taxes for prices.
12345678910111213141516171819201{
2 "data": {
3 "customer_id": null,
4 "address_id": null,
5 "business_id": null,
6 "currency_code": "USD",
7 "address": {
8 "postal_code": "10021",
9 "country_code": "US"
10 },
11 "customer_ip_address": null,
12 "discount_id": null,
13 "details": {
14 "line_items": [
15 {
16 "price": {
17 "id": "pri_01gsz8z1q1n00f12qt82y31smh",
18 "description": "Annual (per seat)",
19 "product_id": "pro_01gsz4t5hdjse780zja8vvr7jg",
20 "billing_cycle": {
Request
This example shows sending a pricing preview request that includes a discount. You might do this when you're running a promotion and want to show discounted prices on your pricing page.
Include a discount_id
in your request to preview a discount on your prices.
API
List discounts by making a GET request to the /discounts
endpoint. Work your way through the results to find the discount that you'd like to work with.
Dashboard
Head to Paddle > Catalog > Discounts, click the … menu next to the discount in the list, then choose Copy ID.
Include a list of items
, with an object containing price ID and quantity for each in your request.
API
List prices by making a GET request to the /prices
endpoint. Work your way through the results to find the price that you'd like to work with.
Dashboard
Head to Paddle > Catalog > Products, click on a product in the list, then click the … menu next to a price and choose Copy ID.
12345678910111213141516171{
2 "items": [
3 {
4 "quantity": 20,
5 "price_id": "pri_01gsz8z1q1n00f12qt82y31smh"
6 },
7 {
8 "quantity": 1,
9 "price_id": "pri_01gsz98e27ak2tyhexptwc58yk"
10 }
11 ],
12 "currency_code": "GBP",
13 "discount_id": "dsc_01gtgztp8fpchantd5g1wrksa3",
14 "address": {
15 "country_code": "GB"
16 }
17}
Response
If successful, Paddle responds with a pricing preview.
Paddle applies the discount you included, returns discounted totals for prices, and includes a discounts
array for each line item with information about discounts applied.
626364656667686970717273747576777879808162 },
63 "product": {
64 "id": "pro_01gsz4t5hdjse780zja8vvr7jg",
65 "name": "ChatApp Pro",
66 "description": "Everything in basic, plus access to a suite of powerful tools and features designed to take your team's productivity to the next level.",
67 "tax_category": "standard",
68 "image_url": "https://paddle-sandbox.s3.amazonaws.com/user/10889/2nmP8MQSret0aWeDemRw_icon1.png",
69 "status": "active"
70 },
71 "discounts": [
72 {
73 "discount": {
74 "id": "dsc_01gtgztp8fpchantd5g1wrksa3",
75 "status": "active",
76 "description": "Black Friday 2024",
77 "enabled_for_checkout": false,
78 "code": "BF2024",
79 "type": "percentage",
80 "amount": "10",
81 "currency_code": null,
Update your page based on the response
Update information on your pricing page based on the response from the pricing preview endpoint.
Common fields from the response that you may need:
details.address.country_code | Country code for the pricing preview. If you sent an IP address, Paddle returns the detected country. |
details.currency_code | Currency code for this pricing preview. You may also include currency_code in your request to set manually. |
details.line_items[].formatted_totals | Totals for a particular line item, formatted as a string for the currency you're working with. |
details.line_items[].formatted_unit_totals | Totals for one unit of a particular line item, formatted as a string for the currency you're working with. |
details.line_items[].discounts[].formatted_total | Totals amount discounted for a discount applied to a line item, formatted as a string for the currency you're working with. |
Your pricing page may let prospects manually choose their country or currency, or adjust quantities using a seat slider or similar functionality. In this case, make an updated request to the pricing preview endpoint with the new country, currency, or items and update your page based on the response.
Open a checkout for signup
Pricing pages typically include a "Subscribe" or "Buy now" button that lets prospects sign up for a plan or a make a purchase.
To open a checkout to handle sign up from a pricing page, extract items and address data from your pricing preview request, then pass them to Paddle.js to open a checkout.
Common fields in a pricing preview request and how they map to properties for Paddle.Checkout.open()
or as HTML data attributes:
Pricing preview | JavaScript property | HTML data attribute |
---|---|---|
items | items | data-items |
address | customer.address | data-customer-address-* |
discount_id | discountId | data-discount-id |
12345678910111213141516171{
2 "items": [
3 {
4 "price_id": "pri_01gsz8z1q1n00f12qt82y31smh",
5 "quantity": 20
6 },
7 {
8 "price_id": "pri_01gsz98e27ak2tyhexptwc58yk",
9 "quantity": 1
10 }
11 ],
12 "discount_id": "dsc_01gtgztp8fpchantd5g1wrksa3",
13 "address": {
14 "postal_code": "10021",
15 "country_code": "US"
16 }
17}
123456789101112131415161718191Paddle.Checkout.open({
2 items: [
3 {
4 priceId: 'pri_01gsz8z1q1n00f12qt82y31smh',
5 quantity: 20
6 },
7 {
8 priceId: 'pri_01gsz98e27ak2tyhexptwc58yk',
9 quantity: 1
10 }
11 ],
12 discountId: 'dsc_01gtgztp8fpchantd5g1wrksa3'
13 customer: {
14 address: {
15 countryCode: 'US',
16 postalCode: '10021'
17 }
18 }
19});
See: Pass or update checkout items