Flex Refund API Guide - Flex Documentation

Documentation Index

Fetch the complete documentation index at: /llms.txt

Use this file to discover all available pages before exploring further.

Important IDs to store:

You can also retrieve the checkout session to get additional details:

GET /v1/checkout/sessions/{checkout_session_id}

Response includes:


Primary Refund Endpoint

POST /v1/checkout/sessions//refund

This is the main refund endpoint for processing refunds on completed checkout sessions.

Base URL: https://api.withflex.com (or your custom domain)

Authentication:

Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

Request Format

Option 1: Line Item-Based Refund (Granular Control)

Refund specific products/prices with custom amounts:

{
  "checkout_session": {
    "line_items": [
      {
        "product": "fprod_01k3m6j3zqcvy6pbj1a65sszpw",
        "amount_to_refund": 2000
      },
      {
        "product": "fprod_01k3m6r0qj2bpc25q6h56r3jar",
        "amount_to_refund": 1500
      }
    ],
    "amount_tax": 350,
    "amount_shipping": 500,
    "amount_discount": 200,
    "refund_metadata": {
      "OrderNo": "ORDER123",
      "Source": "Customer_Request",
      "Reason": "Damaged_Product"
    }
  }
}

Alternative: Use price instead of product

{
  "checkout_session": {
    "line_items": [
      {
        "price": "fprice_01k3m6j3zqcvy6pbj1a65sszpw",
        "amount_to_refund": 2000
      }
    ],
    "refund_metadata": {
      "reason": "customer_request"
    }
  }
}

Option 2: Simple Amount-Based Refund

Refund a specific total amount without line item breakdown:

{
  "checkout_session": {
    "amount": 5000,
    "refund_metadata": {
      "reason": "customer_not_satisfied",
      "order_id": "12345"
    }
  }
}

Option 3: Full Refund

Refund the entire checkout session amount:

{
  "checkout_session": {
    "refund_metadata": {
      "reason": "order_cancelled"
    }
  }
}

Or simply:

{
  "checkout_session": {}
}

Request Parameters

Field Type Required Description
line_items array No Specific line items to refund with amounts
line_items[].product string One of Product ID to refund (e.g., fprod_xxx)
line_items[].price string product/price Price ID to refund (e.g., fprice_xxx)
line_items[].amount_to_refund integer No Amount in cents for this item (omit for full item refund)
amount integer No Total amount to refund in cents (alternative to line_items)
amount_tax integer No Tax amount to refund in cents
amount_shipping integer No Shipping amount to refund in cents
amount_discount integer No Discount amount to refund in cents
refund_metadata object No Key-value pairs for tracking (order ID, reason, etc.)

Success Response

Status Code: 200 OK

{
  "checkout_session": {
    "checkout_session_id": "fcs_01kbjcmbt5mhsmaggfqc1a4rns",
    "status": "complete",
    "amount_total": 10000,
    "amount_subtotal": 9000,
    "currency": "usd",
    "customer": {
      "customer_id": "fcus_xxx",
      "email": "customer@example.com",
      "name": "John Doe"
    },
    "payment_intent": {
      "payment_intent_id": "fpi_xxx",
      "amount": 10000,
      "amount_received": 10000,
      "status": "succeeded"
    },
    "line_items": [...],
    "refunds": [
      {
        "refund_id": "fref_01kbjdxyz123",
        "payment_intent_id": "fpi_xxx",
        "amount": 3500,
        "status": "pending",
        "reason": null,
        "created_at": "2024-12-04T10:30:00Z",
        "test_mode": false,
        "metadata": {
          "OrderNo": "ORDER123",
          "Source": "Customer_Request"
        },
        "reference_id": null,
        "reference_type": "acquirer_reference_number",
        "reference_status": "pending",
        "items": [
          {
            "amount_refunded": 3500,
            "payment_intent": "fpi_xxx",
            "reference_id": null,
            "reference_type": "acquirer_reference_number",
            "reference_status": "pending"
          }
        ]
      }
    ]
  }
}

Key Response Fields:


Error Responses

Checkout Session Not Complete (422 Unprocessable Entity)

{
  "error": {
    "type": "validation_error",
    "message": "Checkout session must be complete",
    "errors": [
      {
        "loc": ["status"],
        "msg": "Checkout session must be complete",
        "type": "invalid_request_error"
      }
    ]
  }
}

Cause: Checkout session status is not complete


Checkout Session Not Found (404 Not Found)

{
  "error": {
    "type": "not_found",
    "message": "checkout session does not exist"
  }
}

Cause: Invalid checkout_session_id or doesn’t belong to your account


Unauthorized (401 Unauthorized)

{
  "error": {
    "type": "unauthorized",
    "message": "Invalid API key"
  }
}

Cause: Missing or invalid Authorization header


Refund Statuses

Status Description
pending Refund initiated, processing in progress
requires_action Additional action required (rare)
succeeded Refund completed, funds returned to customer
failed Refund failed (usually insufficient funds in connected account)
canceled Refund was canceled

Typical Timeline:


Complete Workflow Examples

Example 1: Full Refund

Step 1: Customer completes payment
You receive redirect after successful payment:

https://yoursite.com/success?session_id=fcs_01kbjcmbt5mhsmaggfqc1a4rns

Step 2: Customer requests full refund

