Skip to content

feat(ramps): open order details immediately after UB2 webview callbacks#29623

Open
amitabh94 wants to merge 13 commits into
mainfrom
feat/ramps-ub2-immediate-order-details-after-webview-callback
Open

feat(ramps): open order details immediately after UB2 webview callbacks#29623
amitabh94 wants to merge 13 commits into
mainfrom
feat/ramps-ub2-immediate-order-details-after-webview-callback

Conversation

@amitabh94
Copy link
Copy Markdown
Contributor

@amitabh94 amitabh94 commented May 1, 2026

Description

This PR improves the unified buy (UB2) checkout flow when purchasing via Transak in the WebView: after a successful checkout, the app navigates immediately to Ramps Order Details using callback URL parameters instead of leaving the user on a generic or stale screen.

Order Details now resolves the order from those callback params, surfaces the outcome with a toast, and records metrics so we can observe completion and errors in production.

Motivation: Users should land on a clear, order-specific screen right after Transak completes, with consistent feedback and observability aligned with other ramps flows.

Changelog

CHANGELOG entry: After completing a Transak purchase in unified buy, the app now opens Ramps Order Details with the order resolved from the callback, a confirmation toast, and updated metrics.

Related issues

Fixes: TRAM-3540

Manual testing steps

Feature: Unified buy WebView callback to Ramps Order Details

  Scenario: Transak success navigates to order details with resolved order
    Given the user starts unified buy and opens the Transak WebView checkout
    And checkout completes successfully with callback params that identify the order

    When the WebView returns to the app with the success callback URL
    Then the app navigates to Ramps Order Details for that order
    And the order is resolved and shown without requiring a manual refresh
    And a success toast is shown
    And relevant ramps metrics are emitted for the completed flow

  Scenario: Callback without usable order params still degrades safely
    Given the user returns from the WebView with a callback missing expected order identifiers

    When Order Details attempts to resolve the order
    Then the user sees an appropriate error or empty state (per implementation)
    And no crash occurs; metrics reflect the failure path if applicable

Screenshots/Recordings

Before

Simulator.Screen.Recording.-.Dev1.-.2026-05-01.at.15.24.41.mov

After

Simulator.Screen.Recording.-.Dev1.-.2026-05-01.at.15.14.26.mov

Pre-merge author checklist

Performance checks (if applicable)

  • I've tested on Android
    • Ideally on a mid-range device; emulator is acceptable
  • I've tested with a power user scenario
    • Use these power-user SRPs to import wallets with many accounts and tokens
  • I've instrumented key operations with Sentry traces for production performance metrics

For performance guidelines and tooling, see the Performance Guide.

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Note

Medium Risk
Changes the post-checkout callback handling and navigation flow for unified buy (including headless sessions), which could impact order resolution and user routing if callback params are missing or malformed.

Overview
After a successful unified-buy WebView callback, Checkout no longer fetches/creates the order itself; it immediately navigation.resets to RAMPS_ORDER_DETAILS with callbackUrl + providerCode + walletAddress (and optional cryptocurrency) so the user lands on an order-specific screen right away.

OrderDetails now resolves the order from these callback params, bails back to Build Quote when the callback cannot be resolved or returns a bailed status, emits status-change metrics via handleOrderStatusChangedForMetrics, and shows the showV2OrderToast confirmation. The Transak WebView routing hook is updated to follow the same “navigate first, resolve in OrderDetails” pattern for non-headless flows, while headless flows continue to fetch+close session+pop without showing toasts.

Tests are updated/added to reflect the new responsibility split (navigation params, toast/metrics in OrderDetails, and more robust error normalization/handling).

Reviewed by Cursor Bugbot for commit 517c9b1. Bugbot is set up for automated code reviews on this repo. Configure here.

@amitabh94 amitabh94 requested a review from a team as a code owner May 1, 2026 18:07
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 1, 2026

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.

