How to confirm a stablecoin payment on your server

To confirm a stablecoin payment, let your server act on Cosmos Pay’s signed webhook, not on the page your customer sees. When the network confirms a payment, Cosmos Pay sends PAYMENT_INTENT_SUCCEEDED to your endpoint, signed with that endpoint’s secret. Verify the signature, answer with a 2xx status and deliver the order once per event.

Why your server, not the browser

A checkout that says Paid is only what your customer’s browser shows. The tab can close before it returns to your site, and anyone can open your success page by hand. The network’s confirmation is what makes a payment final.

Cosmos Pay watches the network for you and tells your server when a payment is confirmed. Your server is the place to mark the order as paid and deliver it.

What Cosmos Pay sends

  • An HTTPS POST to the endpoint you register, with a JSON event: id (it starts with evt_), type, createdAt and data. For a payment, data is the payment with its status, amount, asset, network and transaction.
  • The X-Cosmos-Signature header: t=<unix time>,v1=<signature>. The signature is the HMAC-SHA256 of t, a dot and the raw body, keyed with the endpoint’s secret, in hexadecimal.
  • The event types you choose, such as PAYMENT_INTENT_SUCCEEDED, PAYMENT_INTENT_FAILED or ZK_PAYMENT_SUCCEEDED. Match them as written, in capitals with underscores.
  • The X-Cosmos-Event, X-Cosmos-Event-Id and X-Cosmos-Delivery headers, which name the event and the delivery.

Set up a webhook, step by step

  1. Add an endpoint

    In the dashboard, open Webhooks and add the HTTPS address of a route on your server. Choose the events to receive; PAYMENT_INTENT_SUCCEEDED comes selected. The address must be public: private and local addresses are refused.

  2. Store the secret

    The dashboard shows the endpoint’s secret (it starts with whsec_) only once. Keep it in your server’s environment, never in a web page.

  3. Verify every request

    Read the raw body before any JSON parser and check X-Cosmos-Signature against it. With the TypeScript SDK, Webhooks.constructEvent checks the signature, refuses one older than five minutes by default and returns the event.

  4. Answer fast, then work

    Reply with a 2xx status as soon as the signature checks out, and do the slow work, such as emails or stock updates, after that.

  5. Handle each event once

    Store the id of each event you handle and skip one you have seen: a retry or a redelivery sends the same event again.

  6. Send a test

    Use Send test on the endpoint to receive a ping event, then make a test payment in Sandbox and watch its delivery in the endpoint’s list.

When your server does not answer

Only a 2xx answer counts as delivered, and redirects are not followed. Cosmos Pay retries a failed delivery up to three times with a growing pause, then again in later rounds, and the event keeps its id on every attempt.

In the dashboard, each endpoint lists its deliveries, with a filter for the failed ones, and you can send any of them again. Cosmos Pay keeps a delivery’s body for 30 days, so redeliver within that time.

Or check a payment yourself

You can also ask about one payment: fetch it by its id to read its status, or send its transaction hash (on Solana, the transaction signature) to POST /v1/payment-intents/:id/validate. Use it as a fallback, for example when your customer returns before the webhook arrives; the webhook stays the main signal.

Questions and answers.

Payments by network:Stellar paymentsSolana paymentsMonad payments

The dashboard shows payment_intent.succeeded. Which name does the event carry?

The event’s type is PAYMENT_INTENT_SUCCEEDED, in capitals with underscores. The dashboard only displays it in a shorter form.

What happens when I rotate the secret?

The new secret works at once and the old one stops at once, so update your server right after you rotate it.

What if my server was down?

Cosmos Pay retries failed deliveries, and you can send any delivery again from the dashboard for 30 days.

Can I have several endpoints?

Yes. Each endpoint has its own address, events and secret, and every event goes to each endpoint that subscribes to it.

Start accepting stablecoins.

Create a free account, mint a test key and send your first payment link today.

Write to us

Questions about plans, integration or protected payments? Tell us and we will reply by email.

We use these details only to reply to you.