Skip to content

Pending refunds

By default, refunds are submitted immediately when created. A merchant may also be configured to have refunds withheld until the merchant's settlement balance can cover them.

This guide explains the pending refund lifecycle, how Finix funds pending refunds, and what happens if a refund cannot be covered before it expires.

Merchant pending refund strategies

On the Merchant resource, the pending_refunds_strategy field controls how refunds are held.

When a merchant's pending_refunds_strategy is set to SEVEN_DAY_DELAYED_ADJUSTMENT or SAME_DAY_ADJUSTMENT, refunds enter a PENDING state while Finix verifies that there are sufficient funds in the merchant's settlement to cover them.

  • SEVEN_DAY_DELAYED_ADJUSTMENT: Refunds are held in state: PENDING for up to 7 days to be covered by settlement funds. After 7 days, Finix debits the merchant's bank account to cover the refund.
  • SAME_DAY_ADJUSTMENT: Finix issues a debit adjustment near settlement close if the settlement can't cover the refund.

Only users with ROLE_PARTNER credentials can set pending_refunds_strategy.

Pending refund lifecycle

1. Refund created

If a Merchant has a pending_refunds_strategy configured, refunds are not processed immediately.

In the response, the Transfer reversal (i.e., refund) contains state: PENDING and an expires_at datetime 45 days after creation. Finix sets and enforces this expiration window.

Refund - held
{
  "id": "TRhop5SzZD5AbRGz6HC6qB5w",
  "created_at": "2026-09-25T20:36:25.76Z",
  "updated_at": "2026-09-25T20:36:25.79Z",
  "3d_secure_session": null,
  "additional_buyer_charges": null,
  "additional_healthcare_data": null,
  "additional_lodging_data": null,
  "additional_motor_vehicle_rental_data": null,
  "additional_purchase_data": null,
  "address_verification": null,
  "amount": 1000,
  "amount_requested": 1000,
  "application": "APc9vhYcPsRuTSpKD9KpMtPe",
  "created_via": "UNKNOWN",
  "currency": "USD",
  "destination": "PI6iQcTtJNCS8GZAVKYi5Ueb",
  "expires_at": "2026-11-09T20:36:25.76Z", 
  "externally_funded": "UNKNOWN",
  "failure_code": null,
  "failure_message": null,
  "fee": 0,
  "fee_profile": "FPuizPqrhzYLbmJm88u7aqfj",
  "idempotency_id": null,
  "ip_address_details": null,
  "merchant": "MUmfEGv5bMpSJ9k5TFRUjkmm",
  "merchant_identity": "ID6UfSm1d4WPiWgLYmbyeo3H",
  "messages": [],
  "network_details": null,
  "operation_key": "CARD_NOT_PRESENT_REFUND",
  "parent_transfer": "TRqvNLUdn3aPmdwLMSKs3Gxz", 
  "parent_transfer_trace_id": null,
  "processed_at": null,
  "raw": null,
  "ready_to_settle_at": null,
  "receipt_last_printed_at": null,
  "security_code_verification": null,
  "source": null,
  "split_transfers": [],
  "state": "PENDING", 
  "statement_descriptor": "FLX*FINIX FLOWERS",
  "subtype": "API",
  "supplemental_fee": null,
  "tags": {},
  "third_party_details": null,
  "tip_amount": null,
  "trace_id": "9fc0c015-0d97-49f1-93a6-b845d4e50c01",
  "type": "REVERSAL", 
  "_links": {
    "application": {
      "href": "https://finix.sandbox-payments-api.com/applications/APc9vhYcPsRuTSpKD9KpMtPe"
    },
    "self": {
      "href": "https://finix.sandbox-payments-api.com/transfers/TRhop5SzZD5AbRGz6HC6qB5w"
    },
    "parent": {
      "href": "https://finix.sandbox-payments-api.com/transfers/TRqvNLUdn3aPmdwLMSKs3Gxz"
    },
    "destination": {
      "href": "https://finix.sandbox-payments-api.com/payment_instruments/PI6iQcTtJNCS8GZAVKYi5Ueb"
    },
    "merchant_identity": {
      "href": "https://finix.sandbox-payments-api.com/identities/ID6UfSm1d4WPiWgLYmbyeo3H"
    },
    "payment_instruments": {
      "href": "https://finix.sandbox-payments-api.com/transfers/TRhop5SzZD5AbRGz6HC6qB5w/payment_instruments"
    },
    "fee_profile": {
      "href": "https://finix.sandbox-payments-api.com/fee_profiles/FPuizPqrhzYLbmJm88u7aqfj"
    }
  }
}

