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
- An access token needs to be generated in order to use this API (see Authentication - Generate Access Token)
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 Name | Description |
|---|---|
| AccessToken | This is the Access Token field returned from the Authentication - Generate Access Token response. This should be in the format Bearer <AccessToken> |
| Content-Type | application/vnd.carry1st.payments.refund+json |
| X-Signature | The signature of the request. See Gateway - Generating Signatures for how to generate it. |
| X-Timestamp | The 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/createList 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.
| Param | Format | Mandatory | Description |
|---|---|---|---|
| transactionReference | String | Y | The Pay1st identifier that was obtained in the response of Create Payment Request |
| partnerRefundReference | String | N | Your 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. |
| amount | Decimal | N | The 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. |
| reason | String | N | A documented reason for initiating the refund request |
| refundWebhookUrl | String | N | The 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 (
PENDINGorPROCESSING), another refund request for the same transaction is rejected with HTTP409. -
partnerRefundReferenceis 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 therefundReferencein the response, and you can find it with List Refunds using thetransactionReference. -
If you send
partnerRefundReference, make it unique. Every refund request needs its own value, different from the payment'spartnerReference. -
Retries. If a refund request returns an HTTP
5xxerror or times out, do not send a new refund request straight away. The refund may already have been created. First check its status:- with List Refunds, using the
transactionReference; or - with Query Refund by Reference, using the
partnerRefundReferenceyou sent, if you sent one.
Send a new refund request only if no refund exists, or if the existing refund ended
FAILEDorREJECTED. If you usepartnerRefundReference, give the new request a new value. - with List Refunds, using the
Success Response
Valid HTTP Status Codes:
| HTTP Status Code | Name | Description |
|---|---|---|
| 201 | Created | The refund request has been created. Check status in the response body for its current state. |
| 400 | Bad Request | The 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). |
| 401 | Unauthorized | The AccessToken header is missing, invalid or expired. Generate a new access token and retry. |
| 404 | Not Found | No transaction was found for transactionReference (error 4201). |
| 409 | Conflict | A refund for this transaction is already in progress (error 4206). |
| 500 | Internal Server Error | An 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
| Name | Type | Description |
|---|---|---|
| refundReference | String | The unique identifier of the refund |
| transactionReference | String | The original transaction's identifier that was passed in the request |
| partnerReference | String | The partnerReference of the original payment |
| partnerRefundReference | String | Your refund identifier, if it was passed in the request |
| amount | Number | The amount that will be refunded |
| currencyCode | String | The currency code of the refund |
| status | String | The 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. |
| handlingType | String | How 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. |
| fullRefund | Boolean | true if this refund is for the full amount paid |
| reason | String | The reason passed in the request |
| createdDate | String | The 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) |
| lastModifiedDate | String | The 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 Code | HTTP Status | Description |
|---|---|---|
| 4201 | 404 | No transaction was found for transactionReference |
| 4202 | 400 | The transaction does not belong to your account |
| 4203 | 400 | The transaction cannot be refunded because it is not in SUCCESSFUL status (for example, it has already been refunded) |
| 4204 | 400 | No successful payment was found for the transaction |
| 4205 | 400 | The payment method used does not support refunds |
| 4206 | 409 | A refund for this transaction is already in progress |
| 4207 | 400 | amount is greater than the amount paid |
| 4210 | 400 | The transaction has no partner associated with it |
| 4211 | 400 | partnerRefundReference 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.
