Encryption

When charging a card directly through our collection API, you must first encrypt the payload including the card details.

To manually encrypt the payload, you will need your encryption key (found in the Settings > API Keys & Webhooks section of your dashboard side menu). You will encrypt the payload using the 3DES technique.

Here's an illustration of an encryption function in various languages. In each example, the function takes the payload as a hash and converts it to JSON before encrypting and encoding it in base64.

const forge = require('node-forge');
const { DOMParser } = require('xmldom');
const BigInteger = forge.jsbn.BigInteger;

/**
 * Encrypt data using RSA public key.
 *
 * @param {string} data - The data to encrypt.
 * @param {string} rsaPubKey - The RSA public key in base64 XML format.
 * @returns {string} - The encrypted data in base64 encoding.
 */
function encryptForge(data, rsaPubKey) {
  // Decode the base64 encoded public key and remove the prefix
  let rsaKeyValue = Buffer.from(rsaPubKey, 'base64').toString('utf-8');
  rsaKeyValue = rsaKeyValue.replace('4096!', '');

  // Parse the XML to extract Modulus and Exponent
  const parser = new DOMParser();
  const xmlDoc = parser.parseFromString(rsaKeyValue, 'text/xml');
  const modulus = xmlDoc.getElementsByTagName('Modulus')[0].textContent;
  const exponent = xmlDoc.getElementsByTagName('Exponent')[0].textContent;

  // Convert the Modulus and Exponent from base64 to BigInteger
  const modulusBI = parseBigInteger(modulus);
  const exponentBI = parseBigInteger(exponent);

  // Set up the RSA public key
  const pubKey = forge.pki.setRsaPublicKey(modulusBI, exponentBI);

  // Encrypt the data
  const encryptedBytes = pubKey.encrypt(forge.util.encodeUtf8(data));

  // Return the encrypted text in base64 encoding
  return Buffer.from(encryptedBytes, 'binary').toString('base64');
}

/**
 * Convert a base64 encoded string to a BigInteger.
 *
 * @param {string} b64 - The base64 encoded string.
 * @returns {BigInteger} - The BigInteger representation of the string.
 */
function parseBigInteger(b64) {
  const decoded = forge.util.decode64(b64);
  return new BigInteger(forge.util.createBuffer(decoded).toHex(), 16);
}

// Example usage
const data = "Your data to encrypt";
const rsaPubKey = "Your RSA public key in base64 XML format";
const encryptedData = encryptForge(data, rsaPubKey);
console.log(encryptedData);

