How to build a landing page that converts
There's a formula for your landing pages that will guide you toward the reaction you are aiming for. You're paying for the traffic. Now get the most from it. Brian Massey, the Founder of Conversion Sciences will show you the critical formula for high-converting landing pages. You'll get actionable tips and best practices to create results-driven landing pages. Then, Brian will do a real-time audit, review several of your pages and provide suggestions on how to boost your conversion rates. What you'll learn:
|
![]() |
Save prices
Overview
Use the savePrices method to update product prices for a specific pricing configuration.
Parameters
Parameters | Type/Description |
---|---|
sessionID |
Required (string) |
|
Session identifier, the output of the Login method. Include sessionID into all your requests. 2Checkout throws an exception if the values are incorrect. The sessionID expires in 10 minutes. |
Prices |
BasicPrice Object |
|
Details below. |
Quantities |
Object |
|
Details below. |
PriceOptions |
Required (PriceOptionsAssigned object) |
|
Details below. |
PricingConfigCode |
Required (string) |
|
System-generated unique pricing configuration code. Read-only. |
type |
Require (string) • REGULAR • RENEWAL |
Parameters | Type/Description |
---|---|
BasicPrice |
Object |
Currency |
String |
|
The currency ISO code used for shipping costs - ISO 4217. |
Amount |
Float |
|
Basic price. |
Parameters | Type/Description |
---|---|
Quantities |
Object |
MinQuantity |
String |
|
The minimum quantity of volume discounts. Default is 1. |
MaxQuantity |
String |
|
The maximum quantity of volume discounts. Default is 99999. |
Parameters | Type/Description |
---|---|
PriceOptionsAssigned |
Object |
Code |
String |
|
Price option identifier. |
Options |
Array of strings |
|
The pricing options group option code you configured that the 2Checkout system uses to calculate product prices for pricing configurations without a base price. |
Response
bool(true)
<?php
require ('PATH_TO_AUTH');
/**
* ProductCode = 'PDOWNFILE'
* Default currency: EUR
*
* Dynamic pricing configuration
*
* Send two prices, including the required one for the default currency
* The method will append the prices for the sent entries, without removing the previous values
*
* If the quantities intervals were not defined then they will be set.
* If the quantities overlap with existing defined intervals, an Exception will be thrown.
*/
// make call
$Prices = array();
$Price = new stdClass(); // BasicPrice object
$Price->Amount = 140;
$Price->Currency = 'USD';
$Prices[] = $Price;
$Price = new stdClass(); // BasicPrice object
$Price->Amount = 80;
$Price->Currency = 'EUR';
$Prices[] = $Price;
$Quantities = new stdClass(); // QuantityInterval object
$Quantities->MinQuantity = 1;
$Quantities->MaxQuantity = 10;
$PriceOptions = array();
$PricingConfigurationCode = '5553603382';
$type = 'regular';
$jsonRpcRequest = array (
'jsonrpc' => '2.0',
'id' => $i++,
'method' => 'savePrices',
'params' => array($sessionID, $Prices, $Quantities, $PriceOptions, $PricingConfigurationCode, $type)
);
$response = callRPC((Object)$jsonRpcRequest, $host);
var_dump ($response);
// will output:
// bool(true)
/**
* ProductCode = 'PDOWNFILE'
* Default currency: EUR
*
* Flat pricing configuration
* Has the VOLTAGE pricing option group assigned and marked as required.
* If prices are sent WITHOUT setting the pricing option group and options will set the price but without setting values for the options prices.
*/
// Call the login method for authentication
$string = strlen($merchantCode) . $merchantCode . strlen(gmdate('Y-m-d H:i:s')) . gmdate('Y-m-d H:i:s');
$hash = hash_hmac('md5', $string, $key);
$i = 1; // counter for api calls
$jsonRpcRequest = new stdClass();
$jsonRpcRequest->jsonrpc = '2.0';
$jsonRpcRequest->method = 'login';
$jsonRpcRequest->params = array($merchantCode, gmdate('Y-m-d H:i:s'), $hash);
$jsonRpcRequest->id = $i++;
$sessionID = callRPC($jsonRpcRequest, $host);
// make call
$Prices = array();
$Price = new stdClass(); // BasicPrice object
$Price->Amount = 80;
$Price->Currency = 'EUR';
$Prices[] = $Price;
// if PricingOption group is not required, will set price for combination of QuantityInterval - no-pricing-option-value.
$PriceOptions = array();
// if PricingOption group is required, then send options by assigning a PriceOptionsAssigned object (group code and options)
// $optionAssigned = new stdClass(); // PriceOptionsAssigned
// $optionAssigned->Code = 'VOLTAGE';
// $optionAssigned->Options = array('220V'); // radio option group
// $PriceOptions = array($optionAssigned);
$Quantities = new stdClass(); // QuantityInterval object
$Quantities->MinQuantity = 1;
$Quantities->MaxQuantity = 99999; // default maximum value
$PricingConfigurationCode = '54AA62CA31'; // flat pricing configuration
$type = 'regular';
$jsonRpcRequest = array (
'jsonrpc' => '2.0',
'id' => $i++,
'method' => 'savePrices',
'params' => array($sessionID, $Prices, $Quantities, $PriceOptions, $PricingConfigurationCode, $type)
);
$response = callRPC((Object)$jsonRpcRequest, $host);
var_dump ($response);
/**
* ProductCode = 'PDOWNFILE'
* Default currency: EUR
*
* Flat pricing configuration
* Has the COLOR and scalenotmandatory pricing option group assigned and marked as required.
*/
// Call the login method for authentication
$string = strlen($merchantCode) . $merchantCode . strlen(gmdate('Y-m-d H:i:s')) . gmdate('Y-m-d H:i:s');
$hash = hash_hmac('md5', $string, $key);
$i = 1; // counter for api calls
$jsonRpcRequest = new stdClass();
$jsonRpcRequest->jsonrpc = '2.0';
$jsonRpcRequest->method = 'login';
$jsonRpcRequest->params = array($merchantCode, gmdate('Y-m-d H:i:s'), $hash);
$jsonRpcRequest->id = $i++;
$sessionID = callRPC($jsonRpcRequest, $host);
// make call
$Prices = array();
$Price = new stdClass(); // BasicPrice object
$Price->Amount = 10;
$Price->Currency = 'EUR';
$Prices[] = $Price;
$optionAssigned = new stdClass(); // PriceOptionsAssigned
$optionAssigned->Code = 'COLOR'; // checkbox pricing option group, multiple values are allowed
$optionAssigned->Options = array('cyan', 'magenta');
$PriceOptions = array($optionAssigned);
$optionAssigned = new stdClass(); // PriceOptionsAssigned
$optionAssigned->Code = 'scalenotmandatory'; // interval pricing option group
$optionAssigned->Options = array('scalenotmandatory-1-5');
$PriceOptions = array($optionAssigned);
$Quantities = new stdClass(); // QuantityInterval object
$Quantities->MinQuantity = 1;
$Quantities->MaxQuantity = 99999; // default maximum value
$PriceOptions = array();
$PricingConfigurationCode = '54AA62CA31'; // flat pricing configuration
$type = 'regular';
$jsonRpcRequest = array (
'jsonrpc' => '2.0',
'id' => $i++,
'method' => 'savePrices',
'params' => array($sessionID, $Prices, $Quantities, $PriceOptions, $PricingConfigurationCode, $type)
);
$response = callRPC((Object)$jsonRpcRequest, $host);
var_dump ($response);
?>
Retrieve cross-sell campaigns
Overview
Use the searchCrossSellCampaigns method to extract information about the cross-sell campaigns you configured.
Parameters
Parameters |
Type |
Required |
Description |
---|---|---|---|
CampaignName |
String |
Optional |
The name of the campaign. |
Status |
String |
Optional |
The status of the campaign; can be ACTIVE/INACTIVE. |
Products |
Array of strings |
Optional |
Array of product codes to apply to this campaign. |
RecommendedProducts |
Array of strings |
Optional |
Array of product codes recommended to the shopper. |
StartDate |
String |
Optional |
The date when the cross-sell campaign starts, formatted as YYYY-MM-DD |
EndDate |
String |
Optional |
The date when the cross-sell campaign ends, formatted as YYYY-MM-DD |
Type | String | Optional | Can be MERCH/AFF. |
Pagination |
Object |
Optional |
|
Page |
Int |
Optional |
The page number of the results. |
Limit |
Int |
Optional |
The number of results per page. |
Response
Parameters | Type/Description |
---|---|
Items | An array of CrossSellCampaign Objects |
Pagination | Pagination Object with the following parameters: Page, Limit, Count |
Request
<?php
declare(strict_types=1);
// Start clear CLI
echo chr(27).chr(91).'H'.chr(27).chr(91).'J';
// End clear CLI
$executionStartTime = microtime(true);
class Configuration
{
public const MERCHANT_CODE = 'your_merchant_code';
public const MERCHANT_KEY = 'your_merchant_key'';
public const URL = 'http://api.avangate.local/rpc/6.0';
}
class Client
{
private const LOGIN_METHOD = 'login';
private const GET_CROSS_SELL_CAMPAIGN = 'getCrossSellCampaign';
private int $calls = 1;
private function generateAuth(): array
{
$merchantCode = Configuration::MERCHANT_CODE;
$key = Configuration::MERCHANT_KEY;
$date = gmdate('Y-m-d H:i:s');
$string = strlen($merchantCode) . $merchantCode . strlen($date) . $date;
$hash = hash_hmac('md5', $string, $key);
return compact('merchantCode', 'date', 'hash');
}
public function login()
{
$payload = $this->generateAuth();
$response = $this->callForRpc(Configuration::URL, self::LOGIN_METHOD, array_values($payload));
return $response['result'];
}
private function callForRpc(string $url, string $action, ?array $payload = null)
{
$request = json_encode([
'jsonrpc' => '2.0',
'method' => $action,
'params' => $payload,
'id' => $this->calls++,
]);
$headers = [
'Content-Type: application/json',
'Accept: application/json',
'Cookie: XDEBUG_SESSION=PHPSTORM'
];
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($curl, CURLOPT_SSLVERSION, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_POSTFIELDS, $request);
$response = curl_exec($curl);
if (empty($response)) {
die('Server unavailable');
}
echo "\n\r Method " . $action . " result: \n\r";
echo $response . "\n\r";
return json_decode($response, true);
}
public function getCrossSellCampaign($sessionId, $crossSellCampaignCode)
{
$response = $this->callForRpc(
Configuration::URL,
self::GET_CROSS_SELL_CAMPAIGN,
[$sessionId, $crossSellCampaignCode]
);
return $response['result'];
}
}
$crossSellCampaignCode = '2Xrl83J0k+qOr3W1ceTwZnHHr30=';
$client = new Client();
$sessionId = $client->login();
$result = $client->getCrossSellCampaign($sessionId, $crossSellCampaignCode);
var_dump("GET CROSS SELL CAMPAIGN BY CODE: \n\r", json_encode($result, JSON_PRETTY_PRINT));
$executionEndTime = microtime(true);
// The duration will be displayed in seconds and milliseconds.
$seconds = round($executionEndTime - $executionStartTime, 2);
// Print it out
echo "\n\rThis script took $seconds to execute.\n\r";
Disable a subscription
Overview
Use the cancelSubscription method to disable an active subscription. Avangate disabled the subscription immediately and no longer performs any recurring billing actions.
Parameters
Parameters |
Type/Description |
sessionID |
Required (string) |
|
Session identifier, the output of the Login method. Include sessionID into all your requests. Avangate throws an exception if the values are incorrect. The sessionID expires in 10 minutes. |
SubscriptionReference |
Required (string) |
Unique, system-generated subscription identifier. |
Response
Boolean |
true or false depending on whether the call resulted in success or not. |
Request
<?php
$host = "https://api.avangate.com";
$client = new SoapClient($host . "/soap/4.0/?wsdl", array(
'location' => $host . "/soap/4.0/",
"stream_context" => stream_context_create(array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false
)
))
));
function hmac($key, $data)
{
$b = 64; // byte length for md5
if (strlen($key) > $b) {
$key = pack("H*", md5($key));
}
$key = str_pad($key, $b, chr(0x00));
$ipad = str_pad('', $b, chr(0x36));
$opad = str_pad('', $b, chr(0x5c));
$k_ipad = $key ^ $ipad;
$k_opad = $key ^ $opad;
return md5($k_opad . pack("H*", md5($k_ipad . $data)));
}
$merchantCode = "YOUR_MERCHANT_CODE";// your account's merchant code available in the 'System settings' area of the cPanel: https://secure.avangate.com/cpanel/account_settings.php
$key = "YOUR_SECRET_KEY";// your account's secret key available in the 'System settings' area of the cPanel: https://secure.avangate.com/cpanel/account_settings.php
$now = gmdate('Y-m-d H:i:s'); //date_default_timezone_set('UTC')
$string = strlen($merchantCode) . $merchantCode . strlen($now) . $now;
$hash = hmac($key, $string);
try {
$sessionID = $client->login($merchantCode, $now, $hash);
}
catch (SoapFault $e) {
echo "Authentication: " . $e->getMessage();
exit;
}
$subscriptionReference = 'F27CFE06ED';
try {
$disableSubscription = $client->cancelSubscription($sessionID, $subscriptionReference);
}
catch (SoapFault $e) {
echo "disableSubscription: " . $e->getMessage();
exit;
}
var_dump("disableSubscription", $disableSubscription);
Extract invoices
Overview
Use the getInvoices method to extract shopper invoices from the Avangate system based on unique order references. The method returns the binary code for invoices in the PDF file format, Base64 encoded (Base64 is used to represent binary data in the ASCII string format).
getInvoices works for COMPLETE orders for which an invoice was already issued. For refunded orders, getInvoices provides two shopper invoices, one for the original order and the second for the refund, reflecting the repayment made.
In the case of cross-selling orders which contain products from different merchants, getInvoice enables you to re-send only the invoices for your own offerings.
Parameters
Parameters | Type/Description |
---|---|
sessionID |
Required (string) |
|
Session identifier, the output of the Login method. Include sessionID into all your requests. Avangate throws an exception if the values are incorrect. The sessionID expires in 10 minutes. |
reference |
Required (string) |
Unique, system generated reference for orders. |
Request
<?php
require ('PATH_TO_AUTH');
$reference = 'ORDER_REFERENCE';
$jsonRpcRequest = array (
'method' => 'getInvoices',
'params' => array($sessionID, $Reference),
'id' => $i++,
'jsonrpc' => '2.0');
var_dump (callRPC((Object)$jsonRpcRequest, $host, true));
Response
Parameters | Type/Description | |
---|---|---|
InvoicesData |
Array of objects |
|
|
|
Details below. |
|
Sale |
String |
|
|
Base64 encoded PDF file containing an invoice for a Complete order. |
|
Cancellation |
String |
|
|
Base64 encoded PDF file containing a cancellation invoice. |
|
Refunds |
Array of string |
|
|
Base64 encoded PDF files containing invoices for Refunds. |
Order field
Overview
Use this object to retrieve information about additional order/product fields.
Parameters
AdditionalField |
Object |
Label |
String |
|
Field text. |
Code |
String |
|
Field identifier. Alpha-numeric chars, underscores and dashes. |
Type |
String |
|
Field type:
|
ApplyTo |
Sting |
|
|
Values |
Array of values |
|
Custom values you control. |
ValidationRule |
String |
|
The validation rule restricting the type of information shoppers can enter in the additional field during the purchase process. |
Translations |
Array of objects |
|
Details below. |
Translation |
Object |
Label |
String |
|
Field text translated in the language of the Translations object. |
Values |
Object |
|
Custom values you control translated in the language of the Translations object. |
Language |
String |
|
ISO language code. (ISO 639-1 two-letter code). |
Retrieve an order field
Overview
Use the getAdditionalField method to extract information about a specific additional field you set up for your account.
Parameters
sessionID |
Required (string) |
|
Session identifier, the output of the Login method. Include sessionID into all your requests. Avangate throws an exception if the values are incorrect. The sessionID expires in 10 minutes. |
FieldCode |
Required (string) |
|
Field identifier. Alpha-numeric chars, underscores and dashes. |
Response
AdditionalField |
Object |
Request
<?php
$host = "https://api.avangate.com";
$client = new SoapClient($host . "/soap/4.0/?wsdl", array(
'location' => $host . "/soap/4.0/",
"stream_context" => stream_context_create(array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false
)
))
));
function hmac($key, $data)
{
$b = 64; // byte length for md5
if (strlen($key) > $b) {
$key = pack("H*", md5($key));
}
$key = str_pad($key, $b, chr(0x00));
$ipad = str_pad('', $b, chr(0x36));
$opad = str_pad('', $b, chr(0x5c));
$k_ipad = $key ^ $ipad;
$k_opad = $key ^ $opad;
return md5($k_opad . pack("H*", md5($k_ipad . $data)));
}
$merchantCode = "YOURCODE123"; //your account's merchant code available in the 'System settings' area of the cPanel: https://secure.avangate.com/cpanel/account_settings.php
$key = "SECRET_KEY"; //your account's secret key available in the 'System settings' area of the cPanel: https://secure.avangate.com/cpanel/account_settings.php
$now = gmdate('Y-m-d H:i:s'); //date_default_timezone_set('UTC')
$string = strlen($merchantCode) . $merchantCode . strlen($now) . $now;
$hash = hmac($key, $string);
try {
$sessionID = $client->login($merchantCode, $now, $hash);
}
catch (SoapFault $e) {
echo "Authentication: " . $e->getMessage();
exit;
}
$FieldCode = 'SourceOrder';
try {
$AdditionalField = $client->getAdditionalField($sessionID, $FieldCode);
}
catch (SoapFault $e) {
echo "AdditionalField: " . $e->getMessage();
exit;
}
var_dump("AdditionalField", $AdditionalField);
?>
Add/edit cross-sell texts
Overview
Use the addCrossSellCampaignText method to customize the texts that are shown in the shopping cart when a cross-sell campaign is displayed.
Editing a text can be done via the updateCrossSellCampaignText method with the same payload. If during a call to updateCrossSellCampaignText method, a text is not found in the database, it will be added automatically.
Request parameters
Parameters |
Type |
Required |
Description |
---|---|---|---|
language |
String |
Required |
The ISO 639-1 two-letter code of the language; Can be Arabic, Bulgarian, Chinese, Chinese (traditional), Czech, Danish, Dutch, English, Finnish, French, German, Greek, Hebrew, Hindi, Italian, Korean, Norwegian, Persian, Polish, Portuguese, Portuguese (Brazil), Slovak, Slovenian, Spanish, Swedish, Thai, Romanian, Russian |
title |
String |
Required |
The title of the cross sell campaign as it is displayed in the cart |
description |
String |
Required |
The description of the cross sell campaign as it is displayed in the cart |
Response
Both the addCrossSellCampaignText and updateCrossSellCampaignText methods will return the full list of texts available in the platform.
Request sample
<?php
require ('PATH_TO_AUTH');
$csCampaignText = [];
$textObj = new stdClass();
$textObj->Language = "ro";
$textObj->Title = "Numele campaniei mele";
$textObj->Description = "Descrierea campaniei mele";
$csCampaignText[] = $textObj;
$textObj = new stdClass();
$textObj->Language = "en";
$textObj->Title = "My campaign name";
$textObj->Description = "My campaign description";
$csCampaignText[] = $textObj;
$jsonRpcRequest = new stdClass();
$jsonRpcRequest->jsonrpc = '2.0';
$jsonRpcRequest->method = 'addCrossSellCampaignText';
$jsonRpcRequest->params = array($sessionID, $csCampaignText);
$jsonRpcRequest->id = $i++;
$order = callRPC($jsonRpcRequest, $host, true);
Upselling campaigns for manual subscription renewals
Enable upselling campaign for manual subscription renewals
Configure upselling campaigns to impact manual (in-cart) subscription renewals.
- Go to Marketing tools -> Upselling.
- Create a new upselling campaign or edit an existing item in this area.
- Check the option Display campaign for manual subscription renewals.
Impact
Once enabled, this functionality impacts all manual (in-cart) subscription renewal flows, that shoppers access:
- From renewal notification emails.
- From their myAccount.
- From custom emails where you include manual subscription renewal links generated using the 2Checkout API or that you create manually.
How do upselling campaigns for manual subscription renewals work?
You can set up up-sell campaigns to recommend a premium version of the same product or of a different products configured for your account when shoppers add to cart a primary product set up to trigger the special offer. You can:
- Offer a discount (fixed or percent).
- Change the product associated with the subscription.
- Modify the quantity.
- Amend the price options.
Example
In the example below, subscribers renew their subscription (initially generated for Product A) through a manual renewal and choose the recommended product (Product B) per the up-sell campaign configuration. As a result, their existing subscriptions change to reflect Product B's configuration and pricing, as well as the quantity and discount you set up for the campaign.
Does the initial subscription change?
Yes. The 2Checkout system does not generate a new subscription for renewals from up-sell campaigns, but the details of the initial subscription change to reflect the up-sell campaign settings, per the setup you made, including but not limited to:
- Price
- Price options
- Subscription billing cycle
- Quantity
- Product
Renewal price
Your shoppers pay the renewal price you configured for the recommended product in upselling campaigns and not the new acquisition price. Furthermore, unless you defined specific pricing options for the upselling campaign, shoppers are able to change the price options in the cart.
Reporting
2Checkout includes sales generated through upselling campaigns for manual subscription renewals in the Upselling report. 2Checkout does not differentiate between new acquisition and manual renewal purchases when it comes to sales resulting from upselling campaigns.
FAQ
- Does this feature impact manual trial conversion links?
- 2Checkout restricts the trial conversion process to the same product, billing cycle and price as the moment when your customer first accessed the evaluation version.
- Do upselling campaigns work with in-cart upgrade?
- 2Checkout does not support this functionality at this point in time.
- Do you prioritize upselling discounts?
- Yes. 2Checkout will apply upselling discounts first of the triggered campaign. Upselling discounts take priority over auto-applied regular promotions.