Skip to main content
POST
/
collections
/
{collectionId}
/
refund
Create Refund
curl --request POST \
  --url https://api.fyatu.com/api/v3/collections/{collectionId}/refund \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "mode": "FULL",
  "reason": "CUSTOMER_REQUEST"
}
'
{
  "success": true,
  "status": 201,
  "message": "<string>",
  "data": {
    "refundId": "<string>",
    "collectionId": "<string>",
    "amount": 123,
    "currency": "<string>",
    "reason": "<string>",
    "reasonDescription": "<string>",
    "status": "PENDING",
    "recipient": {
      "clientId": "<string>",
      "name": "<string>"
    },
    "createdAt": "2023-11-07T05:31:56Z"
  },
  "meta": {
    "requestId": "req_abc123def456",
    "timestamp": "2023-11-07T05:31:56Z"
  }
}

Overview

Issue a full or partial refund for a completed collection. The refund amount is debited from your business wallet and credited to the payer’s Fyatu account. Important: Each collection can only be refunded once. Choose between a full refund or a partial refund at the time of processing.

Path Parameters

ParameterTypeDescription
collectionIdstringThe collection ID to refund

Request Body

FieldTypeRequiredDescription
modestringNoRefund mode: FULL (default) or PARTIAL
amountnumberConditionalRequired for PARTIAL mode. Refund amount in USD
reasonstringNoReason code (default: CUSTOMER_REQUEST). See available reasons

Refund Modes

ModeDescriptionAmount Required
FULLRefunds the entire net amount automaticallyNo
PARTIALRefunds a specific amount you specifyYes
Use FULL mode to avoid calculation errors. The system automatically determines the maximum refundable amount (net amount after fees).

Refund Reason Codes

Use one of these predefined reason codes in the reason field:
CodeDescription
DUPLICATE_PAYMENTDuplicate payment
FRAUDULENTFraudulent transaction
CUSTOMER_REQUESTCustomer requested refund (default)
ORDER_CANCELLEDOrder was cancelled
PRODUCT_NOT_DELIVEREDProduct/service not delivered
PRODUCT_NOT_AS_DESCRIBEDProduct/service not as described
PRICING_ERRORPricing or billing error
OTHEROther reason
You can also retrieve these programmatically via GET /api/v3/refunds/reasons.

Response

FieldTypeDescription
refundIdstringUnique refund identifier
collectionIdstringOriginal collection ID
amountnumberRefunded amount
currencystringCurrency code
reasonstringReason code
reasonDescriptionstringHuman-readable reason description
statusstringCOMPLETED
recipientobjectPayer who received the refund
recipient.clientIdstringPayer’s Fyatu client ID
recipient.namestringPayer’s name
createdAtstringRefund timestamp

Refund Rules

  1. Only Completed Collections: Cannot refund pending, expired, or failed payments
  2. One Refund Per Collection: Each collection can only be refunded once
  3. Maximum Refundable: Net amount (original amount minus fees)
  4. Fees Non-Refundable: Processing fees are retained
  5. Wallet Balance Required: Your business wallet must have sufficient balance

Example Usage

<?php
$collectionId = 'SCI679A1B2C3D4E5';

// Full refund (recommended - automatically calculates amount)
$response = file_get_contents(
    "https://api.fyatu.com/api/v3/collections/{$collectionId}/refund",
    false,
    stream_context_create([
        'http' => [
            'method' => 'POST',
            'header' => [
                'Content-Type: application/json',
                'Authorization: Bearer ' . $accessToken
            ],
            'content' => json_encode([
                'mode' => 'FULL',
                'reason' => 'CUSTOMER_REQUEST'
            ])
        ]
    ])
);

$result = json_decode($response, true);

if ($result['success']) {
    echo "Refund successful: {$result['data']['refundId']}\n";
    echo "Amount refunded: \${$result['data']['amount']}\n";
    echo "Credited to: {$result['data']['recipient']['name']}\n";
}

