patala is a sovereign, centreless payment-rail substrate — one interface to move money, fiat or crypto, that any product can vendor and self-host. The platform holds no funds, takes no cut, and no one owns the network. Patala is Sesotho/Setswana for "to pay."
168 offline tests pass in the default build, 547 more with every processor feature compiled in — but no rail in this repo has been run against a live network or a live merchant account. Read the full status before you trust it with real money.
Non-custodial by construction — no balance table, no payout queue, no ledger of its own. Value moves over the rail directly; patala is the interface, never the account.
No platform fee, no spread, no rent. You pay the rail its own cost — a processor's fee, a chain's gas — and nothing extra to a middle patala doesn't have.
Centreless: no registry to join, no operator to depend on. Vendor the crate into your own product and self-host it — the substrate is the code, not a company.
Fiat is custodial and reversible — chargebacks, KYC, T+2 settlement. Crypto is non-custodial and final — wallet-to-wallet, no reversal. patala never blurs which one a consumer is getting; the settlement class lives in the type, not a flag.
| Rail | Class | What it is |
|---|---|---|
| Mock patala-core |
— | The offline default. Deterministic, no network, no external crypto dependency — what keeps the default build and CI running with no chain and no processor reachable. |
| Solana patala-solana |
Non-custodial, final | SPL-USDC on Solana. Ed25519 — the app's identity key doubles as the wallet key, no mapping table. Ported from an earlier in-house implementation (~1,760 lines). |
| Stellar patala-stellar |
Non-custodial, final | Native USDC (Stellar Asset), Ed25519 (StrKey), built on SDF's own stellar-xdr/stellar-strkey. The cheapest measured fees of the two crypto rails. |
| Hyperswitch patala-hyperswitch |
Custodial, reversible | A thin HTTP client to a self-hosted Hyperswitch instance, presenting its whole fiat processor set — Stripe, Paystack, Xendit and 100+ connectors — as one rail. Adopted, not rebuilt. |
| Direct fiat adapters patala-fiat |
Custodial, reversible | Twenty processors talked to directly, one Cargo feature each, plus the ISO-4217 minor-unit currency table and an always-on offline manual rail.
Adyen · BTCPay · Checkout.com · Coinbase Commerce · Flutterwave · iyzico · LNbits · Mercado Pago · Midtrans · Mollie · OpenNode · PayFast · PayPal · Paystack · PayU · Razorpay · Square · Stripe · Xendit · Yoco
|
make check runs two gated passes: the default workspace build, and everything again with every processor feature compiled in. Clippy-clean, fmt-clean. What it does not mean: no rail here has been run against a live network or a live merchant account from this repo.
| Crate | Class | Tests | Live-verified? |
|---|---|---|---|
| patala-core | — | 19 + 1 doctest | OFFLINE BY DESIGN |
| patala-fiat | Custodial, reversible | 533 (all features) | NO — NO LIVE MERCHANT ACCOUNT |
| patala-solana | Non-custodial, final | 41 (+1 gated) + 1 doctest | NO — TESTNET STEP IN README |
| patala-stellar | Non-custodial, final | 29 (+1 gated) + 1 doctest | NO — TESTNET STEP IN README |
| patala-hyperswitch | Custodial, reversible | 20 | NO — NEEDS A LIVE INSTANCE |
| patala-py / patala-go | — | 14 Rust + 24 Go | EXECUTED, CI-ENFORCED |
| patala-sidecar | — | 9 (6 HTTP + 3 unit) | EXECUTED |
default_registry() registers exactly one rail, "mock". Reaching Solana, Stellar, Hyperswitch or fiat through the sidecar needs the per-rail registration its src/registry.rs documents and does not yet have.
Every adapter is written once, in the core. Nothing is reimplemented per language — Python, Go and any HTTP client all dispatch through the same PaymentRail trait.
Program against PaymentRail directly. The default build pulls no chain and no processor — opt into a rail with its feature flag.
patala-py wraps the core over UniFFI with synchronous methods — no asyncio loop needed just to call charge().
patala-go, the same UniFFI IDL generated for Go. 24 binding tests, CI-enforced with the pinned uniffi-bindgen-go.
patala-sidecar — quote / charge / verify / webhook as JSON on 127.0.0.1 only, token-gated, fail-closed. Any language, zero FFI.
// The settlement class lives in the type — never flattened to a bool. pub enum RailClass { CustodialReversible, NonCustodialFinal } pub trait PaymentRail { fn id(&self) -> &str; fn capabilities(&self) -> &RailCapabilities; async fn quote(&self, req: &PayRequest) -> Result<Quote>; async fn charge(&self, req: &PayRequest) -> Result<Receipt>; async fn verify(&self, receipt: &Receipt) -> Result<bool>; // fail-closed async fn verify_webhook(&self, d: &WebhookDelivery) -> Result<WebhookEvent>; }
No mockups, no invented JSON. The sidecar actually booted, curl actually hit it, the offline suite actually ran, and the Python and Go bindings actually executed — moments before this page was built. Reproduce it yourself: scripts/capture-transcripts.sh && node scripts/render-shots.mjs.

cargo run -p patala-sidecar, actually booting.

cargo test --workspace — the same 168 offline tests the status table cites, tallied here by a real awk one-liner reading the log, not typed in by hand. Scroll for the full run.
patala-py.
patala is a library, not a service — there is nothing to sign up for. Read exactly what's tested and what isn't before you point it at real money.