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 CBC mode (cipher block chaining), with random and unique 'Initialization vector (IV)' 256 bit IV.
Encryption Key
- Get the secret key for your account from account settings.
- Create the MD5 hash (256 bit) of your account's secret key.
- Use the result as the encryption key.
Hash
Generate a keyed hash value using the HMAC method and the MD5 hashing algorithm of the unencrypted URL (Buy Link) and your account's secret key.
Encryption Format
- URL-encode prefill data: BILL_FNAME=John&BILL_LNAME=Doe...
- Encrypt the URL-encoded data using AES-256 in CBC mode, with a unique randomly generated IV (initialization vector) and the MD5 hash (256 bit) of your account's secret key as the symmetric encryption key.
- Encrypt the IV used at step 2 using AES-256 in ECB mode.
GET request
Build your URL using this format:
https://secure.2checkout.com/order/pf.php?MERCHANT=<Your_Merchant_CODE>&IV=<BASE64_IV>&DATA=<BASE64_DATA>&HASH=<HASH>
Most base 64 encode both the IV and the data. Do the same with the URL-encoded before including it in the URL.
Example
<?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";
}
}
Decryption in pf.php for the above example is:
<?php
$cipher = 'AES-256-CBC';
$decryptedIV = openssl_decrypt(base64_decode($_REQUEST['IV']), $cipher, $encryption_key, OPENSSL_RAW_DATA);
$decrypted_string = trim(openssl_decrypt(base64_decode($_REQUEST['DATA']), $cipher, $encryption_key, OPENSSL_RAW_DATA, $decryptedIV));