Documentation

Payment protocol PaymentsAPI


  • Created: 02.03.2021
  • Update: 21.06.2023

Find out how we can help you. For more information, contact us today ! .


General description of the protocol

Technology: REST HTTP API

Data format: JSON

List of methods:

  • Init - payment initialization
  • Confirm - confirmation of payment

Authentication:

  • Client certificate
  • HMAC signature

2. Authentication

2.1 Client certificate

Each request must contain information about the client certificate An example of using a client certificate in the code of a test utility:


            var client = new RestClient(url);
            if (File.Exists(clientCertPath))
            {
              X509Certificate2 clientCert = new X509Certificate2(clientCertPath, certPass);
              client.ClientCertificates = new X509CertificateCollection() { clientCert };
            }   
 

,where

<clientCertPath –> path to certeficate

<certPass –>pswd of certeficate

If you need more information, please contact US

2.2 Signature HMAC


            If
            CLIENT = Client ID
            BODY = request body (JSON)
            TS = unix timestamp (UTC+0) in milliseconds (calculated each time before request)
            API-SECRET = client's private key
            
            , then the message to sign would be:
            MESSAGE = CLIENT + TS + BODY 
            
            We calculate the signature as HMAC-SHA256
            from MESSAGE using a private key API-SECRET
            and then convert the byte array to string HEX - format
            SIGN = HEX (HMAC-SHA256(MESSAGE, API-SECRET))
            
            When sending a request, fill in the following HTTP headers:
            RP-CLIENT = CLIENT 
            RP-TS = TS
            RP-SIGN = SIGN  
             

Example:


            CLIENT = N1Lin11
            BODY = {
            "clientTranId": "130",
            "account": "282380",
            "amount": 54.80,
            "commissionAmount": 1.50,
            "currency": "DZ",
            "operatorCode": 5293
            }

            TS =1614696692368
            API-SECRET = 12345

            , then the message to be signed will be:
            MESSAGE = N1Lin111614696692368{
            "clientTranId": "130",
             "account": "282380",
             "amount": 54.80,
             "commissionAmount": 1.50,
             "currency": "DZ",
             "operatorCode": 5293
            }
 

We calculate the signature as HMAC-SHA256 from MESSAGE using a private key API-SECRET and then convert the byte array to string HEX - format SIGN = HEX (HMAC-SHA256(MESSAGE, API-SECRET)) = 108b03d50319b9422df3a121991c474fa441df41f94c62683373099d473275b0

When sending a request, fill in the following HTTP headers:

RP-CLIENT N1Lin11

RP-TS 1614696692368

RP-SIGN 108b03d50319b9422df3a121991c474fa441df41f94c62683373099d473275b0

Sample code from test utility :


    var body = edtRequest.Text;
    var request = new RestRequest(Method.POST).AddJsonBody(body);
    
    //sign
    var timestamp = ToTimeStampLong(DateTime.UtcNow);
    var teminalid = edtCLIENT.Text;
    var strToSign = $"{teminalid}{timestamp}{body}";
    var secret = edtSECRET.Text;
    
    string sign = string.Empty;
    var keyByte = Encoding.UTF8.GetBytes(secret);
    byte[] inputBytes = Encoding.UTF8.GetBytes(strToSign);
    using (var hmac = new HMACSHA256(keyByte))
    {
        byte[] hashValue = hmac.ComputeHash(inputBytes);
        sign = ByteArrayToHEXString(hashValue);
    }
    
    request.AddHeader("RP-CLIENT", teminalid);
    request.AddHeader("RP-TS", timestamp.ToString());
    request.AddHeader("RP-SIGN", sign);
    
    ------
    
    public static long ToTimeStampLong(DateTime dt)
    {
        long timestamp = (Int64)(dt.Subtract(new DateTime(1970, 1, 1))).TotalMilliseconds;
        return timestamp;
    }
    
    private static string ByteArrayToHEXString(byte[] ba)
    {
        return BitConverter.ToString(ba).Replace("-", "").ToLower();
    }
    

3. Service methods

3.1 [Payment/Init] Payment initialization method

Request type: POST

This is the first request in a billing session. At this stage, various checks are carried out for the correctness of the payment data and for the possibility of performing this operation.

Request example:


  {
    "clientTranId": "1618817505702",
    "account": "213780221111",
    "amount": 1.00,
    "commissionAmount": 0.00,
    "currency": "DZ",
    "operatorCode": 101,
    "operatorParams": {
       "CheckedIDNP": "2000003147230"
     }
   } 

,where

