Uh oh!
There was an error while loading. Please reload this page.
feat!: granular counterparty payout failure reasons - #689
Conversation
The latest updates on your projects. Learn more about Vercel for GitHub. 2 Skipped Deployments
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
Greptile SummaryThis PR reworks
Confidence Score: 5/5
|
| Filename | Overview |
|---|---|
| openapi/components/schemas/transactions/OutgoingTransactionFailureReason.yaml | Enum reworked: 4 internal-only values removed, 5 granular payout reasons added, 2 deprecated values retained at end. Descriptions added as a Markdown table. Clean change consistent with the PR intent. |
| openapi.yaml | Generated bundle, correctly reflects the source enum change. Only the OutgoingTransactionFailureReason block changed; rest of spec is untouched. |
| mintlify/openapi.yaml | Mintlify-specific bundle, mirrors the openapi.yaml enum change identically. No other differences from the source spec change. |
| mintlify/platform-overview/core-concepts/transaction-lifecycle.mdx | Failure-reason table updated to match new enum; FAILED webhook example corrected to ACCOUNT_INVALID; deprecated-values note added. SCA_NOT_COMPLETED (an active, actionable value) is absent from the table. |
| mintlify/snippets/error-handling.mdx | Five new payout failure reasons added to the snippet list. SCA_NOT_COMPLETED is still absent; the getUserFriendlyMessage code sample still maps the old INVALID_BANK_ACCOUNT key rather than the replacement values. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
TXN([Outgoing Transaction]) --> FAIL{Failed?}
FAIL -- No --> DONE([Completed])
FAIL -- Yes --> FR[failureReason]
FR --> PRE["Pre-execution\n─────────────\nQUOTE_EXPIRED\nFUNDING_AMOUNT_MISMATCH\nSCA_NOT_COMPLETED"]
FR --> EXEC["Execution\n─────────────\nQUOTE_EXECUTION_FAILED\n(covers full settlement path;\nauto-refund if debited)"]
FR --> PAYOUT["Payout-partner (NEW)\n─────────────\nPAYOUT_RETURNED\nLIMIT_EXCEEDED\nACCOUNT_CANNOT_RECEIVE\nACCOUNT_INVALID\nCOMPLIANCE_REJECTED"]
FR --> DEP["Deprecated / legacy\n─────────────\nLIGHTNING_PAYMENT_FAILED\nCOUNTERPARTY_POST_TX_FAILED"]
EXEC --> REFUND["Auto-refund initiated\n(track via refund object +\nOUTGOING_PAYMENT.REFUND_* events)"]
PAYOUT --> REFUND
Reviews (2): Last reviewed commit: "feat(openapi)!: drop internal-only outgo..." | Re-trigger Greptile
| **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 | ||
| - `SETTLEMENT_FAILED` - The settlement leg failed | ||
| - `FUNDING_AMOUNT_MISMATCH` - Funding amount doesn't match expected amount | ||
| - `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 | ||
There was a problem hiding this comment.
Deprecated values not mentioned in snippet
transaction-lifecycle.mdx adds a note that LIGHTNING_PAYMENT_FAILED and COUNTERPARTY_POST_TX_FAILED may still be returned for historical transactions, but this snippet (which is the first error-handling reference many developers will read) has no equivalent callout. A developer whose integration receives a deprecated value for an older transaction will not find it in this list and may treat it as an unexpected/undocumented response.
Prompt To Fix With AI
This is a comment left during a code review.
Path: mintlify/snippets/error-handling.mdx
Line: 143-158
Comment:
**Deprecated values not mentioned in snippet**`transaction-lifecycle.mdx` adds a note that `LIGHTNING_PAYMENT_FAILED` and `COUNTERPARTY_POST_TX_FAILED` may still be returned for historical transactions, but this snippet (which is the first error-handling reference many developers will read) has no equivalent callout. A developer whose integration receives a deprecated value for an older transaction will not find it in this list and may treat it as an unexpected/undocumented response.
How can I resolve this? If you propose a fix, please make it concise.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
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) <noreply@anthropic.com>
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 <cursoragent@cursor.com>
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) <noreply@anthropic.com>
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) <noreply@anthropic.com>
333b174 to
69fd0d8Compare✱ Stainless preview builds for gridThis PR will update the cli go kotlin openapi php python ruby typescript ✅ grid-rubystudio · code
|
|
07cc8b8 to
2a4c7cfCompare2a4c7cf to
aa9f595CompareThe value is never returned. An operational failure on the provider side reaches integrators as QUOTE_EXECUTION_FAILED, which is the same outcome to act on, so the finer distinction has no public meaning. #629 made this call when it added the other missing enum members; this branch reintroduced it by mistake. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Removes the four values #629 added. Each describes an internal step of how a payment is processed rather than an outcome an integrator acts on differently: - EXECUTION_FAILED_POST_DEBIT and SETTLEMENT_FAILED say where on the way to settlement the failure happened. Both collapse into QUOTE_EXECUTION_FAILED, whose description now covers that whole path and states that a debited amount is refunded automatically. - TIMEOUT and MANUAL_REFUND describe operator-initiated refunds. That outcome already surfaces on the refund object, whose reason enum carries TIMEOUT and USER_CANCELLATION. LIGHTNING_PAYMENT_FAILED's deprecation note now points at QUOTE_EXECUTION_FAILED rather than the removed SETTLEMENT_FAILED. BREAKING CHANGE: four values are removed from OutgoingTransactionFailureReason. The server-side mapping for them has to be updated before clients are regenerated, or failureReason renders empty — see #629. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
aa9f595 to
6b40894CompareUh oh!
There was an error while loading. Please reload this page.
Summary
Reworks
OutgoingTransactionFailureReasonso every value is an outcome an integrator acts on, and syncs the docs to match.Added — granular payout failures, set at the payout-partner boundary:
PAYOUT_RETURNED— receiving bank accepted then returned/reversed the payoutLIMIT_EXCEEDED— payout exceeds a recipient-, account-, or corridor-level limitACCOUNT_CANNOT_RECEIVE— account exists but can't accept the payment (dormant/frozen/restricted/unsupported currency)ACCOUNT_INVALID— recipient account not found or details wrongCOMPLIANCE_REJECTED— rejected on compliance grounds (sanctions/watchlist/KYC-AML)Removed — the four values #629 added. Each names an internal step of how a payment is processed rather than something an integrator handles differently:
EXECUTION_FAILED_POST_DEBITandSETTLEMENT_FAILEDsay where on the way to settlement the failure happened. Both collapse intoQUOTE_EXECUTION_FAILED, whose description now covers that whole path and states that a debited amount is refunded automatically.TIMEOUTandMANUAL_REFUNDdescribe operator-initiated refunds. That outcome already surfaces on the refund object, whosereasonenum carriesTIMEOUTandUSER_CANCELLATION.LSP_OPERATIONAL_FAILUREwas on this branch earlier and is removed for the same reason: an operational failure on the provider side reaches integrators asQUOTE_EXECUTION_FAILED, the same outcome to act on.Deprecated in the description, still returned:
LIGHTNING_PAYMENT_FAILED(superseded byQUOTE_EXECUTION_FAILED) andCOUNTERPARTY_POST_TX_FAILED(coarse fallback for historical rows).SCA_NOT_COMPLETED(#762) is untouched — a customer letting an SCA challenge expire is a distinct, actionable outcome.Final enum:
QUOTE_EXPIRED,QUOTE_EXECUTION_FAILED,FUNDING_AMOUNT_MISMATCH,SCA_NOT_COMPLETED,PAYOUT_RETURNED,LIMIT_EXCEEDED,ACCOUNT_CANNOT_RECEIVE,ACCOUNT_INVALID,COMPLIANCE_REJECTED,LIGHTNING_PAYMENT_FAILED,COUNTERPARTY_POST_TX_FAILED.Breaking change
Removing four values is flagged by oasdiff as
request-property-enum-value-removed(ERR), becausefailureReasonalso appears in thewebhook:outgoing-paymentandwebhook:agent-actionbodies. The PR carries thebreaking-changelabel and needs API-reviewer approval.The server-side mapping for the removed values has to be updated before clients are regenerated, or
failureReasonrenders empty — the regression #629 was fixing.Changes
OutgoingTransactionFailureReason.yaml+ bundle): the enum above, with per-value descriptions and deprecation notes.transaction-lifecycle.mdxand the list in theerror-handling.mdxsnippet to the enum — dropped the non-existentINSUFFICIENT_BALANCE, reordered to enum order, and fixed aFAILEDwebhook example to useACCOUNT_INVALID.Rebased onto main, which added #629's values and #762's
SCA_NOT_COMPLETED.Test plan
make build— bundles cleanly; clean rebuild produces no diffmake lint-openapi— 0 errors (redocly + spectral)