DinarPay Card Processing Gateway

API Documentation

Introduction

This document provides instructions on how to consume DinarPay Card Processing Gateway API's for collecting payments from your customers.
In order for you to be able to consume provided API endpoints you need to be provided with following information:

General overview

In this seciton we describe general overview of the payment process. Below are list of steps to be performed In order to collect a payment from customer.

  1. Your application displays a payment information to customer including description of service why he is being charged and amount to pay. It also displays a button to start payment process.
  2. When customer taps a button to start payment process your application calls "Prepare checkout" endpoint that returns you a unique checkout ID and URL address to redirect your customer to for entering card information.
  3. If you are developing a web based application you need to redirect your customer to URL received in step 2. Alternatively if you are developing a mobile application you need to open a web view component and navigate it to URL received in step 2.
  4. Once customer completes payment process our server submits payment status to your server.
  5. Depending on payment status you either provide service or show error message and allow customer to start over from step 1 to try payment again.

Available API endpoints

In this section we describe all the available API endpoints for your application to consume.

Prepare checkout

This is the first endpoint to call when initiating a payment process as described above.
API URL is: https://test.cardgw.dinarpay.az/processing/register-checkout

When invoking this endpoint your application needs to set value of HTTP header Content-Type to application/json and provide json body of request containing following fields:

Field name Type Description Example
merchant_uid uuid Your merchant ID 87dc16fb-59b9-450f-9d7c-5464be5d81fd
merchant_trans_id string (1, 250) Unique transaction ID 12345
amount decimal (10, 2) Amount to charge customer (with 2 decimal places) 5.50
currency string (3) 3 character currency code AZN
lang string (2) User interface language. One of AZ, RU, EN AZ
description string (3, 50) Description of purchase Taxi ride
operation string One of AUTH or CHECKOUT . AUTH request puts hold on amount and later your must issue approve request to confirm payment or refund request to release hold amout. On the other hand CHECKOUT request does payment in single operation CHECKOUT
return_url URL Where to redirect customer after purchase when they tap Return button or if they want to cancel purchase Web example: https://mywebsite.com/purchase?id=12345
Mobile app example: myapp://payment?id=12345 (Note: in mobile app you need to register a handler for URL prefix)
callback_url URL Your API endpoint to be called by our server about purchase status https://api.mywebsite.com/purchase-result
timestamp Datetime in RFC3339 format Current time on your server. 2022-08-04T08:31:11Z
signature string Signature calculated based on request data and a Signing key provided to you. See below for details 9dead0e0cf7c1a ac27b2df961e5a75186eeec535 3c3f32bb302a391a9fd1067d

For example:

{
  "merchant_uid": "87dc16fb-59b9-450f-9d7c-5464be5d80fd",
  "merchant_trans_id": "tr-1",
  "amount": "9.00",
  "currency": "AZN",
  "lang": "AZ",
  "description": "Taxi ride",
  "operation": "CHECKOUT",
  "return_url": "https://mywebsite.com/payment?id=tr-1",
  "callback_url": "https://mywebsite.com/api/payment-result",
  "timestamp": "2022-08-04T08:31:11Z",
  "signature": "15ed08446d9fde5f420933c5b2d567936ab9d2f16af194bfbf813cccc3b29714"
}

Value of signature parameter is calculated as described below:

  1. Concatenate values of following fields: CONCAT( merchant_uid , merchant_trans_id , amount, currency , lang , description , operation , return_url , callback_url , timestamp )
  2. Calculate SHA256 HMAC in HEX format of the string calculated in step 1.

For example, if we take above JSON , value of CONCAT will be equal to: 87dc16fb-59b9-450f-9d7c-5464be5d80fdtr-19.00AZNAZTaxi rideCHECKOUThttps://mywebsite.com/payment?id=tr-1https://mywebsite.com/api/payment-result2022-08-04T08:31:11Z
Now you need to calculate SHA256 HMAC from this string using a Signing key provided to you to get value of signature field.
You can search for a code that calculates SHA256 HMAC for your favorite programming language at this URL: https://github.com/danharper/hmac-examples . Look for a version that says: to lowercase hexits

Possible response codes

HTTP Status code : 200
Example :

{
  "id": 1272234,
  "duplicate": false,
  "checkout_form": "https://test.cardgw.dinarpay.az/processing/checkout-form/KeiTriZiLfspFBBleRy28-Je3tNpCt3XF1mLbTcLHPXQEjyb3NvpyQoa34bFM2Y_JeguQ31BDJtq2kch6qyioA=="
}

Comments : You will receive this response in case of success.


HTTP Status code : 200
Example :

{
  "id": 1272234,
  "duplicate": true,
  "checkout_form": "https://test.cardgw.dinarpay.az/processing/checkout-form/KeiTriZiLfspFBBleRy28-Je3tNpCt3XF1mLbTcLHPXQEjyb3NvpyQoa34bFM2Y_JeguQ31BDJtq2kch6qyioA=="
}

