feat(ramp): bypass order-processing redirect in headless flows (Phase 6)#29340
Conversation
|
CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes. |
d56ac89 to
740efe3
Compare
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsE2E Test Selection:
The changes modify the order completion flow in the Ramp feature, which is a critical user journey. The existing non-headless code paths are preserved with proper fallback behavior. No shared components (TabBar, navigation, modals outside Ramp) are affected. The Performance Test Selection: |
|
|
✅ E2E Fixture Validation — Schema is up to date |



Description
This PR closes Phase 6 of the incremental Unified Buy (v2) headless buy plan (
app/components/UI/Ramp/headless/PLAN.md): when a flow produces an orderId under a live headless session, the consumer'sonOrderCreatedcallback fires and the ramp stack unwinds — no more redirect toRAMPS_ORDER_DETAILS, noshowV2OrderToastthe consumer didn't ask for.Reason
RAMPS_ORDER_DETAILSwith a toast — there was no way for external UIs to know an order was created. Phase 6 closes the loop so consumers can actually react to completion.What changed
app/components/UI/Ramp/Views/Checkout/Checkout.tsx— addsheadlessSessionIdtoCheckoutParams. When the widget callback URL resolves andgetSession(headlessSessionId)returns a live session, the screen firessession.callbacks.onOrderCreated(orderId), callscloseSession(id, { reason: 'completed' }), and pops the parent stack.addOrderandprotectWalletModalVisiblestill dispatch so Redux stays consistent;showV2OrderToastis suppressed. Non-headless behavior is unchanged.app/components/UI/Ramp/hooks/useTransakRouting.ts— extractsheadlessSessionIdfromconfig.baseRouteParams(already threaded by the Host via Phase 5's parameterization) and applies the same branching insidenavigateToOrderProcessingCallback.handleNavigationStateChange's toast is suppressed when the session is live;addOrder+trackEventkeep firing so Redux + analytics parity are preserved.app/components/UI/Ramp/hooks/useContinueWithQuote.ts— threadsctx.headlessSessionIdintocreateCheckoutNavDetailsso the v2 Checkout screen can see it on the aggregator/widget branch.onOrderCreatederrors are caught and logged viaLogger.error; the session still closes and the stack still pops, so a consumer-side bug can never break the flow.PLAN.md— Phase 6 ticked.References
poc/headless-buy-phase-5; when feat(ramp): add Headless Host + quote-first startHeadlessBuy (Phase 5) #29338 merges, GitHub will auto-retarget the base tomainso the final diff is Phase 6-only.main: #29213 (useContinueWithQuoteextraction).Tests
headless session flowdescribe block inapp/components/UI/Ramp/Views/Checkout/Checkout.test.tsx(5 cases): live-session success,addOrder+protectWalletModalVisibleside-effect preservation, consumeronOrderCreatederror swallow, missing-session fallback, absent-headlessSessionIdunchanged path.headless session flowdescribe block inapp/components/UI/Ramp/hooks/useTransakRouting.test.ts(4 cases): the same shape exercised through the Transak native callback path.sessionRegistry.test.ts,useContinueWithQuote.test.ts,HeadlessHost.test.tsx. 101/101 pass across the five suites.Changelog
CHANGELOG entry: null
Related issues
Fixes: No GitHub issue — incremental POC on branch
poc/headless-buy-phase-6.Continuity: #29338 (Phase 5 — Headless Host + quote-first start). #29213 (Phase 4 —
useContinueWithQuote).Manual testing steps
Screenshots/Recordings
Before
N/A — Phase 6 wires the existing callback contract; no UI changes.
After
MoonPay succeeds (similar to Phase)
Can't provide a video for Transak since Transak KYC keeps asking me to submit a live selfie for my iOS simulator (even though my purchase amount is under $30)
Pre-merge author checklist
Performance checks (if applicable)
Pre-merge reviewer checklist
Note
Medium Risk
Changes success-path navigation and notification behavior in checkout/order routing, which could affect user flow completion if session detection or parent stack popping is wrong; covered by new unit tests but still touches core ramp navigation paths.
Overview
Headless buy flows now short-circuit the usual post-checkout UX: when
CheckoutoruseTransakRoutingdetects a liveheadlessSessionId, it calls the session’sonOrderCreated(orderId), closes the session, and pops the ramp stack instead of resetting toRAMPS_ORDER_DETAILSand showing the V2 order toast.useContinueWithQuotenow forwardsheadlessSessionIdintoCheckoutnavigation so aggregator/widget checkouts can participate in this behavior, and the headless plan doc marks Phase 6 complete. Comprehensive unit tests were added to cover live-session success, callback error swallowing + logging, toast suppression, and fallback to the non-headless path when the session is missing/absent.Reviewed by Cursor Bugbot for commit 740efe3. Bugbot is set up for automated code reviews on this repo. Configure here.