// Partial refund example
$partialResponse = file_get_contents(
    "https://api.fyatu.com/api/v3/collections/{$collectionId}/refund",
    false,
    stream_context_create([
        'http' => [
            'method' => 'POST',
            'header' => [
                'Content-Type: application/json',
                'Authorization: Bearer ' . $accessToken
            ],
            'content' => json_encode([
                'mode' => 'PARTIAL',
                'amount' => 10.00,
                'reason' => 'PRODUCT_NOT_AS_DESCRIBED'
            ])
        ]
    ])
);

Example Response (Full Refund)

{
  "success": true,
  "status": 201,
  "message": "Refund processed successfully",
  "data": {
    "refundId": "REF679A1B2C3D4E5",
    "collectionId": "SCI679A1B2C3D4E5",
    "amount": 24.25,
    "currency": "USD",
    "reason": "CUSTOMER_REQUEST",
    "reasonDescription": "Customer requested refund",
    "status": "COMPLETED",
    "recipient": {
      "clientId": "F12345678",
      "name": "John Doe"
    },
    "createdAt": "2026-01-08T14:00:00+00:00"
  },
  "meta": {
    "requestId": "req_refund123",
    "timestamp": "2026-01-08T14:00:00+00:00"
  }
}

Example Response (Partial Refund)

{
  "success": true,
  "status": 201,
  "message": "Refund processed successfully",
  "data": {
    "refundId": "REF679A1B2C3D4E6",
    "collectionId": "SCI679A1B2C3D4E5",
    "amount": 10.00,
    "currency": "USD",
    "reason": "PRODUCT_NOT_AS_DESCRIBED",
    "reasonDescription": "Product/service not as described",
    "status": "COMPLETED",
    "recipient": {
      "clientId": "F12345678",
      "name": "John Doe"
    },
    "createdAt": "2026-01-08T14:00:00+00:00"
  },
  "meta": {
    "requestId": "req_refund124",
    "timestamp": "2026-01-08T14:00:00+00:00"
  }
}

Amount Exceeds Maximum

If you request a partial refund amount that exceeds the maximum refundable, the API will return an error with the maximum amount:
{
  "success": false,
  "status": 400,
  "message": "Requested amount (50.00) exceeds maximum refundable amount",
  "error": {
    "code": "AMOUNT_EXCEEDS_REFUNDABLE",
    "maxRefundable": 24.25
  }
}

Refund Amount Calculation

Original Payment$25.00
Processing Fee-$0.75
Net Amount (Max Refundable)$24.25
Processing fees are non-refundable. The maximum refund amount is the net amount you received, not the original payment amount.

Error Responses

Error CodeHTTPDescription
RESOURCE_NOT_FOUND404Collection not found
INVALID_STATUS400Collection not in COMPLETED status
AMOUNT_EXCEEDS_REFUNDABLE400Requested amount exceeds maximum (includes maxRefundable value)
ALREADY_REFUNDED400Collection has already been refunded
INSUFFICIENT_BALANCE402Business wallet balance too low
PAYER_NOT_FOUND400Payer account no longer exists

Collection Status After Refund

  • Full Refund: Collection status changes to REFUNDED
  • Partial Refund: Collection status changes to PARTIALLY_REFUNDED
  • Customer Notification: Payer receives notification of the refund
Keep track of refund IDs to handle customer inquiries and for accounting purposes.

Authorizations

Authorization
string
header
required

JWT access token obtained from /auth/token

Path Parameters

collectionId
string
required

Collection ID or batch ID

Body

application/json
mode
enum<string>
default:FULL

Refund mode: FULL (auto-calculate) or PARTIAL (specify amount)

Available options:
FULL,
PARTIAL
amount
number

Refund amount (required for PARTIAL mode)

reason
enum<string>
default:CUSTOMER_REQUEST

Reason code for refund

Available options:
DUPLICATE_PAYMENT,
FRAUDULENT,
CUSTOMER_REQUEST,
ORDER_CANCELLED,
PRODUCT_NOT_DELIVERED,
PRODUCT_NOT_AS_DESCRIBED,
PRICING_ERROR,
OTHER

Response

Refund created successfully

success
boolean
Example:

true

status
integer
Example:

201

message
string
data
object
meta
object