From 1dfdd750cbda65483e77a454f4a5f80c46f33bba Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Tue, 7 Jul 2026 12:45:21 -0700 Subject: [PATCH 1/4] feat(openapi): add counterparty payout failure reasons Add 7 counterparty (payout-side) reasons to OutgoingTransactionFailureReason so integrators can act on why a payout partner rejected or failed a transaction, rather than collapsing everything into the generic COUNTERPARTY_POST_TX_FAILED: - COUNTERPARTY_COMPLIANCE_REJECTED - COUNTERPARTY_ACCOUNT_INVALID - COUNTERPARTY_ACCOUNT_CANNOT_RECEIVE - COUNTERPARTY_LIMIT_EXCEEDED - COUNTERPARTY_PAYOUT_RETURNED - COUNTERPARTY_CURRENCY_EXCHANGE_FAILED - COUNTERPARTY_PAYOUT_EXPIRED Also document each value's customer-facing meaning in a markdown table, matching the OutgoingTransactionStatus convention. Co-Authored-By: Claude Opus 4.8 (1M context) --- mintlify/openapi.yaml | 27 ++++++++++++++++++- openapi.yaml | 27 ++++++++++++++++++- .../OutgoingTransactionFailureReason.yaml | 24 ++++++++++++++++- 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/mintlify/openapi.yaml b/mintlify/openapi.yaml index 7105216fe..63f03ce3b 100644 --- a/mintlify/openapi.yaml +++ b/mintlify/openapi.yaml @@ -17066,8 +17066,33 @@ components: - QUOTE_EXECUTION_FAILED - LIGHTNING_PAYMENT_FAILED - FUNDING_AMOUNT_MISMATCH + - COUNTERPARTY_COMPLIANCE_REJECTED + - COUNTERPARTY_ACCOUNT_INVALID + - COUNTERPARTY_ACCOUNT_CANNOT_RECEIVE + - COUNTERPARTY_LIMIT_EXCEEDED + - COUNTERPARTY_PAYOUT_RETURNED + - COUNTERPARTY_CURRENCY_EXCHANGE_FAILED + - COUNTERPARTY_PAYOUT_EXPIRED - COUNTERPARTY_POST_TX_FAILED - description: Reason for failure of an outgoing transaction. This is used to provide more context on why a transaction failed. If the transaction is not in a failed state, this field is omitted. + description: | + Reason for failure of an outgoing transaction. This is used to provide more + context on why a transaction failed. If the transaction is not in a failed + state, this field is omitted. + + | Reason | Description | + |--------|-------------| + | `QUOTE_EXPIRED` | The quote was not executed before its expiry window | + | `QUOTE_EXECUTION_FAILED` | The quote could not be executed | + | `LIGHTNING_PAYMENT_FAILED` | The Lightning settlement leg failed | + | `FUNDING_AMOUNT_MISMATCH` | The funds received did not match the expected amount | + | `COUNTERPARTY_COMPLIANCE_REJECTED` | The payout partner rejected the recipient on compliance grounds — sanctions, watchlist, or KYC/AML screening | + | `COUNTERPARTY_ACCOUNT_INVALID` | The recipient account couldn't be found or the details are wrong — bad IBAN/account number, beneficiary not found, or account closed | + | `COUNTERPARTY_ACCOUNT_CANNOT_RECEIVE` | The account exists but can't accept this payment — dormant, frozen, restricted, or the currency isn't supported for that account | + | `COUNTERPARTY_LIMIT_EXCEEDED` | The payout exceeds a recipient-, account-, or corridor-level limit at the partner | + | `COUNTERPARTY_PAYOUT_RETURNED` | The receiving bank accepted the payout and then returned or reversed it | + | `COUNTERPARTY_CURRENCY_EXCHANGE_FAILED` | The partner couldn't complete the FX conversion required for the payout | + | `COUNTERPARTY_PAYOUT_EXPIRED` | The partner didn't complete the payout within its processing window | + | `COUNTERPARTY_POST_TX_FAILED` | Generic payout failure — the partner gave no usable reason | OutgoingTransaction: title: Outgoing Transaction allOf: diff --git a/openapi.yaml b/openapi.yaml index 7105216fe..63f03ce3b 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -17066,8 +17066,33 @@ components: - QUOTE_EXECUTION_FAILED - LIGHTNING_PAYMENT_FAILED - FUNDING_AMOUNT_MISMATCH + - COUNTERPARTY_COMPLIANCE_REJECTED + - COUNTERPARTY_ACCOUNT_INVALID + - COUNTERPARTY_ACCOUNT_CANNOT_RECEIVE + - COUNTERPARTY_LIMIT_EXCEEDED + - COUNTERPARTY_PAYOUT_RETURNED + - COUNTERPARTY_CURRENCY_EXCHANGE_FAILED + - COUNTERPARTY_PAYOUT_EXPIRED - COUNTERPARTY_POST_TX_FAILED - description: Reason for failure of an outgoing transaction. This is used to provide more context on why a transaction failed. If the transaction is not in a failed state, this field is omitted. + description: | + Reason for failure of an outgoing transaction. This is used to provide more + context on why a transaction failed. If the transaction is not in a failed + state, this field is omitted. + + | Reason | Description | + |--------|-------------| + | `QUOTE_EXPIRED` | The quote was not executed before its expiry window | + | `QUOTE_EXECUTION_FAILED` | The quote could not be executed | + | `LIGHTNING_PAYMENT_FAILED` | The Lightning settlement leg failed | + | `FUNDING_AMOUNT_MISMATCH` | The funds received did not match the expected amount | + | `COUNTERPARTY_COMPLIANCE_REJECTED` | The payout partner rejected the recipient on compliance grounds — sanctions, watchlist, or KYC/AML screening | + | `COUNTERPARTY_ACCOUNT_INVALID` | The recipient account couldn't be found or the details are wrong — bad IBAN/account number, beneficiary not found, or account closed | + | `COUNTERPARTY_ACCOUNT_CANNOT_RECEIVE` | The account exists but can't accept this payment — dormant, frozen, restricted, or the currency isn't supported for that account | + | `COUNTERPARTY_LIMIT_EXCEEDED` | The payout exceeds a recipient-, account-, or corridor-level limit at the partner | + | `COUNTERPARTY_PAYOUT_RETURNED` | The receiving bank accepted the payout and then returned or reversed it | + | `COUNTERPARTY_CURRENCY_EXCHANGE_FAILED` | The partner couldn't complete the FX conversion required for the payout | + | `COUNTERPARTY_PAYOUT_EXPIRED` | The partner didn't complete the payout within its processing window | + | `COUNTERPARTY_POST_TX_FAILED` | Generic payout failure — the partner gave no usable reason | OutgoingTransaction: title: Outgoing Transaction allOf: diff --git a/openapi/components/schemas/transactions/OutgoingTransactionFailureReason.yaml b/openapi/components/schemas/transactions/OutgoingTransactionFailureReason.yaml index 8af526f7a..340eea06a 100644 --- a/openapi/components/schemas/transactions/OutgoingTransactionFailureReason.yaml +++ b/openapi/components/schemas/transactions/OutgoingTransactionFailureReason.yaml @@ -4,8 +4,30 @@ enum: - QUOTE_EXECUTION_FAILED - LIGHTNING_PAYMENT_FAILED - FUNDING_AMOUNT_MISMATCH + - COUNTERPARTY_COMPLIANCE_REJECTED + - COUNTERPARTY_ACCOUNT_INVALID + - COUNTERPARTY_ACCOUNT_CANNOT_RECEIVE + - COUNTERPARTY_LIMIT_EXCEEDED + - COUNTERPARTY_PAYOUT_RETURNED + - COUNTERPARTY_CURRENCY_EXCHANGE_FAILED + - COUNTERPARTY_PAYOUT_EXPIRED - COUNTERPARTY_POST_TX_FAILED -description: >- +description: | Reason for failure of an outgoing transaction. This is used to provide more context on why a transaction failed. If the transaction is not in a failed state, this field is omitted. + + | Reason | Description | + |--------|-------------| + | `QUOTE_EXPIRED` | The quote was not executed before its expiry window | + | `QUOTE_EXECUTION_FAILED` | The quote could not be executed | + | `LIGHTNING_PAYMENT_FAILED` | The Lightning settlement leg failed | + | `FUNDING_AMOUNT_MISMATCH` | The funds received did not match the expected amount | + | `COUNTERPARTY_COMPLIANCE_REJECTED` | The payout partner rejected the recipient on compliance grounds — sanctions, watchlist, or KYC/AML screening | + | `COUNTERPARTY_ACCOUNT_INVALID` | The recipient account couldn't be found or the details are wrong — bad IBAN/account number, beneficiary not found, or account closed | + | `COUNTERPARTY_ACCOUNT_CANNOT_RECEIVE` | The account exists but can't accept this payment — dormant, frozen, restricted, or the currency isn't supported for that account | + | `COUNTERPARTY_LIMIT_EXCEEDED` | The payout exceeds a recipient-, account-, or corridor-level limit at the partner | + | `COUNTERPARTY_PAYOUT_RETURNED` | The receiving bank accepted the payout and then returned or reversed it | + | `COUNTERPARTY_CURRENCY_EXCHANGE_FAILED` | The partner couldn't complete the FX conversion required for the payout | + | `COUNTERPARTY_PAYOUT_EXPIRED` | The partner didn't complete the payout within its processing window | + | `COUNTERPARTY_POST_TX_FAILED` | Generic payout failure — the partner gave no usable reason | From 3ec6db76c1f2e3a0dd3c70850c65db88e2f7b05f Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Tue, 14 Jul 2026 13:48:14 -0700 Subject: [PATCH 2/4] docs(openapi): sync outgoing failure reasons with send enum Rename granular counterparty payout reasons (drop COUNTERPARTY_ prefix), remove COUNTERPARTY_CURRENCY_EXCHANGE_FAILED and COUNTERPARTY_PAYOUT_EXPIRED, and add EXECUTION_FAILED_POST_DEBIT, SETTLEMENT_FAILED, TIMEOUT, MANUAL_REFUND, and LSP_OPERATIONAL_FAILURE. Mark LIGHTNING_PAYMENT_FAILED and COUNTERPARTY_POST_TX_FAILED as deprecated/legacy. Update transaction lifecycle and error handling docs accordingly. Co-authored-by: Cursor --- mintlify/openapi.yaml | 48 ++++++++++++------- .../core-concepts/transaction-lifecycle.mdx | 14 ++++-- mintlify/snippets/error-handling.mdx | 9 +++- openapi.yaml | 48 ++++++++++++------- .../OutgoingTransactionFailureReason.yaml | 48 ++++++++++++------- 5 files changed, 109 insertions(+), 58 deletions(-) diff --git a/mintlify/openapi.yaml b/mintlify/openapi.yaml index 63f03ce3b..b35e4bff5 100644 --- a/mintlify/openapi.yaml +++ b/mintlify/openapi.yaml @@ -17064,35 +17064,47 @@ components: enum: - QUOTE_EXPIRED - QUOTE_EXECUTION_FAILED - - LIGHTNING_PAYMENT_FAILED + - EXECUTION_FAILED_POST_DEBIT + - SETTLEMENT_FAILED - FUNDING_AMOUNT_MISMATCH - - COUNTERPARTY_COMPLIANCE_REJECTED - - COUNTERPARTY_ACCOUNT_INVALID - - COUNTERPARTY_ACCOUNT_CANNOT_RECEIVE - - COUNTERPARTY_LIMIT_EXCEEDED - - COUNTERPARTY_PAYOUT_RETURNED - - COUNTERPARTY_CURRENCY_EXCHANGE_FAILED - - COUNTERPARTY_PAYOUT_EXPIRED + - TIMEOUT + - MANUAL_REFUND + - LSP_OPERATIONAL_FAILURE + - PAYOUT_RETURNED + - LIMIT_EXCEEDED + - ACCOUNT_CANNOT_RECEIVE + - ACCOUNT_INVALID + - COMPLIANCE_REJECTED + - LIGHTNING_PAYMENT_FAILED - COUNTERPARTY_POST_TX_FAILED description: | Reason for failure of an outgoing transaction. This is used to provide more context on why a transaction failed. If the transaction is not in a failed state, this field is omitted. + When a payout partner rejects or fails a payment, one of the granular payout + reasons (`PAYOUT_RETURNED`, `LIMIT_EXCEEDED`, `ACCOUNT_CANNOT_RECEIVE`, + `ACCOUNT_INVALID`, `COMPLIANCE_REJECTED`) is returned when available. + `COUNTERPARTY_POST_TX_FAILED` is a coarse fallback used only when no granular + reason is available. + | Reason | Description | |--------|-------------| | `QUOTE_EXPIRED` | The quote was not executed before its expiry window | - | `QUOTE_EXECUTION_FAILED` | The quote could not be executed | - | `LIGHTNING_PAYMENT_FAILED` | The Lightning settlement leg failed | + | `QUOTE_EXECUTION_FAILED` | The quote could not be executed. No funds were debited | + | `EXECUTION_FAILED_POST_DEBIT` | Execution failed after funds were debited. The amount is refunded automatically | + | `SETTLEMENT_FAILED` | The settlement leg failed | | `FUNDING_AMOUNT_MISMATCH` | The funds received did not match the expected amount | - | `COUNTERPARTY_COMPLIANCE_REJECTED` | The payout partner rejected the recipient on compliance grounds — sanctions, watchlist, or KYC/AML screening | - | `COUNTERPARTY_ACCOUNT_INVALID` | The recipient account couldn't be found or the details are wrong — bad IBAN/account number, beneficiary not found, or account closed | - | `COUNTERPARTY_ACCOUNT_CANNOT_RECEIVE` | The account exists but can't accept this payment — dormant, frozen, restricted, or the currency isn't supported for that account | - | `COUNTERPARTY_LIMIT_EXCEEDED` | The payout exceeds a recipient-, account-, or corridor-level limit at the partner | - | `COUNTERPARTY_PAYOUT_RETURNED` | The receiving bank accepted the payout and then returned or reversed it | - | `COUNTERPARTY_CURRENCY_EXCHANGE_FAILED` | The partner couldn't complete the FX conversion required for the payout | - | `COUNTERPARTY_PAYOUT_EXPIRED` | The partner didn't complete the payout within its processing window | - | `COUNTERPARTY_POST_TX_FAILED` | Generic payout failure — the partner gave no usable reason | + | `TIMEOUT` | The transaction did not complete within its processing window | + | `MANUAL_REFUND` | The transaction was refunded manually | + | `LSP_OPERATIONAL_FAILURE` | A Lightspark-internal operational issue (for example, insufficient operational balance). Not a client error — contact Lightspark to resolve | + | `PAYOUT_RETURNED` | The receiving bank accepted the payout and then returned or reversed it | + | `LIMIT_EXCEEDED` | The payout exceeds a recipient-, account-, or corridor-level limit at the partner | + | `ACCOUNT_CANNOT_RECEIVE` | The account exists but can't accept this payment — dormant, frozen, restricted, or the currency isn't supported for that account | + | `ACCOUNT_INVALID` | The recipient account couldn't be found or the details are wrong — bad IBAN/account number, beneficiary not found, or account closed | + | `COMPLIANCE_REJECTED` | The payout partner rejected the recipient on compliance grounds — sanctions, watchlist, or KYC/AML screening | + | `LIGHTNING_PAYMENT_FAILED` | Deprecated — superseded by `SETTLEMENT_FAILED`. The Lightning settlement leg failed | + | `COUNTERPARTY_POST_TX_FAILED` | Deprecated — coarse fallback retained for historical transactions when no granular payout reason is available | OutgoingTransaction: title: Outgoing Transaction allOf: diff --git a/mintlify/platform-overview/core-concepts/transaction-lifecycle.mdx b/mintlify/platform-overview/core-concepts/transaction-lifecycle.mdx index c9ed40fa3..777197457 100644 --- a/mintlify/platform-overview/core-concepts/transaction-lifecycle.mdx +++ b/mintlify/platform-overview/core-concepts/transaction-lifecycle.mdx @@ -393,11 +393,19 @@ Use for reconciliation and reporting. | Failure Reason | Description | Recovery | |----------------|-------------|----------| | `QUOTE_EXPIRED` | Quote expired before execution | Create new quote | -| `QUOTE_EXECUTION_FAILED` | Error executing the quote | Create new quote | +| `QUOTE_EXECUTION_FAILED` | Error executing the quote; no funds were debited | Create new quote | +| `EXECUTION_FAILED_POST_DEBIT` | Execution failed after debit; funds are refunded automatically | Retry with a new quote | | `INSUFFICIENT_BALANCE` | Source account lacks funds | Fund account, retry | -| `LIGHTNING_PAYMENT_FAILED` | Lightning network payment could not be routed | Retry or use alternative rail | +| `SETTLEMENT_FAILED` | The settlement leg failed | Retry or use alternative rail | | `FUNDING_AMOUNT_MISMATCH` | Funding amount doesn't match expected amount | Verify amounts and retry | -| `COUNTERPARTY_POST_TX_FAILED` | Post-transaction processing at counterparty failed | Contact support | +| `ACCOUNT_INVALID` | Recipient account details are wrong or not found | Correct recipient details | +| `ACCOUNT_CANNOT_RECEIVE` | Recipient account can't accept the payment | Use a different account | +| `LIMIT_EXCEEDED` | Payout exceeds a partner limit | Reduce amount or contact support | +| `COMPLIANCE_REJECTED` | Payout partner rejected on compliance grounds | Contact support | +| `PAYOUT_RETURNED` | Receiving bank returned or reversed the payout | Verify details and retry | +| `LSP_OPERATIONAL_FAILURE` | Lightspark-internal operational issue | Contact Lightspark | + +The `failureReason` field on a transaction may return additional values, including deprecated reasons (`LIGHTNING_PAYMENT_FAILED`, `COUNTERPARTY_POST_TX_FAILED`) retained for historical transactions. When a transaction fails, a refund is initiated automatically. Track the refund via the `refund` object on the transaction and `OUTGOING_PAYMENT.REFUND_*` webhook events. See [Refund Object](#refund-object) above. diff --git a/mintlify/snippets/error-handling.mdx b/mintlify/snippets/error-handling.mdx index c388b5bb5..6ef5f5d7c 100644 --- a/mintlify/snippets/error-handling.mdx +++ b/mintlify/snippets/error-handling.mdx @@ -143,8 +143,15 @@ When a transaction fails, the `failureReason` field provides specific details: **Common outgoing failure reasons:** - `QUOTE_EXPIRED` - Quote expired before execution -- `QUOTE_EXECUTION_FAILED` - Error executing the quote +- `QUOTE_EXECUTION_FAILED` - Error executing the quote; no funds were debited +- `EXECUTION_FAILED_POST_DEBIT` - Execution failed after debit; funds are refunded automatically - `FUNDING_AMOUNT_MISMATCH` - Funding amount doesn't match expected amount +- `ACCOUNT_INVALID` - Recipient account details are wrong or not found +- `ACCOUNT_CANNOT_RECEIVE` - Recipient account can't accept the payment +- `LIMIT_EXCEEDED` - Payout exceeds a partner limit +- `COMPLIANCE_REJECTED` - Payout partner rejected on compliance grounds +- `PAYOUT_RETURNED` - Receiving bank returned or reversed the payout +- `LSP_OPERATIONAL_FAILURE` - Lightspark-internal operational issue; contact Lightspark ### Incoming payment failures diff --git a/openapi.yaml b/openapi.yaml index 63f03ce3b..b35e4bff5 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -17064,35 +17064,47 @@ components: enum: - QUOTE_EXPIRED - QUOTE_EXECUTION_FAILED - - LIGHTNING_PAYMENT_FAILED + - EXECUTION_FAILED_POST_DEBIT + - SETTLEMENT_FAILED - FUNDING_AMOUNT_MISMATCH - - COUNTERPARTY_COMPLIANCE_REJECTED - - COUNTERPARTY_ACCOUNT_INVALID - - COUNTERPARTY_ACCOUNT_CANNOT_RECEIVE - - COUNTERPARTY_LIMIT_EXCEEDED - - COUNTERPARTY_PAYOUT_RETURNED - - COUNTERPARTY_CURRENCY_EXCHANGE_FAILED - - COUNTERPARTY_PAYOUT_EXPIRED + - TIMEOUT + - MANUAL_REFUND + - LSP_OPERATIONAL_FAILURE + - PAYOUT_RETURNED + - LIMIT_EXCEEDED + - ACCOUNT_CANNOT_RECEIVE + - ACCOUNT_INVALID + - COMPLIANCE_REJECTED + - LIGHTNING_PAYMENT_FAILED - COUNTERPARTY_POST_TX_FAILED description: | Reason for failure of an outgoing transaction. This is used to provide more context on why a transaction failed. If the transaction is not in a failed state, this field is omitted. + When a payout partner rejects or fails a payment, one of the granular payout + reasons (`PAYOUT_RETURNED`, `LIMIT_EXCEEDED`, `ACCOUNT_CANNOT_RECEIVE`, + `ACCOUNT_INVALID`, `COMPLIANCE_REJECTED`) is returned when available. + `COUNTERPARTY_POST_TX_FAILED` is a coarse fallback used only when no granular + reason is available. + | Reason | Description | |--------|-------------| | `QUOTE_EXPIRED` | The quote was not executed before its expiry window | - | `QUOTE_EXECUTION_FAILED` | The quote could not be executed | - | `LIGHTNING_PAYMENT_FAILED` | The Lightning settlement leg failed | + | `QUOTE_EXECUTION_FAILED` | The quote could not be executed. No funds were debited | + | `EXECUTION_FAILED_POST_DEBIT` | Execution failed after funds were debited. The amount is refunded automatically | + | `SETTLEMENT_FAILED` | The settlement leg failed | | `FUNDING_AMOUNT_MISMATCH` | The funds received did not match the expected amount | - | `COUNTERPARTY_COMPLIANCE_REJECTED` | The payout partner rejected the recipient on compliance grounds — sanctions, watchlist, or KYC/AML screening | - | `COUNTERPARTY_ACCOUNT_INVALID` | The recipient account couldn't be found or the details are wrong — bad IBAN/account number, beneficiary not found, or account closed | - | `COUNTERPARTY_ACCOUNT_CANNOT_RECEIVE` | The account exists but can't accept this payment — dormant, frozen, restricted, or the currency isn't supported for that account | - | `COUNTERPARTY_LIMIT_EXCEEDED` | The payout exceeds a recipient-, account-, or corridor-level limit at the partner | - | `COUNTERPARTY_PAYOUT_RETURNED` | The receiving bank accepted the payout and then returned or reversed it | - | `COUNTERPARTY_CURRENCY_EXCHANGE_FAILED` | The partner couldn't complete the FX conversion required for the payout | - | `COUNTERPARTY_PAYOUT_EXPIRED` | The partner didn't complete the payout within its processing window | - | `COUNTERPARTY_POST_TX_FAILED` | Generic payout failure — the partner gave no usable reason | + | `TIMEOUT` | The transaction did not complete within its processing window | + | `MANUAL_REFUND` | The transaction was refunded manually | + | `LSP_OPERATIONAL_FAILURE` | A Lightspark-internal operational issue (for example, insufficient operational balance). Not a client error — contact Lightspark to resolve | + | `PAYOUT_RETURNED` | The receiving bank accepted the payout and then returned or reversed it | + | `LIMIT_EXCEEDED` | The payout exceeds a recipient-, account-, or corridor-level limit at the partner | + | `ACCOUNT_CANNOT_RECEIVE` | The account exists but can't accept this payment — dormant, frozen, restricted, or the currency isn't supported for that account | + | `ACCOUNT_INVALID` | The recipient account couldn't be found or the details are wrong — bad IBAN/account number, beneficiary not found, or account closed | + | `COMPLIANCE_REJECTED` | The payout partner rejected the recipient on compliance grounds — sanctions, watchlist, or KYC/AML screening | + | `LIGHTNING_PAYMENT_FAILED` | Deprecated — superseded by `SETTLEMENT_FAILED`. The Lightning settlement leg failed | + | `COUNTERPARTY_POST_TX_FAILED` | Deprecated — coarse fallback retained for historical transactions when no granular payout reason is available | OutgoingTransaction: title: Outgoing Transaction allOf: diff --git a/openapi/components/schemas/transactions/OutgoingTransactionFailureReason.yaml b/openapi/components/schemas/transactions/OutgoingTransactionFailureReason.yaml index 340eea06a..3f936480c 100644 --- a/openapi/components/schemas/transactions/OutgoingTransactionFailureReason.yaml +++ b/openapi/components/schemas/transactions/OutgoingTransactionFailureReason.yaml @@ -2,32 +2,44 @@ type: string enum: - QUOTE_EXPIRED - QUOTE_EXECUTION_FAILED - - LIGHTNING_PAYMENT_FAILED + - EXECUTION_FAILED_POST_DEBIT + - SETTLEMENT_FAILED - FUNDING_AMOUNT_MISMATCH - - COUNTERPARTY_COMPLIANCE_REJECTED - - COUNTERPARTY_ACCOUNT_INVALID - - COUNTERPARTY_ACCOUNT_CANNOT_RECEIVE - - COUNTERPARTY_LIMIT_EXCEEDED - - COUNTERPARTY_PAYOUT_RETURNED - - COUNTERPARTY_CURRENCY_EXCHANGE_FAILED - - COUNTERPARTY_PAYOUT_EXPIRED + - TIMEOUT + - MANUAL_REFUND + - LSP_OPERATIONAL_FAILURE + - PAYOUT_RETURNED + - LIMIT_EXCEEDED + - ACCOUNT_CANNOT_RECEIVE + - ACCOUNT_INVALID + - COMPLIANCE_REJECTED + - LIGHTNING_PAYMENT_FAILED - COUNTERPARTY_POST_TX_FAILED description: | Reason for failure of an outgoing transaction. This is used to provide more context on why a transaction failed. If the transaction is not in a failed state, this field is omitted. + When a payout partner rejects or fails a payment, one of the granular payout + reasons (`PAYOUT_RETURNED`, `LIMIT_EXCEEDED`, `ACCOUNT_CANNOT_RECEIVE`, + `ACCOUNT_INVALID`, `COMPLIANCE_REJECTED`) is returned when available. + `COUNTERPARTY_POST_TX_FAILED` is a coarse fallback used only when no granular + reason is available. + | Reason | Description | |--------|-------------| | `QUOTE_EXPIRED` | The quote was not executed before its expiry window | - | `QUOTE_EXECUTION_FAILED` | The quote could not be executed | - | `LIGHTNING_PAYMENT_FAILED` | The Lightning settlement leg failed | + | `QUOTE_EXECUTION_FAILED` | The quote could not be executed. No funds were debited | + | `EXECUTION_FAILED_POST_DEBIT` | Execution failed after funds were debited. The amount is refunded automatically | + | `SETTLEMENT_FAILED` | The settlement leg failed | | `FUNDING_AMOUNT_MISMATCH` | The funds received did not match the expected amount | - | `COUNTERPARTY_COMPLIANCE_REJECTED` | The payout partner rejected the recipient on compliance grounds — sanctions, watchlist, or KYC/AML screening | - | `COUNTERPARTY_ACCOUNT_INVALID` | The recipient account couldn't be found or the details are wrong — bad IBAN/account number, beneficiary not found, or account closed | - | `COUNTERPARTY_ACCOUNT_CANNOT_RECEIVE` | The account exists but can't accept this payment — dormant, frozen, restricted, or the currency isn't supported for that account | - | `COUNTERPARTY_LIMIT_EXCEEDED` | The payout exceeds a recipient-, account-, or corridor-level limit at the partner | - | `COUNTERPARTY_PAYOUT_RETURNED` | The receiving bank accepted the payout and then returned or reversed it | - | `COUNTERPARTY_CURRENCY_EXCHANGE_FAILED` | The partner couldn't complete the FX conversion required for the payout | - | `COUNTERPARTY_PAYOUT_EXPIRED` | The partner didn't complete the payout within its processing window | - | `COUNTERPARTY_POST_TX_FAILED` | Generic payout failure — the partner gave no usable reason | + | `TIMEOUT` | The transaction did not complete within its processing window | + | `MANUAL_REFUND` | The transaction was refunded manually | + | `LSP_OPERATIONAL_FAILURE` | A Lightspark-internal operational issue (for example, insufficient operational balance). Not a client error — contact Lightspark to resolve | + | `PAYOUT_RETURNED` | The receiving bank accepted the payout and then returned or reversed it | + | `LIMIT_EXCEEDED` | The payout exceeds a recipient-, account-, or corridor-level limit at the partner | + | `ACCOUNT_CANNOT_RECEIVE` | The account exists but can't accept this payment — dormant, frozen, restricted, or the currency isn't supported for that account | + | `ACCOUNT_INVALID` | The recipient account couldn't be found or the details are wrong — bad IBAN/account number, beneficiary not found, or account closed | + | `COMPLIANCE_REJECTED` | The payout partner rejected the recipient on compliance grounds — sanctions, watchlist, or KYC/AML screening | + | `LIGHTNING_PAYMENT_FAILED` | Deprecated — superseded by `SETTLEMENT_FAILED`. The Lightning settlement leg failed | + | `COUNTERPARTY_POST_TX_FAILED` | Deprecated — coarse fallback retained for historical transactions when no granular payout reason is available | From e0f89a6160082c4dd2e62b8c7f4523b93a9ddc71 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Tue, 14 Jul 2026 14:52:35 -0700 Subject: [PATCH 3/4] docs: sync outgoing payment failure reasons in MDX with enum Align the MDX failure-reason references with OutgoingTransactionFailureReason: drop the non-existent INSUFFICIENT_BALANCE, add TIMEOUT and MANUAL_REFUND (plus SETTLEMENT_FAILED in the error-handling snippet), reorder to enum order, and fix the FAILED webhook example to use ACCOUNT_INVALID. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../core-concepts/transaction-lifecycle.mdx | 13 +++++++------ mintlify/snippets/error-handling.mdx | 11 +++++++---- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/mintlify/platform-overview/core-concepts/transaction-lifecycle.mdx b/mintlify/platform-overview/core-concepts/transaction-lifecycle.mdx index 777197457..fa0761594 100644 --- a/mintlify/platform-overview/core-concepts/transaction-lifecycle.mdx +++ b/mintlify/platform-overview/core-concepts/transaction-lifecycle.mdx @@ -237,7 +237,7 @@ Outgoing payment webhooks use the format `OUTGOING_PAYMENT.`. The webhoo "data": { "id": "Transaction:...", "status": "FAILED", - "failureReason": "INVALID_BANK_ACCOUNT" + "failureReason": "ACCOUNT_INVALID" } } ``` @@ -395,15 +395,16 @@ Use for reconciliation and reporting. | `QUOTE_EXPIRED` | Quote expired before execution | Create new quote | | `QUOTE_EXECUTION_FAILED` | Error executing the quote; no funds were debited | Create new quote | | `EXECUTION_FAILED_POST_DEBIT` | Execution failed after debit; funds are refunded automatically | Retry with a new quote | -| `INSUFFICIENT_BALANCE` | Source account lacks funds | Fund account, retry | | `SETTLEMENT_FAILED` | The settlement leg failed | Retry or use alternative rail | | `FUNDING_AMOUNT_MISMATCH` | Funding amount doesn't match expected amount | Verify amounts and retry | -| `ACCOUNT_INVALID` | Recipient account details are wrong or not found | Correct recipient details | -| `ACCOUNT_CANNOT_RECEIVE` | Recipient account can't accept the payment | Use a different account | +| `TIMEOUT` | Transaction didn't complete within its processing window | Retry with a new quote | +| `MANUAL_REFUND` | Transaction was refunded manually | Contact support | +| `LSP_OPERATIONAL_FAILURE` | Lightspark-internal operational issue | Contact Lightspark | +| `PAYOUT_RETURNED` | Receiving bank returned or reversed the payout | Verify details and retry | | `LIMIT_EXCEEDED` | Payout exceeds a partner limit | Reduce amount or contact support | +| `ACCOUNT_CANNOT_RECEIVE` | Recipient account can't accept the payment | Use a different account | +| `ACCOUNT_INVALID` | Recipient account details are wrong or not found | Correct recipient details | | `COMPLIANCE_REJECTED` | Payout partner rejected on compliance grounds | Contact support | -| `PAYOUT_RETURNED` | Receiving bank returned or reversed the payout | Verify details and retry | -| `LSP_OPERATIONAL_FAILURE` | Lightspark-internal operational issue | Contact Lightspark | The `failureReason` field on a transaction may return additional values, including deprecated reasons (`LIGHTNING_PAYMENT_FAILED`, `COUNTERPARTY_POST_TX_FAILED`) retained for historical transactions. diff --git a/mintlify/snippets/error-handling.mdx b/mintlify/snippets/error-handling.mdx index 6ef5f5d7c..3a7447a47 100644 --- a/mintlify/snippets/error-handling.mdx +++ b/mintlify/snippets/error-handling.mdx @@ -145,13 +145,16 @@ When a transaction fails, the `failureReason` field provides specific details: - `QUOTE_EXPIRED` - Quote expired before execution - `QUOTE_EXECUTION_FAILED` - Error executing the quote; no funds were debited - `EXECUTION_FAILED_POST_DEBIT` - Execution failed after debit; funds are refunded automatically +- `SETTLEMENT_FAILED` - The settlement leg failed - `FUNDING_AMOUNT_MISMATCH` - Funding amount doesn't match expected amount -- `ACCOUNT_INVALID` - Recipient account details are wrong or not found -- `ACCOUNT_CANNOT_RECEIVE` - Recipient account can't accept the payment +- `TIMEOUT` - Transaction didn't complete within its processing window +- `MANUAL_REFUND` - Transaction was refunded manually +- `LSP_OPERATIONAL_FAILURE` - Lightspark-internal operational issue; contact Lightspark +- `PAYOUT_RETURNED` - Receiving bank returned or reversed the payout - `LIMIT_EXCEEDED` - Payout exceeds a partner limit +- `ACCOUNT_CANNOT_RECEIVE` - Recipient account can't accept the payment +- `ACCOUNT_INVALID` - Recipient account details are wrong or not found - `COMPLIANCE_REJECTED` - Payout partner rejected on compliance grounds -- `PAYOUT_RETURNED` - Receiving bank returned or reversed the payout -- `LSP_OPERATIONAL_FAILURE` - Lightspark-internal operational issue; contact Lightspark ### Incoming payment failures From 333b17487c6f606bbc59f10a3ced32f46a19327e Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Tue, 14 Jul 2026 15:47:24 -0700 Subject: [PATCH 4/4] docs(openapi): drop unqualified "no funds were debited" claim Remove the negative guarantee from QUOTE_EXECUTION_FAILED across the enum description and docs. EXECUTION_FAILED_POST_DEBIT still carries the affirmative "debited then refunded automatically" wording. Co-Authored-By: Claude Opus 4.8 (1M context) --- mintlify/openapi.yaml | 2 +- .../platform-overview/core-concepts/transaction-lifecycle.mdx | 2 +- mintlify/snippets/error-handling.mdx | 2 +- openapi.yaml | 2 +- .../schemas/transactions/OutgoingTransactionFailureReason.yaml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mintlify/openapi.yaml b/mintlify/openapi.yaml index b35e4bff5..9da320371 100644 --- a/mintlify/openapi.yaml +++ b/mintlify/openapi.yaml @@ -17091,7 +17091,7 @@ components: | Reason | Description | |--------|-------------| | `QUOTE_EXPIRED` | The quote was not executed before its expiry window | - | `QUOTE_EXECUTION_FAILED` | The quote could not be executed. No funds were debited | + | `QUOTE_EXECUTION_FAILED` | The quote could not be executed | | `EXECUTION_FAILED_POST_DEBIT` | Execution failed after funds were debited. The amount is refunded automatically | | `SETTLEMENT_FAILED` | The settlement leg failed | | `FUNDING_AMOUNT_MISMATCH` | The funds received did not match the expected amount | diff --git a/mintlify/platform-overview/core-concepts/transaction-lifecycle.mdx b/mintlify/platform-overview/core-concepts/transaction-lifecycle.mdx index fa0761594..7b53be784 100644 --- a/mintlify/platform-overview/core-concepts/transaction-lifecycle.mdx +++ b/mintlify/platform-overview/core-concepts/transaction-lifecycle.mdx @@ -393,7 +393,7 @@ Use for reconciliation and reporting. | Failure Reason | Description | Recovery | |----------------|-------------|----------| | `QUOTE_EXPIRED` | Quote expired before execution | Create new quote | -| `QUOTE_EXECUTION_FAILED` | Error executing the quote; no funds were debited | Create new quote | +| `QUOTE_EXECUTION_FAILED` | Error executing the quote | Create new quote | | `EXECUTION_FAILED_POST_DEBIT` | Execution failed after debit; funds are refunded automatically | Retry with a new quote | | `SETTLEMENT_FAILED` | The settlement leg failed | Retry or use alternative rail | | `FUNDING_AMOUNT_MISMATCH` | Funding amount doesn't match expected amount | Verify amounts and retry | diff --git a/mintlify/snippets/error-handling.mdx b/mintlify/snippets/error-handling.mdx index 3a7447a47..3f155eb24 100644 --- a/mintlify/snippets/error-handling.mdx +++ b/mintlify/snippets/error-handling.mdx @@ -143,7 +143,7 @@ When a transaction fails, the `failureReason` field provides specific details: **Common outgoing failure reasons:** - `QUOTE_EXPIRED` - Quote expired before execution -- `QUOTE_EXECUTION_FAILED` - Error executing the quote; no funds were debited +- `QUOTE_EXECUTION_FAILED` - Error executing the quote - `EXECUTION_FAILED_POST_DEBIT` - Execution failed after debit; funds are refunded automatically - `SETTLEMENT_FAILED` - The settlement leg failed - `FUNDING_AMOUNT_MISMATCH` - Funding amount doesn't match expected amount diff --git a/openapi.yaml b/openapi.yaml index b35e4bff5..9da320371 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -17091,7 +17091,7 @@ components: | Reason | Description | |--------|-------------| | `QUOTE_EXPIRED` | The quote was not executed before its expiry window | - | `QUOTE_EXECUTION_FAILED` | The quote could not be executed. No funds were debited | + | `QUOTE_EXECUTION_FAILED` | The quote could not be executed | | `EXECUTION_FAILED_POST_DEBIT` | Execution failed after funds were debited. The amount is refunded automatically | | `SETTLEMENT_FAILED` | The settlement leg failed | | `FUNDING_AMOUNT_MISMATCH` | The funds received did not match the expected amount | diff --git a/openapi/components/schemas/transactions/OutgoingTransactionFailureReason.yaml b/openapi/components/schemas/transactions/OutgoingTransactionFailureReason.yaml index 3f936480c..41d43e1e3 100644 --- a/openapi/components/schemas/transactions/OutgoingTransactionFailureReason.yaml +++ b/openapi/components/schemas/transactions/OutgoingTransactionFailureReason.yaml @@ -29,7 +29,7 @@ description: | | Reason | Description | |--------|-------------| | `QUOTE_EXPIRED` | The quote was not executed before its expiry window | - | `QUOTE_EXECUTION_FAILED` | The quote could not be executed. No funds were debited | + | `QUOTE_EXECUTION_FAILED` | The quote could not be executed | | `EXECUTION_FAILED_POST_DEBIT` | Execution failed after funds were debited. The amount is refunded automatically | | `SETTLEMENT_FAILED` | The settlement leg failed | | `FUNDING_AMOUNT_MISMATCH` | The funds received did not match the expected amount |