Skip to main content
Important IDs to store:
  • checkout_session_id - Extract from redirect URL (e.g., fcs_01kbjcmbt5mhsmaggfqc1a4rns)
  • This ID is required for creating refunds
You can also retrieve the checkout session to get additional details:
Response includes:
  • payment_intent_id - Flex’s internal payment ID
  • latest_charge - Charge ID
  • status - Should be complete for refunds

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:

Request Format

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

Refund specific products/prices with custom amounts:
Alternative: Use price instead of product

Option 2: Simple Amount-Based Refund

Refund a specific total amount without line item breakdown:

Option 3: Full Refund

Refund the entire checkout session amount:
Or simply:

Request Parameters


Success Response

Status Code: 200 OK
Key Response Fields:
  • refunds[].refund_id - Store this for tracking refund status
  • refunds[].status - Current refund status (pending, succeeded, failed)
  • refunds[].reference_id - Acquirer Reference Number (ARN) for bank tracking (populated later)
  • refunds[].reference_status - Status of reference number (pending, available, unavailable)

Error Responses

Checkout Session Not Complete (422 Unprocessable Entity)

Cause: Checkout session status is not complete

Checkout Session Not Found (404 Not Found)

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

Unauthorized (401 Unauthorized)

Cause: Missing or invalid Authorization header

Refund Statuses

Typical Timeline:
  • Refund status updates to succeeded within minutes to hours
  • Funds appear in customer’s account within 5-10 business days (varies by bank)

Reference Numbers for Tracking

Flex provides reference numbers that can be used to track refunds with banks and payment networks.

Reference Types

Reference Status

Note: Reference IDs typically become available within hours after the refund is created. Learn More: Stripe Reference Numbers Guide

Complete Workflow Examples

Example 1: Full Refund

Step 1: Customer completes payment You receive redirect after successful payment:
Step 2: Customer requests full refund
Step 3: Response
Step 4: Track refund status (optional)

Example 2: Partial Refund by Line Items

Scenario: Customer returns 1 of 3 items purchased Request:
Explanation:
  • Refunding only the yoga mat: $35.00
  • Including proportional tax: $2.80
  • Not refunding shipping (customer kept other items)
  • Total refund: $37.80

Example 3: Partial Refund by Amount

Scenario: Price adjustment without item-level detail Request:
Explanation:
  • Refunding $20.00 difference due to price match
  • No line item breakdown needed
  • Metadata tracks the reason

Example 4: Multiple Partial Refunds

You can create multiple refunds for the same checkout session until the full amount is refunded. First refund: $50
Second refund: $30
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/

Response:

GET /v1/refunds (List Refunds)

Query Parameters:
  • payment_intent - Filter by payment intent ID
  • checkout_session - Filter by checkout session ID
  • status - Filter by status
Examples:
Response:

PATCH /v1/refunds/ (Update Refund Metadata)

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

Implementation Details

Automatic Handling by Flex

Flex automatically handles: Reverse Transfer - Funds are clawed back from the connected account (partner) ✅ Application Fee Retention - Flex keeps the platform fee (not refunded) ✅ Webhook Processing - Status updates via Stripe webhooks ✅ Charge Tracking - Records which charges were refunded in refund_charge table ✅ Reference Number Retrieval - ARN and other tracking numbers populated when available

Partial Refund Behavior

  • Can refund any amount up to the original charge amount
  • Multiple partial refunds allowed until full amount refunded
  • Track amount_received vs total refunded to calculate remaining refundable amount

Tax, Shipping, and Discount Refunds

When refunding line items, you can specify component amounts:
Best Practice: Calculate proportional tax when refunding partial line items.

Best Practices

1. Store Checkout Session ID

Always save the checkout_session_id after payment completion:

2. Verify Checkout Session Status

Before attempting refund, confirm the session is complete:

3. Use Metadata for Tracking

Always include metadata to track refund context:

4. Handle Refund Webhooks

Subscribe to Flex webhooks for automatic refund status updates: Event Types:
  • refund.created - Refund initiated
  • refund.succeeded - Refund completed successfully
  • refund.failed - Refund failed
Webhook Payload Example:

5. Track Remaining Refundable Amount

For multiple partial refunds, track the remaining amount:

6. Save Reference Numbers

Store ARNs for customer support inquiries:

7. Handle Errors Gracefully


Testing

Test Mode

Use test API keys (starting with sk_test_) to test refunds without affecting real money:
Test Mode Behavior:
  • Refunds complete instantly with status: "succeeded"
  • No actual money movement
  • Reference IDs still generated for testing
  • Full webhook flow works

Test Credentials

For testing payments → refunds flow: Email: miguel@homefit.com Password: password Create test API keys at: http://localhost:3001/partners/dashboard/developers

Troubleshooting

Problem: “Checkout session must be complete”

Cause: Trying to refund a checkout session that hasn’t been paid or is in progress Solution:
  1. Check session status: GET /v1/checkout/sessions/{id}
  2. Ensure status === "complete"
  3. Wait for payment to finish if still processing

Problem: “checkout session does not exist”

Cause: Invalid checkout session ID or doesn’t belong to your account Solution:
  1. Verify the checkout_session_id is correct
  2. Ensure you’re using the right API key (test vs. production)
  3. Check that the session belongs to your partner account

Problem: Refund shows “pending” for too long

Cause: Stripe processing delay or connected account issues Solution:
  1. Wait up to 24 hours for normal processing
  2. Check Stripe dashboard for errors
  3. Verify connected account has sufficient balance
  4. Contact support if still pending after 24 hours

Problem: “Failed to create refund”

Cause: Stripe API error (usually insufficient funds in connected account) Solution:
  1. Check connected account balance in Stripe dashboard
  2. Ensure partner account has funds to cover refund
  3. Review Stripe logs for specific error details
  4. Contact Flex support with checkout_session_id

Problem: Reference ID not available

Cause: Payment network hasn’t provided ARN yet Solution:
  1. Reference IDs typically appear within hours
  2. Check reference_status - if pending, wait
  3. If unavailable, payment network doesn’t provide this type
  4. Poll /v1/refunds/{refund_id} periodically for updates

API Endpoint Summary


Common Use Cases

Use Case 1: Customer Service Full Refund


Use Case 2: Return Processing with Line Items


Use Case 3: Price Adjustment


Additional Resources


Support

For issues or questions about refunds:
  1. Check this guide for common solutions
  2. Review Stripe dashboard for payment details
  3. Contact Flex support with:
    • checkout_session_id
    • refund_id (if refund was created)
    • Error messages
    • Timestamp of the issue