Pactis · 2023–24
A treasury for crypto and fiat, built for cross-border businesses
Lead product designer for a B2B treasury on the web. I worked with the PM, directly with the CTO, and with Legal on AML and KYC.
- settlement at most
- T+1
- settlement at most

The problem
Money was scattered across banks, exchanges and spreadsheets
Businesses moving money across borders ran treasury from bank portals, crypto exchanges and spreadsheets. Each tool held part of the picture; none held all of it.
I interviewed 15 CFOs and treasury managers. The same thing kept coming up: they trusted their spreadsheet more than their bank portal, because it was the only place they saw everything. Wider research agrees: almost eight in ten small companies run treasury on spreadsheets or home-built tools.
- Slow settlements. UK SMEs wait 2.81 days on average for cross-border funds, sometimes five.
- Opaque FX. Nearly half of the same SMEs called their FX pricing unfair.
- Crypto on the side. Most treasury tools don’t support crypto, so teams converted on separate exchanges and moved funds by hand.
- No single view of cash. Balances across countries, currencies and wallets were stitched together manually, so decisions waited on the spreadsheet.
The opportunity
One place to convert, fund, pay out and see every currency
The hard part wasn’t the features. A single trade touched three roles, the merchant, the admin and Finance, and each needed a different view of the same money.
Before design started, I agreed with Product and Engineering what success would mean, and how we’d measure it:
The approach
One trade model, two ways in
Trades start two ways: a merchant requests one in the app, or an admin opens one after agreeing terms offline. So the first question was structural, not visual: one model or two?
I chose the third. Every trade debits the source balance first and credits the destination on settlement, so all three roles watch one trade move through the same states. It cost more design up front, and saved us from reconciling two systems forever.
Pactis is now offline, so I rebuilt the flows below as prototypes from my original designs.
Same trade, different questions
The merchant asks for a quote and sees an estimate as they type. The admin prices it against the broker’s rate, with the margin visible before sending, and the merchant accepts a firm quote before it expires. One broker order covers it, an exact payment is matched automatically, and one confirmation pays the merchant.
The trade-off: a shared model meant admin-only detail, like margin, had to be carefully hidden from merchants rather than living in a separate system.
Balances that replace the spreadsheet
8 of my 15 interviewees kept their spreadsheet because it showed everything and let them account for gaps. Balances had to do that job, or the spreadsheet would stay. So every currency splits into four states:
- Availableready to pay out
- Set asideowed to merchants
- Incomingon its way to us
- In transitsent, awaiting the bank
Only Available can be paid out, and every currency, fiat or crypto, works the same way.
Review before the irreversible step
Payouts are where treasury decisions leave the building. Before anything is sent, the flow puts three things side by side: who’s being paid, which balance it comes from, and how much.
Designing for when the rails fail
Pactis matches a broker’s payment automatically only when the amount and reference are exact. Anything else is held for review, showing what was expected, what arrived and the difference.
I rejected auto-accepting small differences under a threshold. It would have cleared most mismatches, but meant the platform quietly absorbing losses. Instead, each way out states its cost, every fix needs a written reason, and a fix that turns a trade into a loss needs a second approver from Finance. The merchant is always paid what they were quoted.
A log built for audits
For a business managing money, the transaction log is where disputes get resolved and audits get answered. Every entry answers six questions: what happened, when, how much, in which currency, who started it, and where it is now.
Constraints
What we couldn’t control, and how the design absorbed it
- Rates that wouldn’t sit still. Prices streamed from several liquidity providers, so a rate could change between viewing and confirming. Quotes expire after a short window, and the flow always shows which rate you’re committing to.
- Settlement we didn’t own. Fiat ran through licensed partners and banks; crypto settled on-chain, at different speeds. So the target was T+1, not instant, and every state between request and settlement is visible.
- Money arriving where we couldn’t see it. Some pay-ins came through outside channels. Without a manual way to record them, the ledger would be wrong.
- Compliance before any money moved. Multi-layer KYC/AML and on-chain monitoring were required. I worked with Legal so the checks sat inside the flows instead of blocking them.