Skip to content
You're viewing guides for Paddle Classic, which is no longer available for new signups. Head to developer.paddle.com for Paddle Billing guides.

Offering volume discounts

You can add bulk discounting to your Paddle checkout in a number of ways, depending on your requirements. While we don’t currently support defining discount tiers through the dashboard, the logic can be added directly to the checkout fairly simply using our Pay Link API. This API generates a unique checkout URL which can be displayed as an overlay with Paddle.js using the override parameter.

This approach defines a function in your server-side code that receives a request containing a quantity and returns a checkout URL with the quantity and discounted pricing applied.

First set your vendor ID and auth code and retrieve the required quantity, product ID and customer country from the post parameters:

<?php
$data['vendor_id'] = // Your vendor ID
$data['vendor_auth_code'] = //Your auth code
$quantity = !empty($_POST['quantity']) ? (int) $_POST['quantity'] : 1;
$product_id = !empty($_POST['product']) ? (int) $_POST['product'] : null;
$customer_country = !empty($_POST['country']) ? $_POST['country'] : 'US';
?>

Having read the POST parameters, either set the base unit price of the product or fetch the dashboard price from your settings:

<?php
$cp = curl_init('https://checkout.paddle.com/api/2.0/prices?product_ids='.$product_id.'&customer_country=US');
curl_setopt($cp, CURLOPT_RETURNTRANSFER, true);
$price_response = json_decode(curl_exec($cp), true);
$base_unit_price = floatval($price_response['response']['products'][0]['price']['net']);
$currency_code = $price_response['response']['products'][0]['currency'];
?>

Next, calculate the discount you wish to apply to each tier:

<?php
// Calculate correct discount
if ( $quantity < 5 ) {
$unit_price = $base_unit_price;
} elseif ( $quantity < 20 ) {
$unit_price = number_format($base_unit_price * 0.8, 2);
$discount = "20%";
} elseif ( $quantity < 50 ) {
$unit_price = number_format($base_unit_price * 0.7, 2);
$discount = "30%";
} else {
$unit_price = number_format($base_unit_price * 0.6, 2);
$discount = "40%";
}
$data['product_id'] = $product;
$data['quantity'] = $quantity;
$data['quantity_variable'] = false;
// If the $currency_code supplied is different from product's base currency (e.g. USD), the base currency price must be included as well
if ($currency_code != 'USD') {
// append USD price
$data['prices'] = [$currency_code.':'.$unit_price, "USD:$unit_price_usd"];
} else {
$data['prices'] = [$currency_code.':'.$unit_price];
}
$data['custom_message'] = $discount.' off standard price!';
?>

Then, generate and return the Pay Link URL:

<?php
$url = 'https://vendors.paddle.com/api/2.0/product/generate_pay_link';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
echo curl_exec($ch);
?>

A volume pricing setup can also be implemented client-side by pre-generating checkout override links at your required tiers:

Terminal window
curl -X POST \
-H 'Content-Type: application/json' \
-d '{"vendor_id": 123456, "vendor_auth_code":"1a4g5hjk6bc...", "product_id": 123456, "prices": ["USD:XX.XX", "EUR:YY.YY"], "custom_message": "Volume discount: XX%", "quantity": 10, "quantity_variable": 0}' \
https://vendors.paddle.com/api/2.0/product/generate_pay_link

After collecting quantity, open the checkout for the correct volume tier:

Paddle.Checkout.open({
override: load_checkout(quantity)
});
...
function load_checkout (quantity) {
if (quantity < 5) {
return null;
} else if (quantity < 20) {
return 'https://checkout.paddle.com/checkout/custom/xow84y23984hr...';
} else if (quantity < 50) {
return 'https://checkout.paddle.com/checkout/custom/ASD234523u8sf...';
} else {
return 'https://checkout.paddle.com/checkout/custom/lkj34822o34h3...';
}
}

Offering volume discounts with multiple currencies enabled may require more work. If you have set your product pricing to track the base currency then you can simply override the base currency when creating Pay Link URLs and other prices will also be adjusted accordingly.

If your local prices are all set independently, you will need to override all available currencies in the Pay Link API call.