# 3. Initiate Pay

#### API Endpoints

{% tabs %}
{% tab title="Production Endpoint" %}

```
https://kwpaypg.casheer.com/COFWAY/InitiatePay
```

{% endtab %}

{% tab title="Sandbox Endpoint" %}

```
https://kwpaypgsb.casheer.com/COFWAY/InitiatePay
```

{% endtab %}
{% endtabs %}

#### **Sample Request & Response**

The following fields ought to be included in the request body:

{% tabs %}
{% tab title="Sample Request" %}

```
 "Initiate pay request{
     "ReferenceId" : "xxxxxxxxx"
     "MerchantId": xxxxxx, 
     "ECardData" = "encryptedCard", 
      32BIT AES Encryption 
     "ECardKey" = "encryptedKey", 
     "ACS_CallbackURL"= "call back url for 3DS"+ReferenceId   
     }
     
 };
```

{% endtab %}

{% tab title="Sample Response" %}

```
 {
  "errorCode": 0,
  "errorMessgae": "SUCCESS",
  "result": {
    "authentication": {
      "the3Ds1": null,
      "the3Ds2": null,
      "acceptVersions": null,
      "channel": null,
      "purpose": null,
      "redirect": {
        "customized": null,
        "domainName": "ap.gateway.mastercard.com",
        "html": "<div id=\"threedsChallengeRedirect\" xmlns=\"http://www.w3.org/1999/html\" style=\"height: 100vh\"> <form id =\"threedsChallengeRedirectForm\" method=\"POST\" action=\"https://ap.gateway.mastercard.com/acs/mastercard/v2/prompt\" target=\"challengeFrame\"> <input type=\"hidden\" name=\"creq\" value=\"eyJ0aHJlZURTU2VydmVyVHJhbnNJRCI6IjNmN2E4MmVjLTEzZjYtNDg2Ni05ODVjLTlkOTgxZjIzMGQ0OSJ9\" /> </form> <iframe id=\"challengeFrame\" name=\"challengeFrame\" width=\"100%\" height=\"100%\" ></iframe> <script id=\"authenticate-payer-script\"> var e=document.getElementById(\"threedsChallengeRedirectForm\"); if (e) { e.submit(); if (e.parentNode !== null) { e.parentNode.removeChild(e); } } </script> </div>"
      },
      "redirectHtml": null,
      "version": "3DS2",
      "the3Ds": null,
      "method": "OUT_OF_BAND",
      "payerInteraction": null
    }
  }
}
```

{% endtab %}
{% endtabs %}

<table><thead><tr><th width="175">Field Name</th><th width="86">Type</th><th>Description</th></tr></thead><tbody><tr><td>ReferenceId</td><td>String</td><td>15-digit reference id received in the validate requet response</td></tr><tr><td>MerchantId</td><td>String</td><td>Merchant code provided by PSP</td></tr><tr><td>ECardData</td><td>String</td><td>The card data encrypted using AES encryption with a 32-bit key. Explained below</td></tr><tr><td>ECardKey</td><td>String</td><td>The AES encryption key, encrypted using an RSA public key generated at <a href="#ecarddata-encryption">here</a></td></tr><tr><td>ACS_CallbackURL</td><td>String</td><td>Explained <a href="#acs_callbackurl">here</a></td></tr></tbody></table>

### Explanation of the `ECardData` Encryption Object <a href="#ecarddata-encryption" id="ecarddata-encryption"></a>

The `ECardData` field in the request is an encrypted representation of the sensitive card details. The following explains the object that is encrypted using AES encryption before being included in the API request:

```
{
    "CardNumber": "xxxxxxxxxxxxxxxx",//16-digit card number
    "CardName": "John Doe", //Name mentioned on card
    "CardExpiry": "mm/yy", //month/year format
    "CardCVV": "xxx" //3 digit number
    "CardBrand" :"001" // 001 for VISA and 002 for MASTER CARD
}
```

#### Sample code to encrypt ECardData

{% tabs %}
{% tab title="AES Encryption C#" %}

```csharp
 
string aesKeyText = "jcIkNa3ybrNVWxe1GSxycA1ru4GoEETO"; // Generate a 32bit random alphanumeric Key
byte[] aesKey = Encoding.UTF8.GetBytes(aesKeyText);
byte[] IV = new byte[16]; // 16-byte IV initialized to zeros

var cardData = new
{
    CardNumber = "XXXXXXXXXXXXXXXXX",
    CardName = "John Doe",
    CardExpiry = "MM/YY",
    CardCVV = "XXX",
    "CardBrand" :"001"
};

string serializedCardData = JsonConvert.SerializeObject(cardData);
string encryptedData = EncryptStringToBytes_Aes(serializedCardData, aesKey, IV);



public static string EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
{
    
    using (Aes aesAlg = Aes.Create())
    {
        aesAlg.Key = Key;
        aesAlg.IV = IV;
        aesAlg.Mode = CipherMode.CBC;
        aesAlg.Padding = PaddingMode.PKCS7;

        using (var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV))
        using (var msEncrypt = new MemoryStream())
        {
            using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            using (var swEncrypt = new StreamWriter(csEncrypt))
            {
                swEncrypt.Write(plainText);
            }
            return Convert.ToBase64String(msEncrypt.ToArray());
        }
    }
}

```

{% endtab %}

{% tab title="RSA Encryption C#" %}

```csharp

string aesKeyText = "jcIkNa3ybrNVWxe1GSxycA1ru4GoEETO"; //AES KEY Used to encrypt the card data
string publicKeys = "RSA Public Key"   //Previously generated merchant keys

// Encrypt the AES key using the RSA public key
string encryptedKey = RSA_Encrypt(aesKeyText, publicKeys);

public string RSA_Encrypt(string textToEncrypt, string publicKeyString)
{
    if (string.IsNullOrWhiteSpace(textToEncrypt)) throw new ArgumentNullException(nameof(textToEncrypt));
    if (string.IsNullOrWhiteSpace(publicKeyString)) throw new ArgumentNullException(nameof(publicKeyString));

    var bytesToEncrypt = Encoding.UTF8.GetBytes(textToEncrypt);

    using var rsa = new RSACryptoServiceProvider(2048);
    try
    {
        rsa.FromXmlString(publicKeyString);
        var encryptedData = rsa.Encrypt(bytesToEncrypt, true);
        return Convert.ToBase64String(encryptedData);
    }
    finally
    {
        rsa.PersistKeyInCsp = false;
    }
}


```

{% endtab %}
{% endtabs %}

### ACS\_CallbackURL

* The provider will handle the 3D Secure callback if it is empty, and the user will be sent to the callback URL that was supplied in step 1. For more info about redirection refer [here](https://kwpaydocs.casheer.com/sample-code/3.-callback-merchant-portal).
* If provided, the 3D Secure callback will be sent to the merchant's specified URL, and the merchant must call the API at [here](https://kwpaydocs.casheer.com/direct-pay/4.-process-payment) for further processing.

### Response Explaination

Upon receiving the response from the InitiatePay API, the merchant must verify the errorCode to determine the next steps. If the errorCode is 0, indicating a successful initiation, the merchant should parse the result object and render the HTML content provided in *<mark style="color:blue;">**result.redirect.html**</mark>* to proceed with the 3DS authentication process.
