Skip to content

EasyPay / ePay.bg — API Reference

ePay.bg / EasyPay — 21 operations across 11 areas, from the official docs (kb.epay.bg). WEB API endpoints take a base64 ENCODED payload + CHECKSUM. Interactive: the API page; full prose docs + diagrams: Full Docs.

Online Payment (1)

POST /

Card payment via ePay page (credit_paydirect) POST to https://www.epay.bg/ with PAGE=credit_paydirect. Customer is redirected to ePay's payment page. Payload fields (encoded into ENCODED): see OnlinePaymentPayload model.

Payment via EasyPay (3)

GET /ezp/pay_bill.cgi

Simulate EasyPay-office payment (demo only) Demo only. Fires STATUS=PAID to the merchant notification URL.

A success token here can settle nothing. Handed an IDN belonging to the OTHER application root, this endpoint returned STATUS=OK IDN= MERCHANT= AMOUNT= DESCR= — success, every field empty, nothing paid (observed 2026-09-08). A caller that reads STATUS=OK and stops will mark an instalment paid against money nobody handed over. Require IDN to come back, and to match the code that was asked about.

Served on the LEGACY root; no counterpart was found under /xdev/web.

Param In Required
ACTION query True
IDN query True

GET /ezp/reg_bill.cgi

Register EasyPay payment (get 10-digit code) Returns a 10-digit EasyPay code payable at an EasyPay office or ATM. Payload fields (encoded into ENCODED): see EasyPayBillPayload model.

TWO APPLICATION ROOTS, SEPARATE MERCHANT REGISTRIES. demo.epay.bg runs a legacy application at the bare host and a current one under /xdev/web, each with its own merchant registry (established by live call, 2026-09-08). A merchant registered on one root is UNKNOWN on the other, and the error does not say so: the legacy MIN against the current update endpoint answers EPLG_NO_MERCHANT, which is also what a BAD CHECKSUM answers, so the response does not diagnose the request. The current MIN against legacy /ezp/reg_bill.cgi answers 'EMETHOD: Не е намерен валиден търговец!'. Pick a root and use it for registration, invalidation and the portal alike. NOT VERIFIED: whether production splits the same way between www.epay.bg/ezp/... and www.epay.bg/v3main.

Success is reported in more than one way. The documented token is SYS_CODE=OK; a registration answers with the code itself (IDN=<10 digits>), and the live host answers STATUS=OK from the update endpoint. Accept all three — treating only the documented one as success reads every successful invalidation as a failure.

INVOICE collisions are silent. Re-submitting a consumed INVOICE returns the already-bound IDN — pending or paid — and reports success. On a SHARED merchant record two parties can therefore both believe they registered an obligation when only one did. Partition the INVOICE namespace between parties; do not rely on an error.

Param In Required
ENCODED query True
CHECKSUM query True

GET /paylogin/request/update

Extend or invalidate a registered payment Re-registers an existing INVOICE with a new EXP_TIME. A PAST-DATED EXP_TIME invalidates the code — which is how a live code is killed when the loan is settled through another rail.

Served on the CURRENT root only (/xdev/web/paylogin/request/update); the legacy application does not serve it at all.

Errors worth telling apart: EPLG_NO_MERCHANT means wrong root or wrong merchant — and is ALSO what an invalid CHECKSUM returns; BILL_NOT_FOUND means the merchant resolved and the invoice did not, which is good news about the credentials. Success is STATUS=OK.

NOT VERIFIED: whether invalidation is terminal. Re-extending after a past-dated EXP_TIME returned OK; it was not confirmed the code becomes payable again.

Param In Required
ENCODED query True
CHECKSUM query True

Preauthorization (1)

POST /v3main/

Preauthorization: register, finalize or reverse Three phases share this endpoint (distinguished by the ENCODED payload): register (PreauthRegisterPayload), finalize (PreauthFinalizePayload), reverse (PreauthReversePayload).

Change expiring time (1)

GET /v3main

Change the expiry time of an obligation Payload fields (encoded into ENCODED): see ChangeExpiryPayload model.

Param In Required
ENCODED query True
CHECKSUM query True

Bank transfer (1)

GET /send/send_vnbel.cgi

Order a bank transfer Payload fields (encoded into ENCODED): see BankTransferPayload model.

