Prefill customer data in order forms
Overview
Use 2Checkout's order form prefill feature to pre-populate forms in the ordering interface with customer data already stored in your shopping cart platform.
Scenarios
- You're using the secure.2checkout.com domain - Send the details to be auto-filled via a form using either GET or POST to https://secure.2checkout.com/order/pf.php.
- You're using a custom domain such as store.YourDomain.com - Use the custom domain when sending the details with either GET or POST to https://store.YourDomain.com/order/pf.php.
Workflow
2Checkout captures the sent parameters and redirects the customer to the link set by the "URL" parameter.
Parameters
Required |
|
---|---|
URL |
The GET request created either in the Generate Sales Links area or dynamically. Use URL-encoding (RFC 1738) for the value of the URL parameter when working with custom-built links. |
MERCHANT |
Your 2Checkout Merchant Code (view) |
AUTOMODE |
(optional) Send this parameter with value = 1 to skip to the credit card details page, provided all billing information is sent as described below. If any of the fields below are incomplete, the regular form will be shown in order for the customer to fill in the missing fields. |
Optional: billing information |
|
---|---|
BILL_FNAME |
Client first name |
BILL_LNAME |
Client last name |
BILL_COMPANY |
Company name for billing |
BILL_FISCALCODE |
Company Unique registration code(VAT ID) |
BILL_EMAIL |
E-mail address |
BILL_PHONE |
Phone number |
BILL_FAX |
Fax number |
BILL_ADDRESS |
Customer/Company physical address |
BILL_ADDRESS2 |
Customer/Company address (second line) |
BILL_ZIPCODE |
Customer/Company zip code |
BILL_CITY |
City |
BILL_STATE |
State/County |
BILL_COUNTRYCODE |
Country code (two letter code) |
Optional: delivery information |
|
---|---|
DELIVERY_FNAME |
Client first name |
DELIVERY_LNAME |
Client last name |
DELIVERY_COMPANY |
Company name for delivery |
DELIVERY_PHONE |
Phone number |
DELIVERY_ADDRESS |
Client/company address (for delivery) |
DELIVERY_ADDRESS2 |
Client/company address (second line) |
DELIVERY_ZIPCODE |
Client/company zip code |
DELIVERY_CITY |
City |
DELIVERY_STATE |
State/County |
DELIVERY_COUNTRYCODE |
Country code (NL for Netherlands) |
URL encoded string
Not encoded | Encoded |
---|---|
|
|
Example: Submitting customer email in the buy-link
https://secure.2checkout.com/order/pf.php?MERCHANT=YourCode&BILL_EMAIL=john.doe@example.com&URL=https%3A%2F%2Fsecure.2checkout.com%2Forder%2Fcheckout.php%3FPRODS%3D123456%26QTY%3D1
Encrypt prefilled data
Send the data using either GET or POST.
Cryptographic Standard
Advanced Encryption Standard (AES), used with 256-bit keys, in GCM (Galois/Counter Mode), with a random and unique 'Initialization vector (IV)' 96-bit.
Encryption Key
Derive the encryption key from the secret key of your account from Integrations > Webhooks & API page, using a SHA256 HMAC and a cryptographically strong random nonce.
A cryptographic nonce is a random number that is used in communication protocols to assist maintain the privacy of communications. It is a single-use, generated using a cryptographically-strong, high-entropy, random-number generator.
Hash
Generate a keyed hash value using the HMAC method and the SHA2/ SHA3 hashing algorithm of the unencrypted URL (Buy Link) and your account's secret key.
GET request
Build your URL using this format:
https://secure.2checkout.com/order/pf.php?V=2&MERCHANT=<Your_Merchant_CODE>&DATA=<Nonce>.<Tag>.<IV>.<EncryptedData>&URL=<CHECKOUT_URL>
All encrypted parameters are first Base64-encoded and then URL-encoded.
Encrypted Prefill Example PHP
<?php
function generateRandomString($length = 10) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
echo '============================== BUY LINKS ==============================';
$baseUrl = "https://secure.2checkout.com";
$url = $baseUrl . '/order/checkout.php?CART=1&CARD=1';
$prods = '1234567';
$secretKey = '123&^^%$hjBJ';
$merchantCode = 'YourCode';
$urlString = 'PRODS=' . $prods . '&QTY=1&PRICES' . $prods . '[USD]=5&PLNKID='.strtoupper(generateRandomString());
$buyLink = "$baseUrl/order/checkout.php?PRODS=$prods&QTY=1&CART=1&CARD=2&SHORT_FORM=1";
$dataArray = [
'BILL_FNAME' => 'John',
'BILL_LNAME' => 'Doe',
'BILL_EMAIL' => 'test@test.com',
'BILL_COUNTRYCODE' => 'RO'
];
$data = http_build_query($dataArray) . '&URL=' . urlencode($buyLink);
dp('################################################################################################################');
dp('################################################### V2 #######################################################');
dp('################################################################################################################');
$cypherMethod = 'aes-256-gcm';
$ivLength = openssl_cipher_iv_length($cypherMethod);
$keyLength = 256/8;
$tagLength = 16;
$initialKeyingMaterial = $secretKey;
$keyDerivationNonceOrSalt = openssl_random_pseudo_bytes($keyLength);
$iv = openssl_random_pseudo_bytes($ivLength);
dp("NONCE (" . (strlen($keyDerivationNonceOrSalt)*8) . " bits): " . bin2hex($keyDerivationNonceOrSalt));
dp("IKM, IPN KEY (" . (strlen($initialKeyingMaterial)*8) . " bits, text): " . "'$initialKeyingMaterial'");
dp("IKM, IPN KEY (" . (strlen($initialKeyingMaterial)*8) . " bits, HEX): " . bin2hex($initialKeyingMaterial));
dp(" ");
dp("REQUIRED IV LENGTH: " . ($ivLength * 8) . ' bits');
dp("IV (" . (strlen($iv)*8) . " bits): " . bin2hex($iv));
dp(" ");
$encryptionKey = hash_hmac('sha256', $secretKey, $keyDerivationNonceOrSalt, true);
dp("DERIVED ENCRYPTION KEY (" . (strlen($encryptionKey)*8) . " bits): " . bin2hex($encryptionKey));
$encryptedData = openssl_encrypt($data, $cypherMethod, $encryptionKey, OPENSSL_RAW_DATA, $iv, $tag, $keyDerivationNonceOrSalt, $tagLength);
$decryptedString = openssl_decrypt($encryptedData, $cypherMethod, $encryptionKey, OPENSSL_RAW_DATA, $iv, $tag, $keyDerivationNonceOrSalt);
dp(" ");
dp("INPUT DATA (PLAIN): " . $data);
dp("SPECIFIED AUTHENTICATION TAG LENGTH: " . $tagLength . ' bytes');
dp("RESULTING AUTHENTICATION TAG: " . bin2hex($tag));
dp(" ");
dp("openssl_decrypt('" . bin2hex($encryptedData) . "', '" . bin2hex($cypherMethod) . "', '" . bin2hex($encryptionKey) . "', OPENSSL_RAW_DATA, '" . bin2hex($iv) . "', '" . bin2hex($tag) . "', '" . bin2hex($keyDerivationNonceOrSalt) . "')");
dp(" ");
dp("ENCRYPTED DATA: " . bin2hex($encryptedData));
dp("INPUT DATA (HEX): " . bin2hex($data));
dp("DECRYPTED DATA: " . bin2hex($decryptedString));
$base64Payload = base64_encode($keyDerivationNonceOrSalt)
. '.' . base64_encode($tag)
. '.' . base64_encode($iv)
. '.' . base64_encode($encryptedData);
dp(" ");
dp("DATA PAYLOAD STRUCTURE: " . 'base64_encode(NONCE).base64_encode(TAG).base64_encode(IV).base64_encode(ENCRYPTED DATA)');
dp("DATA PAYLOAD (BASE64): " . $base64Payload);
$checkoutUrl = 'checkout.php?PRODS=' . $prods . '&QTY=1';
$url = "$baseUrl/order/pf.php?V=2&MERCHANT={$merchantCode}&DATA=" . urlencode($base64Payload) . '&URL=' . urlencode($checkoutUrl);
dp($url);
function dp($s) {
if (empty($_SERVER['argv'])) {
echo "<pre>" . htmlentities($s) . "\n\n</pre>\n";
} else {
echo "$s\n\n";
}
}
Encrypted Prefill Example C#
using System;
using System.Security.Cryptography;
using System.Text;
namespace Encrypted_Prefill_Example
{
internal class Example
{
public static void Main(string[] arg)
{
Console.WriteLine("============================== BUY LINKS ==============================");
string baseUrl = "https://secure.2checkout.com";
string prods = "12345678";
string secretKey = "YOUR_SECRET_KEY";
string merchantCode = "YOUR_MERCHANT_CODE";
string url = baseUrl + "/order/checkout.php?CART=1&CARD=1";
string urlString = "PRODS=" + Uri.EscapeDataString(prods) + "&QTY=1&PRICES" + Uri.EscapeDataString(prods) + "[USD]=5&PLNKID=" + GenerateRandomString().ToUpper();
string buyLink = baseUrl + "/order/checkout.php?PRODS=" + Uri.EscapeDataString(prods) + "&QTY=1&CART=1&CARD=2&SHORT_FORM=1";
string data = "BILL_FNAME=John&BILL_LNAME=Doe&BILL_EMAIL=test@test.com&BILL_COUNTRYCODE=RO&URL=" + Uri.EscapeDataString(buyLink);
Console.WriteLine("################################################################################################################");
Console.WriteLine("################################################### V2 #######################################################");
Console.WriteLine("################################################################################################################");
string cypherMethod = "AES256GCM"; // Adjusted for .NET's naming
int ivLength = 12; // GCM standard IV length
int keyLength = 32; // 256 bits
int tagLength = 16;
byte[] initialKeyingMaterial = Encoding.UTF8.GetBytes(secretKey);
byte[] keyDerivationNonceOrSalt = GenerateRandomBytes(keyLength);
byte[] iv = GenerateRandomBytes(ivLength);
PrintDebugInfo("NONCE", keyDerivationNonceOrSalt);
PrintDebugInfo("IKM, IPN KEY", initialKeyingMaterial);
PrintDebugInfo("IV", iv);
byte[] encryptionKey = new HMACSHA256(keyDerivationNonceOrSalt).ComputeHash(initialKeyingMaterial);
PrintDebugInfo("DERIVED ENCRYPTION KEY", encryptionKey);
byte[] encryptedData, decryptedData, tag;
encryptedData = Encrypt(Encoding.UTF8.GetBytes(data), encryptionKey, iv, out tag, keyDerivationNonceOrSalt);
decryptedData = Decrypt(encryptedData, encryptionKey, iv, tag, keyDerivationNonceOrSalt);
PrintDebugInfo("RESULTING AUTHENTICATION TAG", tag);
PrintDebugInfo("INPUT DATA", Encoding.UTF8.GetBytes(data));
PrintDebugInfo("ENCRYPTED DATA", encryptedData);
PrintDebugInfo("DECRYPTED DATA", decryptedData);
string base64Payload = Convert.ToBase64String(keyDerivationNonceOrSalt)
+ '.' + Convert.ToBase64String(tag)
+ '.' + Convert.ToBase64String(iv)
+ '.' + Convert.ToBase64String(encryptedData);
Console.WriteLine();
Console.WriteLine("DATA PAYLOAD STRUCTURE (BASE64-encoded components): NONCE.TAG.IV.ENCRYPTED_DATA");
Console.WriteLine("DATA PAYLOAD (BASE64): " + base64Payload);
string checkoutUrl = "checkout.php?PRODS=" + Uri.EscapeDataString(prods) + "&QTY=1";
url = baseUrl + "/order/pf.php?V=2&MERCHANT=" + Uri.EscapeDataString(merchantCode) + "&DATA=" + Uri.EscapeDataString(base64Payload) + "&URL=" + Uri.EscapeDataString(checkoutUrl);
Console.WriteLine();
Console.WriteLine(url);
}
private static void PrintDebugInfo(string prefix, byte[] data)
{
Console.WriteLine(prefix + " (" + (data.Length * 8) + " bits): " + BitConverter.ToString(data).Replace("-", ""));
Console.WriteLine();
}
private static string GenerateRandomString(int length = 10)
{
const string characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
var randomString = new StringBuilder(length);
Random random = new Random();
for (int i = 0; i < length; i++)
{
randomString.Append(characters[random.Next(characters.Length)]);
}
return randomString.ToString();
}
private static byte[] GenerateRandomBytes(int length)
{
// Create a byte array to hold the random bytes
byte[] randomBytes = new byte[length];
// Generate random bytes using RNGCryptoServiceProvider
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
rng.GetBytes(randomBytes);
}
return randomBytes;
}
private static byte[] Encrypt(byte[] plaintextBytes, byte[] key, byte[] iv, out byte[] tag, byte[] associatedData)
{
byte[] ciphertextBytes = new byte[plaintextBytes.Length];
tag = new byte[16]; // GCM tag length of 128 bits
using (AesGcm aesGcm = new AesGcm(key))
{
aesGcm.Encrypt(iv, plaintextBytes, ciphertextBytes, tag, associatedData);
}
return ciphertextBytes;
}
private static byte[] Decrypt(byte[] ciphertextBytes, byte[] key, byte[] iv, byte[] tag, byte[] associatedData)
{
byte[] plaintextBytes = new byte[ciphertextBytes.Length];
using (AesGcm aesGcm = new AesGcm(key))
{
aesGcm.Decrypt(iv, ciphertextBytes, tag, plaintextBytes, associatedData);
}
return plaintextBytes;
}
}
}