Fill in the form to arrange a demo

Custom Checkout

Some use-cases require advanced functionality that simply isn’t available via the dashboard. Custom checkouts allow you to access lots of advanced checkout functionality (such as overriding checkout prices, and splitting transaction earnings between multiple recipients).

Custom Checkouts Overview

Custom checkouts allow you to access a plethora of additional checkout functionality that isn’t available via our dashboard by standard.

Custom checkouts can be based on an existing product (in which case they will inherit certain properties of that product - unless you override them) or can be completely custom, and not based on any existing product.

The API will return a link to the checkout that you can pass the user just like any standard checkout link.

API Endpoint

The endpoint for the custom checkout API is: https://vendors.paddle.com/api/2.0/product/generate_pay_link

Send all field as POST to the API endpoint. A list of accepted fields and their meanings is below.

Field Required Description
vendor_id Yes Your Paddle Vendor/Account ID
vendor_auth_code Yes Your Paddle code/token for authenticating with the API
product_id Yes (if custom product is not used; see description) The Paddle Product ID that you want to base this custom checkout on.

If no product_id is set, custom non-subscription product checkouts can be generated instead by specifying title, webhook_url and prices.
title Yes (if no product_id is set) The name of the product/title of the checkout.
webhook_url Yes (only if no product_id is set; see description) A URL that we will call with transaction information upon successful checkout, to allow you to fulfill the purchase.

Note: This property can only be used if product_id is not set.
prices Yes (if no product_id is set) Price(s) of the checkout for a one-time purchase or initial payment of a subscription.

If a product_id is set, you must also provide the price for the product’s default currency. If a given currency is enabled in the dashboard, it will default to a conversion of the product’s default currency price set in this field unless specified here as well.
recurring_prices No Recurring price(s) of the checkout (excluding the initial payment) if the product_id specified is a subscription. To override the initial payment and all recurring payment amounts, both prices and recurring_prices must be set.

If a product_id is set, you must also provide the price for the subscription’s default currency. If a given currency is enabled in the dashboard, it will default to a conversion of the subscription’s default currency price set in this field unless specified here as well.
trial_days No The number of days before Paddle starts charging the customer the recurring price. If you leave this field empty, the trial days of the Plan will be used.
custom_message No A short message displayed below the product name on the checkout.
coupon_code No A coupon to be applied to the checkout.
discountable No Specifies if a coupon can be applied to the checkout, accepts 0 or 1 (default: 1).
image_url No A URL for the product image/icon displayed on the checkout.
return_url No A URL to redirect to once the checkout is completed. If the variable {checkout_hash} is included within the URL (e.g. http://mysite.com/thanks?checkout={checkout_hash}), the API will automatically populate the checkout ID in the redirected URL.
quantity_variable No Specifies if the user is allowed to alter the quantity of the checkout, accepts 0 or 1 (default: 1).
quantity No Pre-fills the Quantity selector on the checkout.
expires No Specifies if the checkout link should expire, the generated checkout URL will be accessible until 23:59:59 of this date (accepts UTC dates in the 2015-08-05, YYYY-MM-DD format)
affiliates No Other Paddle merchants who should receive funds from this checkout. See the section ‘Splitting Funds Between Vendors’ below, for more details.
recurring_affiliate_limit No If the product_id specified is a subscription and affiliates fields are provided, this field will limit the number of times other Paddle vendors will receive funds from the recurring prices. The checkout is included in the limit. See the section ‘Splitting Funds Between Vendors’ below, for more details.
marketing_consent Variable Whether you have gathered consent to market to the customer. This property is required if customer_email is set and you want to opt the customer into marketing.
customer_email No Pre-fills the customer ‘Email’ field on the checkout.
customer_country Yes (if customer_postcode is also set) Pre-fills the customer ‘Country’ field on the checkout. See the Checkout Parameters documentation for accepted country code values.
customer_postcode No Pre-fills the customer ‘ZIP/Postcode’ field on the checkout. See the Checkout Parameters for countries requiring this field.

Note: customer_country is required for postcode to be pre-filled.
passthrough No A string of metadata you wish to store with the checkout. Will be sent alongside all webhooks associated with the order. See the Paddle Checkout (Web) documentation for more information.
vat_number No Pre-fills the ‘VAT Number’ field on the checkout.
vat_company_name Yes (if vat_number is set) Pre-fills the VAT ‘Company Name’ field on the checkout.
vat_street Yes (if vat_number is set) Pre-fills the VAT ‘Street’ field on the checkout.
vat_city Yes (if vat_number is set) Pre-fills the VAT ‘Town/City’ on the checkout.
vat_state No Pre-fills the VAT ‘State’ field on the checkout.
vat_country Yes (if vat_number is set) Pre-fills the VAT ‘Country’ field on the checkout.
vat_postcode Variable (if vat_number is set) Pre-fills the VAT ‘Postcode’ on the checkout.

Note: This field is required if the vat_country requires postcode. See the Checkout Parameters for countries requiring this field.

Full Example Request


<?php
	$data['vendor_id'] = 123;
	$data['vendor_auth_code'] = '456bd...';
	
	$data['title'] = 'Demo Product'; // name of product
	$data['webhook_url'] = 'http://mysite.com/callback'; // URL to call when product is purchased
	
	// You must provide at least one price for the checkout, here we are setting multiple for different currencies.
	$data['prices'] = [
		'USD:10',
		'GBP:12',
		'EUR:9.5'
	];
	
	// Setting some other (optional) data.
	$data['custom_message'] = '100% Money Back Guarantee!';
	$data['return_url'] = 'http://mysite.com/thanks';
	
	// Here we make the request to the Paddle API
	$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));
	$response = curl_exec($ch);
	
	// And handle the response...
	$data = json_decode($response);
	if($data->success) {
		echo "Success! Checkout URL:".$data->response->url;
	} else {
		echo "Your request failed with error: ".$data->error->message;
	}
