The Custody Problem Hiding Inside Crypto Payments

Wait 5 sec.

I have spent a lot of time around crypto infrastructure. I saw large exchange systems from the inside, including Bybit and, before that, Kraken. I learned many useful things there. I also learned something uncomfortable.Most of crypto is not used like crypto.Bitcoin tried to give people peer-to-peer money. The simple idea was: I can send value to you without asking a bank, processor, or platform to approve the transfer. The network checks the rules. The user controls the key. The payment is not only a row in a private database.But during the last ten years, most of the industry moved in the other direction. We built big exchanges, custodial wallets, hosted checkout pages, broker apps, managed balances, internal ledgers, compliance queues, payout delays, frozen accounts, and support tickets.I do not say this because exchanges are useless. They are useful. I know how hard they are to run. Security, hot wallets, cold wallets, risk systems, KYC, chain monitoring, customer support, and accounting are all hard problems. But we should still be honest: a lot of crypto infrastructure made crypto feel like Web2 with coins.The Exchange LessonWhen you work near exchange systems, you learn that most users do not really use blockchains. They use account balances.A user deposits BTC or USDT. After that, most actions happen inside the exchange database. Trades are internal. Transfers between users are internal. Risk checks are internal. Withdrawal approval is internal. The chain is used at the edge, when money enters or leaves.This design is fast. It is practical. It is also centralized.The user does not control the private key. The exchange controls the wallets. The user sees a balance. That balance is an IOU until withdrawal succeeds.This model became normal because it solves real problems:Speed: an internal ledger is faster than waiting for block confirmations.Fees: internal transfers cost less than on-chain transfers.Support: a platform can reverse some internal mistakes.Compliance: the company can stop risky flows before withdrawal.UX: users can log in with email instead of managing keys.But every solution changes the product. The more we hide keys, chains, and settlement, the more crypto becomes a normal fintech account.Payment Gateways Copied the Same PatternCrypto payment gateways often followed the same path.A merchant wants to accept BTC, ETH, USDT, USDC, or another asset. The gateway gives them a checkout page, an invoice, a QR code, maybe some plugins, and maybe fiat settlement. This is useful. It lowers friction.But many gateways also put themselves in the middle of the money flow.The common model looks like this:customer wallet -> gateway deposit address -> gateway balance -> conversion / payout rules -> merchant bank account or withdrawal walletAgain, this is practical. But it is not the same thing as direct peer-to-peer payment. The merchant now depends on a provider balance, payout policy, withdrawal limits, risk review, and account status.In simple words: the customer paid with crypto, but the merchant still waits for a platform.The Word "Destroyed" Is Strong, But I Understand ItSome people say centralized platforms destroyed the decentralization that Bitcoin was trying to bring. I understand the word.It did not happen because every builder wanted to betray Bitcoin. It happened because convenience won. Users wanted easy login. Traders wanted instant matching. Merchants wanted simple checkout. Companies wanted compliance. Investors wanted scale. Regulators wanted control points.Each decision made sense alone. Together, they moved the industry away from self-custody.The result is strange. We talk about decentralized money, but many users never touch a private key. We talk about open networks, but many payments are just database updates. We talk about permissionless finance, but a merchant can still have funds held by a gateway account.Why Swaps Changed the ProblemFor a long time, decentralized payment routing was hard.A customer may want to pay in BTC. The merchant may want USDT on another chain. Another customer may hold SOL. Another one may hold ETH. A normal merchant does not want to manage all these wallets, prices, and chain risks.Centralized gateways solved this by taking custody and doing conversion inside their own system. That was the easy design.Over the last few years, swap protocols and cross-chain routing improved. We now have more ways to move from one asset to another without building a full custodial payment processor. The tooling is still not perfect, but it is better than before.This changed the design space for merchant payments.Instead of asking, "How do we hold customer funds and pay the merchant later?" we can ask, "How do we create a checkout flow that routes value to the merchant wallet?"What I Tried to BuildMakePay.io came from this question. I did not want to build another custodial balance system with a crypto skin. I wanted to build checkout software where the merchant can receive accepted value in a wallet they control.This is not magic. It is still software with tradeoffs. But the design goal is different.The main rules I used were simple:Do not hold merchant funds as a normal product feature.Do not ask the merchant for private keys.Let the customer pay with the asset they already have.Let the merchant choose the asset and chain they want to receive.Use on-chain settlement as the source of truth, not only an internal balance.Make the checkout simple enough for a normal buyer.The hard part is that merchants do not want ideology at checkout. They want orders to be paid. Developers need a clean state machine. Support needs clear errors. Customers need a QR code and a status page.A Simple Technical ModelThe basic model is close to this:merchant creates invoice -> invoice has target amount, target asset, target wallet -> customer selects pay-in asset -> system gets a decentralised route and quote -> customer sends funds -> route settles accepted value to merchant wallet -> webhook updates merchant backendThe important object is not only the payment link. The important object is the payment state.A simple state machine can look like this:quotedawaiting_depositpendingswappingsendingcompletefailedexpiredunderpaidcancelledThis is developer English, but it matters. Without clear states, support becomes guesswork. A merchant must know if the customer has not paid, if the deposit was seen, if the route is processing, if settlement was sent, or if the payment failed.For webhooks, idempotency is also not optional. Payment systems retry. Networks fail. A backend may receive the same event twice. The merchant backend should process events by payment id, session id, event type, and delivery id.if event.delivery_id was already processed: return okverify signatureload payment sessionapply state transitionmark delivery_id as processedreturn okThis is boring code. It is also the code that makes payments usable.Where Decentralization Still Gets HardI do not want to pretend this design solves everything.Decentralized swap routes can fail. Liquidity can be thin. Quotes can expire. Chain fees move. A customer can send too little. A customer can send on the wrong network. Some routes still depend on third-party infrastructure. Compliance questions do not disappear. Good UX is still hard.Also, full decentralization is not binary. A product can remove custody from one part and still depend on APIs, indexers, route providers, hosted frontends, analytics, or cloud systems in another part.That is why I think we should speak more clearly. The question is not, "Is this 100% decentralized?" The better question is, "Which trust points did we remove, and which trust points remain?"The Part I Care About MostThe part I care about most is merchant custody.If a customer pays and the accepted value reaches the merchant wallet, the payment feels closer to the original idea. The gateway helped with checkout, quote, routing, status, and webhooks, but it did not become the place where merchant money lives.That is a small design choice with a large meaning.In a centralized gateway, the merchant asks:Can I withdraw my funds?In a direct settlement model, the merchant asks:Did the on-chain settlement arrive?Those are very different questions.What I LearnedMy exchange experience made me respect centralized systems. They are not easy. But it also made me careful. When every important action depends on one company database, we should not call that decentralized finance.My work on MakePay.io was one attempt to move a small part of crypto payments back toward the original idea. Not by making checkout harder. Not by forcing every merchant to become a protocol engineer. But by removing the provider balance from the normal merchant flow.I think this is where crypto payments should go:Simple checkout for users.Direct wallet settlement for merchants.Clear state machines for developers.Signed webhooks for backend systems.Open routes where possible.Honest language about remaining trust points.Bitcoin did not fail because people built exchanges. Bitcoin did not fail because merchants need good UX. The problem is that we forgot to keep asking where the control goes.If crypto payments only create new custodians, we did not move very far. We just changed the logo on the middleman.The better path is harder. It needs swaps, better wallets, better routing, better error handling, and better developer tools. But it is worth building.Peer-to-peer money should not end as another hosted balance.