Merchant-visible safeguards

Security built into the payment lifecycle

CryptPays combines confirmation and finality checks, merchant-configured payout destinations, signed callbacks, replay protection, and lifecycle-aware delivery semantics.

Security principles

Controls that remain visible at the integration boundary

These properties are part of the merchant-observable payment contract rather than claims about hidden infrastructure.

Merchant payout destination

Each payment address is created with the merchant's validated address_out.

Confirmation and finality

Confirmed processing waits for the effective network-specific threshold.

Signed delivery

Every callback carries an RSA-SHA256 signature and Unix timestamp.

Replay and duplicate handling

Freshness verification and persistent lifecycle idempotency address different risks.

Bounded retries

Failed delivery is retried within a finite policy; duplicate delivery remains possible.

Payment accounting

Each qualifying deposit reports its own principal, forwarded amount, and deduction.

Forwarding model

A configured destination, not a merchant balance

CryptPays is designed around forwarding qualifying payments to the payout address configured by the merchant rather than maintaining a merchant balance for later withdrawal.

This does not remove the merchant's responsibility to verify the destination before integration. Normal Merchant API use does not require the merchant to provide the private key or seed phrase for that payout address.

Review supported networks and assets

Numeric-confirmation networks

The effective processing threshold is the greater of the operator/network default and the merchant's stored requirement. A merchant cannot lower the default, and a new override above the configured maximum is rejected.

Solana finality

Merchant-facing Solana finality is intentionally binary: confirmations=0 means pending or not final, while confirmations=1 means confirmed or final.

Signed callbacks

Verify exact request bytes before trusting payment data

CryptPays signs the method, hostname, exact path and query, and raw request body together with the Unix timestamp. The signature uses standard base64 encoding and RSA-SHA256.

CryptPays callbacks retain the compatibility headers X-CryptPay-Signature and X-CryptPay-Timestamp.

  • Require X-CryptPay-Signature and X-CryptPay-Timestamp.
  • Reject a non-numeric timestamp or an absolute clock difference over 300 seconds.
  • For POST, preserve the raw body before JSON or form parsing.
  • For GET, the body is empty and the exact path plus query carries the signed payload.
  • Validate the expected order reference and canonical coin after authentication.
Follow the byte-exact verification contract

Delivery semantics

Authenticity and idempotency solve different problems

A fresh valid signature authenticates one delivery attempt. Persistent lifecycle state prevents a valid retry or stage transition from producing duplicate business effects.

Optionalpendingpending=1
Fulfillmentsentpending=0
Possible retrysentsame UUID
  • Pending is informational and must not trigger fulfillment.
  • The same UUID may legitimately advance from pending to sent.
  • A repeated confirmed sent event must be processed idempotently.
  • No merchant callback with result=done is delivered; done is an internal logs state after acknowledgement.
  • Exactly HTTP 200 acknowledges success. The response body is ignored; every other status is a failed attempt.

Delivery failures use a bounded six-attempt policy. This is not exactly-once delivery and does not guarantee that an unreachable merchant endpoint will receive a callback.

Public trust boundaries

Open integration endpoints with explicit verification

Public discovery and payment-address creation do not require a merchant bearer token. A creation request supplies the callback URL and merchant payout destination; the signed callback is the authentication boundary merchants verify before fulfillment.

Public endpoints are request-throttled. Creation inputs are validated for supported asset, callback URL safety, chain-aware payout address format, confirmation settings, and supported priority.

Review the Merchant API contract
Website
https://web-test.cryptpays.com
Product and merchant information
Merchant API
https://api-test.cryptpays.com
Payment creation and public metadata
Documentation
https://docs-test.cryptpays.com
Contracts and verification guidance
Routing boundary
Host-based routing keeps website, API, and documentation routes on their configured public surfaces.

Key and access boundaries

Private operations stay behind server-side controls

CryptPays separates public integration data from the signing and operational controls used to process it.

Server-side signing material

Generated wallet private material is not returned by the Merchant API. Stored wallet private material and the callback private signing key use application encryption; merchants retrieve only the callback public key needed for verification.

Authenticated administration

Administrative APIs require authentication and explicit permissions. Read, manage, retry, pricing, wallet, stream, and system actions are gated separately rather than inheriting access from a public API route.

Operational accountability

Selected sensitive administrative and operational changes record the authenticated actor and before/after or action context in the application activity-log system. These records are operational history, not a claim of immutable external audit.

Authenticated stream intake

The current blockchain stream intake verifies the provider's raw-body HMAC, timestamp, and stream-scoped nonce before accepting a delivery. Missing, stale, modified, or replayed deliveries are rejected.

Constrained callback delivery

Callback destinations are checked at creation and again before delivery. Production requires HTTPS, and outbound resolution rejects local, private, reserved, or otherwise unsafe destinations.

Duplicate-resistant payment intake

Persisted transaction identity and unique deduplication keys prevent a repeated blockchain event from creating the same deposit twice while preserving distinct UTXO outputs and indexed deposits.

Responsibility boundary

Security is shared across the payment integration

CryptPays secures and reports the payment lifecycle; merchants remain responsible for securely acting on the result.

CryptPays handles
  • Detection of supported blockchain deposits
  • Configured confirmation or finality rules
  • Forwarding qualifying payments
  • RSA-SHA256 callback signing
  • Bounded delivery retries
  • Per-payment accounting fields
Merchant handles
  • Correct and secure payout address configuration
  • A stable HTTPS callback endpoint
  • Signature and timestamp verification
  • Expected order and asset validation
  • Persistent lifecycle-aware idempotency
  • Protection of merchant systems and wallet credentials

These technical controls do not replace a merchant's own security, legal, or compliance obligations.

Independent deposits

Network-aware identity without hiding chain differences

CryptPays provides one Merchant API while retaining the identifiers and finality model needed to reconcile each supported network family.

Transaction output identity

Use txid_in together with the separate integer vout. A transaction hash alone can contain multiple relevant outputs.

Compatible address family

Enabled compatible EVM assets can share a generated address family, while each incoming deposit remains an independent payment lifecycle.

Binary merchant finality

SOL and SPL deposits remain independent, and their merchant-facing finality is represented consistently as 0 or 1.

Production checklist

Before accepting live payment callbacks

Use this as an integration review, then follow the complete verification examples in the documentation.

  • Use a stable HTTPS callback URL.
  • Capture the raw body and exact request target.
  • Verify both signature headers before parsing.
  • Validate the 300-second absolute timestamp window.
  • Validate the expected order reference and coin.
  • Allow the same UUID to move from pending to sent.
  • Fulfill each confirmed UUID only once.
  • Use decimal-safe money arithmetic.
  • Return HTTP 200 only after successful processing.

Security FAQ

Questions to resolve before production

The implementation documentation remains the authority for exact verifier behavior and callback fields.

Read callback documentation
Does CryptPays require my wallet private key?

No. Normal Merchant API integration does not require you to provide the private key or seed phrase for the payout address. Protect those wallet credentials and never place them in API requests or support messages.

How do I know a callback came from CryptPays?

Verify X-CryptPay-Signature and X-CryptPay-Timestamp against the current public key and the documented canonical request bytes before trusting the payload.

Can a callback arrive more than once?

Yes. A failed delivery can be retried, and pending plus confirmed stages can share one UUID. Persist lifecycle state and make confirmed fulfillment idempotent.

Does a pending callback mean I should fulfill?

No. Pending is informational. Fulfill only after verifying the confirmed merchant event with result=sent and pending=0.

Why are confirmations or finality required?

CryptPays waits for the effective blockchain confirmation or finality condition before confirmed processing and forwarding. The exact model depends on the network family.

How should UTXO payments be identified?

Use the pair of txid_in and vout for the on-chain deposit identity, while using the callback UUID for its merchant lifecycle.

Does CryptPays deliver a result=done callback?

No. Merchant fulfillment uses result=sent, pending=0. After HTTP 200, done can appear only as an internal delivery state in logs.

Implement the boundary

Verify every callback before fulfillment

Use the maintained signature examples, lifecycle contract, retry policy, and troubleshooting guidance in the CryptPays documentation.