clientTranId - transaction number in the client's system (optional)

account - account

amount – amount to pay

commissionAmount - commission amount

currency - currency

operatorCode - operator code

operatorParams - incoming operator parameters (each operator has its own parameters)

Sample response:


  {
    "serverTranId": 554161817,
    "account": "213780221111",
    "amount": 1,
    "operatorCode": 101,
    "operatorParams": {
      "MonthLimitIncome": "499997838,00",
      "MonthLimitOutgo": "499997844,46",
    },
    "status": "InitSuccess",
    "errorCode": 0,
    "errorMessage": "No Errors"
  }  

,where

serverTranId - transaction identifier (This value then needs to be substituted in the Confirm request)

operatorParams - various operator parameters

status – transaction status (see description of statuses)

errorCode - error code (see description of error codes)

errorMessage error description

operatorParams - outgoing operator parameters

3.2. [Payment/Confirm] Payment confirmation method

Request type: POST

This method is called after successful initialization to process the payment.

Request example:


  {
    "serverTranId": 554161817,
    "account": "213780221111",
    "amount": 1.00,
    "commissionAmount": 0,
    "currency": "DZ",
    "operatorCode": 101
  }

,where

serverTranId - transaction number (comes in response to /Init)

Sample answer:


  {
    "serverTranId": 554161817,
    "account": "213780221111",
    "amount": 1,
    "commissionAmount": 0,
    "commissionType": 0,
    "operatorCode": 101,
    "operatorParams": {
      "MonthLimitIncome": "499997838,00",
      "MonthLimitOutgo": "499997844,46",
    },
    "status": "PaySuccess",
    "errorCode": 0,
    "errorMessage": "No errors"
  }   

3.3. [Payment/Check] Payment verification method

Request type: POST

This method is called to clarify the status of the sent payment or check if the operation ended with an error or the connection was interrupted.

Request example:


  {
    "clientTranId": "1618817505702",
    "serverTranId": "7505702"
  }     

,where

clientTranId - transaction number in the client's system

serverTranId - transaction number in the RunPay system (comes in response to Init/Confirm)

It is enough to fill in one of the parameters.

If both parameters are filled, then the priority serverTrandId.

The response is identical to the response to the Init/Confirm methods.

3.4. [/Balance] Payment verification method

Request type: GET

Note This method is used to query the user's balance.

Request example:


  {
    "balance": "12300.45"
  }     

4. Basic scenario for making a payment

  • Sending request /Init
  • From the answer we take serverTranId and substitute in the request /Confirm
  • We send request /Confirm

5. Converting the certificate

Some cases instead of pfx the certificate needs a different format such as a pem / key pair. For such purposes, you need to use the public utility open_ssl, below are examples of the required commands:

1. Making a root certificate

openssl pkcs12 -in N4XBB.pfx -cacerts -nokeys -out ca.pem

2. Making a pem with a client certificate

openssl pkcs12 -in N4XBB.pfx -clcerts -nokeys -out cert.pem

3. Making a pem with a private key

openssl pkcs12 -in N4XBB.pfx -nocerts -out key.pem


6. Test utility

The TestClient utility has been created to test the API. You can use it to send with a signature

1) API base address

2) Method

3) Client code (issued upon registration)

4) Client password (issued during registration)

5) Client certificate (issued upon registration)

6) Password from the certificate (issued during registration)

7) Request body

8) The generated timestamp value

9) The generated signature value

10) Query result

11) Lead time

12) Send request button

13) Response body


7. List of transaction statuses. Algorithm for working with statuses

# Status Description Suggested actions
1 InitFail payment verification failed another check needs to be done
2 InitPorcess check in progress implementation it is necessary to periodically request the status of the transaction to find out the result of the completion of the check
4 InitSuccess verification was successful you can proceed to the step of conducting the transaction
5 PayFail error processing payment it is necessary to return the money to the client
6 PayProcess payment is in progress it is necessary to periodically request the status of the transaction to find out the result of the completion of the payment
7 PaySuccess payment completed successfully Complete the transaction on your side with the SUCCESS status, provide the client with a confirmation (check/receipt)
8 PayPending postponed holding payment it is necessary to periodically request the status of the transaction to find out the result of the completion of the payment
9 PayCanceled payment canceled need to return money to client
10 CheckFail error checking transaction status you need to try again /Check

Algorithm for working with statuses:

1. Checking the possibility of making a payment (/Init).

