Skip to main content

Prefill customer data in order forms

Prefill customer data in order forms

Last updated: 29-Apr-2024
Rate this article:

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

  1. 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.
  2. 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
https://secure.2checkout.com/order/cart.php?PRODS=123456&QTY=1
https%3A%2F%2Fsecure.2checkout.com%2Forder%2Fcart.php%3FPRODS%3D123456%26QTY%3D1

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;
        }
    }
}

 

Rate this article:

Need help?

Do you have a question? If you didn’t find the answer you are looking for in our documentation, you can contact our Support teams for more information. If you have a technical issue or question, please contact us. We are happy to help.

Not yet a Verifone customer?

We’ll help you choose the right payment solution for your business, wherever you want to sell, in-person or online. Our team of experts will happily discuss your needs.

Verifone logo