Skip to content

FAQ ​

Signing ​

Why timestamp + nonce in addition to the signature? ​

The signature proves the request came from someone holding your private key — not that it hasn't been seen before. Without timestamp + nonce, an attacker who captures one signed request could replay it forever. The timestamp limits the replay window to 60 s; the nonce ensures the request is processed only once even inside that window.

Why is the URL in the signature? ​

Two reasons:

  • Cross-environment replay — a request signed for staging can't be replayed against production.
  • Cross-endpoint replay — a captured request for /api/v2/transaction/init can't be replayed to /api/v2/transfer-out/init.

This is the same pattern used by AWS SigV4, Stripe webhook signing and OAuth 1.0.

My request works in staging but fails in production with signature.verify.failed. ​

Almost certainly your code signs one URL but POSTs to another — e.g. staging-oapi.dmcpay.net vs oapi.dmcpay.net. Make the base URL a config value and use that same value for both the signing string and your HTTP client.

How accurate must my clock be? ​

Within about 60 seconds of UTC (and no more than 5 s ahead). Use NTP. Most cloud VMs sync automatically; on bare-metal install chrony or ntpd.

How long do you remember nonces? ​

About 95 seconds — the timestamp window plus a safety buffer. After that the nonce is forgotten, but by then the timestamp is too old and the request would be rejected anyway.

Can I use a deterministic nonce, e.g. my own request ID? ​

Yes, as long as it's unique per request and matches ^[A-Za-z0-9_-]{16,64}$. We require uniqueness, not cryptographic randomness.

Why PKCS#1 v1.5 and not PSS? ​

PKCS#1 v1.5 is supported by every mainstream crypto library. Both are secure for signing. We may add PSS as an option later.

My language or framework isn't shown. ​

The algorithm is RSA-SHA256 with PKCS#1 v1.5 padding — search your library's docs for "RSA sign PKCS1v1.5 SHA-256". If you're stuck, send your account manager a snippet and we'll help.

Postbacks ​

What URL is in the postback signature? ​

Your registered postback URL — the URL we POSTed to. The format is the same METHOD.FULL_URL.ts.nonce.data, but FULL_URL is your endpoint. If you have separate deposit and withdrawal URLs, each postback is signed with its own URL.

I changed my postback URL and now verification fails. ​

Update your verifier's URL constant to match — postbacks sent after the change are signed with the new URL. Best fix: read the URL from the same config value you register with us.

Do you sign your responses to my API requests? ​

No. Synchronous responses rely on TLS — you're talking directly to our server over HTTPS, which already proves the response came from us. Signing is reserved for postbacks, which arrive on your webhook without you having initiated the connection.

In short: a synchronous response means "we received and accepted your request"; a signed postback is the authoritative final outcome.

Do I need to sign my response to your postbacks? ​

No. Return a plain HTTP 200 within 30 seconds. We don't verify any signature on your acknowledgement, and we don't parse its body.

Keys & migration ​

Can I still use the v1 init endpoints? ​

No. Deposit and withdrawal creation is only available through the signed v2 endpoints (/api/v2/transaction/init and /api/v2/transfer-out/init).

Can I use the same keypair for staging and production? ​

Technically yes, but we strongly recommend separate keypairs so a staging-key compromise doesn't affect production.

What if my private key leaks? ​

Contact us immediately. We revoke your public key, which makes all v2 requests fail. Generate a new keypair and send us the new public key — total downtime is minutes.

Can I rotate my key without downtime? ​

Not yet — uploading a new public key replaces the old one immediately. Plan a brief maintenance window when rotating. We may add overlap support later.

Need help? Contact your DMC Pay account manager.