?>

Bash Example



curl -X POST \
     -d 'vendor_id=123' \
     -d 'vendor_auth_code=456bd...' \
     -d 'title=Demo Product' \
     -d 'webhook_url=http://mysite.com/callback' \
     -d 'prices[0]=USD:16.7' \
     -d 'prices[1]=GBP:12' \
     -d 'prices[2]=EUR:9.5' \
     -d 'custom_message=100% Money Back Guarantee!' \
     -d 'return_url=http://mysite.com/thanks' \
https://vendors.paddle.com/api/2.0/product/generate_pay_link

Example Response

{
    "success": true,
    "response": {
        "url": "https://checkout.paddle.com/checkout/custom/eyJ0IjoiUHJvZ……."
  }
}

Splitting Funds Between Vendors

One of the more useful features of custom checkouts is the ability to split earnings from a transaction between multiple Paddle accounts. This is done by specifying the percentage of the transaction that will be attributed to each account, with the remaining percentage being attributed to the account owner (the vendor making the API request).

This is done by passing the parameter affiliates to the API containing vendor_id’s and commission percentages for each participant. See the example below for a better illustration.


<?php
	$data['vendor_id'] = 123;
	$data['vendor_auth_code'] = '456bd...';
	
	$data['title'] = 'Demo Product'; // name of product
	$data['webhook_url'] = 'http://mysite.com/callback'; // URL to call when product is purchased
	
	// You must provide at least one price for the checkout, here we are setting multiple for different currencies.
	$data['prices'] = [
		'USD:10',
		'GBP:12',
		'EUR:9.5'
	];
	
	// This is where we specify the other participants that we wish to split earnings with
	$data['affiliates'] = [
		'456:0.15', // Vendor 456 gets 15%
		'789:0.15' // Vendor 789 gets 15%
	]; // You (requester) gets 70%
	
	// Here we make the request to the Paddle API
	$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));
	$response = curl_exec($ch);
	
	// And handle the response...
	$data = json_decode($response);
	if($data->success) {
		echo "Success! Checkout URL:".$data->response->url;
	} else {
		echo "Your request failed with error: ".$data->error->message;
	}
?>

Bash Example



