Skip to content

Headless On-Ramp Checkout API in mobile #26733

@OGPoyraz

Description

@OGPoyraz

What is this about?

Goal
Enable a headless buy flow so external features (like MM Pay confirmation) can launch on-ramp checkout directly, without showing TokenSelection / BuildQuote (this is critical as we already know what we need to buy and the amount) screens, and receive orderId programmatically.

Why We Need This

  • We need to integrate buy flow into confirmation UX.
  • Current integration requires stitching together internal screens/routing (BuildQuote, native OTP flow, checkout callbacks), which is brittle.
  • Callback handling differs between provider flows (native vs aggregator), and this leaks complexity to feature teams.
  • We need orderId immediately to store in TransactionPayController and later orchestrate post-fiat steps (Relay).

Requested Capability

  1. Expose a public, supported headless API from the Ramps module/hook (not screen-coupled).
  2. Allow caller to start buy with preselected context:
    • assetId
    • amount
    • currency (we currently need forced USD)
    • providerId
    • paymentMethodId
    • walletAddress
    • metadata // Optional object: This needs to be included into order at the end of checkout, so that we can send { transactionId: "XXX"} and can do regular checks on RampsController state to understand if order is filled
  3. Ramps handles provider-specific auth/checkout/callback internally.
  4. Ramps returns lifecycle events to caller:
    • onOrderCreated(orderId, providerId)
    • onOrderStatusChange(orderId, status)
    • onCheckoutClosed(reason)
    • onError(error)
  5. Preserve ability to render checkout WebView/modal, but caller should not manage intermediate Ramps pages.
  6. Ensure order creation callback works for both native and aggregator providers consistently.

Expected API Shape (Example)

startHeadlessBuy({
  assetId,
  amount,
  currency: 'USD',
  metadata,
  providerId,
  paymentMethodId,
  walletAddress,
  onOrderCreated,
  onOrderStatusChange,
  onClose,
  onError,
});

Acceptance Criteria

  • No navigation to BuildQuote in headless mode.
  • Works for native and aggregator providers.
  • orderId is reliably emitted when available.
  • Caller can close/dismiss and return to its own screen without custom route hacks.
  • Callback URL differences are fully abstracted by Ramps.
  • Public docs/example added for integration teams.

Non-goals (For This Task)

  • UI redesign of existing Ramps screens.
  • Reworking non-headless buy flow behavior.

Demo recording after feature implemented
https://github.com/user-attachments/assets/c1735559-32a4-40f1-9c5a-dc3e7b31776a

Stakeholder review needed before the work gets merged

  • Engineering (needed in most cases)
  • Design
  • Product
  • QA (automation tests are required to pass before merging PRs but not all changes are covered by automation tests - please review if QA is needed beyond automation tests)
  • Security
  • Legal
  • Marketing
  • Management (please specify)
  • Other (please specify)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions