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:
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.
In this section we describe all the available API endpoints for your application to consume.
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:
merchant_uid
,
merchant_trans_id
,
amount, currency
,
lang
,
description
,
operation
,
return_url
,
callback_url
,
timestamp
)
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
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.
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:
https://test.cardgw.dinarpay.az/processing/approve
POST
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 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
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:
register_card: 1
.
token
parameter to Register checkout request.
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.
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.
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:
id
: Unique ID of checkout that you received from Register checkout API.
merchant_trans_id
: Same value as submitted to Register checkout API.
amount
: Same value as submitted to Register checkout API.
currency
: Same value as submitted to Register checkout API.
lang
: Same value as submitted to Register checkout API.
description
: Same value as submitted to Register checkout API.
return_url
: Same value as submitted to Register checkout API.
callback_url
: Same value as submitted to Register checkout API.
status_id
: Payment status. See below for possible values.
status_updated_at
: Datetime that payment status was received in RFC3339 format.
response_code_id
: Additional information about payment status. Main field is
status_id
. This field is only for additional information.
response_code_desc
: Additional information about payment status. Main field is
status_id
. This field is only for additional information.
operation
: Same value as submitted to Register checkout API.
refunded_at
: Contains datetime in RFC3339 format if payment was refunded. Otherwise it contains
null
. During initial payment status callback it is always
null
.
token
: If Register checkout request contained parameter
register_card: 1
or
token: ...
and payment was successfull, then this parameter will contain token generated by payment gateway to be used in tokenized payments as described above on Tokenization section.
card
: Masked card number
card_exp
: Card expiry date
signature
: Signature of 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
)
status_id
field
1
: Pending
2
: Successfull authorization (i.e. hold on amount)
3
: Successfull payment (i.e. payment completed succesfully)
4
: Failed payment
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
).
response_code_id
field
0
: "Approved"
1
: "Unknown"
2
: "System error"
3
: "Duplicate transaction"
4
: "Expired transaction"
5
: "Authentication failed"
6
: "Error in CVC2 or CVC2 ""desc""ription fields"
7
: "Access denied"
8
: "Terminal is locked, please try again"
9
: "Invalid Retrieval reference number"
10
: "Error in merchant terminal field"
11
: "Error in currency field"
12
: "Error in amount field"
13
: "Error in card expiration date field"
14
: "Error in card number field"
15
: "Invalid response"
16
: "Connect failed"
17
: "Server is not responding"
18
: "No or Invalid response received"
19
: "Bad CGI request"
20
: "Mandatory field is empty"
22
: "Call your bank"
23
: "Call your bank"
24
: "Invalid merchant"
25
: "Your card is restricted"
26
: "Transaction declined"
27
: "Your card is disabled"
28
: "Partially approved"
29
: "Invalid transaction"
30
: "Invalid amount"
31
: "No such card"
32
: "No such card/issuer"
33
: "Invalid response"
34
: "No action taken"
35
: "No such record"
36
: "Format error"
37
: "Completed partially"
38
: "Expired card"
39
: "Suspected fraud"
40
: "Restricted card"
41
: "Call your bank"
42
: "Lost card"
43
: "Stolen card"
44
: "Not sufficient funds"
45
: "No savings account"
46
: "Expired card"
47
: "Incorrect PIN"
48
: "No card record"
49
: "Not permitted to client"
50
: "Not permitted to merchant"
51
: "Suspected fraud"
52
: "Exceeds amount limit"
53
: "Restricted card"
54
: "Security violation"
55
: "Exceeds frequency limit"
56
: "Acceptor call acquirer"
57
: "Reply received too late"
58
: "Wrong Reference No."
59
: "Reserved"
60
: "Already reversed"
61
: "Network error"
62
: "Foreign network error"
63
: "Time-out at issuer"
64
: "Transaction failed"
65
: "Pre-authorization timed out"
66
: "Account verification required"
67
: "Reserved"
68
: "Cryptographic failure"
69
: "Authentication failure"
70
: "Issuer unavailable"
71
: "Router unavailable"
72
: "Violation of law"
73
: "Reconcile error"
74
: "System malfunction"
75
: "Aborted"
76
: "Not found"
77
: "User on card entry page"
78
: "User on 3DS page"
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".
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