Skip to content

sdk: add generic external payment flow - #69

Open
a16i wants to merge 7 commits into
masterfrom
feat/hosted-payment-flow
Open

sdk: add generic external payment flow#69
a16i wants to merge 7 commits into
masterfrom
feat/hosted-payment-flow

Conversation

@a16i

@a16i a16i commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add the provider-neutral { type: "external", id: "CashApp" | "Revolut", sourceAmount } payment-method contract and export ExternalPaymentMethodRequest
  • make externalPayment the canonical handoff response, with decimal-string money for source amounts, destination estimates, and fees
  • replace the new public HostedPayment navigation kind with ExternalPayment; hosted remains an implementation strategy, not a payment-method category
  • move compatible Cash App flows onto the external contract while retaining the legacy exchange request/response fallback for old servers and nav trees
  • keep ExchangeId backward compatible but reject Revolut as an exchange
  • reuse one generic external-payment UI for exchanges, Cash App, and Revolut

Compatibility

  • new SDK + new server: Cash App and Revolut use external
  • new SDK + old server: Cash App uses the legacy exchange request unless the nav node carries the external capability marker
  • old SDK + new server: legacy Cash App exchange requests and responses remain supported

Validation

  • pnpm test
  • 33 test files and 209 tests passed
  • SDK TypeScript, native TypeScript, CSS build, lint, and style verification passed

Open in Devin Review

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View 2 additional findings in Devin Review.

Open in Devin Review

Comment on lines +310 to +313
const sourceAmountUnits = formatNavSourceAmountUnits(
amount,
sourceAmount,
);

@devin-ai-integration devin-ai-integration Bot Jul 30, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Malformed backend amount precision can leave the payment screen stuck loading forever

The amount is formatted (formatNavSourceAmountUnits at packages/sdk/src/web/hooks/useSessionNav.ts:310-313) before the error-handling block starts, so if the backend describes the amount with an unsupported number of decimal places, preparing the payment throws and the waiting screen never shows an error.

Impact: In that case the user is left staring at an endless loading spinner with no error message and no way to recover.

Why the throw escapes error handling

formatNavSourceAmountUnits throws "invalid external payment amount" when decimals is non-integer, negative, or > 20 (packages/sdk/src/web/api/navTree.ts:213-220). In fetchExternalPayment this call sits at lines 310-313, before the try at packages/sdk/src/web/hooks/useSessionNav.ts:332. The caller handleNavigate (required>0 path) first pushes an external-payment stack entry with paymentUrl undefined and then calls fetchExternalPayment fire-and-forget; the thrown error becomes an unhandled rejection and the entry stays isLoading with no error set, so the catch block that would surface the error at lines ~372-395 is never reached. In handleAmountContinue the same function is also called at lines 904-907 while building amountContext, which would throw synchronously inside the click handler. This only triggers on malformed backend decimals, hence non-severe.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@a16i a16i changed the title sdk: add generic hosted payment flow sdk: add generic external payment flow Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant