Partners
Existing integrations

Payment-first purchases

Maintain an existing tickets integration without changing its payment contract.

For existing integrations

For new implementations, use checkout reservations. Do not submit one payment to both flows.

How this flow differs

Recommended checkoutExisting payment-first
First callPOST /raffles/{id}/checkoutsGET /raffles/{id}
MemoExact returned payment.memopayment.memo_prefix + : + buyer reference
Submit signaturePromptly after submission, before the checkout deadlineAfter finalized commitment
IdempotencyYour checkout key, then the same signatureTransaction signature; do not send Idempotency-Key
SuccessPurchase status completedHTTP 200
TicketsObjects with ticket_no and codeTicket-code strings

Claim tickets after payment

After the buyer's payment is finalized, call POST /raffles/{raffleId}/tickets from your server:

{"external_user_ref":"buyer_123","qty":2,"tx_signature":"<finalized transaction signature>"}

Use the same transfer rules as wallet payments, but with the payment-first memo above. Allow at least 30 seconds for the request.

On a timeout, 5xx or TX_NOT_FOUND, retry the same signature and body with backoff. replayed: true means you received the original successful purchase. Changing raffle, quantity or buyer for an issued signature returns IDEMPOTENCY_KEY_REUSED.

Refund handling

An unissuable, attributable payment can enter asynchronous refund handling. Show refund_status, not just the HTTP status or presence of a signature:

  • in_flight: refund pending.
  • paid: refund completed; refund_tx_signature provides its transaction.
  • failed: contact Verity support.

Re-post the same tickets request to read the outcome. Once refunded, it returns PAYMENT_REFUNDED and the original rejection in reason. Do not take another payment while the original outcome is unresolved.

A memo mismatch or an unresolved payer can require support if funds moved; an automatic refund is not guaranteed for those cases.

On this page