Tunas Akara
Back to Blog

QRIS MDR on 1 October 2026: Integration Checks

BI's Oct 1 QRIS MDR expansion isn't just a fee cut. It's a fee-logic change your POS and gateway integration has to handle correctly.

by RayhanUpdated 8 min read

For Business

qrispaymentsfintechindonesiaintegration
QRIS MDR on 1 October 2026: Integration Checks
On this page

Bank Indonesia announced on August 17, 2026 that it is expanding the 0% Merchant Discount Rate (MDR), the fee deducted from merchant receipts, policy for QRIS, effective October 1, 2026. Micro merchants (UMI) keep the free tier they already had, up to Rp500,000 per transaction. All merchant categories receive 0% MDR for transactions up to Rp100,000. Small, medium, and large merchants (UKE, UME, UBE) retain 0.7% above that line; other categories follow their own rates. This policy has been in effect since 1 October.

BI's release covers the policy; Kompas's breakdown covers the numbers.

Most coverage stops at "QRIS just got cheaper." For a business running a POS system, an e-commerce checkout, or a payment gateway integration, that's the wrong takeaway. The right one: your fee calculation changes on a fixed date. If the logic behind it is wrong, your settlement totals are wrong from the first transaction after midnight on October 1.

What actually changes

Before this update, regular QRIS MDR for UKE/UME/UBE was 0.7% on every transaction, regardless of size. UMI already had a 0% tier up to Rp500,000, with 0.3% above it.

What changes on October 1: UKE/UME/UBE — the bulk of small and medium businesses running a standard QRIS setup — get the same threshold logic UMI already had. Free up to Rp100,000, 0.7% above it. The announcement came from Destry Damayanti, BI's Acting Governor, at a Jakarta event that also launched the Kartu Kredit Indonesia (KKI) domestic card scheme.

The ceremony isn't what matters to your codebase. What matters: More merchant categories now have amount-based MDR thresholds. It was already conditional for UMI. Now it's conditional for almost everyone.

The fee table to code against

This is the table your fee-calculation logic needs to match:

Merchant category0% MDR thresholdRate above threshold
UMI (micro)Up to Rp500,0000.3%
UKE / UME / UBE (small / medium / large)Up to Rp100,000 — new from Oct 10.7%
EducationUp to Rp100,0000.6%
SPBU / fuel stationsUp to Rp100,0000.4%
BLU, PSO, G2P, P2G, donationsAlways 0%—

The last row matters as much as the new thresholds: those categories were already free and stay free. One constraint worth building into your logic regardless: merchants are prohibited from passing MDR costs to the consumer, so "add the fee to the displayed price" was never compliant and still isn't. Kompas's report lays out the full structure this table is built from.

Why naive fee logic breaks

Think of a tiered parking rate: the first hour is free, the next hours cost money, and a government-plated car pays a different rate entirely. A cashier who memorizes one flat number without checking the vehicle type will bill it wrong every time. Fee logic that stores MDR as one constant fails the same way.

An integration that hardcodes "QRIS = 0.7%" in a settlement script produces wrong numbers on October 1. So does one that calculates MDR from transaction amount alone, without knowing which BI merchant category the transaction belongs to.

Loading diagram…

Both branches have to resolve before the rate does. Skip the category check, and a Rp80,000 transaction from a medium retailer gets charged the old flat 0.7% when it should be free. Skip the amount check, and a Rp600,000 transaction from a micro merchant gets treated as fully free, when 0.3% applies once that merchant crosses Rp500,000. Neither bug throws an error. Both quietly produce a settlement number that doesn't match what the PSP actually pays out.

Reconciliation and settlement impact

This is where the change surfaces for a finance team: not in the policy, but in the gap between what your system calculates and what the settlement file says. Once your payment service provider (PJP) or payment gateway updates its fee engine for October 1, net settlement amounts change for transactions covered by the new free tier. The impact depends on your merchant categories and transaction amounts.

If your reconciliation logic hasn't shifted with it, daily totals stop matching. That's the failure mode to plan for: not an outage, a quiet discrepancy between two numbers that used to agree.

Webhook-driven settlement notifications make this worse if they aren't deduplicated and reconciled carefully — see webhook reliability patterns if that part of your pipeline hasn't been audited recently. Retried settlement callbacks are the other half of that problem: if a status update fires twice for the same transaction and your handler isn't idempotent, you can post the same corrected fee twice. Idempotency in payment APIs covers how to make retries safe.

Build a variance check into your daily reconciliation job: flag any settlement line where computed MDR doesn't match the fee table for that merchant's category and amount, and route it for review instead of letting it post silently.

Merchant-tier awareness

Even before this change, a system needed to distinguish QRIS merchant categories. That remains necessary after October 1: two merchants processing an identical Rp300,000 transaction can owe different fees, because one is registered as UMI and the other as UKE.

Your system needs to know, per merchant or sub-merchant, which BI category it's registered under — not infer it from transaction patterns, not assume it from business size on paper. Running a multi-tenant platform with sub-merchants under one aggregator account? Add BI category as a field on the merchant record, sourced from what your PSP has on file.

Five questions for your payment gateway after the change

Whether you're on Midtrans, Xendit, or another PSP, get documented answers for the rates now in force:

  1. What's the updated fee schedule, and when does it go live on your end? Compare Midtrans's fee documentation with your contract and recent transaction statements; confirm whether its test environment uses production rates.
  2. How is merchant-category mapping exposed to you? Via API field, dashboard label, or not at all — if not at all, ask directly.
  3. Can you verify the new rates in test mode before cutover? Simulate transactions in the test environment, then reconcile small production transactions against provider statements. Test environments do not always apply the latest production rates.
  4. Does the settlement report format change? New columns or category labels break a reconciliation script that parses by fixed position or fixed field name.
  5. What's the rollout timing — hard cutover at midnight, or phased? Xendit's documentation currently lists T+1 settlement; confirm whether that timing shifts during the transition.

Close

This isn't a merchant-fee headline to skim past. It's a compliance-adjacent deadline with a specific date, a specific fee table, and a specific set of systems calculating against it.

Written confirmation from your PSP and tests of the rates now in force help catch discrepancies before they become reconciliation problems or merchant disputes.

Related Posts

Need help applying this approach?

Payment & API Integration

Connect payment services to your business systems. Plan transaction tracking, payment issue handling, and reconciliation of operational records.

Explore related services

Describe the operational problem you are facing so we can discuss a suitable next step.

Share this article
Free Initial Discussion