Comments : You will receive this response if you submitted same merchant_trans_id more than once.


HTTP Status code : 422
Example :

{
  "code": "wrong_signature",
  "details": {
    "message": "signature must be calculated correctly",
    "hint": {
      "string_to_sign": "87dc16fb-59b9-450f-9d7c-5464be5d80fdtr-19AZNAZTaxi ridehttps://mywebsite.com/payment?id=tr-1https://mywebsite.com/api/payment-result2022-08-04T08:31:11Z",
      "how_to": [
        "https://github.com/danharper/hmac-examples"
      ]
    }
  }
}

Comments : code=wrong_signature . When value of signature field is not calculated correctly. Please, note that hint section is only returned on development server.


HTTP Status code : 422
Example :

{
  "code": "field_validation_failure",
  "details": {
    "currency": "must be a valid value"
  }
}

Comments : code=field_validation_failure . When value of some field does not pass validation.


HTTP Status code : 400
Example :

{
  "code": "parsing_error",
  "details": {
    "message": "could not parse"
  }
}

Comments : code=parsing_error . When there is a problem parsing submitted JSON or one of its fields.


Payment confirmation

If you issued register checkout request witth "operation": "AUTH" , later you need to issue either approve or refund request to confirm or release hold amount.
approve request is described here:

Fields:

Field name Type Description Example
checkout_id integer ID of checkout received from Register checkout API 1272231
timestamp Datetime in RFC3339 format Current time on your server. 2022-08-04T08:31:11Z
signature string Signature calculated based on request data and a Signing key provided to you. See below for details ca0f7d0a5ac37130709f585d1bd 85569e42963aa2cb1cfb8c60f56caf225c8d4

For example:

{
  "checkout_id": 1272231,
  "timestamp": "2022-08-04T08:31:11Z",
  "signature": "ca0f7d0a5ac37130709f585d1bd85569e42963aa2cb1cfb8c60f56caf225c8d4"
}

Signature is calculated as described in Register checkout section using concatenation of following fields: CONCAT( checkout_id , timestamp )

If approval is not successfull this endpoint will return an error in JSON format with HTTP Status Code = 422 and code=cannot_approve

Otherwise it will return JSON response with HTTP Status Code = 200 in following format:

{
  "status": "success"
}

Value of status field can be one of the following:
- success : Successfull approval
- duplicate : Already approved by a previous request
- declined : Approval declined
- fault : Approval failed
- unknown : Contact support

Tokenization

Sometimes you want to remember the details of used cards of customer so that next time it is easy to pay buy not entering card number again. In this case you need to use tokenization feature. Below is how it works:

For example. On first request:

{
  "merchant_uid": "87dc16fb-59b9-450f-9d7c-5464be5d80fd",
  "merchant_trans_id": "tr-1",
  "amount": "9.00",
  "currency": "AZN",
  "lang": "AZ",
  "description": "Taxi ride",
  "operation": "CHECKOUT",
  "return_url": "https://mywebsite.com/payment?id=tr-1",
  "callback_url": "https://mywebsite.com/api/payment-result",
  "timestamp": "2022-08-04T08:31:11Z",
  "signature": "4ecfb1b1483f633ac4ccc00e438c9a9f1ee33b1bf880143d0fb04ed42163addb",

  "register_card": "1"
}

After successfull payment, on next request now you submit token for the card customer wants to use. For example:

{
  "merchant_uid": "87dc16fb-59b9-450f-9d7c-5464be5d80fd",
  "merchant_trans_id": "tr-1",
  "amount": "9.00",
  "currency": "AZN",
  "lang": "AZ",
  "description": "Taxi ride",
  "operation": "CHECKOUT",
  "return_url": "https://mywebsite.com/payment?id=tr-1",
  "callback_url": "https://mywebsite.com/api/payment-result",
  "timestamp": "2022-08-04T08:31:11Z",
  "signature": "4ecfb1b1483f633ac4ccc00e438c9a9f1ee33b1bf880143d0fb04ed42163addb",

  "token": "k328e1BiCxmTj2BQHGLEkmiLoMRx_8hEVl3-pTFN7kI="
}

Please, note that register_card and token parameters DO NOT participate in signature calculation.
If you submit incorrect token or token was deleted from gateway side you will receive an error with HTTP Status = 422 and code=wrong_token . In this case you must delete saved card/token combination from your database.

Direct payment with token

Once you have a token, your back-end application can also make direct payments without user interaction. For this, include additional parameter called direct_payment: "1" together with a token. For example:

