Capital Markets and Settlement
Where Money Leaks Between Authorisation and Capture
In one line
A card payment is split into two events, authorization and capture, with hours to days in between, and in that interval you get missed captures, partial-capture leftovers, and double charges from idempotency failures.
Why this was needed
When you join a PG (payment service provider) company, the first question you usually get is this: "Why is the number of authorizations different from the number of captures?"
Being different is normal. A card payment does not finish in one step.
승인 authorization 이 카드로 이만큼 쓸 수 있는지 확인하고
그만큼을 한도에서 떼어 둔다. 돈은 아직 안 움직인다.
매입 capture 실제로 청구한다. 여기서 돈이 움직인다.
Many merchants capture after delivery is complete, so the gap between the two stretches from hours to days. That is why the authorization count and the capture count differ by nature. The problem is not the fact that they differ but not being able to name the reason for the difference. If you cannot name the reason, you cannot tell even when a real incident is mixed into that difference.
How it works
Every authorization ends up as one of three things.
전량 매입 승인 금액만큼 청구됐다. 정상 종료.
부분 매입 승인 금액보다 적게 청구됐다. 주문 일부 취소·품절이 원인.
차액은 승인 취소를 따로 내지 않으면 고객 한도에 계속 묶인다.
매입 없음 승인만 나고 끝났다. 여기가 위험하다.
Why an authorization without a capture is dangerous is that authorizations have an expiry period. They usually release automatically somewhere between several days and a month, and a capture attempted after the release is declined. By then there is no way to undo it — the merchant ends up having shipped the goods without getting paid. So the items that have only an authorization and no capture must be found before the expiry period passes, and this is the kind of check that has to run daily as a batch.
The remaining balance of a partial capture has the same nature. If only 30,000 won was captured on a 50,000 won authorization, the 20,000 won stays tied up in the customer's limit unless a separate authorization void is issued. The customer's next payment is declined because of 20,000 won they never spent, and that inquiry comes to the call center.
Idempotency keys and double charges. A payment request may actually have succeeded even when it timed out. A client that did not get a response retries, and if the server does not return the same result for the same request, the authorization happens twice. If the two authorizations are each captured, the customer is charged twice.
The most important fact here is this: the two authorizations have different auth_id values. If you look for duplicates by authorization number, nothing comes up. The fact that the same thing was done twice remains only in the idempotency key. So a double-charge investigation always starts from a tally by idempotency key. If the system does not store the idempotency key at all, that fact itself is the first item to report.
What it looks like in the field
At one PG, complaints about double charges once piled up for a particular merchant. That merchant's payment module set the response timeout to 3 seconds, and the card issuer's authorization response normally took about 2.8 seconds. It normally got by just barely, but whenever the card issuer side got slightly slower, timeouts hit in bulk, and a retry went out each time. The idempotency key was in the request body, but the PG server did not store it and just passed it through.
Two things were fixed. Rather than lengthening the timeout, they made it store the idempotency key and return the same response for the same key. Retries do not go away, so the receiving side has to stop them. And they found the double charges that had already happened and refunded them, and what they used to build that list was a tally by idempotency key. The 45 cases that never came up however hard they searched by authorization number came out all at once the moment they were grouped by idempotency key.
The authorization-to-capture time lag has the same structure as T+2 in securities. The event is split in two, the state lives between them, and if you do not watch that state, money leaks. The domain is different, but the shape of the problem you have to deal with is the same.
What you will do in the next lab
You build logs of 3,045 authorizations and 2,745 captures and explain the difference completely in terms of authorization voids, declines, partial captures, and no capture. You produce the amount of authorizations with no capture and the remaining balance of partial captures separately, and finally you group by idempotency key to find the amount that was double charged.