Questions
What merchants ask before they integrate, and what they ask at two in the morning afterwards.
If the answer you need is not here, the documentation is written to be read rather than searched — Quickstart is twenty minutes end to end.
The basics
What is UnifiWallet Payments?
A payment gateway for crypto. A shop asks us to create a payment, we give the buyer a checkout page, and the buyer's money moves straight to the shop's own wallet. We tell the shop when it arrived.
What does "non-custodial" actually mean here?
We never hold merchant money. Not for a second, not in a pooled account, not "in transit". The buyer's transaction pays the merchant's address directly, and our fee comes out in the same transaction.
The practical consequences are the point: there is no balance to withdraw, no payout schedule, nothing for us to freeze, and nothing to lose if we are compromised. It also means we cannot reverse anything, which is the trade you are making.
Which chains and tokens can I take?
Whatever your deployment has contracts and price feeds for — typically
stablecoins on Base, Ethereum, Arbitrum, Optimism, Polygon and BSC.
GET /v1/assets and GET /v1/chains answer for
your account rather than in general; read those instead of hard-coding
a list.
Do I need to hold crypto to use this?
You need a wallet that can receive the token you settle in. You do not need the chain's native coin: we pay the gas and take it out of the payment, so a merchant who has never touched ETH can still be paid in USDC on Ethereum.
Do my buyers need the native coin for gas?
No, on the wallet path. The buyer signs an authorisation and our relayer submits it, so somebody holding only USDC can pay. The one exception is a token that supports neither EIP-3009, Permit2 nor EIP-2612, where the buyer must send an approval themselves — and that is the only path that needs them to hold gas.
How long does a payment take?
The transfer is one transaction, so seconds to a minute on an L2. What
takes longer is confidence: we wait for the confirmations
your chain needs before saying completed — 20 blocks on
Base, 12 on Ethereum, 128 on Polygon. Ship on
completed, not before.
Money, fees and settlement
When do I get paid?
When the buyer pays. There is no settlement delay because there is no settlement step — the transaction that pays you is the payment. Money is in your wallet before we have finished telling you about it.
What does it cost?
A percentage of each payment, taken in the same transaction, plus the network fee. Both are shown in the payment's snapshot before the buyer pays, and on every settlement afterwards. There is no monthly fee, no chargeback fee and no payout fee, because there are no payouts.
Who pays the network fee?
You choose, per account or per payment. gas_payer: buyer
adds it to the buyer's total as its own line;
gas_payer: merchant takes it out of your settlement
beside our fee. Buyer is the default.
On a cheap chain this is a fraction of a cent either way. On Ethereum at a busy hour it can exceed our own fee, which is the argument for settling on an L2.
Can I be paid in a different currency than the buyer pays in?
That needs conversion, and conversion needs a routing adapter your deployment may not have wired up yet. Without one, a payment is same-asset: the buyer pays what you settle in. The checkout only ever offers assets it can actually quote, so a buyer never picks something that then fails.
What is a settlement destination, and why the wait?
The wallet your money goes to. Adding one requires signing a message with that wallet — proof you hold the key, not just that you can type an address — and then it sits out a cooling period before it can receive.
The cooling period exists for one scenario: somebody steals your credentials at 3am, points settlement at their own wallet and waits. The delay, the email to every owner and the signature requirement are three separate things they would all have to beat.
Can I send each payment somewhere different?
Yes — a marketplace paying each seller directly. Name
settlement.address on the payment. It is off by default
and switched on from the panel by an owner re-entering their password,
because an API key that can name any payout address is an API key that
can drain the account.
What if I lose access to my settlement wallet?
The money is gone, and we cannot help. We never had it. This is the honest cost of a design where nobody can freeze your funds — the same property that protects you from us also means we cannot recover anything for you. Use a wallet you will still control in five years.
Holds, captures and refunds
Can I authorise now and charge later?
Yes, where escrow is deployed. Create the payment with
capture_method: manual and the buyer's money moves into a
contract instead of to you. Charge it when the order ships, charge
part of it, or release it — releasing costs you nothing and owes the
buyer no refund. See Holds and captures.
How long can I hold an order?
Seven days by default, which is what a card authorisation gets, and up to thirty if your platform allows it. After that the buyer takes their money back without needing you or us. If you ship slower than your own window, lengthen it — you get a warning a day before one lapses.
Why can a held payment only be paid in one currency?
Because a hold has to hand back exactly what the buyer put in. If we converted on the way in, releasing it would return a different amount than they sent, since the rate moved while you were deciding.
How do refunds work if you never hold my money?
You send them. We record what is owed with a deadline, build the exact transaction for you, and verify on chain that it arrived before marking it done. We cannot move your money, so we cannot refund on your behalf — which also means nobody can make us.
Can I refund a payment that has just settled?
Wait for completed. A settled payment can still be undone
by a chain reorganisation, and a refund you had already sent would not
come back with it — you would be out twice. Asking earlier returns
payment_not_final.
What happens if a buyer pays after the payment expired?
It reaches you, and we tell you with
payment.late_settled rather than staying silent.
Expiring a payment does not reach into the buyer's wallet — an order
they signed before the deadline can still be mined. The money is
yours to fulfil or refund.
A buyer sent the wrong token to a deposit address. Now what?
We record it, tell you with
payment.unsupported_asset_received, and send it back to
the buyer's refund address after the payment expires. You do not have
to do anything, and it never counts as payment.
A buyer underpaid. Can they top it up?
On a deposit address, yes — send the rest to the same address before it expires and the sum is what counts. The amount must arrive in full: the address enforces the exact figure on chain, so there is no tolerance to be had. If it never arrives, everything sent goes back to the buyer.
Recurring charges
How does a customer cancel a subscription?
From their own link, without asking you and without an account. Every
subscription gets a manage_url when it is created, and it
goes in every subscription email we send the payer. One button, no
confirmation screen, no retention offer, no reason required.
Put that link in your own emails and account pages as well. A customer who cannot find the cancel button does not keep paying — they charge back, complain, or tell people.
What happens to me when a buyer cancels?
You get a webhook —
subscription.cancel_scheduled if they let the paid period
run out, subscription.canceled if they ended it now —
both carrying canceled_by: "buyer". We stop charging
immediately; stopping the service is yours to do, and serving someone
you are no longer billing is your bill to pay.
By default, does cancelling cut them off mid-month?
No. The default stops the renewal and lets the period they have already paid for run to its end, because that is what people mean by cancelling. Someone who never meant to subscribe at all can ask to end it immediately instead.
Can I put a retention flow in front of the cancel button?
Not on our page, and we are not going to build one. A cancel flow that argues with the person using it is a dark pattern, it is increasingly illegal, and it contradicts the product. You are free to make an offer in your own emails; the one-click route stays open regardless.
Can you charge my customer after they cancel?
No, and for an auto_charge subscription they need not take
our word for it. What they signed is a spend permission living on
chain, and their own wallet can revoke it — immediately, without us or
you, and we cannot undo it. Our cancellation is a promise we keep;
their revocation is the half that needs nobody's good behaviour.
Is there a stored card anywhere?
There is no card. A recurring charge is a signed permission with a ceiling and an expiry, and the ceiling does not accumulate: a buyer who authorises 19.99 a month can never be charged 240 because eleven cycles were skipped. Nobody holds credentials that could be charged after the customer has walked away.
Integrating
How do I know a payment really happened?
The webhook, or reading the payment back. Never the redirect — the buyer's browser returning to your success page proves only that a browser visited a URL, and anybody can visit a URL.
My webhook signature will not verify.
Almost always the raw body. The signature is over the exact bytes we sent, and most frameworks parse JSON before your handler sees it, which re-serialises and changes them. Capture the raw body for that route. The panel's delivery log usually shows this in one line.
Will I get the same event twice?
Yes, eventually. Delivery is at-least-once and order is not
guaranteed — a retried payment.settling can arrive after
the payment.completed that followed it. Deduplicate on
the event id, in something that survives a restart, and treat each
event as a statement about an object rather than a step in a sequence.
What if my server is down when you send an event?
We retry with backoff over roughly three days. An endpoint failing for
72 hours is disabled and every owner is emailed. Nothing is thrown
away: GET /v1/events is the polling fallback, and you can
replay what you missed.
Do I need an Idempotency-Key?
On every POST, and it is required on the ones that move money. Reuse the same key when you retry and you get the original response instead of a second payment. Reusing a key with a different body is refused rather than quietly obeyed.
Can I test without real money or testnet funds?
Yes. Test-mode keys drive the real state machine and fire real webhooks with the on-chain part simulated, including the awkward endings — underpaid, expired, reorged, late. See Testing.
Can a test key touch live data?
No. Every read and write is scoped to the key's own mode, including the simulator — a test key cannot see, cancel, refund or simulate a live payment. Test data never reaches live reporting.
Is there an SDK?
Not yet. The API is ordinary signed HTTP and the reference carries working requests in six languages; the signing is about twenty lines. There is an OpenAPI document if you would rather generate a client, and an MCP server if you are working with an AI coding agent.
Security and risk
What happens if my API key leaks?
Revoke it in the panel; it stops working immediately. Then consider what it could have done: a key cannot create another key, cannot add a settlement destination, and cannot turn on per-payment routing — those need a person signed into the panel with their password. A leaked key can create payments and read data, which is bad but recoverable.
What if my whole account is compromised?
Use the emergency stop in the panel. It suspends the account: every key stops, checkout links stop building payable transactions, and nothing new can be created until a person restores it.
Can UnifiWallet freeze or take my money?
No, and not as a promise — as an architecture. Your money is in your wallet. We have no key to it and no contract that can move it. The only funds any of our contracts can hold are escrow holds, which can go to you or back to the buyer and nowhere else, and which the buyer reclaims unilaterally after expiry.
What stops somebody faking a payment?
Every settlement event is checked field by field against the terms the
payment was created with: the chain, the receiving address, the token,
the amount and the fee. A transaction carrying a real payment id but
paying somebody else is quarantined as evidence, never credited, and
you get payment.settlement_rejected. Worth alerting on —
it means somebody tried.
Are you PCI compliant?
PCI DSS is about card data. We never touch a card number, so it does not apply. What matters here instead is key management, and the honest summary is that the keys that matter are yours: your wallet's, and your API credentials'.
Legal and practical
Who is the merchant of record?
You are. We are a technology provider, not a party to the sale. The money moves from your buyer to you and never through us, which is what makes that true rather than a definition we chose.
Do you handle tax?
We compute and record it: the rate, the jurisdiction, the evidence and the totals are snapshotted onto the payment and reversed pro rata on a refund. We do not file anything for you, and the fiat valuation is recorded at the moment of settlement because most jurisdictions treat receiving crypto as a disposal.
What data do you keep about my buyers?
As little as the job needs: an optional customer reference and country, the paying address, and an email address only if you asked us to send a receipt — encrypted at rest and decrypted once, to send it. See the privacy policy.
Can I use this anywhere in the world?
That depends on your jurisdiction and ours, and it is a question for your own advisers rather than a support article. What we can tell you plainly is what the service does and does not do, which is the whole of this documentation and the terms.
What happens if UnifiWallet disappears tomorrow?
Money already in your wallet stays there — we were never in the path. Deposit addresses and escrow holds are contracts with no owner: anyone can trigger a deposit to complete, and a buyer can reclaim an expired hold, without us existing. What you would lose is the service: new checkouts, the dashboard, webhooks and support.
Still stuck?
Every error we return carries a request_id. Quote it and we can
find the exact line in our logs — it is the difference between a support
thread and a guessing game.