{
  "merchant_uid": "87dc16fb-59b9-450f-9d7c-5464be5d80fd",
  "merchant_trans_id": "tr-1",
  "amount": "9.00",
  "currency": "AZN",
  "lang": "AZ",
  "description": "Taxi ride",
  "operation": "CHECKOUT",
  "return_url": "https://mywebsite.com/payment?id=tr-1",
  "callback_url": "https://mywebsite.com/api/payment-result",
  "timestamp": "2022-08-04T08:31:11Z",
  "signature": "4ecfb1b1483f633ac4ccc00e438c9a9f1ee33b1bf880143d0fb04ed42163addb",

  "token": "k328e1BiCxmTj2BQHGLEkmiLoMRx_8hEVl3-pTFN7kI=",
  "direct_payment": "1"
}

On successfull payment, you will receive HTTP Status = 200 and exactly same response as you receive during callback as explained below in a section called "Payment status callback".

Note: In order to use this feature you need to ask for a permission to be configured on gateway side.

If direct payment request fails for some reason (for example, insufficient balance etc), then used token gets locked, and your application must notify customer, and collect payment using user interface. After one successfull payment by customer with this token using user interface, token will get unlocked and you can again send direct payment requests with that token. When trying to make direct payment with a locked token you will receive an error with HTTP Status = 422 and code=tocken_locked .

Note: Be very careful with this feature, do not make double charges etc.

Payment status callback

Upon successfull or failed payment by customer our server sends a callback to URL provided in callback_url parameter of Register checkout request. Callback is sent in JSON format using HTTP POST method. Example:

{
  "id": 1272231,
  "merchant_trans_id": "2",
  "amount": "9",
  "currency": "AZN",
  "lang": "AZ",
  "description": "Some description",
  "return_url": "http://www.dinarpay.az",
  "callback_url": "https://www.google.com",
  "status_id": 2,
  "status_updated_at": "2022-08-05T11:59:26+04:00",
  "response_code_id": 0,
  "response_code_desc": "Approved",
  "operation": "CHECKOUT",
  "refunded_at": "2022-08-05T12:05:51.720637+04:00",
  "token": null,
  "card": "4127XXXXXXXX9541",
  "card_exp": "25/04",
  "signature": "6b2147cc8b0a206699b333bb9ea90de0485eed864c9f0fca3040e14373a077b0"
}

In above request:

Signature is calculated as described in Prepare checkout section above using following fields: CONCAT( id , merchant_trans_id , amount , currency , lang , description , operation , return_url , callback_url , status_id )

Possible values of status_id field

Please, note that if refunded_at field contains non-null datetime value, it means payment is refunded (or hold released) (status_id remains as 2 or 3 ).

Possible values of response_code_id field

Checkout status

You can request status of a checkout by its id using following endpoint:
- URL: https://test.cardgw.dinarpay.az/processing/checkout-status
- HTTP Method: POST
- Value of Content-Type HTTP header: application/json

Fields:

Field name Type Description Example
checkout_id integer ID of checkout received from Register checkout API 1272231
timestamp Datetime in RFC3339 format Current time on your server. 2022-08-04T08:31:11Z
signature string Signature calculated based on request data and a Signing key provided to you. See below for details ca0f7d0a5ac37130709f585d1bd 85569e42963aa2cb1cfb8c60f56caf225c8d4

For example:

{
  "checkout_id": 1272231,
  "timestamp": "2022-08-04T08:31:11Z",
  "signature": "ca0f7d0a5ac37130709f585d1bd85569e42963aa2cb1cfb8c60f56caf225c8d4"
}

Signature is calculated as described in Register checkout section using concatenation of following fields: CONCAT( checkout_id , timestamp )

Response from this API is exactly same as described in section "Payment status callback".

Refund

In order to refund any successfull payment or release hold amount you need to submit following request:
- URL: https://test.cardgw.dinarpay.az/processing/refund
- HTTP Method: POST
- Value of Content-Type HTTP header: application/json

Fields:

Field name Type Description Example
checkout_id integer ID of checkout received from Register checkout API 1272231
timestamp Datetime in RFC3339 format Current time on your server. 2022-08-04T08:31:11Z
signature string Signature calculated based on request data and a Signing key provided to you. See below for details ca0f7d0a5ac37130709f585d1bd 85569e42963aa2cb1cfb8c60f56caf225c8d4

For example:

{
  "checkout_id": 1272231,
  "timestamp": "2022-08-04T08:31:11Z",
  "signature": "ca0f7d0a5ac37130709f585d1bd85569e42963aa2cb1cfb8c60f56caf225c8d4"
}

Signature is calculated as described in Register checkout section using concatenation of following fields: CONCAT( checkout_id , timestamp )

If refund is not successfull this endpoint will return an error in JSON format with HTTP Status Code = 422 and code=cannot_refund

Otherwise it will return JSON response with HTTP Status Code = 200 in following format:

{
  "status": "success"
}

Value of status field can be one of the following:
- success : Successfull refund
- duplicate : Already refunded by a previous request
- declined : Refund declined
- fault : Refund failed
- unknown : Contact support