Skip to main content
POST
Simulate a deposit landing on a sandbox payment intent
Sandbox-only. Flips a pending sandbox payment intent to completed, persists a fake deposit transaction (visible in GET /connect/v1/transactions), and enqueues a payment.completed webhook for delivery to the organization’s configured webhook URL. The outbound payload carries livemode: false so partner handlers can branch. Returns 404 on live keys. Idempotent: calling twice on the same intent returns the same envelope without re-firing the webhook (the intent’s completed_at is the idempotency anchor).

Authorizations

Authorization
string
header
required

Paste your Connect API key (sk_live_… for production, sk_test_… for sandbox) without the Bearer prefix. Mint and rotate keys from the admin panel.

Path Parameters

payment_intent_id
string
required

Payment intent UUID as returned from POST /payment-intents.

Response

Successful Response

Stripe-shaped payment intent envelope.

id
string
required

Payment intent UUID. Pass to GET /payment-intents/:id.

currency
string
required

Primary asset code, uppercase (e.g. USDT).

object
string
default:payment_intent

Always payment_intent. Stripe convention.

amount
number | null

Requested amount in the intent's primary asset.

status
string | null

Intent status. One of: pending, partial, completed, expired (snake_case, Stripe-compatible).

ref_code
string | null

5-character public-page identifier. Embedded in hosted checkout URLs (zopay.cash/pay/<ref_code>).

external_ref
string | null

Partner-supplied attribution key as passed to POST /payment-intents. Echoed verbatim. Use for your own per-user reconciliation.

description
string | null

Partner-supplied description, echoed verbatim.

metadata
Metadata · object | null

Partner-supplied metadata, echoed verbatim. NULL when no metadata was sent at creation.

addresses
ConnectPaymentIntentAddress · object[]

Per (asset, network) deposit destinations. One row per currency / network pair available on this intent.

created_at
string<date-time> | null

When the intent was minted.

expires_at
string<date-time> | null

When the intent stops accepting deposits.

completed_at
string<date-time> | null

When the intent transitioned to status='completed'. NULL while pending. Idempotency anchor for the completion transition -- a retried call sees the same value, never a fresh one.

deposit
ConnectPaymentIntentDeposit · object | null

Chain-side details of the deposit that fulfilled this intent. NULL while pending; populated on completion. Field-for-field parity with the payment_intent.completed webhook event payload so pull and push reconciliation see one shape. On a partial-then-complete intent this object reflects the LATEST deposit, not the cumulative total; use amount_received for the cumulative figure.

amount_received
number
default:0

Cumulative amount credited against this intent across all completed deposits. Always present; defaults to 0.0 when nothing has landed yet. On a partial payment this is the partial total; once the intent transitions to completed it equals (or slightly exceeds, by up to the 0.01 tolerance) amount.

amount_remaining
number
default:0

Raw remaining amount: max(0, amount - amount_received). No tolerance applied -- partners that want to render a 'pay X more' UI should check partial_payment first and read this value as the literal shortfall. A near-complete intent within the 0.01 tolerance shows a small positive value here but partial_payment=false.

partial_payment
boolean
default:false

True iff the intent has received at least one deposit but is not yet completed: amount_received > 0 AND status == 'pending'. Use this as the canonical 'is incomplete' boolean for partial-payment UI. Tolerance is handled transitively through status: the credit flow only leaves the intent in pending when the cumulative received amount is below the (amount - 0.01) threshold, so a near-complete intent within tolerance has already transitioned to completed and surfaces as partial_payment=false here.