Download OpenAPI specification:
Slovenčina · English
Welcome to the documentation of the VIAMO PayGate REST API (PAPI). This API handles the communication between a merchant and VIAMO.
Objects (services) are split into groups — a merchant may be entitled to only some of them:
GET /payments/{id} (the issuer has up to 72 hours to authorise it)The test interface is available at https://api.viamo.info/paygate.
The production interface is available at https://api.viamo.sk/paygate.
number
and represents the number of seconds since the start of the Unix epochstring in ISO 8601
format YYYY-MM-DD (e.g. 2029-03-15). The day is always inclusive — a mandate with
expiresOn 2029-03-15 is valid for the whole of 15 March 2029number (e.g. €2.43 is 243)object field telling what type of object it is
(e.g. payment, recurring)list object is returned with the fields object,
url, hasMore (true if more objects match the criteria than were returned) and data
(at most 50 objects)Content-Type: application/json) or as a form
(Content-Type: application/x-www-form-urlencoded); the response is always JSONThe merchant authenticates against the API with an assigned API key in the HTTP header
X-API-KEY. Calls are only accepted from pre-registered IP addresses. All calls must be
made over HTTPS — calls over HTTP or without authentication end with an error.
The API key must be kept safe. Never share it in publicly accessible places such as GitHub, client-side code and the like.
| HTTP status | Meaning |
|---|---|
| 400 | bad request — the body contains an error object with an error code (e.g. WRONG_AMOUNT) |
| 401 | missing or invalid API key |
| 403 | the API key has no access to that service group or object; where the missing entitlement can be named, the body contains an error object with a code (e.g. MODEL_NOT_ALLOWED) |
| 404 | the object does not exist |
A recurring BLIK payment lets a merchant charge the payer without their interaction, based on a consent (a mandate) the payer confirmed in their banking app. Three models are supported:
| Model A | Model M | Model O | |
|---|---|---|---|
| Payment authorisation | automatic | the payer confirms every payment in the banking app | automatic (MIT) |
| Amount | fixed (limitAmt) |
arbitrary | arbitrary |
| Frequency | fixed (frequency) |
arbitrary | arbitrary |
| Mandate validity | max. 10 years | until revoked, or max. 10 years | until revoked, or max. 10 years |
| Note | — | — | requires merchant onboarding in BLIK; a payment may lose the MIT exemption (scaRejected) |
Mandate lifecycle:
POST /payments with a BLIK code (blik.type=TICKET) and a recurring
block — the invitation to set up a mandate is attached to an ordinary payment. The amount may
also be 0 (the mandate is set up without charging the payer anything); a zero amount is
allowed only together with a recurring block, otherwise the request fails with
WRONG_AMOUNT. No transaction fee is charged for a zero-amount payment. Beware: with a zero
amount there is nothing to settle, so an issuer that does not support PAYID aliases rejects
the whole payment (PAYID_NOT_SUPPORTED) — the same as with refuseNoPayid=true.
The mandate is created in the INVITED state; its id is returned in the recurringId field.ACTIVE state — the merchant is
notified by a webhook (payloadType=recurring). Only from this moment on can the mandate be
charged. If the registration does not happen within 24 hours, the mandate moves to the
REJECTED state.POST /payments with blik.type=RECURRING and blik.recurringId. The issuer has up
to 72 hours to authorise it — the payment stays in the PROCESSING state; the merchant
polls GET /payments/{id}. With models A and O an immediate answer can be requested
(blik.noDelay=true).blik.retryPaymentId (the id of the rejected
payment) — the payment keeps the same id; it can be retried at most 3 times (4 attempts in
total). Retries do not extend the 72-hour window of the original payment, they only share it.DELETE /recurrings/{id}), or by expiry. The merchant is notified by a webhook about every
state change.Refunding a payment made from a mandate is done the standard way through POST /stornos.
If the merchant has a notification URL configured, VIAMO sends an HTTP POST with a
notification object to it. The payloadType field determines the payload type:
alias — a OneClick alias change (an alias object)recurring — a recurring payment mandate change (a recurring object); if the notification
concerns a specific payment (loss of the MIT exemption, scaRejected), its id is in the
paymentId fieldThe authenticity of the payload can be verified through the sign field — see below.
sign)The recurring and alias objects carry a sign field. By verifying it the merchant makes
sure the payload comes from VIAMO and was not altered on the way — this applies equally to
webhooks and to the responses of GET /recurrings/{id}, GET /recurrings/search and
GET /aliases/search.
The signature is made with the merchant's assigned API key — the very same value used to
authenticate PAPI calls (the X-API-KEY header). The key is a shared secret: it enters the
hash, but is never itself transmitted in the payload.
Procedure:
| Object | Signed fields (in order) |
|---|---|
recurring |
id + state + model + expiresOn + apiKey |
alias |
userId + appKey + appLabel + expiresOn + state + apiKey |
A missing field enters the signature as the literal null (four characters). The payload is
serialised without empty fields, so a field you do not see in the JSON enters the string as
null — this concerns expiresOn of both a mandate and an alias (with no end of validity) as
well as appLabel of an alias.
Example — a mandate with no end of validity, API key TEST_API_KEY_123:
id = b3f1c0d4e5a6478fa1b2c3d4e5f60718
state = ACTIVE
model = M
expiresOn = (field missing)
string: b3f1c0d4e5a6478fa1b2c3d4e5f60718ACTIVEMnullTEST_API_KEY_123
sign: 676d7bd8d58d4f63f3e21e636f82093e0a88afd259af4786fbfa51290064d9f4
Example — a mandate with an end of validity (expiresOn enters as a date, exactly as it is in
the JSON):
id = b3f1c0d4e5a6478fa1b2c3d4e5f60718
state = ACTIVE
model = A
expiresOn = 2029-03-15
string: b3f1c0d4e5a6478fa1b2c3d4e5f60718ACTIVEA2029-03-15TEST_API_KEY_123
sign: 79dd1332418f5d9359b06fa34892a3a0dd301dff28cdc00abea69cbf8a2de630
Example — an alias:
userId = payer@example.com
appKey = 655158
appLabel = TEST APP
expiresOn = 1798761600
state = VALID
string: payer@example.com655158TEST APP1798761600VALIDTEST_API_KEY_123
sign: e62668164aed280de0f68d999a0b51c1285e0dea26a68c9f006f2cfe3bacef4f
Creates a new BLIK payment. The way the payer is authenticated is given by blik.type:
TICKET — the payer entered a 6-digit BLIK code on the merchant's site (LEVEL 0).
Optionally, the same request may ask for the registration of a OneClick alias
(blik.userId + blik.userLabel) and/or for setting up a recurring payment mandate
(the recurring block).ONECLICK — a payment with a registered OneClick alias (blik.userId,
blik.userLabel, blik.appKey).RECURRING — charging an active recurring payment mandate (blik.recurringId),
without any payer interaction. The issuer has up to 72 hours to authorise it. With models
A and O an immediate answer can be requested (blik.noDelay=true); for model M noDelay
is not allowed. A rejected payment can be retried through blik.retryPaymentId. With
model A the amount must equal the agreed fixed amount (limitAmt) and the sum of the
mandate's payments — both settled and in flight (awaiting the issuer's authorisation) —
must not exceed totLimitAmt.The payment is processed asynchronously — the response contains the payment in the
PROCESSING state; the final state is obtained through GET /payments/{id}.
Requests with a recurring block or with blik.type=RECURRING require access to the
Recurring payments group; model O additionally requires a separate entitlement —
without it the response is 403 with the code MODEL_NOT_ALLOWED.
| method required | string Value: "BLIK" payment method |
| amount required | integer [ 0 .. 1000000 ] amount in cents; 0 only for a mandate invitation (the recurring block) |
| currency required | string Value: "EUR" currency |
required | object (BlikPayerSelector) |
| message | string <= 35 characters message for the payer |
| vs | string[0-9]{0,10} variable symbol |
| ss | string[0-9]{0,10} specific symbol |
| cs | string[0-9]{4} constant symbol |
| rid | string[0-9a-zA-Z]{1,16} merchant reference |
object An optional invitation to set up a recurring payment mandate. Allowed only with |
| object | string Value: "payment" |
| id | string payment identifier |
| txRef | string the transaction reference in the BLIK scheme |
| state | string Enum: "PROCESSING" "OK" "BANK_PROC" "FAIL" payment state |
| funding | string the source of the payment (e.g. |
| amount | integer amount in cents |
| stornoAmount | integer refunded amount in cents |
| feeAmount | integer fee in cents |
| currency | string Value: "EUR" |
| payer | string the payer's IBAN or masked card number |
| createdOn | integer <int64> time of creation (timestamp) |
| processedOn | integer or null <int64> time of processing (timestamp) |
| paidOn | integer or null <int64> time of payout (timestamp) |
| vs | string variable symbol |
| ss | string specific symbol |
| cs | string constant symbol |
| ee | string the payer's reference |
| message | string message |
| rid | string merchant reference |
| recurringId | string or null the identifier of the mandate the payment belongs to |
| scaRejected | boolean or null
|
{- "method": "BLIK",
- "amount": 1000000,
- "currency": "EUR",
- "message": "string",
- "vs": "string",
- "ss": "string",
- "cs": "string",
- "rid": "string",
- "blik": {
- "type": "TICKET",
- "ticket": "string",
- "userId": "string",
- "userLabel": "string",
- "appKey": 0,
- "recurringId": "stringstringstringstringstringst",
- "noDelay": true,
- "retryPaymentId": "stringstringstringstringstringst"
}, - "recurring": {
- "model": "A",
- "label": "string",
- "expiresOn": "2029-03-15",
- "frequency": "string",
- "initDate": "2026-09-30",
- "limitAmt": 1,
- "totLimitAmt": 1,
- "refuseNoPayid": true
}
}{- "object": "payment",
- "id": "string",
- "txRef": "string",
- "state": "PROCESSING",
- "funding": "string",
- "amount": 0,
- "stornoAmount": 0,
- "feeAmount": 0,
- "currency": "EUR",
- "payer": "string",
- "createdOn": 0,
- "processedOn": 0,
- "paidOn": 0,
- "vs": "string",
- "ss": "string",
- "cs": "string",
- "ee": "string",
- "message": "string",
- "rid": "string",
- "recurringId": "string",
- "scaRejected": true
}Returns the payment identified by id. Payment states:
| State | Description |
|---|---|
PROCESSING |
the payment is awaiting authorisation (up to 72 hours for recurring payments) |
OK |
the payment succeeded |
BANK_PROC |
the payment is being processed by the bank — check the state again later |
FAIL |
the payment failed, was rejected or expired |
| id required | string [ 32 .. 36 ] characters payment identifier |
| object | string Value: "payment" |
| id | string payment identifier |
| txRef | string the transaction reference in the BLIK scheme |
| state | string Enum: "PROCESSING" "OK" "BANK_PROC" "FAIL" payment state |
| funding | string the source of the payment (e.g. |
| amount | integer amount in cents |
| stornoAmount | integer refunded amount in cents |
| feeAmount | integer fee in cents |
| currency | string Value: "EUR" |
| payer | string the payer's IBAN or masked card number |
| createdOn | integer <int64> time of creation (timestamp) |
| processedOn | integer or null <int64> time of processing (timestamp) |
| paidOn | integer or null <int64> time of payout (timestamp) |
| vs | string variable symbol |
| ss | string specific symbol |
| cs | string constant symbol |
| ee | string the payer's reference |
| message | string message |
| rid | string merchant reference |
| recurringId | string or null the identifier of the mandate the payment belongs to |
| scaRejected | boolean or null
|
{- "object": "payment",
- "id": "string",
- "txRef": "string",
- "state": "PROCESSING",
- "funding": "string",
- "amount": 0,
- "stornoAmount": 0,
- "feeAmount": 0,
- "currency": "EUR",
- "payer": "string",
- "createdOn": 0,
- "processedOn": 0,
- "paidOn": 0,
- "vs": "string",
- "ss": "string",
- "cs": "string",
- "ee": "string",
- "message": "string",
- "rid": "string",
- "recurringId": "string",
- "scaRejected": true
}At least one of the criteria vs, ss, rid, from, to is required.
| vs | string <= 10 characters [0-9]{0,10} variable symbol |
| ss | string <= 10 characters [0-9]{0,10} specific symbol |
| rid | string <= 50 characters merchant reference |
| from | integer <int64> >= 0 created from (timestamp) |
| to | integer <int64> >= 0 created to (timestamp) |
| object | string Value: "list" |
| url | string |
| hasMore | boolean |
Array of objects (PaymentResource) <= 50 items |
{- "object": "list",
- "url": "string",
- "hasMore": true,
- "data": [
- {
- "object": "payment",
- "id": "string",
- "txRef": "string",
- "state": "PROCESSING",
- "funding": "string",
- "amount": 0,
- "stornoAmount": 0,
- "feeAmount": 0,
- "currency": "EUR",
- "payer": "string",
- "createdOn": 0,
- "processedOn": 0,
- "paidOn": 0,
- "vs": "string",
- "ss": "string",
- "cs": "string",
- "ee": "string",
- "message": "string",
- "rid": "string",
- "recurringId": "string",
- "scaRejected": true
}
]
}Mandates for recurring BLIK payments — created through POST /payments with a recurring block.
Returns the recurring payment mandate identified by id. Mandate states:
| State | Description |
|---|---|
INVITED |
the invitation was sent, awaiting the payer's confirmation and the issuer's registration |
ACTIVE |
the mandate is active — it can be charged |
REJECTED |
the setup failed (the payment carrying the invitation was rejected, or the registration never happened) |
UNREGISTERED |
the mandate was cancelled (by the payer, by the merchant or by VIAMO) |
EXPIRED |
the mandate's validity has elapsed |
| id required | string = 32 characters mandate identifier |
| object | string Value: "recurring" |
| id | string mandate identifier |
| state | string Enum: "INVITED" "ACTIVE" "REJECTED" "UNREGISTERED" "EXPIRED" mandate state |
| model | string Enum: "A" "M" "O" |
| label | string mandate name |
| expiresOn | string or null <date> the last day of the mandate's validity (date, inclusive); |
| frequency | string or null payment frequency |
| initDate | string or null <date> the date of the first payment (date) |
| limitAmt | integer or null the fixed payment amount in cents (model A) |
| totLimitAmt | integer or null the limit of the whole series in cents (model A) |
| currency | string Value: "EUR" |
| payIdEligible | boolean or null whether the payer's bank supports recurring payments; |
| scaRejected | boolean model O only — |
| createdOn | integer <int64> time of creation (timestamp) |
| activatedOn | integer or null <int64> time of activation (timestamp) |
| finishedOn | integer or null <int64> time of termination (timestamp) |
| sign | string the object signature; for the computation and an example see the chapter "Object signature (sign)" in the introduction: hex(sha256(id + state + model + expiresOn + apiKey)), a missing field as the literal |
{- "object": "recurring",
- "id": "string",
- "state": "INVITED",
- "model": "A",
- "label": "string",
- "expiresOn": "2029-03-15",
- "frequency": "string",
- "initDate": "2026-09-30",
- "limitAmt": 0,
- "totLimitAmt": 0,
- "currency": "EUR",
- "payIdEligible": true,
- "scaRejected": true,
- "createdOn": 0,
- "activatedOn": 0,
- "finishedOn": 0,
- "sign": "string"
}Cancels the mandate — VIAMO unregisters the PAYID alias in the BLIK scheme. A mandate in the
INVITED state is merely rejected locally (nothing is registered in BLIK yet). Returns the
mandate in its final state (UNREGISTERED, or REJECTED respectively).
The operation is idempotent towards the BLIK scheme: if the alias no longer exists in the
BLIK scheme (the payer cancelled the mandate in the banking app), the mandate is closed as
UNREGISTERED and the response is successful. Other errors on the BLIK scheme's side return
400 with the code UNREGISTER_FAILED.
Cancelling an already cancelled mandate, however, returns 400 with the code
RECURRING_NOT_ACTIVE, not the mandate in its final state — count on that when repeating the
request, and read the final state through GET /recurrings/{id} in such a case.
| id required | string = 32 characters |
| object | string Value: "recurring" |
| id | string mandate identifier |
| state | string Enum: "INVITED" "ACTIVE" "REJECTED" "UNREGISTERED" "EXPIRED" mandate state |
| model | string Enum: "A" "M" "O" |
| label | string mandate name |
| expiresOn | string or null <date> the last day of the mandate's validity (date, inclusive); |
| frequency | string or null payment frequency |
| initDate | string or null <date> the date of the first payment (date) |
| limitAmt | integer or null the fixed payment amount in cents (model A) |
| totLimitAmt | integer or null the limit of the whole series in cents (model A) |
| currency | string Value: "EUR" |
| payIdEligible | boolean or null whether the payer's bank supports recurring payments; |
| scaRejected | boolean model O only — |
| createdOn | integer <int64> time of creation (timestamp) |
| activatedOn | integer or null <int64> time of activation (timestamp) |
| finishedOn | integer or null <int64> time of termination (timestamp) |
| sign | string the object signature; for the computation and an example see the chapter "Object signature (sign)" in the introduction: hex(sha256(id + state + model + expiresOn + apiKey)), a missing field as the literal |
{- "object": "recurring",
- "id": "string",
- "state": "INVITED",
- "model": "A",
- "label": "string",
- "expiresOn": "2029-03-15",
- "frequency": "string",
- "initDate": "2026-09-30",
- "limitAmt": 0,
- "totLimitAmt": 0,
- "currency": "EUR",
- "payIdEligible": true,
- "scaRejected": true,
- "createdOn": 0,
- "activatedOn": 0,
- "finishedOn": 0,
- "sign": "string"
}| state | string Enum: "INVITED" "ACTIVE" "REJECTED" "UNREGISTERED" "EXPIRED" mandate state |
| createdFrom | integer <int64> >= 0 created from (timestamp) |
| createdTo | integer <int64> >= 0 created to (timestamp) |
| object | string Value: "list" |
| url | string |
| hasMore | boolean |
Array of objects (RecurringResource) <= 50 items |
{- "object": "list",
- "url": "string",
- "hasMore": true,
- "data": [
- {
- "object": "recurring",
- "id": "string",
- "state": "INVITED",
- "model": "A",
- "label": "string",
- "expiresOn": "2029-03-15",
- "frequency": "string",
- "initDate": "2026-09-30",
- "limitAmt": 0,
- "totLimitAmt": 0,
- "currency": "EUR",
- "payIdEligible": true,
- "scaRejected": true,
- "createdOn": 0,
- "activatedOn": 0,
- "finishedOn": 0,
- "sign": "string"
}
]
}Creates a refund (storno) of a successful payment — full or partial. Refunds of payments made from recurring payment mandates are done the same way, with no extra parameters.
In exceptional cases a BLIK payment cannot be refunded at all (it is missing its transaction
identifier in the BLIK scheme, which is sent along with the refund) — the response is then
400 with the code PAYMENT_NOT_REFUNDABLE. This is a permanent state, repeating the
request will not help; contact VIAMO.
| paymentId required | string [ 30 .. 36 ] characters the identifier of the payment to refund |
| stornoAmount | integer or null amount in cents (no field = full refund) |
| object | string Value: "storno" |
| id | string |
| paymentId | string the identifier of the refunded payment |
| state | string refund state |
| stornoAmount | integer amount in cents |
| currency | string Value: "EUR" |
| createdOn | integer <int64> |
| paidOn | integer or null <int64> |
{- "paymentId": "stringstringstringstringstring",
- "stornoAmount": 0
}{- "object": "storno",
- "id": "string",
- "paymentId": "string",
- "state": "string",
- "stornoAmount": 0,
- "currency": "EUR",
- "createdOn": 0,
- "paidOn": 0
}| id required | string = 36 characters |
| object | string Value: "storno" |
| id | string |
| paymentId | string the identifier of the refunded payment |
| state | string refund state |
| stornoAmount | integer amount in cents |
| currency | string Value: "EUR" |
| createdOn | integer <int64> |
| paidOn | integer or null <int64> |
{- "object": "storno",
- "id": "string",
- "paymentId": "string",
- "state": "string",
- "stornoAmount": 0,
- "currency": "EUR",
- "createdOn": 0,
- "paidOn": 0
}| object | string Value: "payout" |
| id | string |
| state | string payout state |
| type | string
|
| amountPaidOut | integer paid out amount in cents |
| amountStorno | integer refunded amount in cents |
| amountRefund | integer returned amount in cents |
| requestedOn | integer or null <int64> |
| transctionsUntil | integer or null <int64> transactions until (timestamp) |
| createdOn | integer or null <int64> |
| paidOn | integer or null <int64> |
| plan | string or null payout plan |
{- "object": "payout",
- "id": "string",
- "state": "string",
- "type": "string",
- "amountPaidOut": 0,
- "amountStorno": 0,
- "amountRefund": 0,
- "requestedOn": 0,
- "transctionsUntil": 0,
- "createdOn": 0,
- "paidOn": 0,
- "plan": "string"
}| id required | string payout identifier |
| object | string Value: "payout" |
| id | string |
| state | string payout state |
| type | string
|
| amountPaidOut | integer paid out amount in cents |
| amountStorno | integer refunded amount in cents |
| amountRefund | integer returned amount in cents |
| requestedOn | integer or null <int64> |
| transctionsUntil | integer or null <int64> transactions until (timestamp) |
| createdOn | integer or null <int64> |
| paidOn | integer or null <int64> |
| plan | string or null payout plan |
{- "object": "payout",
- "id": "string",
- "state": "string",
- "type": "string",
- "amountPaidOut": 0,
- "amountStorno": 0,
- "amountRefund": 0,
- "requestedOn": 0,
- "transctionsUntil": 0,
- "createdOn": 0,
- "paidOn": 0,
- "plan": "string"
}Returns the current balance of the merchant (BID) the API key belongs to.
| object | string Value: "balance" |
| id | string merchant identifier (BID) |
| ts | integer <int64> the time the balance was taken (timestamp) |
| balance | integer balance in cents |
{- "object": "balance",
- "id": "string",
- "ts": 0,
- "balance": 0
}Returns the valid OneClick aliases for the given userId (the payer's identifier in the merchant's system).
| userId required | string [ 1 .. 255 ] characters |
| object | string Value: "list" |
| url | string |
| hasMore | boolean |
Array of objects (AliasResource) <= 50 items |
{- "object": "list",
- "url": "string",
- "hasMore": true,
- "data": [
- {
- "object": "alias",
- "userId": "string",
- "appKey": 0,
- "appLabel": "string",
- "expiresOn": 0,
- "state": "VALID",
- "sign": "string"
}
]
}Sent to the merchant's notification URL on every mandate state change (activation, rejection,
cancellation, expiry) and on the loss of the MIT exemption (scaRejected, model O).
On the loss of the MIT exemption the paymentId field carries the id of the specific payment
concerned (one notification arrives for each such payment); on mandate state changes
paymentId is empty. A 2xx response is expected. Verify the authenticity of the payload
through the sign field.
| object | string Value: "notification" |
| payloadType | string Value: "recurring" |
object (RecurringResource) | |
| paymentId | string or null id of the payment the notification concerns (only with |
{- "object": "notification",
- "payloadType": "recurring",
- "payload": {
- "object": "recurring",
- "id": "string",
- "state": "INVITED",
- "model": "A",
- "label": "string",
- "expiresOn": "2029-03-15",
- "frequency": "string",
- "initDate": "2026-09-30",
- "limitAmt": 0,
- "totLimitAmt": 0,
- "currency": "EUR",
- "payIdEligible": true,
- "scaRejected": true,
- "createdOn": 0,
- "activatedOn": 0,
- "finishedOn": 0,
- "sign": "string"
}, - "paymentId": "string"
}Sent on the registration, change, cancellation or expiry of a OneClick alias.
| object | string Value: "notification" |
| payloadType | string Value: "alias" |
object (AliasResource) |
{- "object": "notification",
- "payloadType": "alias",
- "payload": {
- "object": "alias",
- "userId": "string",
- "appKey": 0,
- "appLabel": "string",
- "expiresOn": 0,
- "state": "VALID",
- "sign": "string"
}
}