Blog · non-custodial · api · payment-gateway · developer · guide
Crypto Payment API: Accept Stablecoins Without Custody
inzi team · Published · 9 min read
A non-custodial crypto payment API lets your backend create payment requests and read their status, while the stablecoins move from the customer's wallet straight to a wallet you control. The API never sits in the money path. inzi works this way: 0% per transaction on every plan, funds go to the merchant wallet, and no account inzi controls holds them in between.
What does "without holding customer funds" actually mean?
It describes where the money sits at each step of a payment. In a custodial design, the customer pays the provider, the provider records a balance in your name, and at some later point it pays you out. For that window, the provider holds your money and decides when it moves.
In a non-custodial design, the payment is a transfer on a public blockchain from the customer's wallet to an address you own. The API's job is coordination: it generates the payment request, tells the customer where to send funds, watches the chain for the transfer, and tells your backend when it arrived.
That gives you three practical differences:
- No balance to withdraw. There is no provider-side ledger entry waiting for a payout. The funds are in your wallet when the transfer confirms.
- No provider-side hold. Since the provider never has the funds, it cannot delay or restrict them. inzi has no mechanism to freeze a merchant's balance, because it has no balance to freeze.
- Security is yours. The wallet's keys, backups, and access policy belong to your business. This is the real cost of the model, covered in its own section below.
For a longer treatment of the processor side of this design, see the non-custodial crypto payment processor guide.
How does a non-custodial payment flow work, step by step?
The details differ between providers, but the shape is consistent. Here is the generic sequence a developer integrates against.
1. Your backend creates a payment request
When a customer reaches checkout, your server tells the API what it needs: an amount, a token, a chain, and usually a reference such as your own order ID. The reference matters more than it looks. It is the key that later ties an on-chain transfer to an order in your system.
2. The customer is shown where to pay
The response gives your frontend what the customer needs to pay: a destination address resolving to your merchant wallet, the exact amount, and the network. The customer opens their own wallet and sends the transfer. inzi is not a party to that transfer, and nothing about it passes through a provider account.
3. The chain confirms the transfer
The API watches the relevant network for a matching transfer. Confirmation behavior is a property of the chain, not of the API: a transfer on one network may be final in seconds, another may take longer. Your integration should treat "payment seen" and "payment final enough to fulfill" as separate states, and decide where in that range your product ships the goods.
4. Your backend is notified
Once the payment is matched to the request, your backend learns the status changed, and your order moves to paid. Build this step to be idempotent: the same notification arriving twice should not fulfill an order twice. That is a general rule for any payment integration, custodial or not.
5. Funds are already in your wallet
There is no payout step for ordinary payments, since the transfer landed in your wallet in step 3. What remains is your own treasury work: moving funds between wallets, converting, or paying suppliers and contractors. For the last of these, inzi's batch payouts are in a guided pilot that businesses can request. For the bookkeeping side of the same flow, see the crypto accounting guide for stablecoin payments.
Which tokens and chains can the API accept?
The branch point here is that not every token runs on every chain. A payment request has to name a valid chain and token pair, so your checkout needs to offer only combinations that exist. inzi supports six networks, with this token coverage:
| Network | USDC | USDT | EURC |
|---|---|---|---|
| Polygon | Yes | Yes | No |
| Base | Yes | No | Yes |
| Ethereum | Yes | Yes | Yes |
| Tron | No | Yes | No |
| TON | No | Yes | No |
| Solana | Yes | No | No |
A few consequences follow from the table:
- USDC is available on Polygon, Base, Ethereum, and Solana.
- USDT is available on Polygon, Ethereum, Tron, and TON.
- EURC is available on Base and Ethereum only, so a euro-denominated checkout has two chain options.
- A checkout that says "USDT on any chain" or "USDC on all six networks" would be wrong, and a customer who sends the wrong token to the wrong network can lose the transfer. Generate the options list from the pairs above rather than from a hard-coded assumption.
Which chain suits your business depends on who your customers are. Customers who already hold USDT on Tron or TON are easiest to serve on those networks. Customers moving USDC from an exchange often start on Ethereum, Base, Polygon, or Solana. Network fees and speed differ between chains, and each chain's own documentation is the place to check current behavior (see the sources at the end).
Who pays the network fee?
On a standard on-chain transfer, the sender submits the transaction and pays the network fee in that chain's native asset. In a non-custodial flow the customer sends the transfer from their own wallet, so that fee is part of their side of the payment. It is separate from what a payment platform charges.
The platform charge is the part you can read off a pricing page. inzi takes 0% per transaction on every plan, so the only recurring cost is the flat monthly fee. The practical effect is that your cost does not rise as payment volume rises.
What does the API cost?
Pricing is flat by plan. The per-transaction fee is 0% on all three:
| Plan | Price | Notes |
|---|---|---|
| Starter | $0/month | No subscription, for small merchants |
| Growth | $49/month | Unlimited payment links, for growing businesses |
| Scale | $149/month | For high-volume merchants; contact sales |
Scale is not self-serve: its call to action is "contact sales" rather than a signup button. Starter and Growth can be started directly from registration.
A worked example makes the flat model concrete. The numbers below are illustrative, not an inzi quote. Suppose a business receives $40,000 a month in stablecoin payments. At a hypothetical 1% per-transaction fee, that is $400 a month in fees. At 0% per transaction plus a $49/month plan, the platform cost is $49. At $400,000 a month, the hypothetical percentage fee would be $4,000, and the flat plan cost would stay where it is. The break-even point where a flat plan beats a percentage fee depends entirely on your volume and on whatever rate you are comparing against. See inzi's pricing page for the current plan details.
What do you take on by staying non-custodial?
Non-custodial is a tradeoff, not a free upgrade. The things a custodial provider does for you become your responsibility.
Wallet security. Whoever controls the keys controls the funds. If the keys are lost, the funds are lost. If they are stolen, the funds are stolen, and there is no provider-side balance to appeal to. Businesses commonly handle this with hardware-backed or multi-signature wallets and written access policies, but the choice and the operational discipline are yours.
Irreversibility. An on-chain transfer cannot be recalled by a card-network-style chargeback process. Refunds are new outgoing transfers that you initiate, from your wallet, at your discretion. That is good for merchants worried about disputes and a real design consideration for customer-service flows.
Wrong-network and wrong-token errors. Because the customer sends funds themselves, they can pick a chain or token that does not match the request. Clear checkout copy and a constrained options list, built from the per-chain table above, reduce this.
Your own accounting. Without a provider ledger holding your balance, the record of what came in, when, and at what value is something you assemble from payment references and chain data. Many teams reconcile the order ID from step 1 against the on-chain transaction hash.
Cash-out paths. Moving from stablecoins to a bank account is a separate job from accepting payments. inzi does not offer SEPA or card payout as a feature today; those are on the roadmap, not shipped. If your business needs fiat in a bank account, that conversion happens through whatever exchange or off-ramp you choose to use.
How should a developer structure the integration?
A few patterns recur in well-built stablecoin payment integrations, whatever the provider.
- Treat your own order ID as the primary key. Pass it as the reference when creating the payment request and store the API's payment identifier next to it.
- Make the status handler idempotent. The same status update may be delivered more than once. The handler should check the order's current state before changing it.
- Separate "seen" from "final." Decide per chain and per order value when you release digital goods or access. A low-value download and a large annual contract can reasonably differ.
- Handle underpayment and overpayment. Customers sometimes send slightly less than requested, for example because a wallet deducted fees from the amount, or more. Decide in advance whether you accept, top up, or refund, and write that rule into the handler instead of resolving each case by hand.
- Handle expiry. A payment request that has been open for a long time may no longer reflect the price you quoted. Give requests a finite life and make the customer start again after it.
- Separate test and live wallets. Use a test environment and a dedicated test wallet before pointing real customer payments at an address.
- Keep your fulfillment logic off the frontend. The customer's browser saying "I paid" is not evidence. Fulfillment should key off the confirmed status your server receives from the API.
The specific endpoints, parameters, and notification formats are defined in inzi's API documentation, and this post does not restate them so that nothing here drifts out of date.
How does this compare with a custodial crypto payment API?
The table summarizes the structural differences, which hold for any provider built on each model.
| Question | Custodial provider | Non-custodial (inzi) |
|---|---|---|
| Where does the customer's payment land first? | An account the provider controls | The merchant's own wallet |
| Is there a balance to withdraw? | Yes | No |
| Who holds the keys? | The provider | The merchant |
| Who carries wallet security risk? | Mostly the provider | The merchant |
| Can the provider restrict access to funds? | Depends on its terms | There is no provider-held balance |
| Payout step for ordinary payments | Yes | No, funds arrive directly |
Neither column is automatically right. A business with no appetite for key management may prefer to hand that job to a custodian. A business that wants no counterparty holding its revenue, or that wants to avoid payout delays, has a reason to prefer the other column. For named alternatives to a specific vendor, see the BitPay alternatives post.
Where to start
The lowest-commitment path is the Starter plan at $0/month with 0% per transaction. Creating a merchant wallet connection and a first test payment shows how the five-step flow above behaves against your own checkout before you decide on a paid plan. Growth is $49/month, high-volume teams talk to sales about Scale at $149/month, and teams that need batch payouts can request the guided pilot. You can create an inzi account to begin.