Partners
API referenceEndpointsPayment-first (existing)

Issue tickets against a settled USDC payment

POST
/raffles/{raffleId}/tickets

Existing payment-first flow. Submit the signature of a finalized USDC transfer and receive ticket codes.

Building the payment

import { createTransferCheckedInstruction, getAssociatedTokenAddressSync } from "@solana/spl-token";import { PublicKey, Transaction, TransactionInstruction, sendAndConfirmTransaction } from "@solana/web3.js";const MEMO_PROGRAM_ID = new PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr");// Public payment details fetched by your server. Never expose your partner API key.const { treasury_ata, usdc_mint, decimals, memo_prefix } = detail.data.payment;// 2. Exact amount, fixed-point. Floats will drift you off by base units.function decimalToBaseUnits(value, decimals = 6) {  const match = /^(\d+)(?:\.(\d+))?$/.exec(value);  if (!match || !Number.isInteger(decimals) || decimals < 0 || decimals > 9) {    throw new Error("Invalid token amount");  }  const fraction = match[2] ?? "";  if (fraction.length > decimals && /[1-9]/.test(fraction.slice(decimals))) {    throw new Error("Amount exceeds token precision");  }  return BigInt(match[1]) * 10n ** BigInt(decimals)    + BigInt(fraction.slice(0, decimals).padEnd(decimals, "0") || "0");}const baseUnits = decimalToBaseUnits(detail.data.ticket_price_usd, decimals) * BigInt(qty);// 3. transferChecked (NOT transfer) + exactly one memo.const mint = new PublicKey(usdc_mint);const tx = new Transaction().add(  createTransferCheckedInstruction(    getAssociatedTokenAddressSync(mint, payer.publicKey),    mint,    new PublicKey(treasury_ata),    payer.publicKey,    baseUnits,    decimals,  ),  new TransactionInstruction({    keys: [],    programId: MEMO_PROGRAM_ID,    data: Buffer.from(`${memo_prefix}:${externalUserRef}`, "utf8"),  }),);// 4. Wait for FINALIZED before submitting to Verity.const signature = await sendAndConfirmTransaction(connection, tx, [payer], {  commitment: "finalized",});

Timing

Verity verifies the transaction at finalized commitment. Network confirmation can take time; a client timeout does not prove the purchase failed.

  • Wait for finalized yourself before calling this endpoint.
  • Set your HTTP timeout to at least 30 seconds. This is not a fast call.
  • 409 TX_NOT_FOUND means "not visible yet, retry", not "invalid".

Two 200 outcomes

replayed: false — tickets issued now. replayed: true — this signature was already issued and you are receiving the original result. Both are successes.

Retry only with the same signature, raffle, quantity and buyer. A changed purchase identity returns IDEMPOTENCY_KEY_REUSED. Do not send this payment through the checkout API as well.

Authorization

PartnerApiKey
headerAuthorizationBearer <token>

Authorization: Bearer <your_api_key>

Keep this credential on your server, never in browser or mobile app code. A missing, invalid or disabled key returns 401 PLATFORM_KEY_INVALID. Ask Verity to replace a lost or exposed key.

Path Parameters

raffleId*integer
Range1 <= value

Request Body

application/json
  1. body
tx_signature*string

Base58 signature of the finalized USDC transfer. This doubles as the idempotency key — do not send an Idempotency-Key header.

Match^[1-9A-HJ-NP-Za-km-z]+$
Length64 <= length <= 88
external_user_ref*string

Your stable, unique, permanent id for this buyer — it is their identity for tickets, winning, buyback and refunds. A Rarible user id is ideal; an email or display name is not.

No leading or trailing whitespace: "alice" and " alice" would otherwise collide onto one memo but two different users.

Match^\S(.*\S)?$
Length1 <= length <= 255
display_name?|

Optional. Shown on public leaderboards.

Lengthlength <= 64
qty*integer

The paid amount must equal ticket_price_usd × qty exactly.

Range1 <= value <= 1000

Response Body

Tickets issued, or replayed from a previous identical request.

application/json
  1. response
success*boolean
data*
Example Request
curl -X POST 'https://api-staging.theverity.xyz/api/v1/platform/raffles/77/tickets' \  -H 'Authorization: Bearer <your_partner_api_key>' \  -H 'Content-Type: application/json' \  -d '{  "tx_signature": "5NxJZ8bTqf9vK2mR7wYpL4dHnQ3sXcV6aB1eG8tU9yWfM2kPjR5hN7xC4vD6zA3bQ8sT1mL9pK2wY7nH4gF6",  "external_user_ref": "usr_8812",  "display_name": "alice",  "qty": 5}'
Example Response
{  "success": true,  "data": {    "purchase_id": 9134,    "raffle_id": 77,    "qty": 5,    "total_usd": 250,    "tickets": [      "R077-T00410",      "R077-T00411",      "R077-T00412",      "R077-T00413",      "R077-T00414"    ],    "replayed": false  }}