Direct card payment

A direct card payment is a payment transaction in which your customer has authorized you to take money from their card using their full card details. However, the Card details are sent as an encrypted string.

Posting a direct card request is the same as posting a card payment however theencrypted_card parameter will have to be specified. By providing this field, kitegateway will know that the transaction is a direct card payment.

Providing encrypted_card

Encryption

1. Create JSON of the Card details

{
    "full_name": "Nakimbugwe Racheal",
    "card_number": "012345666777888999",
    "expiry_month": "02",
    "expiry_year": "24",
    "cvv": "111",
    "billing_address": "Some Street",
    "billing_city": "Some City",
    "billing_zip": "88653",
    "billing_state": "JK",
    "billing_country": "UK"
}

2. Downloading Public Key

// Live
GET https://kitegateway.com/v1/public-key
// Sandbox
GET https://sandbox.kitegateway.com/v1/public-key
// live
curl -v -X GET 'https://kitegateway.com/v1/public-key -H 'Authorization: JWT ***' --output kitegateway.public.key.pem

3.Encryption Card

const crypto = require('crypto');
const fs = require('fs');

const card_data = {
        full_name: "Ankunda Ruth",
        card_number: "0002221238737737737",
        expiry_month: "02",
        expiry_year: "24",
        cvv: "111",
        billing_address: "Kensington Street No. 2",
        billing_city: "London",
        billing_zip: "12345",
        billing_state: "London",
        billing_country: "UK",
    };

function encrypt(card_data) {
    // Stringify card data
    const payload = JSON.stringify(card_data);
    console.log(`Payload size: ${Buffer.from(payload).length} bytes`);

    // Load public key
    const publicKeyFile = "path-to-file/kitegateway.public.key.pem";
    const publicKey = fs.readFileSync(publicKeyFile).toString().replace(/\\n/g, '\n');

    // Check payload size (max 214 bytes for 2048-bit key with OAEP padding)
    if (Buffer.from(payload).length > 214) {
        // Generate AES key and IV
        const aesKey = crypto.randomBytes(32); // 256-bit AES key
        const iv = crypto.randomBytes(16); // 128-bit IV

        // Encrypt payload with AES-256-CBC
        const cipher = crypto.createCipheriv('aes-256-cbc', aesKey, iv);
        let encryptedData = cipher.update(payload, 'utf8', 'base64');
        encryptedData += cipher.final('base64');
        console.log(`AES encrypted data size: ${Buffer.from(encryptedData, 'base64').length} bytes`);

        // Encrypt AES key with RSA-OAEP
        const encryptedAesKey = crypto.publicEncrypt(
            {
                key: publicKey,
                padding: crypto.constants.RSA_PKCS1_OAEP_PADDING
            },
            aesKey
        );
        // Combine encrypted data, IV, and encrypted AES key
        const result = `${encryptedData}::${iv.toString('base64')}::${encryptedAesKey.toString('base64')}`;
        const base64Result = Buffer.from(result).toString('base64');

        // Validate base64
        if (!/^[A-Za-z0-9+/=]+$/.test(base64Result)) {
            console.error('Invalid base64 encoding of hybrid ciphertext.');
            return null;
        }
        console.log(`Hybrid encrypted data (base64): ${base64Result}`);
        return base64Result;
    }

    // Standard RSA-OAEP encryption
    const encryptedData = crypto.publicEncrypt(
        {
            key: publicKey,
            padding: crypto.constants.RSA_PKCS1_OAEP_PADDING
        },
        Buffer.from(payload)
    );
    const base64Result = encryptedData.toString('base64');

    // Validate base64
    if (!/^[A-Za-z0-9+/=]+$/.test(base64Result)) {
        console.error('Invalid base64 encoding of ciphertext.');
        return null;
    }

    return base64Result;
}

4. Set card_cipher parameter

From the step above, the resultant string after encryption is what we need to set as the encrypted_card and include it in the Post Collection Request when making a Card Collection Request

{
  ...
  "encrypted_card": "***"
  ...
}

When the encrypted_card the parameter is specified in the collection request body, Kitegateway will know that you want to make a direct card payment.

Since it's 3D processing, the response object will contain the bank authentication URL where you will redirect the customer to complete the payment.

Last updated