Skip to main content

Refund Flow


Create a Refund

Send a server-side request to create a refund for a paid session.
POST /v1/refunds
Authorization: Bearer <your_access_token>
Content-Type: application/json

{
  "payment_id": "pay_xyz789",
  "reason": "Customer request"
}
Parameters:
  • payment_id: The original payment ID to refund
  • reason: Optional reason for the refund
Response: A Refund object.
{
  "id": "ref_xyz789",
  "payment_id": "pay_xyz789",
  "status": "pending",
  "reason": "Customer request",
  "created_at": "2023-06-01T12:00:00Z"
}

Refund Statuses

Refunds can have the following statuses:
  • pending: Refund created but not yet processed
  • succeeded: Refund has been successfully processed and funds returned
  • failed: Refund failed (e.g., insufficient funds, payment method issues)
  • cancelled: Refund was cancelled before completion
Status Flow:
  1. Refund starts as pending
  2. Refund resolves to either succeeded, failed, or cancelled

Timestamp Fields

Refunds include relevant timestamp fields based on their final status:
  • created_at: When the refund was initiated
  • succeeded_at: When the refund completed successfully (if applicable)
  • failed_at: When the refund failed (if applicable)
  • cancelled_at: When the refund was cancelled (if applicable)

Webhook Events

ToffeePay sends webhooks for the following refund-related events: See the Webhooks page for implementation details and signature verification.

Handle Refund Notifications

When a refund is processed, ToffeePay sends a signed webhook to your backend. Sample Payload:
{
  "type": "refund.succeeded",
  "timestamp": "2023-06-01T12:10:00Z",
  "data": {
    // Refund object
  }
}
For webhook signature verification, see the Webhooks page.

Check Refund Status

You can check the status of a refund at any time:
GET /v1/refunds/ref_xyz789
Authorization: Bearer <your_access_token>
Response:
{
  "id": "ref_xyz789",
  "payment_id": "pay_xyz789",
  "status": "succeeded",
  "reason": "Customer request",
  "created_at": "2023-06-01T12:00:00Z",
  "succeeded_at": "2023-06-01T12:05:00Z"
}

List Refunds

Retrieve historical refunds for audit and analytics:
GET /v1/refunds?payment_id=pay_xyz789&status=succeeded&limit=50&offset=0
Authorization: Bearer <your_access_token>
Response:
[
  {
    "id": "ref_xyz789",
    "payment_id": "pay_xyz789",
    "status": "succeeded",
    "reason": "Customer request",
    "created_at": "2023-06-01T12:00:00Z",
    "succeeded_at": "2023-06-01T12:05:00Z"
  }
]

Best Practices

  1. Idempotency: Use Idempotency-Key header to prevent duplicate refunds
  2. Revoke Items: When processing a refund webhook, revoke the purchased items from the user’s account
  3. Webhook verification: Always verify webhook signatures (see Webhooks)