Online Payment Process - 1.8

Download as pdf or txt
Download as pdf or txt
You are on page 1of 15

Payment Gateway Integration

REVISION HISTORY
Document
REV Description of Change Author Effective Date

1 Creation of the Document Lead Team 26-Aug-2021

2 Reviewed Soumyakanta Mantry 18-Jan-2022


Table of Contents

Table of Contents ............................................................................................................................ 2


1 Objective ................................................................................................................................. 3
2 APIs Required for Integrations ............................................................................................. 3
2.1 API 1: API form payment gateway provider for Online Payment ...................................... 3
2.2 API 2: Proposed Payment status updating in case of pending ........................................... 4
2.3 API 3: Intimation on remittance of fund in respective account ......................................... 7
1 Objective

Khanij Online (KO) application provide the facility to make online payment for different aspects.
After successful payment, the users will redirect back to the Khanij Online portal. The KO portal will
receive the payment status. However, in some cases user will not redirect back to the portal, hence
the users will not be able to receive the bank transaction number.

Updated API will be provided to back which will includes the encryption key and the API will be
responsible to push the relevant data to KO portal after successful payment transaction.

2 APIs Required for Integrations

There are 4 APIs required for the complete scope of integration.

1. API 1: Bank will provide a Payment Gateway API which will be consume by KO system
to push the online payment details.
2. API 2: KO will provide an API for pushing successful transaction details in case status is
pending during payment made.
3. API 3: KO will provide an API for getting intimation on remittance of collected amount
to respective accounts.
4. API 4: Bank will provide API for the double verification of the payment status manually
in case of failure in updation through API 2.

2.1 API 1: API form payment gateway provider for Online Payment

➢ Khanij Online portal will show the payment details like payment amount against the
different heads to the user.
➢ Then user will do online payment through Khanij Online Portal using Payment Gateway.
➢ For that a ‘Make Payment’ option will be activated to the user against a particular
application no. On clicking the “Make Payment” button, it will navigate to respective
payment gateway chosen by the user.
➢ Gateway will receive payment details from Khanij Online portal against multiple head of
accounts in a single transaction.
➢ After Successful transaction, gateway will return transaction confirmation to Khanij Online
Portal with Transaction No., Reference No. and status (Success/ Pending/ Failure) &
payment successful date and time.

2.2 API 2: Proposed Payment status updating in case of pending


➢ The API will be exposed by KO portal.
➢ In case of any pending transactions, once bank received the paid amount in escrow/pool
account then bank will push success information in real time to KO portal immediately
using this API.
➢ On successful updation KO portal value will be returned as “True” to bank and an SMS will
be fired from KO portal to the user.
➢ During updation in pool account if any transaction is not updated
i. KO portal will return as “false”, and then bank will try to push 3 times in every 30
mins.
ii. If still issue persists then bank will fire auto mail to the dedicated mail IDs of DGM
which will be provided during integration.
iii. Mail subject will be “Error in Payment Status Updation:< Unique Khanij Online
Transaction Number>”

Mail Format:

Subject: Error in Payment Status Updation: <KO Unique Number>

Dear Khanij Online Team,


Payment status updation for <KO Unique Number>.

Bank Name:
Client Transaction Reference: <KO Unique Number>
Bank Transaction ID:
Transaction Amount:
Transaction Date:
Pool Account date:
Transaction Status: Push String:
Transaction Response Error:
Regards, <Bank> Team

Below is the testing URL exposed by Khanij Online portal for bank consumption and below
are the details.

API URL:

https://164.100.131.139/KhanijDev//api/Service/KOApi/KOBankPushPaymentTransactionStatus

API Body:
{"Encdata":"8PNDq5ceNQGa8DhjtbCpUVoSuY3czF7WWCW5jW+INIrzEneA+Xyd28ZzRWruVUaSRP5
LMTxcmQFde8MOllBzKYnzFcxtxEzrZof8ulm8TY4jTowMHOTu6aQV1vUMJpbpvnNeIA+zn4oIT1Vr5j
YnQtlMpafbm3SYPV7B44XknCcQIxFhcaFHKgNeqk1MYETJaGy9fkI62ViIxxy8UALv7zRkk9538Lhjg5k
JOHbJKss="}

The sample process of transaction string posting is explained as below. The input parameters are
case sensitive. The sample parameters can be as below

Parameters
Variable
SL# Name Parameter Type Data Type
1 Encdata Input String

Input Variable
Parameter Data Type Descriptio
SL# Variable Name Type n Example
1 BANK_NAME Input String Bank name SBI
String Khanij
Online
Reference VPF825F34DE
2 CLIENT_TXN_REF Input number C7
String Bank
unique
Transaction
number
against each
Client
3 BANK_TXN_ID Input transaction IK00EVQAU3
String Transaction
4 TXN_AMOUNT Input Amount 1000.00
5 TRANSACTION_DATE Input String On which 2018-07-08
Date 18:44:58.000
Transaction
Initiate
String On which
Date
Amount
Credited to
the
department’
s pool 2018-07-08
6 POOL_ACCOUNT_DATE Input account 18:44:58.000
String Status of the
7 TRANSACTION_STATUS Input transaction SUCCESS

The transaction string in plain text will be as shown below.


BANK_NAME=SBI|CLIENT_TXN_REF=BP30415|BANK_TXN_ID=CPB0138922|TXN_AMOUNT=700.00
0|TRANSACTION_DATE=2021-08-24|POOL_ACCOUNT_DATE=2021-08-
24|TRANSACTION_STATUS=SUCCESS

The transaction string in Encrypted format as shown below.


8PNDq5ceNQGa8DhjtbCpUVoSuY3czF7WWCW5jW+INIrzEneA+Xyd28ZzRWruVUaSRP5LMTxcmQF
de8MOllBzKYnzFcxtxEzrZof8ulm8TY4jTowMHOTu6aQV1vUMJpbpvnNeIA+zn4oIT1Vr5jYnQtlMpafb
m3SYPV7B44XknCcQIxFhcaFHKgNeqk1MYETJaGy9fkI62ViIxxy8UALv7zRkk9538Lhjg5kJOHbJKss=

Note:
The encrypted string should be passed in parameter “Encdata“ and Each parameter will be
appended with ‘|’ (Pipe symbol) as separator.
Return Response: Against each transaction bank will received the True or False as the status of
individual transaction.

2.3 API 3: Intimation on remittance of fund in respective account

➢ KO portal will expose an API for pushing the remittance details to Khanij Online portal
and it will be consumed by Payment Gateway service providers.
➢ This API will update the remittance status along with head wise remittance reference
number, remittance date and time against the successful transactions in Khanij Online
Portal.
➢ On successful updation KO portal value will be returned as “True”.
➢ During updation of remittance details
i. KO portal will return as “False”, and then bank will try to push 3 times in every 30
mins.
ii. If still issue persists then bank will fire auto mail to the dedicated mail IDs of DGM
which will be provided during integration.
iii. Mail subject will be “Error in Remittance Status Updation:<Unique Khanij
Online Transaction Number>”.

Mail:
Subject: Error in Remittance Status Updation :<KO Unique Number>
Dear Khanij Online Team,
Remittance Status Updation :<KO Unique Number>.

Bank Name:
Client Transaction Reference:
Bank Transaction ID:
Remittance Reference No:
Remittance Date:
Transaction Status:
Push String:
Transaction Response Error:

Regards, <Bank> Team

Below is the testing URL exposed by Khanij Online portal for bank consumption and below are the
details.

API URL:
https://164.100.131.139/Khanijdev/api/Service/KOApi/KOBankPushPaymentTransactionStatus

Api Body:
{"Encdata":"fcKadFUdidVeaiMK3HfYsSpCWVPwZpWFSrbebMU9PRiAneGk7wMk6QsyjEfpISsOh89Ml
BcnM7e8dOZNAwEifH3bMd9zCDJXECG2xiHRDRo7abNRZFZh71QvLTYQznWuk4XfnJlytbC/wDtDYQ
rB0HbjL0wgMlhsrvLDvnDELVJSsywILE2ONe9ZHUO7lRN843tzR9PabRRD2GasAuHauN61EP8BNrcn
p0ljXcMYkTLSriaHt9VNx6Gex2dgYPL/ZNogPq3apTI0t3yZxmT3NA=="}

The sample process of transaction string posting is explained as below. The input parameters are
case sensitive. The sample parameters as shown below.

Parameters
Variable
SL# Name Parameter Type Data Type
1 Encdata Input String

Input Variable
SL# Variable Name Parameter Type Data Type Description
1 CLIENT_TXN_REF Input String Khanij Online Number
Bank Transaction
2 BANK_TXN_ID Input String Number
KO01:1~KO43:1~KO
3 RESPONSE_STRING Input String 31:1
4 TREASURY_REFF_NO Input String KO01:040607060~KO
43:040607065~KO31
:040607071
KO01~2020-09-
18|KO04~2020-09-
18|KO05~2020-09-
5 REMITTANCE_DATE Input String 18|KO31~2020-09-18

The transaction string in plain text will be as below


CLIENT_TXN_REF=BP30415|BANK_TXN_ID=CPB0138922|RESPONSE_STRING=KO01:1~KO43:1~KO
31:1|TREASURY_REFF_NO=KO01:TEST001~KO43:TEST002~KO31:TEST003|REMITTANCE_DATE=
KO01~2021-08-24|KO43~2021-08-24|KO31~2021-08-24

Encrypting the transaction string


fcKadFUdidVeaiMK3HfYsSpCWVPwZpWFSrbebMU9PRiAneGk7wMk6QsyjEfpISsOh89MlBcnM7e8dO
ZNAwEifH3bMd9zCDJXECG2xiHRDRo7abNRZFZh71QvLTYQznWuk4XfnJlytbC/wDtDYQrB0HbjL0wg
MlhsrvLDvnDELVJSsywILE2ONe9ZHUO7lRN843tzR9PabRRD2GasAuHauN61EP8BNrcnp0ljXcMYkT
LSriaHt9VNx6Gex2dgYPL/ZNogPq3apTI0t3yZxmT3NA==

Note: The encrypted string should be passed in parameter “Encdata“ and Each parameter will be
appended with ‘|’ (Pipe symbol) as separator.

Return Response: Against each transaction bank will received the True or False as the status of
individual transaction
Note: The codes provided below in the document are not complete in itself, kindly arrange to
complete the same from the understanding of the flow mentioned.

For encryption use the below keys and Encryption code


string hexKey =
"AF27949FCA7F555299868AC02E6AF5ADE2A240C7A9E666E0F809760789F2826F";
string hexIV = "23AB6DB03E8B10232A7E768614074993";

Sample Codes

AES-256 Algorithm to implement in .Net Platform


using System;
using System.Text;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;

namespace ConsoleApp1
{
class AesGcm256
{
private static readonly SecureRandom Random = new SecureRandom();

// Pre-configured Encryption Parameters


public static readonly int NonceBitSize = 128;
public static readonly int MacBitSize = 128;
public static readonly int KeyBitSize = 256;

private AesGcm256() { }

public static byte[] NewKey()


{
var key = new byte[KeyBitSize / 8];
Random.NextBytes(key);
return key;
}

public static byte[] NewIv()


{
var iv = new byte[NonceBitSize / 8];
Random.NextBytes(iv);
return iv;
}
public static Byte[] HexToByte(string hexStr)
{
byte[] bArray = new byte[hexStr.Length / 2];
for (int i = 0; i < (hexStr.Length / 2); i++)
{
byte firstNibble = Byte.Parse(hexStr.Substring((2 * i), 1),
System.Globalization.NumberStyles.HexNumber); // [x,y)
byte secondNibble = Byte.Parse(hexStr.Substring((2 * i) + 1, 1),
System.Globalization.NumberStyles.HexNumber);
int finalByte = (secondNibble) | (firstNibble << 4); // bit-operations
// only with numbers, not bytes.
bArray[i] = (byte)finalByte;
}
return bArray;
}

public static string toHex(byte[] data)


{
string hex = string.Empty;
foreach (byte c in data)
{
hex += c.ToString("X2");
}
return hex;
}

public static string toHex(string asciiString)


{
string hex = string.Empty;
foreach (char c in asciiString)
{
int tmp = c;
hex += string.Format("{0:x2}", System.Convert.ToUInt32(tmp.ToString()));
}
return hex;
}

public static string encrypt(string PlainText, byte[] key, byte[] iv)


{
string sR = string.Empty;
try
{
byte[] plainBytes = Encoding.UTF8.GetBytes(PlainText);

GcmBlockCipher cipher = new GcmBlockCipher(new AesFastEngine());


AeadParameters parameters =
new AeadParameters(new KeyParameter(key), 128, iv, null);

cipher.Init(true, parameters);

byte[] encryptedBytes = new byte[cipher.GetOutputSize(plainBytes.Length)];


Int32 retLen = cipher.ProcessBytes
(plainBytes, 0, plainBytes.Length, encryptedBytes, 0);
cipher.DoFinal(encryptedBytes, retLen);
sR = Convert.ToBase64String(encryptedBytes, Base64FormattingOptions.None);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}

return sR;
}

public static string decrypt(string EncryptedText, byte[] key, byte[] iv)


{
string sR = string.Empty;
try
{
byte[] encryptedBytes = Convert.FromBase64String(EncryptedText);

GcmBlockCipher cipher = new GcmBlockCipher(new AesFastEngine());


AeadParameters parameters =
new AeadParameters(new KeyParameter(key), 128, iv, null);
//ParametersWithIV parameters = new ParametersWithIV(new KeyParameter(key), iv);

cipher.Init(false, parameters);
byte[] plainBytes = new byte[cipher.GetOutputSize(encryptedBytes.Length)];
Int32 retLen = cipher.ProcessBytes
(encryptedBytes, 0, encryptedBytes.Length, plainBytes, 0);
cipher.DoFinal(plainBytes, retLen);

sR = Encoding.UTF8.GetString(plainBytes).TrimEnd("\r\n\0".ToCharArray());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
return sR;
}
}
}

AES-256 Algorithm to implement in JAVA Platform

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.SecureRandom;
import java.util.Base64;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.AESFastEngine;
import org.bouncycastle.crypto.modes.GCMBlockCipher;
import org.bouncycastle.crypto.params.AEADParameters;
import org.bouncycastle.crypto.params.KeyParameter;

public class AesGcm256 {

private static final SecureRandom SECURE_RANDOM = new SecureRandom();

// Pre-configured Encryption Parameters


public static int NonceBitSize = 128;
public static int MacBitSize = 128;
public static int KeyBitSize = 256;

private AesGcm256() {
}

public static byte[] NewKey() {


byte[] key = new byte[KeyBitSize / 8];
SECURE_RANDOM.nextBytes(key);
return key;
}

public static byte[] NewIv() {


byte[] iv = new byte[NonceBitSize / 8];
SECURE_RANDOM.nextBytes(iv);
return iv;
}

public static byte[] HexToByte(String hexStr) {


int len = hexStr.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2)
{
data[i / 2] = (byte) ((Character.digit(hexStr.charAt(i), 16) << 4)
+ Character.digit(hexStr.charAt(i + 1), 16));
}
return data;
}

public static String toHex(byte[] data) {


final StringBuilder builder = new StringBuilder();
for (byte b : data) {
builder.append(Integer.toString(b, 16));
}
return builder.toString();
}

public static String encrypt(String PlainText, byte[] key, byte[] iv) {


String sR = "";
try {
byte[] plainBytes = PlainText.getBytes("UTF-8");

GCMBlockCipher cipher = new GCMBlockCipher(new AESFastEngine());


AEADParameters parameters =
new AEADParameters(new KeyParameter(key), MacBitSize, iv, null);

cipher.init(true, parameters);

byte[] encryptedBytes = new byte[cipher.getOutputSize(plainBytes.length)];


int retLen = cipher.processBytes(plainBytes, 0, plainBytes.length, encryptedBytes, 0);
cipher.doFinal(encryptedBytes, retLen);
sR = Base64.getEncoder().encodeToString(encryptedBytes);
} catch (UnsupportedEncodingException | IllegalArgumentException |
IllegalStateException | DataLengthException | InvalidCipherTextException ex) {
System.out.println(ex.getMessage());
}

return sR;
}

public static String decrypt(String EncryptedText, byte[] key, byte[] iv) {


String sR = "";
try {
byte[] encryptedBytes = Base64.getDecoder().decode(EncryptedText);
GCMBlockCipher cipher = new GCMBlockCipher(new AESFastEngine());
AEADParameters parameters =
new AEADParameters(new KeyParameter(key), MacBitSize, iv, null);

cipher.init(false, parameters);
byte[] plainBytes = new byte[cipher.getOutputSize(encryptedBytes.length)];
int retLen = cipher.processBytes
(encryptedBytes, 0, encryptedBytes.length, plainBytes, 0);
cipher.doFinal(plainBytes, retLen);

sR = new String(plainBytes, Charset.forName("UTF-8"));


} catch (IllegalArgumentException | IllegalStateException |
DataLengthException | InvalidCipherTextException ex) {
System.out.println(ex.getMessage());
}

return sR;
}
}

You might also like