module.exports = encryptForge;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import javax.crypto.Cipher;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
//import javax.xml.bind.DatatypeConverter;
public class EncryptionHelper {
    private PrivateKey privateKey;
    private PublicKey publicKey;
    public  static String getXmlComponent(String xmlstring, String _field) throws IOException, SAXException, ParserConfigurationException {
        // Create a DocumentBuilder
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
        // Parse the XML string
        Document doc = dBuilder.parse(new java.io.ByteArrayInputStream(xmlstring.getBytes("UTF-8")));
        // Normalize the document
        doc.getDocumentElement().normalize();
        NodeList modulusNodeList = doc.getElementsByTagName(_field);
        String modulusValue = "";
        if (modulusNodeList.getLength() > 0) {
            Element modulusElement = (Element) modulusNodeList.item(0);
            // Extract the Modulus value
            modulusValue = modulusElement.getTextContent();
            System.out.println("Modulus Value: " + modulusValue);
        } else {
            System.out.println("Modulus element not found.");
        }
        return modulusValue;
    }
    public static byte[] encrypt(String _data, String publicXml) throws Exception {
        try {
            var data = _data.getBytes();
            if (data == null || data.length < 1) {
                throw new Exception("Data sent for encryption is empty");
            }
            // Extract the Modulus and Exponent from the XML
            // Decode the Base64 string
            byte[] decodedBytes = Base64.getDecoder().decode(publicXml);
            // Convert the decoded bytes to a string
            String decodedString = new String(decodedBytes);
            var publicxmllkey = decodedString.split("!")[1];
            System.out.println(publicxmllkey);
            var modulus = getXmlComponent(publicxmllkey, "Modulus");
            var exponent = getXmlComponent(publicxmllkey, "Exponent");
            String modulusBase64 = modulus;
            String exponentBase64 = exponent/* extract Exponent from publicXml */;
            // Convert the Base64-encoded Modulus and Exponent to byte arrays
            byte[] modulusBytes = Base64.getDecoder().decode(modulusBase64);
            byte[] exponentBytes =Base64.getDecoder().decode(exponentBase64);
            // Create RSAPublicKeySpec from Modulus and Exponent
            RSAPublicKeySpec keySpec = new RSAPublicKeySpec(
                    new java.math.BigInteger(1, modulusBytes),
                    new java.math.BigInteger(1, exponentBytes)
            );
            // Generate the PublicKey from the RSAPublicKeySpec
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(keySpec);
            // Initialize the Cipher for encryption
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            // Encrypt the data
            byte[] encryptedBytes = cipher.doFinal(data);
            return encryptedBytes;
        } catch (Exception e) {
            throw e;
        }
    }
    public EncryptionHelper() throws Exception {
        var rowdata = "Hello World";
        var publicxml = "NDA5NiE8UlNBS2V5VmFsdWU+PE1vZHVsdXM+eTJTSXdvQTY4cmNwZlNYcjJwbWhUYmp3NzRLOEgwTW5CN2NhbWNSVStlMVZmZ3o3d2xISysvYi9kdE9NLzVtYVBZV1l0aW1YcURoNlppTHZyUytqaklhVkhjS2trS3dscTNrK1BTSDR1ckpqeElOQSt4RHBQSW1aWFVLMjJobmp2c2s1YTM2Vkx2Q1NPd2IwTXJXaHJwaXNKem9sS3VEaFR1MjhnYWNsT1FaR2JoNStNazdyV0ZnVjVLZThqcUFZK1FIMk16RmZYNys3ZldKbXhGQTlReEI5SThTODhBMC9SWm5SNUlJQWtrRHh3aGtsSlB0NEtQeG5GT0RmTHQyR3Z0YXp3NmlTNmNUUlBHVkF5MmNocDRrZmZSVFcrd0FhaTlycTV5V2h0cHFaOVlCZ1N1MUFLd2twd01NL3o0cVJHWDJOdWZoOEtnMWV6cUs0WkVnTGhOYnN1aXZ5NmdZNEZxMjdSZWpndDN1S0hmdmExaUtYLysxVVI5cmlIMjJYUVZEMzFIamFieUJoZ2lTcVBIMzgwUVBNMnlpdnpKZDdyWDZqMEpzZk1NRFlGejJzMCtIUHJoQmd6cFBua3l2S0RGMUFZcjRTc2RQaitCNUxrYlZESUg4TC9zZE1DcEpyblJqMWlHRXgvWUl4U1ExdEJFZWFnbWFxVVF2VVJYV2hOeHNIS0Nxa3Buelh3bVdpT3FUR1RNRWdpc2UvbkI3SHVuVlRITEZ0d0UyVE1LYXZxbEFkUHNxMytlSFNqUzhQVmZNK1IxL1VoMUVTR09aOFZZdThTMjdFYWl6dDY4SmhVbDQ0NnVjT0R4VEJTckFYS0ptdGhjZk9MZzNYekU5TVlkaEZiWisxRzlHbi91YkVFd2ZiZVZsOVViVXZ6WDEwZmxTZXRlUnZ0ZDg9PC9Nb2R1bHVzPjxFeHBvbmVudD5BUUFCPC9FeHBvbmVudD48L1JTQUtleVZhbHVlPg==";
        var result = encrypt(rowdata, publicxml);
        // Encode the byte array to a Base64 string
        String base64String = Base64.getEncoder().encodeToString(result);
        System.out.println("Converted successfully");
        System.out.println(base64String);
    }
    public static void main(String[] args) throws Exception {
        EncryptionHelper keyPairGenerator = new EncryptionHelper();
    }
}
<?php
// Include the phpseclib library for RSA encryption
require 'vendor/autoload.php';

use phpseclib3\Crypt\RSA;
use phpseclib3\Math\BigInteger;

/**
 * Encrypt data using RSA public key.
 *
 * @param string $data The data to encrypt.
 * @param string $rsa_pub_key The RSA public key in XML format.
 * @return string The encrypted data in base64 encoding.
 */
function encryptForge($data, $rsa_pub_key) {
    // Decode the base64 encoded public key and remove the prefix
    $rsaKeyValue = base64_decode($rsa_pub_key);
    $rsaKeyValue = str_replace('4096!', '', $rsaKeyValue);

    // Load the XML document
    $xmlDoc = new DOMDocument();
    $xmlDoc->loadXML($rsaKeyValue);

    // Extract the Modulus and Exponent values from the XML
    $modulus = $xmlDoc->getElementsByTagName('Modulus')[0]->nodeValue;
    $exponent = $xmlDoc->getElementsByTagName('Exponent')[0]->nodeValue;

    // Convert the Modulus and Exponent from base64 to BigInteger
    $modulusBI = parseBigInteger($modulus);
    $exponentBI = parseBigInteger($exponent);

    // Set up the RSA public key
    $rsa = RSA::loadPublicKey([
        'n' => $modulusBI,
        'e' => $exponentBI,
    ]);

    // Encrypt the data
    $encryptText = $rsa->encrypt($data);

    // Return the encrypted text in base64 encoding
    return base64_encode($encryptText);
}

/**
 * Convert a base64 encoded string to a BigInteger.
 *
 * @param string $b64 The base64 encoded string.
 * @return BigInteger The BigInteger representation of the string.
 */
function parseBigInteger($b64) {
    $decoded = base64_decode($b64);
    return new BigInteger(bin2hex($decoded), 16);
}

// Example usage
$data = "Your data to encrypt";
$rsa_pub_key = "Your RSA public key in base64 XML format";
$encryptedData = encryptForge($data, $rsa_pub_key);
echo $encryptedData;
?>

import base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
from Crypto.Util.Padding import pad
import xml.etree.ElementTree as ET
def encrypt(data, public_xml):
    try:
        if not data:
            raise Exception("Data sent for encryption is empty")
        print(data)
        # Decode the Base64 string
        decoded_bytes = base64.b64decode(public_xml)
        # Convert the decoded bytes to a string
        decoded_string = decoded_bytes.decode('utf-8')
        public_xml_key = decoded_string.split('!')[1]
        modulus = getXmlComponent(public_xml_key, "Modulus")
        exponent = getXmlComponent(public_xml_key, "Exponent")
        modulus_bytes = base64.b64decode(modulus)
        exponent_bytes = base64.b64decode(exponent)
        # Create an RSA public key from Modulus and Exponent
        key = RSA.construct((int.from_bytes(modulus_bytes, byteorder='big'), int.from_bytes(exponent_bytes, byteorder='big')))
        # Initialize the Cipher for encryption
        cipher = PKCS1_v1_5.new(key)
        # Encrypt data
        encrypted_bytes = cipher.encrypt(bytes(data, 'utf-8'))
        print(encrypted_bytes)
        #Convert to base 64 string
        encrypted_bytes_ = base64.b64encode(encrypted_bytes)
        print(encrypted_bytes_)
        return encrypted_bytes
    except Exception as e:
        raise e
def getXmlComponent(xmlstring, _field):
    try:
        # Parse the XML string
        root = ET.fromstring(xmlstring)
        # Find elements with the specified field name
        modulusElements = root.findall(_field)
        modulusValue = ""
        if modulusElements:
            # Extract the Modulus value from the first element
            modulusValue = modulusElements[0].text
            print("Modulus Value:", modulusValue)
        else:
            print("Modulus element not found.")
        return modulusValue
    except Exception as e:
        # Handle exceptions (e.g., parsing errors)
        print("Error:", str(e))
        return ""
# Example usage:
_data = "{\"order\":{}}"
public_xml = "NDA5NiE8UlNBS2V5VmFsdWU+PE1vZHVsdXM+eTJTSXdvQTY4cmNwZlNYcjJwbWhUYmp3NzRLOEgwTW5CN2NhbWNSVStlMVZmZ3o3d2xISysvYi9kdE9NLzVtYVBZV1l0aW1YcURoNlppTHZyUytqaklhVkhjS2trS3dscTNrK1BTSDR1ckpqeElOQSt4RHBQSW1aWFVLMjJobmp2c2s1YTM2Vkx2Q1NPd2IwTXJXaHJwaXNKem9sS3VEaFR1MjhnYWNsT1FaR2JoNStNazdyV0ZnVjVLZThqcUFZK1FIMk16RmZYNys3ZldKbXhGQTlReEI5SThTODhBMC9SWm5SNUlJQWtrRHh3aGtsSlB0NEtQeG5GT0RmTHQyR3Z0YXp3NmlTNmNUUlBHVkF5MmNocDRrZmZSVFcrd0FhaTlycTV5V2h0cHFaOVlCZ1N1MUFLd2twd01NL3o0cVJHWDJOdWZoOEtnMWV6cUs0WkVnTGhOYnN1aXZ5NmdZNEZxMjdSZWpndDN1S0hmdmExaUtYLysxVVI5cmlIMjJYUVZEMzFIamFieUJoZ2lTcVBIMzgwUVBNMnlpdnpKZDdyWDZqMEpzZk1NRFlGejJzMCtIUHJoQmd6cFBua3l2S0RGMUFZcjRTc2RQaitCNUxrYlZESUg4TC9zZE1DcEpyblJqMWlHRXgvWUl4U1ExdEJFZWFnbWFxVVF2VVJYV2hOeHNIS0Nxa3Buelh3bVdpT3FUR1RNRWdpc2UvbkI3SHVuVlRITEZ0d0UyVE1LYXZxbEFkUHNxMytlSFNqUzhQVmZNK1IxL1VoMUVTR09aOFZZdThTMjdFYWl6dDY4SmhVbDQ0NnVjT0R4VEJTckFYS0ptdGhjZk9MZzNYekU5TVlkaEZiWisxRzlHbi91YkVFd2ZiZVZsOVViVXZ6WDEwZmxTZXRlUnZ0ZDg9PC9Nb2R1bHVzPjxFeHBvbmVudD5BUUFCPC9FeHBvbmVudD48L1JTQUtleVZhbHVlPg=="
encrypted_data = encrypt(_data, public_xml)