@metamaskbotv2 metamaskbotv2 Bot added the team-money-movement issues related to Money Movement features label May 1, 2026
@github-actions github-actions Bot added the size-L label May 1, 2026
@amitabh94 amitabh94 changed the base branch from chore/ramps-controller-preview-b9e7d98a6 to main May 1, 2026 18:49
- Views/Checkout: reset to RampsOrderDetails with callbackUrl + provider
  params instead of awaiting getOrderFromCallback in the WebView sheet.
- useTransakRouting: same pattern for Transak payment webview redirects
  (delegate fetch to OrderDetails).
- OrderDetails: show V2 order toast after callback fetch; optional
  cryptocurrency route param for toast fallback; status metrics on
  callback resolution.
- rampsNavigation: document optional cryptocurrency on order details params.

Tests: Checkout, OrderDetails, useTransakRouting.
Co-authored-by: Cursor <cursoragent@cursor.com>
@amitabh94 amitabh94 force-pushed the feat/ramps-ub2-immediate-order-details-after-webview-callback branch from 0124e2a to adb6c97 Compare May 1, 2026 18:57
Comment thread app/components/UI/Ramp/Views/Checkout/Checkout.tsx
…k tests

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread app/components/UI/Ramp/Views/OrderDetails/OrderDetails.tsx Outdated
@saustrie-consensys saustrie-consensys self-assigned this May 6, 2026
saustrie-consensys and others added 8 commits May 6, 2026 19:39
Bugbot flagged that wrapping non-Error rejections via `new Error(String(fetchError))`
makes `normalizedError.message` truthy for almost any value (e.g., "undefined",
"[object Object]", "null"), so the localized fallback was nearly unreachable and
users could see those raw strings as the error. Mirror the `handleOnRefresh` guard
(`fetchError instanceof Error && fetchError.message`) for the user-facing message
while keeping the normalized Error for `Logger.error`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-webview-callback

Conflicts resolved in:
- app/components/UI/Ramp/Views/Checkout/Checkout.tsx
- app/components/UI/Ramp/Views/Checkout/Checkout.test.tsx
- app/components/UI/Ramp/hooks/useTransakRouting.ts

Reconciled with main's headless buy session changes: when a live headless
session is present, Checkout/useTransakRouting still fetch the order in
the hook, fire `onOrderCreated`, close the session, and pop out of the
ramp stack (skipping `RAMPS_ORDER_DETAILS`). For the regular non-headless
path, this branch's behavior wins — leave the WebView immediately and
let `OrderDetails` resolve the order from callback params. When a session
id is present but the registry has no live session, fall through to the
non-headless path rather than the previous toast + reset to keep one
post-checkout UI shape.
CI's `format:check` flagged a few long lines added during the merge with
main's headless flow. Prettier's --write reflowed the
`RAMPS_TRANSACTION_CONFIRMED` event payload and the failure log message.
No behavior change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…e-order-details

Conflicts resolved in:
- app/components/UI/Ramp/Views/Checkout/Checkout.tsx
- app/components/UI/Ramp/Views/Checkout/Checkout.test.tsx
- app/components/UI/Ramp/hooks/useTransakRouting.ts
- app/components/UI/Ramp/hooks/useTransakRouting.test.ts

Reconciled with main's Phase 7 (`feat(ramp): surface headless buy errors as data`):
- `Checkout.tsx`: imports `failSession` and adds `failHeadlessCheckout` to
  forward callback exceptions and WebView HTTP errors to the headless
  consumer's `onError` callback instead of showing the in-app `ErrorView`.
  This branch's non-headless path (navigate immediately to `OrderDetails`
  with callback params) is preserved; the headless branch still fetches the
  order and fires `onOrderCreated` before pop.
- `useTransakRouting.ts`: imports `failSession`, calls it in the headless
  catch path of `handleNavigationStateChange`, and reintroduces
  `navigateToOrderProcessingCallback` so the manual bank transfer
  approval flow can hand a successful headless order to `onOrderCreated`
  without showing the toast or routing to bank-details. `LimitExceededError`
  now carries `headlessBuyErrorCode: 'LIMIT_EXCEEDED'` and `details` so the
  Host can surface limit failures as data; the approved-flow catch
  rethrows it unchanged.