A request to check the possibility of making a payment is sent (/Init). In case of receiving a response:

  • InitSuccess - a payment confirmation request must be sent (/Confirm).
  • InitProcess - a status check request must be sent (/Check). Call Check until InitSuccess or InitFail is received. The periodic status polling time is regulated by the agent. Standard polling time: once every 10 seconds.
  • InitFail - attempts to process the transaction must be completed. The payment operation cannot be performed.

2. Payment confirmation (/Confirm).

A payment confirmation request (/Confirm) is sent. If a response is received

  • PaySuccess - payment has been successfully processed. Transaction processing is complete. A receipt is issued to the user.
  • PayProcess - the transaction is in the queue for processing. It is necessary to send a status check request (/Check). Call Check until PaySuccess or PayFail is received. The periodic status polling time is regulated by the agent. The standard polling time is once every 10 seconds.
  • PayPending - the transaction has received an intermediate status. It has been processed, but the operator needs more time to process it. It is necessary to send a status check request (/Check). Call Check until PaySuccess or PayFail is received. The periodic status polling time is regulated by the agent. The standard polling time is once every 10 seconds.
  • PayFail - it is not possible to make a payment due to technical problems of the operator(s). Attempts to make a payment have been canceled. It is necessary to stop the request process in PaymentsAPI and return the funds to the client.
  • PayCanceled - the transaction was carried out successfully, but at the request of the user the operation was canceled by the operator. It is necessary to make a refund of funds on the integrator's side. (This status is extremely rare. You will probably never encounter it on /Confirm.)

3. Checking the transaction status (/Check).

By calling the /Check method, you will receive the current transaction status depending on which stage you have completed (/Init) or (/Confirm):

  • CheckFail - an error occurred during the transaction status check. Requires repeating (/Check).
  • InitSuccess - You can proceed to payment (/Confirm)
  • InitProcess - Requires repeating (/Check) in 10 seconds
  • InitFail - You need to complete the transaction processing attempts. The payment processing operation is not possible
  • PaySuccess - payment was successfully processed.
  • PayProcess - Requires repeating (/Check) in 10 seconds.
  • PayPending - Requires repeating (/Check) in 10 seconds.
  • PayFail - It is not possible to make a payment due to technical problems with the operator(s). The payment attempts have been cancelled. It is necessary to stop the process of requests in PaymentsAPI and return funds to the client.
  • PayCanceled - the transaction was carried out successfully, but at the request of the user the operation was cancelled by the operator. It is necessary to make a refund on the integrator's side.
Example I (user) made a payment on the integrator's website. The integrator made the payment by contacting PaymentsApi, receiving PaySuccess. A month later, the user contacted the integrator, writing a request for a refund. The integrator forwarded this question to our technical support. Our technical support staff will try to cancel the payment on the operator's side and, if successful, will cancel the transaction in processing. The aggregator will manually query the status of the transaction (/Check), contacting PaymentsApi and will receive the PayCanceled status. Thus, already marking the operation as canceled and proceeding to return the funds to the user to his original place (from where they were written off) if it is technically possible to perform such actions. .
If at (/Check) after the PayProcess status (/Confirm) you received the status InitSuccess (status mismatch with the completed stage), you can repeat the request (/Confirm) with the same data as you sent the first time (clientTranId and serverTranId). There is no possibility of duplicating the payment. This situation is rare and is possible due to the fact that when we accepted the payment, an error occurred during the process of writing to the database.

8. Return of funds to the client.

Refunds to the client are possible only if the following conditions are met:

1. The payment service's response to the payment request (Payment/Confirm)

  • PayCanceled ("status": "PayCanceled")
  • PayFail ("status": "PayFail")

2. The transaction status check (Payment/Check) returns the status

  • PayCanceled ("status": "PayCanceled")
  • PayFail ("status": "PayFail")

If any other transaction status is received, a timeout occurs in executing the request, or the network/HTTP-status is not equal to 200, it is necessary to repeat the transaction status check request until the terminal payment status is received. In such cases, refunds to the client are prohibited!


9. List of error codes

# Message
0 No error
1 Incorrect query parameters
2 Request log not found
3 No active store or active business found
4 Repeat Request ID
5 No matching validation request found. Perhaps the wrong status of the transaction, ie. repeat command
6 Subagent terminal code is not registered in the database
7 Certificate expired according to DB
8 Phone number/account length is too long
9 No gateway found for online command
10 Operator blocked or subagent banned
11 Transaction date too old
12 Error adding payment to the queue
14 Certificate verification error
15 Invalid optional parameter format or missing required parameter
100 Data not found
101 Internal Server Error
34 Prohibited payment currency
114 Exceeding the limit for the period