Skip to main content
POST
/
v1
/
payments
/
{id}
/
refund
Refund a payment
curl --request POST \
  --url https://api.flowlix.dev/v1/payments/{id}/refund \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "reason": "Customer requested refund",
  "amount": 1500
}
'
{
  "id": "pay_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "object": "payment",
  "amount": 4999,
  "currency": "eur",
  "status": "succeeded",
  "description": "Order #1234",
  "card": {
    "brand": "visa",
    "last4": "1111",
    "exp_month": 12,
    "exp_year": 2027,
    "country": "US"
  },
  "customer": {
    "email": "jenny@example.com",
    "name": "Jenny Rosen"
  },
  "metadata": {
    "order_id": "ord_1234",
    "sku": "WIDGET-XL"
  },
  "decline_code": null,
  "decline_message": null,
  "redirect_url": null,
  "refunded_at": null,
  "succeeded_at": 1719792000,
  "failed_at": null,
  "created": 1719792000,
  "livemode": false,
  "refunded_amount": 4999,
  "refunds": [
    {
      "id": "01h9zacxv2pq8r1s3t4v5w6x7y",
      "amount": 4999,
      "currency": "eur",
      "reason": "Customer requested refund",
      "status": "pending",
      "decline_code": null,
      "decline_message": null,
      "created_at": 1719878400,
      "updated_at": 1719878400,
      "completed_at": null,
      "provider_refund_id": null
    }
  ],
  "next_action": null
}

Authorizations

Authorization
string
header
required

Use your secret API key as the Bearer token. Test (sandbox) mode keys start with fl_test_sk_ and live mode keys start with fl_live_sk_. Both modes use the same API host; the mode is determined by the key.

Authorization: Bearer fl_test_sk_abc123def456

Headers

Idempotency-Key
string

A unique key to ensure the request is processed only once. If a request with the same idempotency key and the same body has already been processed successfully (HTTP 2xx), the cached response is returned. Non-2xx responses are not cached, so you may freely retry on errors. Keys expire after 24 hours.

For one-shot requests (e.g. creating a payment from a checkout button) a random UUIDv4 is fine. For requests tied to a specific business operation (e.g. refunding order #1234) a deterministic key like refund-order-1234 is preferred so retries collapse correctly across processes.

Maximum string length: 255

Path Parameters

id
string
required

The unique identifier of the payment (pay_ prefix + UUID).

Pattern: ^pay_[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$

Body

application/json
reason
string
required

Reason for the refund. Required. Maximum 50 characters. Stored in the refund audit trail, returned in subsequent GET calls via the refunds array, and forwarded to the upstream provider as the refund comment.

Required string length: 1 - 50
Example:

"Customer requested refund"

amount
integer<int64>

Refund amount in minor units (e.g., cents). Omit for full refund. Must be a positive integer not exceeding the remaining refundable amount.

Required range: x >= 1
Example:

1500

Response

Refund accepted for processing.

A Payment object represents a single attempt to move money. It is created when you submit a payment request and is updated as the payment progresses through its lifecycle.

id
string
required

Unique identifier for the payment (pay_ prefix + UUID).

Pattern: ^pay_[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$
Example:

"pay_a1b2c3d4-e5f6-7890-abcd-ef1234567890"

object
enum<string>
required

Object type; always payment.

Available options:
payment
Example:

"payment"

amount
integer<int64>
required

The payment amount in minor units.

Example:

4999

currency
string
required

Three-letter ISO 4217 currency code.

Example:

"eur"

status
enum<string>
required

The current status of the payment.

  • pending -- The payment has been created and is being processed asynchronously.
  • succeeded -- The payment was successful. A succeeded payment may have refunds; check refunds array and refunded_amount.
  • failed -- The payment was declined or failed.
  • requires_action -- The payment requires customer action (e.g. 3D Secure authentication). Redirect the customer to next_action.redirect_url.
  • expired -- The required customer action (e.g. 3D Secure challenge) was not completed in time.
  • canceled -- The payment was canceled before completion.
Available options:
pending,
succeeded,
failed,
requires_action,
expired,
canceled
Example:

"succeeded"

created
integer<int64>
required

Unix timestamp when the payment was created.

Example:

1719792000

livemode
boolean
required

Whether this payment was created using a live API key (true) or a test API key (false).

Example:

false

description
string | null

The description attached to the payment.

Example:

"Order #1234"

card
object

The masked card details. null for HPP payments that have not yet been completed.

customer
object

The customer associated with the payment.

metadata
object

Arbitrary key-value metadata attached to the payment.

Example:
{ "order_id": "ord_1234" }
decline_code
string | null

If the payment was declined, the decline code indicating the reason. Common codes include insufficient_funds, expired_card, lost_card, stolen_card, and do_not_honor. For 3D Secure failures the code is one of three_d_secure_failed, three_d_secure_timeout, three_d_secure_not_supported, or three_d_secure_error. See the decline codes reference for the full list, and 3D Secure Declines for 3DS-specific codes.

Example:

null

decline_message
string | null

If the payment was declined, a human-readable message explaining why.

Example:

null

redirect_url
string<uri> | null

For HPP payments, the URL of the hosted payment page to redirect the customer to. null for direct API payments.

Example:

null

refunded_at
integer<int64> | null

Unix timestamp when the payment was fully refunded (refunded_amount equals the original amount), or null if not fully refunded.

Example:

null

succeeded_at
integer<int64> | null

Unix timestamp when the payment succeeded, or null if not yet succeeded.

Example:

1719792000

failed_at
integer<int64> | null

Unix timestamp when the payment failed, or null if not failed.

Example:

null

next_action
object

Present (non-null) when status is requires_action. Contains information needed to complete the payment. Otherwise null.

refunded_amount
integer<int64>

Total amount refunded so far, in minor units. This accumulates across partial refunds (only succeeded refunds contribute to the total).

Example:

0

provider_transaction_id
string | null

The payment service provider's reference for this transaction. Useful for dispute resolution and reconciliation with your PSP. null while the payment is still being submitted to the provider.

Example:

"1402758057"

refunds
object[]

All refunds on this payment, oldest first. Each entry is created by a call to POST /v1/payments/{id}/refund. A refund starts as pending and transitions to succeeded or failed.