curl -X POST \
     -d 'vendor_id=123' \
     -d 'vendor_auth_code=456bd...' \
     -d 'title=Demo Product' \
     -d 'webhook_url=http://mysite.com/callback' \
     -d 'prices[0]=USD:16.7' \
     -d 'prices[1]=GBP:12' \
     -d 'prices[2]=EUR:9.5' \
     -d 'affiliates[0]=456:0.15' \
     -d 'affiliates[1]=789:0.15' \
     https://vendors.paddle.com/api/2.0/product/generate_pay_link

Example Response

{
    "success": true,
    "response": {
        "url": "https://checkout.paddle.com/checkout/custom/eyJ0IjoiUHJvZ……."
  }
}

Limit Splitting Recurring Funds Between Vendors

If the product specified in the product_id field is a subscription, the completed checkout will result in recurring payments charged to the customer. As usual, this will result in earnings for you, the requester. But if you have specified affiliates, then by default every recurring payment will also result in earnings for the other specified Paddle merchants. To limit the number of times this split occurs, you can specify the recurring_affiliate_limit field. The specified limit must be at least 1 and specifies the number of recurring payments (including the checkout payment) for which the other Paddle merchants will receive funds. After the number of payments, you will receive the full earnings of the recurring payments.

See the example below for the usage of this parameter.


<?php
    $data[‘vendor_id’] = 123;
    $data[‘vendor_auth_code’] = ‘456bd...’;
    
    // The fictional Plan has a billing interval of 1 month.
    $data['product_id'] = 123456;
    $data['recurring_affiliate_limit'] = 2;
    $data['affiliates'] = [
        '456:0.15', // Vendor 456 will receive 15% for 2 payments, including the checkout and the first recurring payment.
        '789:0.15' // Vendor 789 will also receive 15% for 2 payments, including the checkout and the first recurring payment.
    ];
    
    // Here we make the request to the Paddle API
    $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));
    $response = curl_exec($ch);
    
    // And handle the response...
    $data = json_decode($response);
    if ($data->success) {
        echo "Success! Checkout URL:" . $data->response->url;
    } else {
        echo "Your request failed with error: " . $data->error->message;
    }

Bash Example



curl -X POST \
     -d 'vendor_id=123' \
     -d 'vendor_auth_code=456bd...' \
     -d 'product_id=123456' \
     -d 'affiliates[0]=456:0.15' \
     -d 'affiliates[1]=789:0.15' \
     -d 'recurring_affiliate_limit=2' \
     -https://vendors.paddle.com/api/2.0/product/generate_pay_link

Example Response

{
    "success": true,
    "response": {
        "url": "https://checkout.paddle.com/checkout/custom/eyJ0IjoiUHJvZ……."
  }
}

Opening Custom Checkouts with Paddle.js (Overlay)

Checkouts created with the Custom Checkout API can be opened as an overlay using Paddle.js in the same way a normal checkout would.

Instead of specifying data-product/product within either the checkout button or Javascript call, you will need to specify data-override/override as shown below.

Button Example

<a href="#!" class="paddle_button" data-override="https://checkout.paddle.com/custom/abc123...">Buy Now!</a>

Javascript Example

Paddle.Checkout.open({
  override: 'https://checkout.paddle.com/custom/abc123...'
});

Opening Custom Checkouts with Paddle.js (Inline)

Checkouts created with the Custom Checkout API can alternatively be displayed as an inline checkout by passing method: 'inline' into Paddle.js as shown below.

HTML Example


<div class="checkout-container"></div>
<script type="text/javascript">
	Paddle.Checkout.open({
		method: 'inline',
		override: 'https://checkout.paddle.com/custom/abc123...',
		frameTarget: 'checkout-container', // The className of your checkout <div>
		frameInitialHeight: 366,
		frameStyle: 'width:360px; background-color: transparent; border: none;'
	});
</script>

Note: You must have completed the Paddle.js Basic Setup for the above examples to work correctly.

Questions about Paddle?

If you need any help regarding your Paddle integration, please get in touch with our Customer Success team using the form below.

Questions about Paddle?