MMeridian
Live on Celo Sepolia — not a simulation

Watch a payment become
on-chain settlement, fully traced.

Meridian instruments a real Naira-to-stablecoin settlement flow — payment processor, an async webhook, and a genuine Celo Sepolia transaction — as a single connected trace in SigNoz. When something stalls, it says exactly where, with real evidence, not a guess.

meridian.app/dashboard — live tracestreaming

Payment received · ₦4,200

Provider charged

Webhook resumed trace

chain.estimate_gas

rpc.send_transaction

chain.wait_for_receipt

Settlement confirmed

Span attributes

settlement.idstl_9c7299f6
amount.ngn4200

Chain

Celo Sepolia

Visibility

pending

Confidence

Built on real, verifiable infrastructure

Celo SepoliaSigNozOpenTelemetryviemNext.js
Meridian architecture

One payment, seen the way it actually happens

This is the whole point: the parts of a settlement nobody normally sees — the async gap, the chain leg, the exact moment something stalls — made visible, in order.

Status quo

Customer pays

Crosses 5–6 systems, each with its own logs — or none

Support checks five dashboards, guesses from timestamps

"We don't know where your money is."

⟲ Merchant refreshes, assumes they've been scammed, churns.
1

RECEIVE

settlement.receive_payment

Customer taps pay. payment-api creates the settlement record — root span starts here.

2

CHARGE

payment.provider.charge

The mock processor charges the customer — the observed boundary before the async gap.

3

WEBHOOK GAP

⋯ async gap ⋯

The webhook lands seconds later, on a different request, no shared process state. Context is restored explicitly via a span link — not started over.

4

RESUME

settlement.on_confirmation

The original trace resumes. This is the hard part most tracers get wrong silently.

5

CONVERT

fx.convert

NGN → cUSD. Mocked, deliberately — this leg isn't the differentiator.

6

SETTLE

chain.settle

Real viem transaction on Celo Sepolia: estimate gas, read nonce, sign, send, wait for receipt. The one un-fakeable component.

7

DIAGNOSE

diagnosis.type / .confidence / .evidence

If it stalls: a published rule table maps the observed signals to a named verdict. No LLM — same signals in, same verdict out.

8

NOTIFY

balance.update · merchant.notify

Balance updates, merchant is notified — the phone flips to ✓.

Status quo

Meridian

Five siloed systems, five sets of logs (or none)

One trace, one payment, start to finish

An engineer cross-references timestamps by hand

One connected story — tap it, see it

"We don't know where your money is."

An answer in two seconds

Black box past the processor boundary

Observed vs. inferred, labeled on every span

Not a mockup — the real span tree, attribute names included
settlement.receive_payment
└─ payment.create_record
└─ payment.provider.chargeobserved
⋯ webhook gap — context bridged via span link ⋯
└─ settlement.on_confirmation
└─ fx.convert
└─ chain.settle
└─ chain.estimate_gas
└─ chain.read_nonce
└─ wallet.sign
└─ rpc.send_transactionobserved
└─ chain.wait_for_receiptobserved→inferred
└─ balance.update
└─ merchant.notify

Four things a normal payment trace can't do

What makes this different, mechanically.

01

The chain leg is real

Every settlement is an actual viem transaction against a deployed contract on Celo Sepolia — not a simulated delay. Take any trace's tx hash to the explorer yourself.

02

One trace across the async gap

The payment webhook arrives on a different request, seconds later, with no shared process state. Context is restored explicitly, so fiat charge to on-chain receipt is one connected trace, not two.

03

Deterministic diagnosis, no LLM

When a settlement stalls, a fixed rule table classifies why from the actual signals observed — same signals in, same verdict out, every time.

04

Observed vs. inferred, honestly

Every diagnosis is labeled with what was actually seen versus what's inferred past a real visibility boundary, plus a confidence level — never a guess dressed up as certainty.

See it happen in three steps

No setup needed — this is running against a real testnet right now.

01

Trigger a payment

One click on /pay fires a real charge through the mock processor — the same shape a real Flutterwave/Paystack webhook would take.

02

The trace resumes across the gap

Seconds later, the webhook lands on a different request. Meridian restores the original trace context explicitly, rather than starting a new one.

03

Watch it settle on Celo Sepolia

A real transaction is estimated, signed, sent, and confirmed — or, deterministically diagnosed if it doesn't. Both outcomes show up live on the dashboard.

See it for yourself

Trigger a real settlement, then watch it land — in the dashboard and in SigNoz — as a single trace, with a real transaction hash at the end of it.

Make a test payment