If the refund is not funded by the expiration, it expires.

2. Daily funding check

Before a Settlement belonging to a Merchant moves to status: AWAITING_APPROVAL:

  1. Finix checks whether the Settlement balance covers each pending refund, starting with the oldest pending refund.
  2. If it does, Finix submits the refund, moves the refund state to SUCCEEDED, and deducts it from the Settlement.
  3. If the balance cannot cover a refund, the refund state stays PENDING. How long Finix waits before collecting via bank account debit depends on the merchant's pending_refunds_strategy.

Pending refunds are processed in the order they were created. If the oldest pending refund cannot be covered, the refunds behind it wait, even if they are smaller.

3. Finix collects the refund

If incoming sales cannot cover the refund and it reaches the maximum days allowed in state: PENDING, as set by the pending_refunds_strategy, Finix debits the Merchant's bank account for the refund amount.

To collect the refund, Finix:

  1. Creates a debit adjustment Transfer for the amount of the refund which will be deducted from the next Settlement.
  2. Submits the refund 3 business days after the debit clears and creates an offsetting credit adjustment Transfer so the two adjustments net to zero for the Merchant.

For more information, see Refund Adjustments.

End customers do not need to take action

The pending refund process is between Finix and the merchant. The refund is submitted to the cardholder's or bank account holder's financial institution only after it is funded; if funding is not secured by expires_at, the refund fails.

4. Refund expiration

If the bank account debit fails and the refund still cannot be covered by the expires_at datetime, the refund's state is set to FAILED with a failure_code of REFUND_EXPIRED.

Refund - Expired
{
    "id": "TR8fezr4xCMFJvH5rzCqrUkF",
    "created_at": "2026-10-24T17:38:19.09Z",
    "updated_at": "2026-12-08T17:38:19.09Z",
    ...
    "expires_at": "2026-12-08T17:38:19.09Z",
    "failure_code": "REFUND_EXPIRED",
    "failure_message": "The refund has expired.",
    "state": "FAILED",
    "type": "REVERSAL"
}

Refund adjustments

If necessary to collect funds, Finix may create adjustment Transfers with two possible operation_key values. These adjustments are system-generated and are always in state: SUCCEEDED.

SubtypeTypeDescription
REFUND_MERCHANT_DEBIT_ADJUSTMENTDEBITDeducts the refund amount from the Merchant's Settlement.
REFUND_MERCHANT_CREDIT_ADJUSTMENTCREDITOffsets the refund amount when the refund is submitted, or returns pending funds if the refund expires.
Refund adjustment
{
    "id": "TRaB91xboyy8mfFxZNFWf1F",
    ...
    "parent_transfer": "TR8fezr4xCMFJvH5rzCqrUkF",
    "state": "SUCCEEDED",
    "operation_key": "REFUND_MERCHANT_DEBIT_ADJUSTMENT",
    "type": "DEBIT"
}

Both adjustments reference the pending refund in the parent_transfer field.

Debit adjustment
{
    "id": "TRaB91xboyy8mfFxZNFWf1F",
    ...
    "parent_transfer": "TR8fezr4xCMFJvH5rzCqrUkF",
    "state": "SUCCEEDED",
    "operation_key": "REFUND_MERCHANT_DEBIT_ADJUSTMENT",
    "type": "DEBIT"
}
Credit adjustment
{
    "id": "TR4Lxcmkn1py9him81swz4FD",
    ...
    "parent_transfer": "TR8fezr4xCMFJvH5rzCqrUkF",
    "state": "SUCCEEDED",
    "operation_key": "REFUND_MERCHANT_CREDIT_ADJUSTMENT",
    "type": "CREDIT"
}

On the Settlement Entry:

  • subtype matches the adjustment operation_key.
  • The parent_entity_id field matches the adjustment parent_transfer.

Webhooks

You may subscribe to Transfer webhooks to receive a notification each time a pending refund changes state:

  • PENDING to SUCCEEDED: The refund was submitted.
  • PENDING to FAILED: The refund could not be funded. The webhook payload includes failure_code: REFUND_EXPIRED and the expires_at timestamp when this is due to expiration.