Creating an invoice
General recommendations on working with invoice API
Make sure that your shop is activated and set up for working with API: shop ID is received, interaction URL is entered, secret key is generated and whitelisted IP addresses are indicated.
Payways for invoices can be found in the personal profile (shop settings, section "Payment methods").
The invoicing process goes as follows:
-
Preliminary calculation and additional data request
tryis sent; -
When receiving
result==ok, presence of additional data is checked inadd_ons_config, if found, it is necessary to pass this additional data in the invoice request. When receivingresult==error, it is necessary to analyze an error inmessage; -
After checking
try, the invoice request is sent, with indication of mandatory parameters and additional data inadd_ons_config(if mandatory for the chosen payway); -
The response returns information with an invoice and data to be sent by the specified method to the specified URL, to make the payment;
-
After the payment is made, the Qostiq system will send a notification to the shop interaction URL with information about the payment.
Preliminary calculation of the invoice [/invoice/try]
This method is not mandatory for invoicing. It returns additional data to create an invoice and preliminary fee calculation.
URL: https://core.qostiq.com/invoice/try
Method: POST
Mandatory parameters: amount, currency, payway, shop_id, shop_order_id, sign
Example of request:
{
"currency": "980",
"sign": "912b985f18959620bb981485132016b58fc344361a51a24eda27687613141f7f",
"payway": "card_uah",
"amount": "12.34",
"shop_id": 112,
"shop_order_id": 4128
}
| Parameter | Description | Format | Example |
|---|---|---|---|
shop_id | shop ID in Qostiq system | Integer | 5 |
amount | invoice amount | Number (no more than 2 characters after the dot) | 1, 1.0, 1.00 or "1.00" |
currency | invoice currency | Integer | 980 — UA Hryvnia, 840 — US Dollar, 978 — Euro |
payway | payway, for which a preliminary calculation is conducted | String | "card_uah" (can be checked with the manager or in the personal profile) |
sign | signature | String | "a7f5bcbb774cea9d9886cbb3ce2f8731359e356a7d759437b4e9e31da1152109" |
shop_order_id | bill ID on the side of your service | String | "h8fj38dkh-hf8k-4f8d-9c8c-jd8dh38dksn92" |
description | bill description (optional) | String | "test bill" |
Example of response:
{
"data": {
"add_ons_config": {},
"manual": {},
"payer_price": 10.0,
"paymethod_id": 3,
"paymethod_name": "Visa/MasterCard",
"ps_currency": 980
},
"error_code": 0,
"message": "Ok",
"result": true
}
or
{
"data": {
"add_ons_config": {
"email": {
"comment": {
"en": "Enter your e-mail",
"ru": "Введите Ваш e-mail"
},
"example": "mail@example.com",
"label": {
"en": "E-mail",
"ru": "E-mail:"
},
"regex": "^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$"
}
},
"manual": {},
"payer_price": 10.0,
"paymethod_id": 4,
"paymethod_name": "Visa/MasterCard",
"ps_currency": 980
},
"error_code": 0,
"message": "Ok",
"result": true
}
Example of error:
{
"data": null,
"error_code": 4,
"message": "Payer price amount is too small, min: 1.0",
"result": false
}
Preliminary calculation of the invoice [POST]
- Request (application/json)
{
"currency": "980",
"sign": "912b985f18959620bb981485132016b58fc344361a51a24eda27687613141f7f",
"payway": "card_uah",
"amount": "12.34",
"shop_id": 112,
"shop_order_id": 4128
}
- Response 200 ()
{
"data": {
"add_ons_config": {},
"manual": {},
"payer_price": 12.34,
"paymethod_id": 3,
"paymethod_name": "Visa/MasterCard",
"ps_currency": 980
},
"error_code": 0,
"message": "Ok",
"result": true
}
Creating an invoice [/invoice/create]
Invoice. This method is used to create payments in other payment systems.
Prod URL: https://core.qostiq.com/invoice/create
Test URL: https://core.test-qostiq.com/invoice/create
Method: POST
Mandatory parameters: amount, currency, payway, shop_id, shop_order_id, sign
Uniqueness of shop_order_id is checked depending on the shop settings, we recommend to use this feature and pass the unique value to your shop to avoid duplicate billing.
The request can pass additional parameters, for example, description – bill description, or phone – phone number for payment through mobile commerce.
Example of request:
{
"currency": "980",
"payway": "card_uah",
"amount": "12.34",
"shop_id": 112,
"shop_order_id": 4129,
"description": "Test invoice",
"sign": "8fb2cafda4da9de1f1c00787dd5d22e6a8094256d0e47b633783f652624b81d4"
}
| Parameter | Description | Format | Example |
|---|---|---|---|
shop_id | shop ID in Qostiq system | Integer | 5 |
amount | invoice amount | Number (no more than 2 characters after the dot) | 1, 1.0, 1.00 or "1.00" |
currency | invoice currency | Integer | 980 — UA Hryvnia, 840 — US Dollar, 978 — Euro |
payway | payway for which the invoice is created | String | "card_uah" (can be checked with the manager or in the personal profile) |
sign | signature | String | "a7f5bcbb774cea9d9886cbb3ce2f8731359e356a7d759437b4e9e31da1152109" |
shop_order_id | bill ID on the side of your service | String | "h8fj38dkh-hf8k-4f8d-9c8c-jd8dh38dksn92" |
Also, additional parameters can be passed in the request; they do not participate in signature formation.
| Parameter | Description | Format | Example |
|---|---|---|---|
description | bill description (optional) | String | "test bill" |
failed_url | URL to which the payer will be redirected after unsuccessful payment | String | "https://qostiq.com/failed" |
success_url | URL to which the payer will be redirected after successful payment | String | "https://qostiq.com/success" |
callback_url | URL for notification of successful payment | String | "https://qostiq.com/callback_url_kvt" |
callback_rejected_url | URL for notification of unsuccessful payment | String | "https://qostiq.com/callback_rejected_url_kvt" |
Important! Success URL, Fail URL, URL notifications, URL reject notifications listed in the shop settings have a higher priority than those in the request, so they have to be deleted from the shop settings.
Example of response:
{
"data": {
"data": {
"session_id": "07bdd98b1c264fc4bd41f875419907a2"
},
"id": 1218989,
"method": "GET",
"url": "https://card.qostiq.com/en/payform/07bdd98b1c264fc4bd41f875419907a2"
},
"error_code": 0,
"message": "Ok",
"result": true
}
Where,
| Parameter | Description |
|---|---|
data | source for sending parameters from data using the method |
method | method for sending data to source, format: POST, GET |
url | URL to which data must be sent using method |
id | unique invoice identifier in Qostiq system |
After receiving the response to the invoice creation request, the merchant must create an HTML page containing a form with auto-fill and automatic data submission. This is required for the client to be correctly redirected to the payment page.
The response body contains parameters that must be sent via POST to the specified URL. It is recommended to use an HTML form with auto-submit to ensure reliable and secure data transmission.
Note: A simple redirect via the link from the response does not initiate payment. Using an HTML form is mandatory, as data must be transmitted via POST.
Important: Behavior when paying with cryptocurrency
If the merchant issues an invoice in fiat and the client pays in cryptocurrency, at the time of final settlement there may be a discrepancy between the original amount and the actually credited amount.
Always verify shop_refund, shop_amount and client_price in notifications. When is_overwritten:true, amounts will differ from the originals.
When can amounts change?
| Scenario | Example | How it manifests |
|---|---|---|
Exchange rate change | Client pays BTC, rate changed during confirmation | shop_amount ≠ original amount |
Overpayment | Client sent more cryptocurrency than required | client_price > calculated value |
Underpayment | Client sent insufficient cryptocurrency | client_price < calculated value |
Example of error when creating invoice:
{
"data": null,
"message": "Payway (id=3) is not found",
"error_code": 1,
"result": false
}
Where
| Parameter | Description |
|---|---|
message | error description |
error_code | error code |
Create invoice [POST]
- Request (application/json)
{
"currency": "980",
"payway": "card_uah",
"amount": "12.34",
"shop_id": 112,
"shop_order_id": 4129,
"description": "Test invoice",
"sign": "8fb2cafda4da9de1f1c00787dd5d22e6a8094256d0e47b633783f652624b81d4"
}
- Response 200 ()
{
"data": {
"data": {
"session_id": "07bdd98b1c264fc4bd41f875419907a2"
},
"id": 2403182,
"method": "GET",
"url": "https://card.qostiq.com/en/payform/07bdd98b1c264fc4bd41f875419907a2"
},
"error_code": 0,
"message": "Ok",
"result": true
}
Possible errors [/invoice/errors]
Example of error in console: "error_code": 10
| Error code | Description |
|---|---|
| 1 | PaywayNotFound |
| 2 | PaywayNotUsed |
| 3 | PaywayNotAvailable |
| 4 | AmountTooSmall |
| 5 | AmountTooLarge |
| 6 | OperationNotUnique |
| 7 | OperationNotFound |
| 8 | OperationIsProcessing |
| 9 | InsufficientBalance |
| 10 | IncorrectRequestParam |
| 11 | ShopNotFound |
| 12 | ShopNotActive |
| 13 | AccountNotFound |
| 14 | IncorrectAccountStatus |
| 15 | RequestIpDenied |
| 16 | InvalidCurrencyExchange |
| 17 | InvalidShopContract |
| 18 | IncorrectAccountType |
| 19 | ShopAggregatorRequire |
| 20 | InvalidProject |
| 21 | ProjectNotActive |
| 100 | IncorrectOperationStatus |
| 2000 | Other error |
Example of receiving error [POST]
- Request (application/json)
{
"amount": "120000.00",
"currency": 980,
"payway": "card_uah",
"shop_id": 112,
"shop_order_id": 4129,
"description": "Test invoice",
"sign": "8fb2cafda4da9de1f1c00787dd5d22e6a8094256d0e47b633783f652624b81d4"
}
- Response 200 ()
{
"data": null,
"error_code": 5,
"message": "Payer price amount is too large, max: 100000.0",
"result": false
}
Offline payment methods [/invoice/offline]
When creating an invoice for payment via offline systems, the response to the invoice request will return method = offline and url = offline, and data will contain information for the payer in HTML format (information may be provided in several languages). In this case, the client does not need to be redirected anywhere.
Offline methods include mobile commerce and terminal payments.
Example of offline payment request [POST]
- Request (application/json)
{
"amount": 100,
"currency": 980,
"payway": "vodafone_uah",
"phone": "9827908437",
"shop_id": "112",
"shop_order_id": "Invoice#61586603",
"sign": "56789cc6d34ebc6e064daf416911baa9ae3aac9ca269e3566b13236cc554e1fb"
}
- Response 200 ()
{
"data": {
"data": {
"en": "<h4>Dear client!</h4> <p>Your request has been successfully accepted. An SMS with detailed instructions to complete the payment has been sent to you.</p>",
"ru": "<h4>Уважаемый клиент!</h4> <p>Ваш запрос успешно принят. Вам отправлено СМС с подробной инструкцией для завершения оплаты.</p>"
},
"id": 132411408,
"method": "OFFLINE",
"url": "OFFLINE"
},
"error_code": 0,
"message": "Ok",
"result": true
}
Payment notification [/invoice/callback]
Callback - This function is applied only for Bill and Invoice methods.
After the invoice is paid, the Qostiq system sends a notification to the shop interaction URL specified in the settings.
Notifications are sent from IP addresses:
- 34.90.243.164
- 34.147.48.238
- 34.90.176.128
- 34.90.34.134
- 35.242.192.50
It is mandatory to verify the values from the notification against the invoice values and check the signature in the notification.
Important! Always verify operation amounts — shop_refund, shop_amount, client_price upon receiving the notification.
When the notification contains "is_overwritten":true, the operation amounts will have been changed.
To find out if the amount change feature is enabled for a payway — contact your manager or support.
Method: POST, Content-Type=application/x-www-form-urlencoded
Example of notification:
{
"client_price": 5.0,
"created": "2019-10-30 12:27:48",
"description": null,
"is_overwritten": false,
"lang": "ru",
"payment_id": 107120419,
"payway": "card_uah",
"processed": "2019-10-30 12:28:47",
"ps_currency": 980,
"ps_data": {
"ps_payer_account": "537541XXXXXX7424"
},
"shop_amount": 5.0,
"shop_currency": 980,
"shop_id": 2104,
"shop_order_id": "test_invoice",
"shop_refund": 4.8,
"sign": "f50c81db95829fdaf06263ef77a299eea7b3cf01efb04c053f37124cb21692db",
"status": "success"
}
Where,
| Parameter | Description |
|---|---|
client_price | amount paid by the client, in payment system currency |
created | date and time of invoice creation |
processed | date and time of invoice status change (payment or rejection) |
description | invoice description |
is_overwritten | whether the original payment amount was changed. When true, the payment amount was changed and differs from the original |
payment_id | unique invoice ID in Qostiq system |
payway | payway in Qostiq system through which the user paid |
ps_currency | currency of the payway through which the user paid |
ps_data | additional data from the payment system, e.g. payer account |
shop_amount | invoice amount in invoice currency |
shop_currency | invoice currency |
shop_id | unique shop ID on whose behalf the payment is made |
shop_order_id | invoice number, identifier passed by the shop |
shop_refund | amount credited to the shop's balance, in invoice currency |
status | invoice status: success — paid and credited, rejected — rejected by client or PS |
sign | signature |
test_add_on | custom parameter passed by the shop when creating the invoice |
When receiving a notification for a rejected payment, the rejection reason is added in rejected_reason.
Example parameter in rejected-callback:
"ps_data": "{\"ps_payer_account\": \"533669XXXXXX8888\", \"rejected_reason\": \"Na schete karty nedostatochno sredstv dlja vypolnenija operatsii\"}""status": "rejected"
The signature is formed by the same algorithm as when creating an invoice, but all parameters whose value is not null or empty string participate in the signature formation.
Upon correct receipt and processing of the notification, return http status 200 and message body OK. Otherwise notifications will be resent with increasing intervals, 25 attempts total, the last one after one day.
Example string for signature generation
5.0:2019-10-30 12:27:48:false:ru:107120419:card_uah:2019-10-30 12:28:47:980:{"ps_payer_account": "537541XXXXXX7424"}:5.0:980:2104:test_invoice:4.8:successTestkey1
Example of successful payment notification [POST]
- Request (application/x-www-form-urlencoded)
{
"client_price": 2500,
"created": "2020-01-19 15:38:59",
"description": null,
"is_overwritten": false,
"payment_id": 132803748,
"payway": "card_uah",
"processed": "2020-01-19 15:39:17",
"ps_currency": 980,
"ps_data": "{\"paymentPayerCode\": \"410014233707050\", \"ps_payer_account\": \"410014233707050\"}",
"shop_amount": 2500,
"shop_currency": 980,
"shop_id": 112,
"shop_order_id": "2750",
"shop_refund": 2300,
"sign": "490001f775c752c08a5a9de2337b0f26fcf6287c4a780eb70edce38386f5ffd8",
"status": "success"
}
- Response 200 ()
{
"response_data": "OK",
"shop": 112,
"transfer": null,
"withdraw": null
}
Example of unsuccessful payment notification [POST]
- Request (application/x-www-form-urlencoded)
{
"client_price": 1500,
"created": "2019-12-23 15:26:36",
"description": null,
"payment_id": 123166089,
"payway": "card_uah",
"processed": "2019-12-23 15:26:41",
"ps_currency": 980,
"ps_data": "{\"ps_payer_account\": \"533669XXXXXX8843\", \"rejected_reason\": \"Prevyshen limit po schetu karty\"}",
"shop_amount": 1500,
"shop_currency": 980,
"shop_id": 112,
"shop_order_id": "37962464",
"shop_refund": 1440,
"sign": "3f00f3b370ffce41d9de6a019e2c7a331b4f472e25ac26fef90f0bba49b7101d",
"status": "rejected"
}
- Response 200 ()
{
"response_data": "OK",
"shop": 112,
"transfer": null,
"withdraw": null
}
Status request [/invoice_check]
URL: https://core.qostiq.com/invoice/check
Method: POST
Mandatory parameters: now, shop_id, shop_order_id
Example of request:
{
"now": "2018-06-15 09:58:01.01",
"shop_id": 1,
"shop_order_id": "123456789",
"sign": "32b2c32caa8adecf89c6dfa72ffca3a0506f33febfe3aaab090cdbfbd0e8b953"
}
Important! Always verify operation amounts — shop_refund, shop_amount, client_price from the received response.
When the parameter "is_overwritten":true is received, the operation amounts will have been changed.
To find out if the amount change feature is enabled for a payway — contact your manager or support.
| Parameter | Description | Format | Example |
|---|---|---|---|
now | request time | String | "2018-06-15 09:58:01.01" |
shop_id | shop ID in Qostiq system | Integer | 1 |
shop_order_id | bill ID on the side of your service | String | "123456789" |
sign | signature | String | "32b2c32caa8adecf89c6dfa72ffca3a0506f33febfe3aaab090cdbfbd0e8b953" |
Example of response:
{
"data": {
"client_price": 10.2,
"created": "2018-06-18 17:22:49",
"description": "Test+invoice",
"is_overwritten": false,
"is_unique": false,
"payment_id": 11639480,
"payway": "card_uah",
"processed": null,
"ps_currency": 980,
"ps_data": null,
"shop_amount": 10.0,
"shop_currency": 980,
"shop_id": 3,
"shop_order_id": "101",
"shop_refund": 9.6,
"status": 2,
"updated": null
},
"error_code": 0,
"message": "Ok",
"result": true
}
Where,
| Parameter | Description |
|---|---|
client_price | payment amount |
created | date of creation |
description | invoice name |
is_overwritten | whether the original payment amount was changed. When true, the payment amount was changed and differs from the original |
is_unique | payment ID uniqueness |
payment_id | payment identifier |
payway | payway |
processed | date of payment processing |
ps_currency | currency of the invoice |
ps_data | additional data from the payment system, e.g. payer account |
shop_amount | invoice amount from the shop |
shop_currency | invoice currency credited to the shop |
shop_id | shop ID in Qostiq system |
shop_order_id | invoice number on the shop's side |
shop_refund | amount credited to the shop's balance, in invoice currency |
status | invoice status: Created=1, Waiting=2, PsCreatingError=3, Success=4, CallbackError=5, Rejected=6, Refunded=7, Hold=8, IntRefunded=9, Captured=10 |
updated | date and time of last payment status change |
Warning! Status request must be done no more often than once every 10 seconds.
If shop_order_id is not unique in the Invoice operations within the shop, the response will include "is_unique":false and the method will return the info about the last created Invoice.
Request invoice status [POST]
- Request (application/json)
{
"now": "2018-06-15 09:58:01.01",
"shop_id": 1,
"shop_order_id": "123456789",
"sign": "32b2c32caa8adecf89c6dfa72ffca3a0506f33febfe3aaab090cdbfbd0e8b953"
}
- Response 200 ()
{
"data": {
"client_price": 10.2,
"created": "2018-06-18 17:22:49",
"description": "Test+invoice",
"is_overwritten": false,
"is_unique": false,
"payment_id": 11639480,
"payway": "card_uah",
"processed": null,
"ps_currency": 980,
"ps_data": null,
"shop_amount": 10.0,
"shop_currency": 980,
"shop_id": 3,
"shop_order_id": "101",
"shop_refund": 9.6,
"status": 2,
"updated": null
},
"error_code": 0,
"message": "Ok",
"result": true
}
Invoice operation statuses [/invoice/allstatuses]
If the payment is successfully created, the response will return a unique payment ID and its status. Status can be final or non-final; for non-final status, status requests must be made until the final status is received.
| Status | Value | Description | Final? |
|---|---|---|---|
| 1 | Created | Payment request created | No |
| 2 | Waiting | Payment is pending user action | No |
| 3 | PsCreatingError | Payment creation error on the payment system side | No |
| 4 | Success | Payment successfully completed | Yes |
| 5 | CallbackError | Error receiving payment notification from the payment system | No |
| 6 | Rejected | Rejected by the payment system | Yes |
| 7 | Refunded | Invoice amount returned to payer by payment system | Yes |
| 8 | Hold | Invoice payment funds held (on hold) by payment system | No |
| 9 | IntRefunded | Invoice amount returned to payer by Qostiq system | Yes |
| 10 | Captured | Invoice payment funds blocked by payment system | No |
Warning! Status Rejected can be changed to Success.
Request invoice status [POST]
- Request (application/json)
{
"now": "2018-06-15 09:58:01.01",
"shop_id": 1,
"shop_order_id": "123456789",
"sign": "32b2c32caa8adecf89c6dfa72ffca3a0506f33febfe3aaab090cdbfbd0e8b953"
}
- Response 200 ()
{
"data": {
"client_price": 10.2,
"created": "2018-06-18 17:22:49",
"description": "Test+invoice",
"is_unique": false,
"payment_id": 11639480,
"payway": "card_uah",
"processed": null,
"ps_currency": 980,
"ps_data": null,
"shop_amount": 10.0,
"shop_currency": 980,
"shop_id": 3,
"shop_order_id": "101",
"shop_refund": 9.6,
"status": 2,
"updated": null
},
"error_code": 0,
"message": "Ok",
"result": true
}