Танилцуулга / QR Switch
QR Switch — MNQR profile
EMVCo MPQR + CPQR-аар verbatim adopt + Mongol-аар "MNQR" profile.
Tag 81 mn.paygrid:// pay_uri-аар Deeplink ≡ QR ≡ NFC
architectural unity. UPI / PIX / PromptPay / DuitNow / VietQR pattern-аас сурсан.
1. Яагаад QR Switch хэрэгтэй вэ
Mongol-ын одоогийн QR landscape
- QPay (Hi Payment Solutions) — closed-loop, EMVCo MPQR-аар ч QPay-ын merchant-уудаар л; T+1 acquirer-аар settlement
- Bank-аар бие даасан QR-ууд (Khan QR, Golomt QR, Most QR) — bank тус тусдаа онбоординг; cross-bank ажиллахгүй; fragmented
- Switch / NPS — QR-аар суурилсан гүйлгээ дэмждэггүй
Gap
- Universal QR байхгүй: нэг QR-аар бүх wallet/bank app-аас scan хийж pay
- IBAN-based routing байхгүй: direct A2A settlement
- Cross-PSP merchant acceptance байхгүй: bank-аар тус тусдаа гэрээ
PayGrid QR Switch-аар нэмэх value
- Universal MNQR: нэг QR-аар бүх wallet/bank-аас pay
- Direct IBAN A2A routing — Berlin Group NextGenPSD2 backbone-аар
- Cross-PSP merchant: мерчант нэг PSP-аас бүртгэгдсэн ч бүх PSP-аас pay
- EMVCo verbatim conformance — interoperable globally
- Deeplink ≡ QR ≡ NFC unity (architectural)
- Static + Dynamic + CPQR гурвыг хослуулсан
2. Олон улсын analog
| Орон | QR Switch | Operator | Coverage |
|---|---|---|---|
| Энэтхэг | UPI QR / BharatQR | NPCI | Universal |
| Сингапур | SGQR | ABS-MAS | Universal |
| Тайланд | PromptPay QR | BoT | Universal |
| Бразил | PIX QR | BCB | Universal |
| Индонез | QRIS | Bank Indonesia | Universal |
| Малайз | DuitNow QR | PayNet | Universal |
| Вьетнам | VietQR | NAPAS | Universal |
| Монгол | (QPay closed-loop одоо) | — | — |
| Монгол (PayGrid proposal) | MNQR | PayGrid LLC | Universal |
3. Стандартууд
EMVCo QR Code Specification for Payment Systems:
─ Merchant-Presented Mode (MPQR) — мерчант QR харуулна, consumer scan
─ Consumer-Presented Mode (CPQR) — consumer QR харуулна, мерчант scan
Common features:
─ TLV (Tag-Length-Value) encoding
─ CRC-16/CCITT-FALSE checksum
─ UTF-8 string support
─ QR error correction Level M (15%)
Versions:
─ MPQR v1.1 (2018-аас)
─ CPQR v1.0 (2017-аас)
| Layer | Standard |
|---|---|
| QR encoding | EMVCo MPQR v1.1 + CPQR v1.0 |
| QR symbology | ISO/IEC 18004 |
| Checksum | CRC-16/CCITT-FALSE |
| Currency | ISO 4217 (MNT = 496) |
| Country code | ISO 3166-1 (MN) |
| Merchant Category Code | ISO 18245 |
| Settlement | ISO 20022 pacs.008 |
| URI scheme | mn.paygrid://pay?... |
4. EMVCo TLV layout (MNQR profile)
4.1 Static MPQR (sticker — no amount)
00 02 01 Payload Format Indicator (PFI) = "01"
01 02 11 Point of Initiation Method = "11" (static)
26 60 Merchant Account Information template (ID 26)
00 12 mn.paygrid Globally Unique Identifier
01 28 MN20910010000000XXXX IBAN (creditor account)
02 11 GWMNUBXX BIC (creditor agent)
03 16 cafemonkey@gerege Alias (optional)
52 04 5814 Merchant Category Code = 5814 (Restaurants)
53 03 496 Currency = 496 (MNT)
58 02 MN Country = MN
59 13 CAFE MONKEY Merchant Name (max 25)
60 09 ULAANBAATAR Merchant City (max 15)
62 11 Additional data field template
01 09 REF202605 Reference label
63 04 ABCD CRC-16/CCITT-FALSE checksum
4.2 Dynamic MPQR (one-time, amount + nonce)
00 02 01 PFI
01 02 12 POI = "12" (dynamic)
26 60 Merchant Account Information template
00 12 mn.paygrid
01 28 MN20910010000000XXXX
02 11 GWMNUBXX
52 04 5814 MCC
53 03 496 Currency
54 06 100000 Transaction Amount = 100,000 ₮
58 02 MN
59 13 CAFE MONKEY
60 09 ULAANBAATAR
62 27 Additional data field
01 09 REF202605
05 0E ord-12345-abc Bill / order ID
07 0A GW2026XXXX Reference number
81 4F PayGrid Tag 81 — pay_uri
mn.paygrid://pay?pa=cafemonkey@gerege&pn=Cafe%20Monkey
&am=100000&cu=MNT&tr=ord-12345-abc&nonce=ABCD1234
&exp=1714660800&sig=...
63 04 ABCD CRC checksum
4.3 CPQR (Consumer-Presented)
Гол ялгаа: CPQR нь нэг удаа dynamic, expire window богино (≤5 мин):
00 02 01 PFI
49 56 Consumer Account Information template (ID 49)
00 12 mn.paygrid
01 28 MN10080010100012345678 Debtor IBAN
02 11 KHANUBXX Debtor agent BIC
03 16 eddy@gerege Consumer alias
04 12 <ephemeral-token> One-time token
52 04 0000 MCC = generic
53 03 496 Currency
58 02 MN
62 17 Additional data
05 0E ref-2026-04-30-001
81 5C pay_uri
mn.paygrid://pay?pa=eddy@gerege&consumer&token=...&exp=...
63 04 ABCD CRC
5. Tag 81 — pay_uri (PayGrid Mongol extension)
EMVCo нь Tag 80-99-аар RFU-merchant defined range. PayGrid Tag 81-ийг URI-аар сонгосон.
Tag 81: pay_uri (URI string)
Value: mn.paygrid:// URI containing payment parameters
Why?
1. URI-аар QR-аас гадна Universal Link / NFC NDEF / SMS-аар
явуулах боломж
2. App-to-app handoff (bank/wallet app handle URI-аар)
3. Deeplink ≡ QR ≡ NFC architectural unity
Routing logic:
def handle_qr(tlv):
if tlv.has_tag(81):
pay_uri = tlv.get_tag(81)
if user.has_default_bank_app and prefers_bank_handoff:
return route_to_bank_app(pay_uri) # Universal Link
# Default: PayGrid-аар IBAN-аас IBAN routing
return route_via_paygrid(tlv)
Tag 81-ыг unaware EMVCo parser хэвшсэнээр (TLV-аар skip-аар) read-аар алдалгүй уншиж pass хийж чадна. Энэ нь vanilla EMVCo conformance-аас зөрчилгүй.
6. QR Switch ажиллах flow
6.1 MPQR scenario (хамгийн их volume)
Cafe Monkey static QR sticker
Онбоординг үед үүсгэгдсэн.
Бат wallet app-аас scan хийнэ
Wallet app TLV parse
Extract: IBAN, BIC, MCC.
Дүн оруулна
"Cafe Monkey-руу төлөх — Дүн оруулна уу" → 25,000 ₮.
Wallet → PayGrid:
POST /v1/qr/resolveResponse: iban, psp_bic, alias, kyc_level, merchant_name.
Wallet → PayGrid:
POST /v1/payments/sepa-credit-transfersс creditorAlias=cafemonkey@gerege.
Standard PayGrid flow
Wallet-ын bank PISP API → SCA via e-ID Mongolia → bank pacs.008 → PayGrid → Cafe Monkey's PSP credit.
Bank webhook → Wallet → "Paid"
Cafe Monkey notification (via PSP).
6.2 Dynamic MPQR (POS-аас generated)
POST /v1/qr/dynamic/create
{
"creditor_iban": "MN20910010000000XXXX",
"creditor_psp_bic": "GWMNUBXX",
"amount_minor": 100000,
"currency": "MNT",
"merchant_category_code": "5814",
"reference": "ord-12345-abc",
"ttl_seconds": 300,
"callback_url": "https://merchant.example.com/qr-callback/ord-12345"
}
Response:
{
"qr_id": "qr_dyn_660f9510...",
"qr_payload": "00020112...63048CD7",
"qr_image_url": "https://api.paygrid.mn/qr/qr_dyn_660f9510.png",
"expires_at": "2026-05-06T14:28:00Z",
"pay_uri": "mn.paygrid://pay?...",
"deeplink_universal": "https://api.paygrid.mn/p/qr_dyn_660f9510"
}
6.3 CPQR scenario (high-volume retail)
- User wallet app-аас "Pay" товч → CPQR generate
- POS scanner-аар QR уншина
- POS → PayGrid:
/v1/qr/resolve+/v1/payments/sepa-credit-transfers - User → bank app SCA (e-ID Mongolia)
- Settlement, webhook to POS
7. QR endpoint specs
POST /v1/qr/resolve
Request:
{
"qr_payload": "00020101...63048CD7",
"psu_ip_address": "203.0.113.42"
}
Response (200):
{
"qr_type": "MPQR_STATIC",
"creditor_iban": "MN20910010000000XXXX",
"creditor_psp_bic": "GWMNUBXX",
"creditor_alias": "cafemonkey@gerege",
"creditor_name_display": "Cafe Monkey",
"merchant_category_code": "5814",
"merchant_city": "ULAANBAATAR",
"kyc_level": "QUALIFIED",
"verified_business": true,
"amount_minor": null, // null for static
"currency": "MNT",
"reference": "REF202605",
"expires_at": null,
"pay_uri": "mn.paygrid://pay?pa=cafemonkey@gerege&...",
"frm_score": 0.05,
"frm_warnings": []
}
Алдааны код
400 invalid_qr_format | TLV parse failure |
400 invalid_qr_checksum | CRC mismatch |
404 unknown_creditor | IBAN/alias not in registry |
410 qr_expired | Dynamic QR past expiry |
422 qr_blocked | Sanctions match or revoked alias |
Бусад endpoint
POST /v1/qr/static/create Generate static MPQR
POST /v1/qr/dynamic/create Generate one-time dynamic MPQR (POS)
POST /v1/qr/cpqr/generate Generate Consumer-Presented QR
GET /v1/qr/{qr_id}/status QR status
DELETE /v1/qr/{qr_id} Cancel/revoke QR
8. Database schema (qr_codes)
CREATE TYPE qr_type AS ENUM (
'MPQR_STATIC', 'MPQR_DYNAMIC', 'CPQR'
);
CREATE TYPE qr_status AS ENUM (
'CREATED', 'SCANNED', 'PAID', 'EXPIRED', 'CANCELLED'
);
CREATE TABLE qr_codes (
qr_id VARCHAR(40) PRIMARY KEY,
type qr_type NOT NULL,
creditor_iban VARCHAR(34),
creditor_alias VARCHAR(128),
creditor_psp_bic CHAR(11),
debtor_iban VARCHAR(34),
debtor_psp_bic CHAR(11),
amount_minor BIGINT,
currency CHAR(3) NOT NULL DEFAULT 'MNT',
merchant_category CHAR(4),
reference VARCHAR(50),
qr_payload TEXT NOT NULL,
pay_uri TEXT,
status qr_status NOT NULL DEFAULT 'CREATED',
expires_at TIMESTAMPTZ,
callback_url VARCHAR(500),
payment_id VARCHAR(40) REFERENCES payments(payment_id),
scanned_at TIMESTAMPTZ,
paid_at TIMESTAMPTZ,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
9. QPay parity / migration path
Phase 1: Coexistence (2026 Q4 - 2027 Q1)
- MNQR launched
- QPay continues operating
- Wallets accept BOTH QPay and MNQR formats
- Merchants can choose
Phase 2: Convergence (2027 Q2-Q3)
- QPay merchants get free MNQR conversion
- Hi Payment Solutions optionally joins PayGrid as PSP-аар (so QPay merchants become MNQR-routed)
- Cross-acceptance via aliasing
Phase 3: Sunset (2027 Q4+)
- QPay-only QRs deprecated
- All merchants on MNQR via their PSP
- Single national QR standard
QPay → MNQR translation
| QPay merchant ID | PayGrid alias (qpay-merchant-12345@hipayment) |
| QPay invoice (one-time) | Dynamic MPQR with TTL |
| QPay static QR | Static MPQR via API |
| QPay settlement (T+1) | PayGrid DNS settlement (T+0 net) |
| QPay acquirer fee | PayGrid 0.3% capped |
10. Security (QR-specific)
Anti-tampering
- Static QR: CRC-16, optional pay_uri JWS by PSP, anti-sticker-swap (regular sweeps + verified business badge)
- Dynamic QR: Nonce + expiry in pay_uri, server-side single-use state, replay detection (PAID status check)
Anti-phishing
- pay_uri verifies against PayGrid DICT
- Wallet app shows verified business badge for QUALIFIED merchants
- Confirmation of Payee on resolve
- Suspicious URL warning (TLD typo, near-miss alias)
Sanctions
/v1/qr/resolvecalls FRM engine- If creditor on sanctions list: 422 + audit + alert ops
- Daily refresh: re-screen all active QRs
Privacy
- Static QR contains only: alias, IBAN (last-4 visible), MCC
- Owner identity (full name) NOT in QR
- Scan events anonymized after 30 хоног
11. Performance targets
QR resolve: p50 < 100ms, p95 < 300ms (cached)
QR generate (static): p50 < 200ms, p95 < 500ms
QR generate (dynamic):p50 < 300ms, p95 < 800ms
QR image render: p50 < 100ms (PNG cached)
QR scan event log: async (non-blocking)
Throughput:
Phase 2: 50 QR resolves/sec sustained
Phase 3: 500 QR resolves/sec
12. Deployment timeline
Phase 1.5:
─ EMVCo TLV encoder/decoder library
─ Static MPQR generation
─ /v1/qr/resolve endpoint
─ Sandbox testing with Wallet partners
Phase 2:
─ Dynamic MPQR
─ CPQR
─ QR scan analytics
─ FRM integration on resolve
─ MNQR profile published (Mongolbank consultation)
Phase 2.5:
─ QPay format compat layer
─ POS SDK with QR generation
─ Production launch
Phase 3:
─ QPay migration / coexistence
─ Cross-PSP merchant directory
─ QR analytics dashboard for PSPs
Эх сурвалж: PLAN/15-QR-SWITCH.md.
Дараагийн хуудас: Phase plan →