Refunds API
Refunds API is a tool that allows businesses to initiate and manage refunds for transactions made through their payment processing system. When a customer requests a refund, the Refunds API enables the business to process the refund quickly and easily, without having to manually handle the refund process.
This API handles the communication with the payment processor to ensure that the refund is processed correctly and in compliance with any relevant regulations.
Create a refund¶
Endpoint
POST /v1/refunds/
Creates a refund for a specific charge. You can optionally specify an amount for partial refunds. If no amount is provided, the full charge amount will be refunded.
Requirements
- Charge must exist in the system
- Charge must not already be fully refunded
- For production (live) charges: charge must not be already paid to your account
Fields:
| Parameter | Description | Type | Required |
|---|---|---|---|
| charge_id | The charge id | string | true |
| amount | Amount to refund (partial refund). If omitted, full refund is processed | decimal | false |
| reason | duplicate, fraudulent or requested_by_customer | string | true |
| test | Indicates if the refund is in test mode (true for testing, false for production). | boolean | false |
Request (Full Refund):
curl -X POST 'https://api.4geeks.io/v1/refunds/' \
-u 'sk_test_51O62xYzAbcDef123:' \
-H 'Content-Type: application/json' \
-d '{
"charge_id": "1BSt6hCqnAMAMqhvMGiBxOWe",
"reason": "requested_by_customer"
}'
Request (Partial Refund):
curl -X POST 'https://api.4geeks.io/v1/refunds/' \
-u 'sk_test_51O62xYzAbcDef123:' \
-H 'Content-Type: application/json' \
-d '{
"charge_id": "1BSt6hCqnAMAMqhvMGiBxOWe",
"amount": 10.50,
"reason": "requested_by_customer"
}'
Response (Full Refund - 201 Created):
{
"id": "1BiPhgCqnAMsdzqhvCTntF7aD",
"provider_refund_id": "re_1ABC123XYZ456",
"charge_id": "1BSt6hCqnAMAMqhvMGiBxOWe",
"amount": "100.00",
"currency": "usd",
"reason": "requested_by_customer",
"status": "succeeded",
"test": true,
"created_at": "2025-12-04T15:30:00Z"
}
Response (Partial Refund - 201 Created):
{
"id": "1BiPhgCqnAMsdzqhvCTntF7aD",
"provider_refund_id": "re_1ABC123XYZ456",
"charge_id": "1BSt6hCqnAMAMqhvMGiBxOWe",
"amount": "10.50",
"currency": "usd",
"reason": "requested_by_customer",
"status": "succeeded",
"test": true,
"created_at": "2025-12-04T15:30:00Z"
}
Get a refund¶
Endpoint
GET /v1/refunds/{refund_id}/
This endpoint returns a specific refund object by its ID.
Path Parameters:
| Parameter | Description | Type | Required |
|---|---|---|---|
| refund_id | The refund ID (without ‘re_’ prefix) | string | true |
Request:
curl -X GET 'https://api.4geeks.io/v1/refunds/1BiPhgCqnAMsdzqhvCTntF7aD/' \
-u 'sk_test_51O62xYzAbcDef123:'
Response (200 OK):
{
"id": "1BiPhgCqnAMsdzqhvCTntF7aD",
"provider_refund_id": "re_1ABC123XYZ456",
"charge_id": "1BSt6hCqnAMAMqhvMGiBxOWe",
"amount": "10.00",
"currency": "usd",
"reason": "duplicate",
"status": "succeeded",
"test": true,
"created_at": "2025-12-04T14:20:00Z"
}
List refunds¶
Endpoint
GET /v1/refunds/
This endpoint returns all refunds for your account. You can filter by charge_id using query parameters.
Query Parameters:
| Parameter | Description | Type | Required |
|---|---|---|---|
| charge_id | Filter refunds by specific charge ID (optional) | string | false |
| test | Indicates if filtering test mode refunds | boolean | false |
Request (List All Refunds):
Request (Filter by Charge ID):
curl -X GET 'https://api.4geeks.io/v1/refunds/?charge_id=1BSt6hCqnAMAMqhvMGiBxOWe' \
-u 'sk_test_51O62xYzAbcDef123:'
Response (200 OK):
[
{
"id": "1BiOrQCqNertMqhvvUMhJajE",
"provider_refund_id": "re_1XYZ123ABC456",
"charge_id": "1BSt5sCqnAMAMqhvd871C1Vl",
"amount": "10.00",
"currency": "usd",
"reason": "duplicate",
"status": "succeeded",
"test": true,
"created_at": "2025-12-03T10:15:00Z"
},
{
"id": "1BiPDoCqnNerAMqhvSzxyFXl2",
"provider_refund_id": "re_2ABC456XYZ789",
"charge_id": "1BSt5sCqnAMAMqhvd871C1Vl",
"amount": "40.00",
"currency": "usd",
"reason": "fraudulent",
"status": "succeeded",
"test": true,
"created_at": "2025-12-02T16:45:00Z"
}
]
Error Handling¶
The API returns standard HTTP status codes to indicate the success or failure of a request. Below are common errors specific to refunds:
400 Bad Request¶
Occurs when the request is missing required fields or has invalid data.
Scenarios:
| Scenario | Error Message | Solution |
|---|---|---|
| Missing charge_id | "Charge object doesn't exist." | Verify the charge_id is correct and exists |
| Partial refund exceeds charge amount | "The amount provided is greater than the amount of the payment." | Reduce the refund amount to be less than or equal to the charge |
| Charge already fully refunded | "Charge requested is already refunded" | Check if the charge has already been refunded |
| Missing reason field | "reason field is required" | Include a valid reason: duplicate, fraudulent, or requested_by_customer |
Example Error Response:
{
"code": 400,
"title": "Refund error",
"content": "The amount provided is greater than the amount of the payment.",
"type": "danger"
}
401 Unauthorized¶
Authentication failed. API Key is invalid, missing, or malformed.
Example:
Solution: - Verify you included the Authorization: Basic <base64_key> header or used -u in cURL - Ensure your API Key is correct and active - Test with Postman to debug
404 Not Found¶
The requested charge or refund does not exist.
Example:
Solution: - Verify the charge_id or refund_id exists - Check that you’re using the correct ID format (without prefixes like ch_ or re_) - Ensure the charge belongs to your developer account
409 Conflict¶
The charge has already been paid out to your account and cannot be refunded.
Example:
{
"code": 400,
"title": "Charge status error",
"content": "The charge requested is already paid to your account.",
"type": "danger"
}
Solution: - Refunds are only possible before charges are deposited to your bank account - Contact support if you need assistance with paid charges
Refund Reasons¶
When creating a refund, you must specify one of the following reasons:
| Reason | Use Case |
|---|---|
duplicate | The charge was duplicated or processed twice |
fraudulent | The charge was fraudulent or unauthorized |
requested_by_customer | The customer requested a refund |
Best Practices¶
- Always specify a reason - This helps with tracking and dispute resolution
- Use partial refunds when possible - If you’re processing a correction, use partial refunds instead of full refunds
- Process refunds promptly - Refunds are more likely to succeed if initiated soon after the charge
- Verify before refunding - Check that the charge belongs to your account and hasn’t been paid out
- Monitor refund status - Use the GET endpoint to verify refund completion
- Handle errors gracefully - Implement proper error handling for common scenarios
Troubleshooting¶
Problem: “Charge object doesn’t exist”¶
Cause: The charge_id provided doesn’t match any charge in the system
Solution: - Verify the charge_id format (remove ‘ch_’ prefix if included) - Confirm the charge belongs to your developer account - Use the Payments API to list all charges and find the correct ID
Problem: “Charge requested is already refunded”¶
Cause: A full refund has already been processed for this charge
Solution: - Check if a refund was already created using GET /v1/refunds/?charge_id=xxx - If you need additional refunds, process them before the initial full refund
Problem: “The charge requested is already paid to your account”¶
Cause: The charge has been deposited to your bank account
Solution: - Refunds can only be processed before payout - Contact support for charges that have already been paid out
FAQ¶
Q: Can I refund a partial amount of a charge?
A: Yes, specify the amount parameter in the request. The charge amount will be reduced accordingly.
Q: What happens to my balance when I refund?
A: Your available balance is adjusted. For full refunds, the entire charge is reversed. For partial refunds, your balance reflects the reduced amount.
Q: Can I cancel a refund?
A: No, once initiated, refunds cannot be cancelled. Plan carefully before creating a refund.
Q: What’s the difference between full and partial refunds?
A: Full refunds revert the entire charge amount and mark it as refunded. Partial refunds reduce the charge amount and mark it as partially refunded.
Q: Can I refund a charge multiple times?
A: Yes, you can issue multiple partial refunds as long as the total refunded amount doesn’t exceed the original charge amount.
- Login or signup into Console.
- Check out the changelog.
- Contact our enterprise support team.