ISO 8583 Parser
Free ยท Reference ยท ~8 min read ยท Updated 2026-08-09

Partial Approval & DE 54: When the Approved Amount Isn't What You Asked For

There is 30.00 on the card and the customer is trying to pay 50.00. One possible answer is a decline โ€” DE 39 = 51, insufficient funds. The other is a partial approval: the issuer approves 30.00, says so explicitly in the response, and leaves the remaining 20.00 to be collected some other way. It is routine on gift and prepaid cards โ€” and it quietly breaks every system built on the assumption that the DE 4 you get back is the DE 4 you sent.
On this page: What a partial approval is ยท No opt-in, no partial approval ยท One transaction, two different DE 4s ยท Slicing DE 54 ยท After the approval

What a partial approval is

An ordinary authorization is all-or-nothing: the issuer either approves the full DE 4 amount or declines the whole thing. A partial approval is the third outcome. When the account can cover some of the purchase but not all of it, the issuer approves exactly what the balance allows and reports the approved figure back to the terminal.

The classic customers are cards whose balance nobody knows off-hand: gift cards (who remembers there is 7.42 left on it?), prepaid cards, and debit cards running low. For the merchant it converts a dead decline into most of a sale โ€” 30.00 captured now, 20.00 collected in cash or on another card. That is valuable enough that card networks push acceptance of it hard for common merchant segments on prepaid products.

Mechanically there is nothing exotic: no new message type, no special MTI. It is the same 0100/0110 authorization pair (or 0200/0210 financial pair) you already know, with three fields carrying the whole story:

No opt-in, no partial approval

The issuer never springs a partial approval on a terminal that isn't ready for it. It will only answer with one if the authorization request declared support first โ€” a partial-approval support indicator set by the terminal or acquirer. No indicator, and the same card in the same shop gets a plain DE 39 = 51 insufficient-funds decline; the sale dies even though 30.00 was sitting right there. (Some issuers still attach the available balance in DE 54 of the decline, but nothing is approved.)

Where does the indicator travel? This is the one part of the flow ISO 8583 itself does not pin down. Each network defines its own subfield for it inside the additional-data fields (the DE 48 / DE 60 family), so the exact tag and position come from your interface spec, not from the standard. What is universal is the contract: the flag in the request is what unlocks code 10 in the response.

Setting that flag is a promise, not a formality. It commits the POS side to three behaviours: display and print the approved amount rather than the requested one, run a split-tender flow for the difference, and reverse the authorization if the customer abandons the sale. If your terminal software can't do all three, don't set the flag.

One transaction, two different DE 4s

Here is the whole exchange at a glance โ€” the same purchase, request and response side by side:

Partial approval: the same transaction in request and response โ€” DE 4 is 50.00 in the 0100 request but 30.00 in the 0110 response, with DE 39 = 10 and the remaining balance in DE 54 0100 ยท Authorization request terminal / acquirer โ†’ issuer DE 3 ยท Processing code 000000 = goods & services DE 4 ยท Amount, transaction 000000005000 = 50.00 requested DE 49 ยท Currency code 840 = USD, 2 decimals Support indicator ยท network-defined subfield partial approvals supported 0110 ยท Authorization response issuer โ†’ terminal / acquirer DE 39 ยท Response code 10 = partial approval, not 00 DE 4 ยท Amount, transaction 000000003000 = 30.00 approved DE 54 ยท Additional amounts 0002 840 C 000000000000 Still owed by the customer 20.00 = split tender or walk away two DE 4s, two values
The request asks for 50.00; the response approves 30.00. DE 4 is not echoed back โ€” it is rewritten. DE 39 = 10 is the only reliable signal that this happened, and DE 54 reports what is left on the account (spaces added inside DE 54 for readability).

Three things to internalise, one per field:

Want to poke at it yourself? Paste these two ASCII messages into the parser โ€” the request first, then the response, and watch DE 4 change between them:

01007020000000808000164000001234567890000000000000005000123456TERM0001840

0110302000000680840000000000000000300012345665432110TERM00018400200002840C000000000000

Slicing DE 54 โ€” Additional Amounts

DE 54 is a variable-length field (LLL, up to 120 characters) whose content is one to six fixed 20-character groups, concatenated with no separators. The length is therefore always a multiple of 20, and the only correct way to parse it is index arithmetic: take the LLL length, divide by 20, cut. Each group reads:

PositionsSub-elementMeaning
1โ€“2Account typeSame code list as positions 3โ€“4 of DE 3, the processing code: 00 default, 10 savings, 20 checking, 30 credit
3โ€“4Amount typeWhat this amount is. The two you will actually meet: 01 ledger balance, 02 available balance. The full list is interface-specific
5โ€“7Currency codeISO 4217 numeric โ€” check it in currency codes & exponents. Read it per group: it need not equal DE 49, e.g. when the issuer reports the balance in the cardholder's billing currency
8SignC credit (positive), D debit (negative, e.g. overdrawn)
9โ€“20Amount12 digits, right-justified, zero-padded, in minor units of the group's currency โ€” same convention as DE 4 (see why amounts have no decimal point)

Apply that to our response value:

0002840C000000000000
โ”‚ โ”‚  โ”‚  โ”‚โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚ โ”‚  โ”‚  โ”‚ amount: 000000000000 โ†’ 0.00
โ”‚ โ”‚  โ”‚  โ”” sign: C (positive)
โ”‚ โ”‚  โ”” currency: 840 = USD, exponent 2
โ”‚ โ”” amount type: 02 = available balance
โ”” account type: 00 = default

Reading: "the default account's available balance is now USD 0.00." A two-group value is just two of these back to back โ€” 40 characters, e.g. ledger balance followed by available balance:

0001840C000000003000  โ† ledger balance 30.00
0002840C000000003000  โ† available balance 30.00
(on the wire: one 40-character string, no separator)

That shape โ€” same structure, different amount type โ€” is also how balances come back on ATM balance inquiries and on declines that report the balance. Learn to cut it once and you can read all of them.

After the approval: collect the rest, or give it back

A partial approval leaves the sale unfinished by design, and the two loose ends are both the terminal's job:

In short: the terminal declares support in the request; the issuer answers with DE 39 = 10, rewrites DE 4 to the approved amount, and reports the remaining balance in DE 54 as 20-character groups. The response DE 4 is the money that exists; the request DE 4 is only what you asked for. Collect the difference another way โ€” and if the sale dies, reverse the hold instead of leaving it to rot.

Read next