- Introduction — The World Behind the Pay Button
- The Cast of Five
- Authorization vs Capture vs Settlement — The Three Phases
- Following the Authorization Flow
- 3-D Secure — Authentication That Shifts Liability
- Chargebacks — When the User Disputes
- Idempotency — The Constant That Prevents Double Charges
- Reconciliation — Making the Books Agree
- PCI-DSS — The Rules for Handling Card Data
- Seeing the Whole Picture Again
- Conclusion
- References
Introduction — The World Behind the Pay Button
When a user taps "Pay," it looks like it takes less than a second. But inside that second, the card number travels through half a dozen companies and at least two payment networks all the way to the issuing bank and back. And the money does not actually move from account to account at that moment — it moves days later.
Payments are, more than almost any other system, a domain where being wrong is unacceptable. If a search result is off by one, the user is merely inconvenienced. If a payment is off by one, someone loses money. That is why consistency, idempotency, and auditability come before everything else in a payment system.
This post is a map for engineers who are designing or trying to understand a payment system for the first time. We will look at how authorization, capture, and settlement differ; which players sit between them; what 3-D Secure and chargebacks are; and why reconciliation, idempotency, and PCI-DSS are constants of payments. Since security is mandatory here, if you want the fundamentals of authentication and tokens, see this site's Auth & Security Lab, and if the response codes that show up below are unfamiliar, keep the HTTP Status Code Reference handy.
The Cast of Five
The first step to understanding card payments is knowing who does what. A single card payment involves at least five players.
- Merchant: the party selling goods or services. This is the service we build.
- PSP / gateway (payment service provider / payment gateway): the intermediary that connects the merchant to the complex financial rails. Companies like Stripe, Adyen, or Braintree. They receive card details securely and talk to all the players below on the merchant's behalf.
- Acquirer (acquiring bank): the bank that "acquires" the card funds on behalf of the merchant. It is the party that gets money into the merchant's settlement account.
- Card network (scheme): networks like Visa and Mastercard that route transactions between acquirers and issuers. They also set the rules and the interchange fees.
- Issuer (issuing bank): the bank that issued the card. It holds the final authority to decide whether to approve a transaction, checking limits, balance, and fraud.
Here is how the five connect.
[Merchant] --card data--> [PSP/gateway] --> [Acquirer]
│
▼
[Card network]
│
▼
[Issuer] --approve/decline--> (response returns in reverse)
The core intuition: the card network is a "router," the issuer is the "decision maker," the acquirer is the "merchant's bank," and the PSP is the "adapter" that hides all of this complexity. In our code, we usually face just one PSP API, but behind it the whole chain moves on every transaction.
Authorization vs Capture vs Settlement — The Three Phases
The most common misconception when learning payments is thinking "payment = money moving." In reality, three phases are separated in time. If you fail to distinguish them, your payment state management will inevitably tangle.
1. Authorization. The step where you ask the issuer, "May this card pay this amount?" and get an answer. The issuer checks limits, balance, and fraud signals and responds approve or decline. When approved, that amount is placed on hold against the card's available credit. But money has not actually left at this moment. It is closer to a "reservation."
2. Capture. The step where you confirm you actually intend to charge the authorized amount. In online commerce you typically capture when the goods ship. Separating authorization from capture is clean: if you must cancel an order because it is out of stock, you can void the authorization before capture. You can also capture less than the authorized amount (partial capture).
3. Settlement. The step where funds actually move from the issuer to the acquirer and into the merchant's account. This usually happens in a batch, once a day. So there is a gap of several days between the day a user pays and the day the merchant actually receives the money.
The relationship becomes clear on a timeline.
T+0s authorization -> hold on credit, money hasn't moved yet
T+hours~day capture -> confirm "charge this amount"
T+1~3d settlement -> actual money movement, merchant account credited
For instant or one-tap payment products, authorization and capture can appear to happen together (a sale/purchase flow). But internally these phases still exist, and settlement always happens later in a batch — that does not change. A payment system's state machine should be designed to reflect exactly these three phases.
Following the Authorization Flow
Let us trace how a single authorization flows, step by step, from the moment the user enters card details and taps pay.
1) User enters card details -> merchant frontend
2) Merchant (or PSP SDK) sends card data to the PSP (tokenized)
3) PSP -> authorization request to the acquirer
4) Acquirer -> routes to the card network
5) Card network -> forwards to the correct issuer
6) Issuer judges limit/balance/fraud -> approve or decline
7) The response travels back along the same path in reverse
8) Merchant receives the result and updates the order state
There are a few points here that engineers must watch carefully.
First, this round trip crosses several network hops, so it is slow and can fail. Timeouts, dropped connections, and PSP outages happen. So you must always assume the case of "I never got a response." This is exactly why the idempotency covered later is necessary.
Second, declines come in several kinds: insufficient funds, over limit, card reported lost, suspected fraud, temporary issuer outage, and more. Some declines may succeed on retry (soft decline), while others are pointless to retry and only worsen the card's fraud score (hard decline). Distinguishing and handling these two directly affects conversion.
Third, the response usually comes with an authorization code. This code is the key to identifying the transaction later in capture, void, refund, and reconciliation, so you must store it.
3-D Secure — Authentication That Shifts Liability
Online payments (card-not-present) lack a physical card and are therefore vulnerable to fraud. To compensate, the card networks created an authentication protocol called 3-D Secure (3DS). It is known under brands like Visa's "Verified by Visa" and Mastercard's "Identity Check," and the widely used version today is 2.x.
In summary, 3DS works like this. During payment, the user is sent to an authentication step controlled by the issuer. There the issuer may require extra authentication (an app push approval, a one-time password, biometrics). Once authentication finishes, control returns to the payment flow and authorization proceeds.
payment request
│
▼
3DS authentication starts -> issuer authentication screen (if needed)
│ (app approval / OTP / biometrics)
▼
authentication result carried into the authorization request
│
▼
approve or decline
The core of 3DS is not the technology but the commercial concept of liability shift. When fraud occurs on a 3DS-authenticated transaction, responsibility for the loss moves from the merchant to the issuer. In other words, 3DS is less a tool that stops fraud entirely and more a mechanism that changes who bears the fraud loss.
3DS 2.x is smarter than earlier versions. It lets low-risk-looking transactions pass without asking the user anything (frictionless flow) and only requires extra authentication when things look risky (challenge flow). Europe's PSD2/SCA (Strong Customer Authentication) regulation effectively made such authentication mandatory. When designing a payment system, you must treat every case in the 3DS step as a state: the user abandoning, authentication failing, or the callback being delayed.
Chargebacks — When the User Disputes
A successful payment is not the end. The user can later dispute that payment. This is a chargeback.
A chargeback begins when a user disputes a transaction with their own card issuer, saying "this transaction is wrong." The reasons vary: I never received the item, it differs from the description, I did not make this charge (fraud), it was billed twice. If the issuer accepts the dispute, it reverses the money that already went to the merchant and refunds the user.
User -> raises a dispute with the issuer
│
▼
Issuer starts a chargeback via the acquirer -> funds pulled back from the merchant
│
▼
Merchant can push back with evidence (representment)
│
▼
Final ruling via the card network's arbitration
A chargeback differs from a refund. A refund is the merchant voluntarily returning money; a chargeback is money forcibly pulled back through the card system. Chargebacks are unfavorable to merchants in several ways. You not only lose the funds but also pay a separate chargeback fee, and if your chargeback ratio gets high, the card networks may impose penalties or even revoke your merchant status.
So a payment system needs a flow for handling chargebacks: receiving the chargeback notice and updating the order state, gathering evidence and submitting a representment, and monitoring the chargeback ratio. To reduce fraud-driven chargebacks, you combine the liability shift of 3DS with fraud detection rules.
Idempotency — The Constant That Prevents Double Charges
Because the payment flow crosses the network several times, failures are frequent, and failures lead to retries. Here a fear peculiar to payments arises: a retry can create a double charge.
The scenario: the merchant sends an authorization request to the PSP. The PSP successfully makes it all the way to the issuer and the authorization succeeds. But on the way back, the network drops the success response. From the merchant's side, all it knows is "I got no response," so it cannot tell whether it succeeded or failed. To be safe, it retries. But the first request already succeeded, so the retry creates a second payment. The user is charged twice.
The standard solution is the idempotency key. If the client generates a unique key for each payment request and sends it along, then when the server receives a request with the same key a second time, instead of processing it anew it returns the first result as-is. No matter how many times you retry, the payment happens only once.
Request 1: POST /charges Idempotency-Key: abc-123 -> run payment, store result
(response lost)
Request 2: POST /charges Idempotency-Key: abc-123 -> return the stored result as-is
(payment does not happen again)
This post only touches the concept, but idempotency is so central to payment systems that a separate post covers key lifetime, dedup windows, unique constraints, and the payment state machine in depth. For now, it is enough to firmly internalize the principle that "a payment request must always be idempotent."
Reconciliation — Making the Books Agree
A task that does not surface visibly yet is decisively important in a payment system is reconciliation. Reconciliation means checking whether "the transactions our system recorded," "the transactions the PSP or card company recorded," and "the money that actually landed in the bank account" all agree.
Why is this needed? Because payments pass through many players and many phases, a mismatch can arise at any point.
- Our system recorded an authorization as successful, but the PSP's settlement report may be missing that transaction.
- There were 100 captures, but the settlement deposit covers only 98 (because of fees, chargebacks, refunds deducted).
- When the double charges, partial captures, and refunds we saw earlier get entangled, the amounts drift subtly.
The basic idea of reconciliation: compare the list of transactions in our internal ledger against the settlement file the PSP provides daily, and classify each into present in both, present only on our side, and present only on the PSP's side.
transactions in internal ledger vs transactions in PSP settlement file
│ │
▼ ▼
match (by transaction ID / auth code / amount)
│
├─ present in both -> OK
├─ ours only -> settlement missing? needs investigation
└─ PSP only -> a transaction we missed? needs investigation
When a mismatch appears, you classify it as an exception for a human to investigate or an automated rule to resolve. A well-built payment system runs reconciliation automatically every day and observes the count and amount of mismatches as metrics. Clean reconciliation is the most direct evidence that "we are not losing money." And to make reconciliation possible at all, every transaction must be recorded as an immutable entry in the first place. At this point payments naturally meet the design of an accounting ledger.
PCI-DSS — The Rules for Handling Card Data
A card number is extremely sensitive information, because a leak leads straight to financial harm. So the card industry created a security standard called PCI-DSS (Payment Card Industry Data Security Standard) and requires everyone who stores, processes, or transmits card data to follow it.
PCI-DSS has a vast set of requirements, but the big principles for an engineer to understand first are these.
- If you can avoid storing it, do not store it. The moment you directly store the full card number (PAN), expiry, or CVC, the scope of PCI compliance explodes. The CVC must never be stored after authorization.
- Use tokenization. Instead of the real card number, keep only a meaningless token that stands in for it in our system. The real card number is held only in a PCI-certified PSP or a dedicated vault. Most services minimize their PCI scope this way.
- Minimize scope. The fewer systems that card data passes through, the easier auditing and management become. Using a PSP's hosted payment page or client-side tokenization (for example, sending card details straight from the browser to the PSP and receiving back only a token) can keep the card number from ever passing through our servers.
In short, for most services today the best PCI strategy is "never touch raw card data." Lean heavily on tokenization and the PSP's payment forms so that sensitive data never enters our system. If you want more on the fundamentals of authentication and tokens, you can practice the related concepts in the Auth & Security Lab.
Seeing the Whole Picture Again
Let us gather the pieces into a single picture — the entire journey from the moment a user taps pay, through the merchant actually receiving money, to handling a refund or chargeback if needed.
| Phase | What happens | Engineer's concern |
|---|---|---|
| Payment request | Card entry, tokenization | Minimize PCI scope |
| 3DS auth | Issuer authentication if needed | Handle abandon/failure/callback delay |
| Authorization | Issuer checks limit, places hold | Idempotency, soft/hard decline |
| Capture | Confirm charge (e.g. at shipping) | Partial capture, void |
| Settlement | Actual funds move in a batch | Reflect fees/deductions |
| Reconciliation | Compare internal records vs settlement | Detect mismatches, handle exceptions |
| Refund/chargeback | Post-hoc return of funds | State management, evidence, ratio monitoring |
This table is a summary of payment system design. Each row is a state and a point of failure, and weaving all of them into a state machine is the essence of a payment backend.
Conclusion
A payment system is a world where, behind the simple surface of "press pay and money moves," five players, three phases, and many failure scenarios are layered on top of one another. Authorization is a reservation, capture is confirmation, settlement is the actual movement. Between them, 3DS guards with authentication, chargebacks handle after-the-fact disputes, idempotency prevents double charges, reconciliation makes the books agree, and PCI-DSS controls sensitive data.
The first lesson of payment engineering is that a system moving money must minimize room for error. That is why idempotency, immutable records, and daily reconciliation become constants rather than choices. With this map in hand, the next two topics come into focus naturally: implementing the idempotency that prevents double charges, and designing the double-entry ledger that never loses money.
References
- Stripe Docs: Payments — https://stripe.com/docs/payments
- Visa: 3-D Secure (EMV 3DS) — https://www.visa.com/3ds
- EMVCo: EMV 3-D Secure Specification — https://www.emvco.com/emv-technologies/3-d-secure/
- PCI Security Standards Council: PCI DSS — https://www.pcisecuritystandards.org/
- Stripe Docs: Idempotent requests — https://stripe.com/docs/api/idempotent_requests
- Adyen: Payments 101 — https://www.adyen.com/knowledge-hub/payments-101
현재 단락 (1/116)
When a user taps "Pay," it looks like it takes less than a second. But inside that second, the card ...