MagicPayments Integration Guides

Moldova MIA Gate

Pay-inMDLMIA

Accept MIA instant bank pay-ins in Moldovan Leu (MDL) — the payer is redirected and approves in their banking app. Pay-in only.

When to use it

The Moldova MIA Gate accepts instant bank pay-ins over MIA, Moldova's national instant-payments scheme. You create an invoice and redirect the payer; they land on the MIA payment page, pick their bank and approve the transfer inside their own banking app — no card, no card data on your side. Amounts are in MDL (Moldovan Leu, 2 decimal places — so 25000 means MDL 250.00).

OperationRailHow the integration looks
Pay-inMIA instant bank transferCreate an invoice, redirect the payer; we forward them to the MIA payment page.
Pay-outNot supported on this method (see below).
Pay-in only

The Moldova MIA Gate is a collection-only method — there is no MIA payout rail behind it. Don't build a disbursement flow against this gate. If you need to send funds out, ask your account manager which payout-capable cascade to use and follow the matching guide.

Prerequisites

You need your signing credentials from Getting started and a pay-in gate_id for the Moldova MIA gate. Your account manager provides it.

How the redirect flow works

Unlike the gates where we render the payment form ourselves, this one hands the payer straight to the MIA payment page. You never see or collect bank credentials.

  1. Create the invoice Call the gate endpoint with your gate_id, the amount in MDL minor units, and — required on this gate — a customer.id.
  2. Redirect the payer Send the customer's browser to the invoice_url we return. We create the payment and forward them to the MIA payment page; there is no intermediate form of ours to fill in.
  3. Payer approves in their banking app They choose their bank and confirm the transfer. MIA settles instantly.
  4. Receive the result We call your callback_url on every status change. Poll invoice status as a fallback — but see Tracking the pay-in below, because the callback is what actually settles this rail.

Pay-in — MIA instant transfer

POST/api/invoice
Request body
{
  "gate_id": "md-mia-gate",
  "invoice": {
    "invoice_id": "order-md-2026-000123",
    "currency": "MDL",
    "amount": 25000,
    "description": "Wallet top-up",
    "ttl_minutes": 20
  },
  "customer": {
    "id": "cust-88412",
    "full_name": "Ion Popescu"
  },
  "workflow_hooks": {
    "callback_url": "https://merchant.example.com/mp/callbacks",
    "return_success_url": "https://merchant.example.com/orders/123/done",
    "return_decline_url": "https://merchant.example.com/orders/123/retry"
  }
}
Python
resp = signed_post("/api/invoice", {
    "gate_id": "md-mia-gate",
    "invoice": {
        "invoice_id": "order-md-2026-000123",
        "currency": "MDL",
        "amount": 25_000,             # MDL 250.00 (2 decimals)
        "description": "Wallet top-up",   # shown to the payer in their banking app
        "ttl_minutes": 20,
    },
    "customer": {
        "id": "cust-88412",           # required on this gate - see below
        "full_name": "Ion Popescu",
    },
    "workflow_hooks": {
        "callback_url": "https://merchant.example.com/mp/callbacks",
        "return_success_url": "https://merchant.example.com/orders/123/done",
        "return_decline_url": "https://merchant.example.com/orders/123/retry",
    },
})
redirect_url = resp.json()["invoice_url"]   # send the payer here
Response
{
  "request_status": "success",
  "invoice_id": "7e2c9a14-3d55-4f80-b1a2-6c0d9e3f8a44",
  "merchant_invoice_id": "order-md-2026-000123",
  "invoice_status": "unpaid",
  "invoice_url": "https://stage.example-mp.com/public/invoice/7e2c9a14-3d55-4f80-b1a2-6c0d9e3f8a44",
  "message": "Invoice (Gate PayIn) with internal uid=7e2c9a14-... has been created."
}
customer.id is required on this gate

customer is optional on the invoice API in general, but this rail needs a stable customer identifier and the payment fails at creation without one. Send your own customer id in customer.id — the same value for the same person across invoices. If you already send it under client_id or customer_id we'll read those too, but customer.id is the field to use.

What the payer sees as the reference

Your invoice.description becomes the payment reference shown in the payer's banking app, so keep it short and recognisable — the payer reads it while deciding whether to approve. The field holds 35 bytes, and anything longer is cut: that is 35 plain characters, but Romanian diacritics (ă, î, ș, ț) take two bytes each, so "Achitare serviciu ăîșț 12345" is 28 characters but 32 bytes. Omit the field and we fall back to our own payment identifier. Reconcile on merchant_invoice_id from the callback either way.

Skip the JSON round-trip

To have us redirect straight to the payment page from the create call, set "redirect_to_gate_payment_page": true at the top level of the request body and follow the 303 redirect instead of reading invoice_url.

Tracking the pay-in

Look the invoice up by your own id (or our invoice_uid). It reaches paid once MIA confirms the transfer.

POST/api/invoice/status
resp = signed_post("/api/invoice/status", {
    "merchant_invoice_id": "order-md-2026-000123"
})
invoice = resp.json()
# invoice["status"] -> "paid" | "payment_failed" | "expired" | "declined_by_payer" | ...
# invoice["actual_payment"]["processing_info"]["amount_acquired"] -> settled MDL minor units
ttl_minutes is the deadline for the whole attempt

On this rail the payer's confirmation is what moves the invoice to paid; an unconfirmed payment stays in paying until ttl_minutes runs out and then lands in a failure state. Polling faster does not make an abandoned payment resolve sooner. The payment link expires on the same clock — send the payer there promptly, because a link opened after the invoice has expired is dead. Set ttl_minutes to how long you are willing to hold the order, and handle the callback.

Pay-out

Not available for this method

The Moldova MIA Gate does not support payouts. There is no payout endpoint to call for this method. For disbursements, use a payout-capable cascade and the relevant guide, or contact your account manager.

Testing & go-live