Skip to content

Refunds API

🤖 Explain with AI

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):

curl -X GET 'https://api.4geeks.io/v1/refunds/' \
     -u 'sk_test_51O62xYzAbcDef123:'

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:

{
    "detail": "Authentication credentials were not provided."
}

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:

{
    "detail": "Refund doesn't exist in your list."
}

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

  1. Always specify a reason - This helps with tracking and dispute resolution
  2. Use partial refunds when possible - If you’re processing a correction, use partial refunds instead of full refunds
  3. Process refunds promptly - Refunds are more likely to succeed if initiated soon after the charge
  4. Verify before refunding - Check that the charge belongs to your account and hasn’t been paid out
  5. Monitor refund status - Use the GET endpoint to verify refund completion
  6. 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.