Skip to content

EasyPay — Money Send (Cash Disbursement)

Source: EasyPay's internal integration doc for the disbursement connection (README_MONEY_SEND, provided by Zdravko Slavchev, Jul 2026), reconciled against the public kb.epay.bg "Money Send via EasyPay" page. This is the loan-disbursement path: pay a named recipient in cash at any EasyPay office — no recipient bank account required.

This page is the authoritative internal reference. The interactive request/response lives on the API page (GET /ezp/send.cgi, GET /ezp/pay_money_send.cgi); the full scraped vendor prose is under Full Docs.

Onboarding

Same merchant registration as everything else — see Authentication. Per EasyPay (Zdravko, Jul 2026), the disbursement capability needs no separate contract; it's the same CIN + 64-char SECRET, only a different technical connection.

Flow

  1. Merchant sends a money-transfer request (GET /ezp/send.cgi). If valid, ePay.bg returns a system code (SYS_CODE) in the same HTTP session.
  2. The recipient collects the cash at any EasyPay office.
  3. ePay.bg tracks each transfer and, on payout, POSTs a notification to the merchant's registered URL.
  4. The merchant responds to each notification (OK / ERR / NO).
Merchant  --[ money-transfer request ]-->  ePay.bg
ePay.bg   --[ SYS_CODE ]-->                Merchant
Recipient --[ collects cash ]-->           EasyPay office
ePay.bg   --[ notification (POST) ]-->     Merchant
Merchant  --[ response OK/ERR/NO ]-->      ePay.bg

Endpoints

Env Order transfer Simulate payout (demo only)
Production GET https://www.epay.bg/ezp/send.cgi
Demo GET https://demo.epay.bg/ezp/send.cgi GET https://demo.epay.bg/ezp/pay_money_send.cgi?SYS_CODE=<sys-code>

Both request and notification use the standard ePay signing: ENCODED = Base64 (RFC 3548, EOL='') of the payload, CHECKSUM = hmac_sha1_hex(ENCODED, SECRET). See Authentication.

Request payload (ENCODED)

Encode as newline-joined KEY=VALUE, then Base64.

Field Required Notes
MIN Yes Merchant CIN
INVOICE Yes Digits only; unique — see one-time rule below
AMOUNT Yes > 0.01 (e.g. 22, 22.8, 22.80)
RCPT_NAME Yes Recipient name, ≤100 chars
RCPT_PID Conditional Recipient national ID (ЕГН). Supply RCPT_PID and/or RCPT_ID_NO
RCPT_ID_NO Conditional Personal-document number (ID card / driver's licence / passport). Supply RCPT_PID and/or RCPT_ID_NO
RCPT_ID_DATE Conditional Document issue date DD.MM.YYYYrequired if RCPT_ID_NO is supplied
RCPT_ADDRESS No ≤256 chars
RCPT_PHONE No ≤16 digits (keep as string — preserves leading 0, e.g. 029210850)
CURRENCY No Defaults to BGN — see currency discrepancy below
DESCR No ≤100 chars
ENCODING No utf-8 or CP1251 (default CP1251) — applies to DESCR, RCPT_NAME, RCPT_ADDRESS

Recipient identification is mandatory (as a group)

The request must carry the recipient's national ID (RCPT_PID) and/or a valid personal-document number (RCPT_ID_NO). If a personal document is given, its issue date (RCPT_ID_DATE) is also required. The public kb.epay.bg table mislabels all three as individually "Mandatory" — the real rule is this conditional one.

One INVOICE, one transfer

An INVOICE can enter the system only once. Repeating a request with the same data returns the same SYS_CODE — it never orders a second transfer. So it's safe (and expected) to retry until you get a spec response.

Response (same HTTP session)

SYS_CODE=1234567890        # transfer ordered (digits only, up to 64)
or
ERR=<error description>

An empty or absent response is not a signal of success or failure — retry with identical data until you receive SYS_CODE=… or ERR=….

Notification (payout confirmation)

On payout, ePay.bg POSTs ENCODED + CHECKSUM to your registered URL. Decoded, ENCODED is a colon-delimited line:

INVOICE=123456:STATUS=PAID:PAY_TIME=20170715135123:STAN=000000:BCODE=000000
Field Notes
INVOICE The request ID
STATUS PAID (collected) or EXPIRED (never collected)
PAY_TIME YYYYMMDDhhmmss
STAN Transaction number — always 000000 for money-send
BCODE BORICA auth code — always 000000 for money-send

EXPIRED must be handled

Unlike a card payment, a money-send transfer can expire uncollected. Your notification handler must treat STATUS=EXPIRED as a terminal non-payout (e.g. mark the disbursement failed / re-attempt out of band). The public money-send page only illustrates PAID.

Merchant response to each notification

Return one line per invoice:

INVOICE=123456:STATUS=OK      # processed OK  -> ePay stops resending
INVOICE=123457:STATUS=ERR     # error         -> ePay keeps retrying
INVOICE=123458:STATUS=NO      # unknown invoice -> ePay stops resending
  • OK or NO → ePay.bg stops resending that notification.
  • ERR (or no/incorrect response) → ePay.bg keeps retrying (see schedule).
  • A global problem (e.g. bad CHECKSUM) → return ERR=<description>.

If you don't register a notification URL, you can still read transfer statuses from your ePay.bg Microaccount, but you won't get push notifications.

Retry schedule

If a notification isn't acknowledged with OK/NO, ePay.bg retries:

  1. 5 attempts within < 1 minute
  2. 4 attempts over 15 minutes
  3. 5 attempts over 1 hour
  4. 6 attempts over 3 hours
  5. 4 attempts over 6 hours
  6. 1 attempt per day

⚠️ Discrepancies to confirm with EasyPay

Two sources disagree — confirm before go-live

  • Currency: EasyPay's disbursement doc (Zdravko) says BGN only; the public kb.epay.bg money-send page says BGN / USD / EUR. Don't rely on USD/EUR payouts until confirmed.
  • Notification retry window: the disbursement doc says ePay.bg stops resending a notification after 30 days; the public page says 14 days. This affects how long a disbursement can stay unreconciled — confirm the actual value.