Skip to main content
POST /api/actions/refund-ticket/create-ticket Authentication: Merchant API Key (server-to-server).

Request body

FieldTypeRequiredDescription
paymentIdstringYesShort ID of the payment to refund, e.g. PAY_6eYCunG3IMmIgcQOnaXdoA
reasonstringYesFree-text reason shown to the consumer / dashboard
requestedAmount.amountstringYesRefund amount in display format (e.g. "10.50"), must be > 0 and ≤ payment.amount
requestedAmount.currencystringYesISO 4217 code, must match the payment currency
refundTicketMerchantExternalIdstringNoYour business-side refund-ticket reference (max 128 chars).

Success response (200)

{
  "data": {
    "ticket": {
      "id": "TKT_3bVzrkD0FJjFdZNLk8Ualx",
      "status": "processing",
      "subjectId": "PAY_6eYCunG3IMmIgcQOnaXdoA",
      "refundTicketMerchantExternalId": "REF-2026-00891"
    }
  }
}
When the merchant submits via API Key, the ticket is auto-approved and goes straight to processing.

Errors

Retry policy: Never retry 4xx — fix the request and resubmit. Retry 5xx with exponential backoff (start 5s, max 3 attempts).
Statuserrors[0].messageWhat it meansRecommended handling
400Missing required field: <name>Required field missing (paymentId, reason, requestedAmount.amount, requestedAmount.currency)Fix the body, resubmit
400Expected format: PAY_xxx, got "..."paymentId Short ID could not be decodedFix paymentId format, resubmit
400Invalid requestedAmount.amount formatAmount string could not be parsedUse a display string like "10.50" (not minor units)
400refundTicketMerchantExternalId must be at most 128 charactersValue exceeds 128 charsShorten to 128 chars or less
401UnauthorizedInvalid API Key signatureVerify auth headers
404Payment not foundPayment doesn’t exist or doesn’t belong to your storeVerify paymentId
409Payment status is X, must be succeededOriginal payment is not in succeeded stateDo not retry — the payment never succeeded
409Payment is not yet fully processed by PSP, please retry laterPSP confirmation hasn’t been written back yetRetry after 5–30 seconds (transient)
409Refund period expired (X days, max 14)Past the 14-day windowDo not retry — refunds are no longer allowed
409Requested amount must be greater than 0Amount is ≤ 0Fix the amount, resubmit
409Requested amount exceeds payment amountAmount > payment.amountFix the amount, resubmit
409Currency mismatch: requested X, payment YCurrency must match the original paymentUse the payment’s currency
409A refund record already exists for this paymentA previous refund already succeeded against this paymentDo not retry — query existing refunds via GraphQL
409A refund ticket already exists for this paymentAnother in-flight ticket is blockingWait for the existing ticket to terminate, then resubmit if still needed
500Internal server errorUnexpected server-side failureRetry with exponential backoff (start 5s, max 3 attempts)
Use GraphQL to query the created ticket and the executed refund record. Filter executed refunds by the ticket reference using refunds(filter: { refundTicketMerchantExternalId: ... }).