Param In Required
ENCODED query True
CHECKSUM query True

Deposit slip (1)

GET /ezp/reg_vnbel.cgi

Register a deposit-slip payment request Payload fields (encoded into ENCODED): see DepositSlipPayload model.

Param In Required
ENCODED query True
CHECKSUM query True

Money send (3)

GET /ezp/pay_money_send.cgi

Simulate an EasyPay-office cash payout (demo only) Demo only. Simulates the recipient collecting the cash transfer at an EasyPay office; fires the STATUS=PAID notification (with STAN/BCODE=000000) to the merchant's registered notification URL, same as a real payout would.

Param In Required
SYS_CODE query True

GET /ezp/send.cgi

Money send via EasyPay (cash pickup) Order a cash payout collectable by a named recipient at any EasyPay office (loan-disbursement use case). Payload fields (encoded into ENCODED): see MoneySendEasyPayPayload model. On payout, ePay POSTs a notification to your registered URL with STATUS=PAID (or STATUS=EXPIRED if never collected); STAN/BCODE are always 000000 for money-send. Full flow: see the Money Send (disbursement) page. Demo payout simulation: /ezp/pay_money_send.cgi.

Param In Required
ENCODED query True
CHECKSUM query True

GET /send/send.cgi

Money send via ePay.bg Payload fields (encoded into ENCODED): see MoneySendEpayPayload model.

Param In Required
ENCODED query True
CHECKSUM query True

Payment notification (1)

POST /{merchant_notify_url}

Payment notification (merchant-hosted) ePay POSTs here on payment status change. Verify CHECKSUM and the RSA SIGNATURE. Respond with a line per invoice: INVOICE=STATUS (OK/ERR/NO). Payload fields (encoded into ENCODED): see NotificationPayload model.

Param In Required
merchant_notify_url path True

Billing API (2)

GET /pay/confirm

Payment / deposit notification (merchant-hosted)

Param In Required
IDN query True
MERCHANTID query True
TID query True
DATE query True
TOTAL query True
TYPE query True
INVOICES query False
CHECKSUM query True

GET /pay/init

Obligation / deposit check (merchant-hosted) STATUS codes: 00=OK; 13=Invalid amount; 14=Invalid IDN; 62=No obligation; 80=Temporarily unavailable; 93=Invalid checksum; 94=Duplicate; 96=General error

Param In Required
IDN query True
MERCHANTID query True
TYPE query True
TID query False
TOTAL query False
CHECKSUM query True

One Touch API (6)

GET /xdev/api/api/code/get

Get pairing code / register device

Param In Required
APPID query True
DEVICEID query True
KEY query True
UTYPE query False
DEVICE_NAME query False
BRAND query False
OS query False
MODEL query False
OS_VERSION query False
PHONE query False

GET /xdev/api/api/token/get

Get access token from code

Param In Required
APPID query True
DEVICEID query True
CODE query True

GET /xdev/api/api/token/invalidate

Invalidate a token

Param In Required
APPID query True
DEVICEID query True
TOKEN query True

GET /xdev/api/payment/check

Check a payment before sending

Param In Required
APPID query True
DEVICEID query True
TOKEN query True
TYPE query True
ID query True
AMOUNT query True
RCPT query True
RCPT_TYPE query True
DESCRIPTION query False
REASON query False
PINS query False
SHOW query False

GET /xdev/api/payment/init

Initialize a payment

Param In Required
APPID query True
DEVICEID query True
TOKEN query True
TYPE query True
EXP query False

GET /xdev/api/payment/send/status

Send payment / get status

Param In Required
APPID query True
DEVICEID query True
TOKEN query True
TYPE query True
ID query True
AMOUNT query True
RCPT query True
RCPT_TYPE query True
DESCRIPTION query False
REASON query False
PINS query False
SHOW query False

One Touch No Reg API (1)

GET /xdev/api/api/payment/noreg/send/status

No-registration payment / status CHECKSUM = hmac_sha1_hex over the sorted KEY VALUE lines with the app SECRET.

Param In Required
APPID query True
DEVICEID query True
ID query True
AMOUNT query True
RCPT query True
RCPT_TYPE query True
CHECKSUM query True
DESCRIPTION query False
REASON query False
SAVECARD query False