curl -X POST https://api.withflex.com/v1/checkout/sessions/fcs_01kbjcmbt5mhsmaggfqc1a4rns/refund \
  -H "Authorization: Bearer sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "checkout_session": {
      "refund_metadata": {
        "reason": "customer_cancelled_order",
        "order_id": "ORD-12345",
        "requested_by": "customer_service"
      }
    }
  }'

Step 3: Response

{
  "checkout_session": {
    "checkout_session_id": "fcs_01kbjcmbt5mhsmaggfqc1a4rns",
    "status": "complete",
    "amount_total": 15000,
    "refunds": [
      {
        "refund_id": "fref_01kbjdxyz123",
        "amount": 15000,
        "status": "pending",
        "created_at": "2024-12-04T10:30:00Z",
        "metadata": {
          "reason": "customer_cancelled_order",
          "order_id": "ORD-12345"
        }
      }
    ]
  }
}

Step 4: Track refund status (optional)

curl -X GET https://api.withflex.com/v1/refunds/fref_01kbjdxyz123 \
  -H "Authorization: Bearer sk_live_xxx"

Example 2: Partial Refund by Line Items

Scenario: Customer returns 1 of 3 items purchased
Request:

curl -X POST https://api.withflex.com/v1/checkout/sessions/fcs_01kbjcmbt5mhsmaggfqc1a4rns/refund \
  -H "Authorization: Bearer sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "checkout_session": {
      "line_items": [
        {
          "product": "fprod_yoga_mat",
          "amount_to_refund": 3500
        }
      ],
      "amount_tax": 280,
      "amount_shipping": 0,
      "refund_metadata": {
        "reason": "item_returned",
        "rma_number": "RMA-2024-1234",
        "returned_items": "Yoga Mat (Blue)"
      }
    }
  }'

Explanation:


Example 3: Partial Refund by Amount

Scenario: Price adjustment without item-level detail
Request:

curl -X POST https://api.withflex.com/v1/checkout/sessions/fcs_01kbjcmbt5mhsmaggfqc1a4rns/refund \
  -H "Authorization: Bearer sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "checkout_session": {
      "amount": 2000,
      "refund_metadata": {
        "reason": "price_match_guarantee",
        "original_amount": 15000,
        "adjusted_amount": 13000,
        "competitor": "CompetitorStore"
      }
    }
  }'

Explanation:


Example 4: Multiple Partial Refunds

You can create multiple refunds for the same checkout session until the full amount is refunded.
First refund: $50

curl -X POST https://api.withflex.com/v1/checkout/sessions/fcs_xxx/refund \
  -H "Authorization: Bearer sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{"checkout_session": {"amount": 5000}}'

Second refund: $30

curl -X POST https://api.withflex.com/v1/checkout/sessions/fcs_xxx/refund \
  -H "Authorization: Bearer sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{"checkout_session": {"amount": 3000}}'

Important: Track the total refunded amount to avoid over-refunding.


Secondary Refund API

Tracking and Listing Refunds

After creating a refund via the checkout session endpoint, use the secondary refund API to track status:

GET /v1/refunds/

curl -X GET https://api.withflex.com/v1/refunds/fref_01kbjdxyz123 \
  -H "Authorization: Bearer sk_live_xxx"

Response:

{
  "refund": {
    "refund_id": "fref_01kbjdxyz123",
    "payment_intent_id": "fpi_xxx",
    "amount": 5000,
    "status": "succeeded",
    "reason": null,
    "created_at": "2024-12-04T10:30:00Z",
    "test_mode": false,
    "metadata": {
      "order_id": "12345"
    },
    "reference_id": "ARN8493274932",
    "reference_type": "acquirer_reference_number",
    "reference_status": "available",
    "items": [...]
  }
}

GET /v1/refunds (List Refunds)

Query Parameters:

Examples:

# All refunds
curl -X GET https://api.withflex.com/v1/refunds \
  -H "Authorization: Bearer sk_live_xxx"

# Refunds for specific checkout session
curl -X GET https://api.withflex.com/v1/refunds?checkout_session=fcs_01kbjcmbt5mhsmaggfqc1a4rns \
  -H "Authorization: Bearer sk_live_xxx"

# Succeeded refunds only
curl -X GET https://api.withflex.com/v1/refunds?status=succeeded \
  -H "Authorization: Bearer sk_live_xxx"

Response:

{
  "refunds": [
    {
      "refund_id": "fref_01kbjdxyz123",
      "payment_intent_id": "fpi_xxx",
      "amount": 5000,
      "status": "succeeded",
      "created_at": "2024-12-04T10:30:00Z",
      ...
    },
    {
      "refund_id": "fref_01kbjdabc456",
      "payment_intent_id": "fpi_yyy",
      "amount": 3000,
      "status": "pending",
      "created_at": "2024-12-03T15:20:00Z",
      ...
    }
  ]
}

PATCH /v1/refunds/ (Update Refund Metadata)

Update refund metadata or reason (does not change amount or status):

curl -X PATCH https://api.withflex.com/v1/refunds/fref_01kbjdxyz123 \
  -H "Authorization: Bearer sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "refund": {
      "reason": "fraudulent",
      "metadata": {
        "updated_by": "admin",
        "investigation_id": "INV-2024-001"
      }
    }
  }'

Testing

Test Mode

Use test API keys (starting with sk_test_) to test refunds without affecting real money:

curl -X POST https://api.withflex.com/v1/checkout/sessions/fcs_test_xxx/refund \
  -H "Authorization: Bearer sk_test_xxx" \
  -H "Content-Type: application/json" \
  -d '{"checkout_session": {}}'

Test Mode Behavior: