How Tos
Checkout
Subscriptions
Track & Report

Offering Volume Discounts

Volume discounting allows you to offer your buyers a special offer if they buy multiple licenses.

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.

Server-side function

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';
?>

You can retrieve the detected user location on the checkout page using our Localized Prices API and reading the country field from the response.

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);
?>

Client-side function

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

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_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),
  quantity: 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...';
  }
}

If you are using the client-side option, you should obfuscate all functions and variable names to protect your volume pricing code.

Multiple-currency volume pricing

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.