KKI on QRIS: What Merchant Systems Must Handle

KKI on QRIS: What Merchant Systems Must Handle
Bank Indonesia and ASPI launched Kartu Kredit Indonesia for the retail segment on 17 August 2026. In its first phase it is a digital card that acts as a funding source for QRIS. Merchants need no new QR code, terminal, or contract. What changes is downstream: bigger tickets, unfamiliar issuer codes, and a refund path worth confirming in writing.
That last sentence is the whole article. The rest is the detail behind it.
What exactly launched on 17 August?
KKI is a deferred-payment instrument processed on domestic rails instead of an international card network. Bank Indonesia and the Indonesian Payment System Association introduced it on 17 August 2026 for the general retail segment.
The first phase is deliberately narrow:
- Digital card only. No plastic yet. Physical cards and online-payment support are planned for later phases.
- QRIS is the acceptance rail. It works across QRIS MPM, QRIS CPM, and QRIS TAP.
- Eight issuers at launch. Seven first movers — BCA, Bank Mandiri, BNI, BRI, CIMB Niaga, Permata Bank, and Bank Mega — plus BSI as a next mover, with more payment service providers to follow.
- Rp10 million per transaction, with merchant fees quoted at 0% to 0.7% and an interest ceiling of 1.75% per month or 21% per year.
Scale matters here. QRIS reached 65.77 million users and 44.86 million merchants, 96.68% of them MSMEs, with 12.55 billion transactions worth Rp1.12 quadrillion in the first half of 2026 — up 93.92% year on year according to Bank Indonesia figures published on 17 August 2026. A change to what can fund a QRIS payment is a change that reaches almost every payment integration in the country.
KKI holders can also pay abroad through QRIS Cross Border in partner countries. That is an outbound story for travellers, not a new inbound scheme for Indonesian merchants — if you serve foreign guests, your existing cross-border QRIS arrangement with your acquirer is what governs that, and it is unchanged.
Why does a funding source matter to a merchant at all?
QRIS was designed to keep two things apart: how a customer funds a payment, and how a merchant accepts one. The merchant integration binds to the acceptance side only.
This is why the honest answer to "what do we have to build?" is nothing. The QR payload is the same. The callback contract is the same. Your acquirer relationship is the same.
What is not the same is the distribution of what arrives. A payment method that used to be capped by whatever sat in someone's wallet balance is now capped by a credit line.
What breaks when tickets get bigger?
Systems built during the era of small QRIS payments carry assumptions nobody wrote down. Those assumptions are where this shows up.
The regulatory ceiling is Rp10,000,000 per transaction under PADG No. 3 of 2025, dated 19 February 2025, and KKI carries the same per-transaction figure. Issuers may set lower daily and monthly limits of their own. Rp10 million is the number your validation should tolerate; anything lower is somebody else's risk policy, not yours to hardcode.
Go looking for these:
- Amount caps below Rp10 million. Often a constant from a launch two years ago that nobody revisited. A hard rejection at Rp2 million now declines real money.
- QR expiry that is too short. Fifteen seconds is fine for a bakery. It is not fine for a Rp6 million purchase where the customer reads the amount twice before scanning.
- Velocity and fraud rules tuned for small tickets. A rule that flags anything above the 99th percentile of last year's amounts will start flagging ordinary sales.
- Invoice splitting workarounds. Some systems split a large bill into several QRIS payments because "QRIS is for small amounts." That workaround now produces multiple partial settlements to reconcile for no reason.
- Settlement float assumptions. A larger average ticket changes the cash-flow gap between sale and settlement, which matters more for a hotel or a contractor than for a warung.
None of these are exotic. They are the kind of thing you find in an afternoon by grepping for currency constants.
Will unknown issuer codes break your reconciliation?
This is the failure I would bet on. The issuer list is explicitly phased — seven first movers, then BSI, then other qualified providers over time. Any code that treats issuer identifiers as a closed set will eventually meet a value it has never seen.
The pattern to avoid:
// Brittle: a new issuer becomes an exception in production.
const ISSUERS = ["BCA", "MANDIRI", "BNI", "BRI"] as const;
if (!ISSUERS.includes(tx.issuer)) throw new Error("unknown issuer");
The rule is simple: an identifier you do not recognise is still a valid transaction. Store the raw string, record that it was unrecognised, and continue. The same applies to the funding-source field, where a value meaning credit is new in a field that previously only carried balance or debit.
// Tolerant: unknown values are data, not errors.
const known = ISSUER_LABELS[tx.issuer];
if (!known) logger.info({ issuer: tx.issuer }, "unmapped issuer code");
return { ...tx, issuerLabel: known ?? tx.issuer };
Rejecting an unrecognised value in a payment path converts a cosmetic gap in a lookup table into lost revenue. Same reasoning as idempotency keys in payment APIs: payment code should be the most forgiving code in your system about inputs it did not anticipate, and the least forgiving about doing work twice.
What about refunds and disputes?
Here I will describe questions rather than answers, because the honest position is that the operational detail differs by acquirer.
QRIS refunds have always been merchant-initiated and processed through the acquirer. Credit introduces a cardholder with a monthly statement, an issuing bank, and a consumer-protection relationship that a topped-up wallet does not have. Do not assume the two behave identically.
Put these to your acquirer in writing before your first large KKI-funded sale:
- What is the refund window for a KKI-funded QRIS transaction, and does it differ from a wallet-funded one?
- Are partial refunds supported, and do they settle on the same schedule?
- Who bears the merchant fee on a refunded transaction?
- If a cardholder disputes a charge with their issuer, what is the merchant's notification path and evidence requirement?
- Which field in the settlement file identifies the funding source, and is it present in the real-time callback as well as the end-of-day file?
Question five is the one that decides whether you can even measure this. If the funding source only appears in the daily file, your live dashboards cannot separate KKI volume from wallet volume, and you will be reconciling blind.
Does this change your MDR math?
Not the logic, only the inputs. Merchant fees for KKI-funded QRIS are quoted in the same 0%–0.7% band as the wider QRIS structure, and the tiering that takes effect on 1 October 2026 applies on top: MDR 0% for transactions up to Rp100,000 across all merchant categories, and up to Rp500,000 for micro merchants.
If you already handle fees as a function of merchant category and transaction value rather than a fixed percentage, KKI adds nothing new. If you do not, the fee-logic work is the same work described in the October MDR changes, and it is now overdue rather than upcoming.
One rule survives every fee change: store gross amount, fee, and net amount as three separate fields, and reconcile on net. Systems that store gross and recompute the fee always drift when the rate table moves.
A test matrix you can run this week
You cannot test KKI end to end without a KKI card. You can test everything on your side that a KKI transaction will touch.
| Case | Input | Expected |
|---|---|---|
| Fee-free boundary | Rp99,999 / Rp100,000 / Rp100,001 | Correct tier chosen at each, no rounding gap |
| Micro-merchant boundary | Rp500,000 on a UMi-classified merchant | Fee 0, net equals gross |
| Regulatory ceiling | Rp10,000,000 | Accepted |
| Above ceiling | Rp10,000,001 | Rejected with a clear message, not a crash |
| Unknown issuer | Issuer code ZZZZ | Recorded and settled, logged as unmapped |
| Unknown funding source | Funding type CREDIT | Recorded and settled |
| Fee non-zero path | Rp750,000 on a non-UMi merchant | Gross, fee, and net stored separately |
| Refund of a large ticket | Refund Rp6,000,000 | Fee handling matches your acquirer's written answer |
Eight cases. Most of them are amount constants and one enum. An afternoon of work, run before the volume arrives rather than during the first month-end close that does not balance.
What this actually asks of you
The temptation with a launch this visible is to treat it as a project. It is not. The acceptance layer did not move, and no merchant has to sign anything.
But a payment method that was quietly bounded by wallet balances is now bounded by credit limits, and every assumption your code made about "QRIS means small" is now a defect waiting for the right customer. Find the constants. Loosen the enums. Ask your acquirer the refund questions and keep the answers.
The systems that will handle this badly are not the ones that did nothing. They are the ones that were sure nothing needed doing.
Related Posts
Building something similar?
IoT Backend & Multi-Protocol Integration
Backends that ingest device telemetry across MQTT, WebSocket, Modbus, and BLE, and normalize it into reliable real-time dashboards.
See how I can help