Skip to Content
FAQOne-time payments

FAQ — one-time payments

How do I make sure the signature is computed correctly before the first request?

Run the test vectors (callisto_sigtest.json, see Request signature) against your own signing function before the first network call: every value in them is fixed, the timestamp included, so two strings are compared locally instead of being debugged through 401s. The negative vectors must not match.

How do I test callback handling locally, without a public address?

Two ways: the test_info.callback_url field — the callback address right in the request (available to partners with the flag enabled, https only); or the delivery log through the callback_last tool of the MCP server — then you need neither a receiver nor a tunnel.

A callback arrived twice — is that an error?

No, that is normal: an unconfirmed delivery is retried. Answer with any 2xx and deduplicate on the event identifier, the X-Event-Id header — it stays the same across the attempts of one event, while the attempt number arrives separately in X-Request-Attempt (X-Event-Attempt in the legacy envelope). Details are in Webhooks.

Should I wait for the callback or poll the status?

The callback is the main channel; polling GET /invoices/{invoice_id} is the fallback. Retries are not infinite: in production the platform makes 173 attempts over roughly a day and then stops delivering; the sandbox gives up after the seventh. The status is always available by polling, so a callback cannot be treated as the only source of payment state. The retry schedule is in Webhooks.

I create a second invoice for the same customer and get a 409 — why?

That is deduplication: while the customer has an open invoice, a new one is rejected with INVOICE_ALREADY_EXISTS, and the id of the existing invoice arrives in error.details.invoice_id — read it or cancel the invoice. The error table is in Codes & reference.

What arrives at my site after the payment?

The customer is returned to your project’s return address with the invoiceId, merchantOrderId and success parameters. success is good enough for a result screen but not for releasing goods: it comes from the browser, carries no signature, and the customer may never come back at all. Details are in Cards, SBP, SberPay.

How do I move from the sandbox to production?

Production addresses and credentials are issued by your i-Free manager; both protocols — XML v2.9 and JSON v3 — work in production. Everything else that changes is collected in Sandbox ↔ Production differences.