Provider-agnostic payment orchestration.
One clean API, any gateway. Iyzico, PayTR and bank virtual POS plug in as connectors behind a single type-safe interface — your code never knows which one is handling a payment.
v0.3 · Verified · Iyzico sandboximport { iyzico } from "@orvacon/connector-iyzico";
const orva = orvacon({
connectors: [iyzico({ apiKey, secretKey })],
});
// your code — identical for every gateway
const payment = await orva.authorize(order);Swap the connector — your orva.authorize(…) call never changes.
One clean API. Any gateway. Connectors plug in behind a single type-safe interface — so your application code never knows which gateway is handling a payment. Swap or add one by changing configuration, not logic.
Your code shouldn't know the gateway.
You've written gateway-specific glue before — branching on provider, mapping error codes, re-implementing 3-D Secure for each one. orvacon moves that surface area behind a connector boundary.
One type-safe API in your app; gateway differences isolated to configuration. Swap or add a connector without touching application logic.
Glue code, or a clean boundary.
The same payment, two ways. The hard parts of payments don't have to leak into your application code.
if (provider === "iyzico") {
// sign, map fields, 3DS dance…
} else if (provider === "paytr") {
// a totally different shape
}
total = amount * 1.18; // float drift
// verify the callback? trust the POST
verifyWebhook(req.body); // shared secret// one shape, every gateway
const result = await orva.authorize(order);Built like infrastructure, not a wrapper.
Decisions made at the boundary — custody, types, money, signatures — so the hard parts of payments stay out of your code.
Never holds money
Funds flow from the cardholder straight to your own gateway account. No wallet, no balance, no payout — which keeps orvacon out of money-custody regulation and off your PCI-custody burden.
End-to-end type safety
Payment state and results are discriminated unions. The state machine is enforced at compile time — an invalid transition won't type-check.
type PaymentState =
| "created" | "authorized"
| "captured" | "refunded"
| "requires_action"
| "failed" | "voided";Money as integer minor units
A branded Money type — integer minor units plus currency — keeps floats out of the core.
Bring your own database
No imposed datastore. Connect yours through an adapter — and the Supabase adapter generates a schema with default-deny row-level security out of the box.
Asymmetric webhook signatures
Outgoing webhooks are signed with Ed25519, so a leaked verification key can't forge events. Every signature and token check is timing-safe.
Idempotency & immutable ledger
Idempotency is enforced by a database unique constraint. The ledger is hash-chained — append-only and tamper-evident by construction.
Stateful 3-D Secure, orchestrated.
3DS is two requests plus a browser wait. orvacon persists the in-between as requires_action, and trusts the signed finalize response — never the raw callback POST.
What orvacon is — and isn't.
One line you can hold onto, and three things it deliberately is not.
A stateful payment orchestrator that runs in your own runtime — coordinating gateways behind one type-safe API, and never touching the money.
Built like infrastructure.
Three ideas that keep payments boring — the parts you'd want a payments core to get right before you trust it with a charge.
Cross-cutting core
Logging, errors, timeouts, retries and idempotency live in the core as interfaces — not bolted on as plugins.
Provider-agnostic
Every gateway plugs in as a connector behind one type-safe API. Your code never learns which one ran the payment.
Tamper-evident
Writes land in an append-only ledger, hash-chained so any edit to past records is detectable.
v0.3 — honest about scope.
This is an early release. The Iyzico raw-card and stored-card 3-D Secure flows are both verified end-to-end against the gateway sandbox. The API is 0.x and may change before 1.0.
No "supports every gateway" — these aren't shipped yet, and we won't pretend otherwise.
Tailored to your stack.
Drop it into the app you already have — your framework, your database, your runtime. Install only what you need.
Fits your existing stack
Your framework, your database, your runtime — no proprietary tooling, no vendor lock-in.
One clean API, any gateway
Your code calls orva.authorize(…) and never knows which gateway handled the payment.
Default-deny, out of the box
Bring your own database. The Supabase adapter generates a schema where row-level security denies by default.
alter table orvacon_payments
enable row level security;Install only what you need.
A shadcn-style DX: one unscoped CLI, and connectors you opt into. Unused gateways never enter your bundle.
bun add @orvacon/paykit @orvacon/connector-iyzico @orvacon/adapter-supabase @orvacon/adapter-nextjs postgres$ bunx orvacon keys$ bunx orvacon generateShipped in the open.
Iyzico 3-D Secure, verified
authorize3DScapturerefundreconcile, end-to-end against the gateway sandbox.
Stored-card tokens
Vault a card behind the gateway, then charge it later by token — sandbox-verified end-to-end.
Ed25519-signed webhooks
Asymmetric signatures so a leaked verification key can't forge events. Timing-safe checks throughout.
Schema with default-deny RLS
Generates a Postgres schema with row-level security locked down out of the box.
Hash-chained ledger
Append-only and tamper-evident by construction; idempotency enforced by a unique constraint.
No held money. No hidden service. Just type-safe code, running in your own runtime.
Build payments without
the glue code.
Wire up one type-safe API, keep money custody with your own gateway, and ship the verified Iyzico 3-D Secure flow today.