Refund Request

Use this API to request refunds through the Pay1st Gateway

Used in Gateway Integration

📘

NOTE This API feature is still in an beta state

Overview

A Refund Request can to be created with the Pay1st gateway after a payment has been processed. This API is a POST request that takes Pay1st transaction reference as input, and returns the refund details as a JSON response.

Pre Requisites

Request Signature

A valid signature should be generated for this request. See Gateway - Generating Signatures for a detailed description on how this should be implemented.

API Description

HTTP Headers

Header NameDescription
AccessTokenThis is the Access Token field returned from the Authentication - Generate Access Token response. This should be in the format Bearer <AccessToken>
Content-Typeapplication/vnd.carry1st.payments.refund+json
X-SignatureThe signature of the request. See Gateway - Generating Signatures for how to generate it.
X-TimestampThe current time as an ISO-8601 UTC date-time (for example 2025-03-17T08:10:52.544Z). This must be exactly the same timestamp that was used to generate the signature.

URL Format

POST https://<payments_url>/api/pay1st/transactions/refunds/create

List of Refund Request POST fields

These are the list of POST fields that needs to be passed from the Pay1st Partner to the Pay1st Gateway.

ParamFormatMandatoryDescription
transactionReferenceStringYThe Pay1st identifier that was obtained in the response of Create Payment Request
partnerRefundReferenceStringNYour unique identifier for this refund request.
This field is optional. If you don't need it, leave it out of the request entirely (do not send an empty value). Without it, find the refund with List Refunds using the transactionReference.
If you send it, it must be unique for every refund request, and it must be different from the partnerReference you sent when creating the payment.
Use a new value for every refund attempt, including a new attempt after a FAILED refund. A value that has already been used is rejected.
If you send it, you can use it to look up the refund with Query Refund by Reference.
amountDecimalNThe amount to refund, in the currency of the original payment. It must be at least 0.01 and no more than the amount paid.
If amount is not provided, the full amount paid is refunded.
reasonStringNA documented reason for initiating the refund request
refundWebhookUrlStringNThe URL that will receive the refund webhooks for this refund. It must be a valid URL. If it is not provided, the refund webhook URL configured for your account is used.

Example JSON Request

The following JSON Request is an example of a correctly constructed Refund Request:

{
  "transactionReference": "C-CA5CGGMV7QQG1HUY05Z-P",
  "partnerRefundReference": "refund-7f3c2a91",
  "amount": 50.00,
  "reason": "Customer requested refund",
  "refundWebhookUrl": "https://partner.example.com/webhooks/pay1st/refunds"
}

Refund Rules

  • One refund in progress at a time. While a refund for a transaction is still in progress (PENDING or PROCESSING), another refund request for the same transaction is rejected with HTTP 409.

  • partnerRefundReference is optional. The simplest option is to leave it out of the request entirely (do not send an empty value). The refund is still identified by the refundReference in the response, and you can find it with List Refunds using the transactionReference.

  • If you send partnerRefundReference, make it unique. Every refund request needs its own value, different from the payment's partnerReference.

  • Retries. If a refund request returns an HTTP 5xx error or times out, do not send a new refund request straight away. The refund may already have been created. First check its status:

    Send a new refund request only if no refund exists, or if the existing refund ended FAILED or REJECTED. If you use partnerRefundReference, give the new request a new value.

Success Response

Valid HTTP Status Codes:

HTTP Status CodeNameDescription
201CreatedThe refund request has been created. Check status in the response body for its current state.
400Bad RequestThe X-Signature HTTP header does not match the request.
The X-Timestamp HTTP header is not within 5 minutes of the current server time.
The request body is invalid, or the refund cannot be made (see Refund Error Codes).
401UnauthorizedThe AccessToken header is missing, invalid or expired. Generate a new access token and retry.
404Not FoundNo transaction was found for transactionReference (error 4201).
409ConflictA refund for this transaction is already in progress (error 4206).
500Internal Server ErrorAn error on the Carry1st side. Before retrying, check whether the refund was created (see Refund Rules).

HTTP Response Body:

{
  "refundReference": "C-7MV6T02M8O88UCRCBYW-R",
  "transactionReference": "C-CA5CGGMV7QQG1HUY05Z-P",
  "partnerReference": "48502830697945",
  "partnerRefundReference": "refund-7f3c2a91",
  "amount": 50.00,
  "currencyCode": "NGN",
  "status": "PROCESSING",
  "handlingType": "PSP_API",
  "fullRefund": false,
  "reason": "Customer requested refund",
  "createdDate": "2026-Mar-10 12:00:00",
  "lastModifiedDate": "2026-Mar-10 12:00:01"
}

HTTP Response Fields

NameTypeDescription
refundReferenceStringThe unique identifier of the refund
transactionReferenceStringThe original transaction's identifier that was passed in the request
partnerReferenceStringThe partnerReference of the original payment
partnerRefundReferenceStringYour refund identifier, if it was passed in the request
amountNumberThe amount that will be refunded
currencyCodeStringThe currency code of the refund
statusStringThe current status of the refund: PENDING, PROCESSING, SUCCESSFUL, FAILED or REJECTED.
For PSP_API refunds, the response can already contain PROCESSING, SUCCESSFUL or FAILED. For PSP_MANUAL refunds it is PENDING.
Later changes are sent to you by the Refund Webhook.
handlingTypeStringHow the refund will be handled: PSP_API (refunded automatically through the payment provider) or PSP_MANUAL (processed manually by Carry1st). Payment methods that do not support refunds are rejected with error 4205.
fullRefundBooleantrue if this refund is for the full amount paid
reasonStringThe reason passed in the request
createdDateStringThe date and time the refund was created, in UTC, in the format yyyy-MMM-dd HH:mm:ss (e.g. 2026-Mar-10 12:00:00)
lastModifiedDateStringThe date and time the refund was last updated, in UTC, in the format yyyy-MMM-dd HH:mm:ss

Error Response

Errors from the refund checks (see Refund Error Codes) have this format:

{
  "errorMessage": "A refund has already been processed for this transaction.",
  "errorCode": "4206",
  "sessionId": "SESSION_ID"
}

Use errorCode to handle errors. The text of errorMessage can change. If the response includes a sessionId, send it to Carry1st when you need help with a failed request.

Refund Error Codes

Error CodeHTTP StatusDescription
4201404No transaction was found for transactionReference
4202400The transaction does not belong to your account
4203400The transaction cannot be refunded because it is not in SUCCESSFUL status (for example, it has already been refunded)
4204400No successful payment was found for the transaction
4205400The payment method used does not support refunds
4206409A refund for this transaction is already in progress
4207400amount is greater than the amount paid
4210400The transaction has no partner associated with it
4211400partnerRefundReference is already in use (for example, it is the same as the payment's partnerReference). Send a new, unique value

See Handling Error Codes for the general error codes and how to handle error responses.