- Tests cover: callback failure → `failSession` (no ErrorView), WebView
  HTTP error → `failSession`, `LimitExceededError` preservation,
  manual bank transfer headless success path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-webview-callback

Resolve Checkout.tsx: keep headless callback fetch + pop; non-headless resets
to Order Details with callback params and closeSourceRef for funnel analytics.

Co-authored-by: Cursor <cursoragent@cursor.com>
- Non-headless callback: expect checkout_closed callback_success (order
  fetch moved to OrderDetails).
- Headless: assert callback_error when getOrderFromCallback returns null.

Co-authored-by: Cursor <cursoragent@cursor.com>
@amitabh94 amitabh94 enabled auto-merge May 14, 2026 01:44
Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c3b4b09. Configure here.

Comment thread app/components/UI/Ramp/hooks/useTransakRouting.ts
Comment thread app/components/UI/Ramp/Views/Checkout/Checkout.tsx
amitabh94 and others added 2 commits May 13, 2026 23:07
Align non-headless Transak redirect with Checkout: optional cryptocurrency
from selected token for OrderDetails toast fallback. Include selectedToken
in handleNavigationStateChange deps. Extend tests (symbol mock + headless
registry-miss path).

Co-authored-by: Cursor <cursoragent@cursor.com>
@amitabh94
Copy link
Copy Markdown
Contributor Author

@copilot resolve conflicts

…-webview-callback

Co-authored-by: amitabh94 <12572750+amitabh94@users.noreply.github.com>
auto-merge was automatically disabled May 15, 2026 19:27

Head branch was pushed to by a user without write access

Copy link
Copy Markdown
Contributor

Copilot AI commented May 15, 2026

@copilot resolve conflicts

Conflicts resolved in commit 517c9b1. The only conflict was in Checkout.tsx's import section: our branch used HeaderCompactStandard while main had refactored to HeaderStandard (from the MMDS design system). Resolved by keeping HeaderStandard (already used in the merged body) and dropping the unused temp import.

@github-actions
Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokeMoney
  • Selected Performance tags: None (no tests recommended)
  • Risk Level: medium
  • AI Confidence: 90%
click to see 🤖 AI reasoning details

E2E Test Selection:
The changes are focused entirely on the Ramp (fiat on/off-ramp) component area:

  1. Checkout.tsx: Refactored the checkout callback flow. In non-headless mode, instead of fetching the order in Checkout and navigating with orderId, it now navigates to RAMPS_ORDER_DETAILS with callbackUrl, providerCode, and walletAddress params, deferring order resolution to OrderDetails. Removed useRampsUnifiedV2Enabled and showV2OrderToast from Checkout.

  2. OrderDetails.tsx: Now handles order fetching from callback URL (previously done in Checkout), shows the V2 order toast, fires analytics via handleOrderStatusChangedForMetrics, and improves error handling for non-Error rejections.

  3. useTransakRouting.ts: Refactored Transak-specific order processing - headless mode now calls onOrderCreated callback and closes session; non-headless mode navigates to RAMPS_ORDER_DETAILS with callback params (same pattern as unified buy).

  4. rampsNavigation.ts: Added cryptocurrency field to RampsOrderDetailsParams interface.

These changes affect the critical checkout completion → order details navigation flow in the ramp stack. The SmokeMoney tag covers ramps flows including onramp-unified-buy.spec.ts, deeplink-to-buy-flow.spec.ts, and deeplink-to-sell-flow.spec.ts, which exercise the checkout and order details screens. No other feature areas (swap, confirmations, wallet platform, etc.) are affected by these changes.

Performance Test Selection:
The changes are refactoring the navigation flow between Checkout and OrderDetails screens in the Ramp stack. There are no changes to rendering performance, list components, data loading patterns, or app initialization. The refactoring moves order fetching from Checkout to OrderDetails but doesn't introduce new async patterns or rendering bottlenecks that would warrant performance testing.

View GitHub Actions results

@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size-L team-money-movement issues related to Money Movement features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants