Encrypting API requests

Encrypt your request payload for more secure communication

For every order or payment you initiate, You need to encrypt your payload first before sending the request to us. This ensures complete privacy between your servers and ours when conducting transactions.

Before you encrypt your request, you'd need to retrieve your encryption key from your dashboard. Here is a step-by-step on obtaining your keys:

  1. Log into your dashboard.
  2. Navigate to your settings.
  3. Select API keys and Webhook from the settings sub-menu.
  4. Copy your encryption key.

To encrypt your request, use the RSA algorithm with your keys (learn more about RSA here).

🚧

Testing Encryption

To use the encrypt order or encrypt payment request endpoint, you need to retrieve your Encryption key.

Encryption sequence

To encrypt your request

  1. Retrieve your encryption key from the dashboard.
  2. Decode your encryption key using base 64.
  3. Split the resulting output into an array with two elements using "!" as a delimiter.
  4. Your RSA public key xml is the data contained at element[1] of the array output from step 3.
  5. Encrypt your request with RSA using the RSA public key generated in step 4. If you are encrypting in Java, be sure to parse the XML to obtain the RSA public key.

For a quick start, you can make use of these samples to encrypt your request:

import base64, json
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 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
    else:
      print("Modulus element not found.")

    return modulusValue

  except Exception as e:
    # Handle exceptions (e.g., parsing errors)
    print("Error:", str(e))
    return ""


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(json.dumps(data), 'utf-8'))
    # print(encrypted_bytes)
    #Convert to base 64 string
    encrypted_bytes_ = base64.b64encode(encrypted_bytes)
    final_encrypted = encrypted_bytes_.decode('utf-8')
    print(final_encrypted)
    return final_encrypted

  except Exception as e:
    raise e

   
 # Update your payload.
# See encrypting orders (https://arca-payment-gateway.readme.io/reference/encrypting-orders)
# and encrypting payment details (https://arca-payment-gateway.readme.io/reference/encrypting-payment-requests)
# for more information.
payload = {
    "customer": {
        "first_name": "Example",
        "last_name": "User",
        "mobile": "+2348101234544",
        "country": "NG",
        "email": "[email protected]"
    },
    "order": {
        "amount": 100,
        "reference": "Example-Reference-0025",
        "description": "Test Payment",
        "currency": "NGN"
    }
}
_data = payload

# Enter your Encryption key
public_xml = "YOUR_ENCRYPTION_KEY"

encrypted_data = encrypt(_data, public_xml)
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace ArcaPg
{
    internal class Program
    {
        private static string publicXml = "";
        private static string merchantEncKey = "";
        private static int keySize = 0;
        static void Main(string[] args)
        {
            //Console.WriteLine("Hello, World!");

            merchantEncKey = "YOUR_ENCRYPTION_KEY";
            GetKeyFromEncyptionString(merchantEncKey, out keySize, out publicXml);

            var payload = "{\n" +
                "  \"customer\": {\n" +
                "    \"first_name\": \"Test\",\n" +
                "    \"last_name\": \"User\",\n" +
                "    \"mobile\": \"+2348034123310\",\n" + //234123412331
                "    \"country\": \"NG\",\n" +
                "    \"email\": \"[email protected]\"\n" +
                "  },\n" +
                "  \"order\": {\n" +
                "    \"amount\": 100,\n" +
                "    \"reference\": \"ORDfg6h20po948fbnbd4609\",\n" +
                "    \"description\": \"Another test Payment\",\n" +
                "    \"currency\": \"NGN\"\n" +
                "  }\n" +
                "}"; ;
            Console.WriteLine(Encrypt(payload));
        }




        /*
         * 
         * Encrypt Data using RSA Algorithm
         * 
         */

        public static string Encrypt(string plaintext)
        {
            try
            {
                var data = Encoding.UTF8.GetBytes(plaintext);
                if (data == null || data.Length < 1) throw new Exception("Data sent for encryption is empty");
                int maxLength = GetMaximumDataLength(keySize);
                if (data.Length > maxLength) throw new ArgumentException(string.Format("Max data length is {0}", maxLength), "data");
                if (!IsKeySizeValid(keySize)) throw new ArgumentException("Key size is invalid", "keyzie");
                if (string.IsNullOrEmpty(publicXml)) throw new ArgumentException("Key is either null or invalid", "publicxml");
                using (var rsaProvider = new RSACryptoServiceProvider(keySize))
                {
                    rsaProvider.ImportFromPem(merchantEncKey);
                    //rsaProvider.FromXmlString(publicXml);
                    return Convert.ToBase64String(rsaProvider.Encrypt(data, false));
                }

            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("Value cannot be null")) throw new Exception("ENCRPTNULL");
                throw new Exception("ENCYPT001");
            }
        }

        /*
         * 
         * Retrive RSA Public Key from Merchant Encryption Key
         * 
         */
        public static void GetKeyFromEncyptionString(string rawkey, out int keysize, out string xmlKey)
        {
            keysize = 0;
            xmlKey = "";
            if (!string.IsNullOrEmpty(rawkey))
            {
                byte[] keyBytes = Convert.FromBase64String(rawkey);
                var stringkey = Encoding.UTF8.GetString(keyBytes);
                if (stringkey.Contains(""!))
                {
                    var spliitedValues = stringkey.Split(new char[] { '!' }, 2);

                    try
                    {
                        keysize = int.Parse(spliitedValues[0]);
                        xmlKey = spliitedValues[1];

                    }
                    catch (Exception) { }
                }
            }
        }

        private static int GetMaximumDataLength(int keysize)
        {
            return ((keysize - 384) / 8) * 37;
        }
        private static bool IsKeySizeValid(int keysize)
        {
            return keysize >= 384 && keysize <= 32768 && keysize % 8 == 0;
        }
    }
}

What’s Next