Guide

React Native · Custodial cash-out · Stellar / USDC

Custodial off-ramp in React Native: WebView, RAMPS_DEPOSIT_ADDRESS, and server-side Stellar USDC transfers.

1–2 hoursCustodialReact NativeUSDC · off-ramp

MoneyGram Ramps: Custodial Cash-Out (React Native / Stellar / USDC)

Preview · Custodial partners · React Native · Cash-out only ·

Overview

This guide is for custodial partners building a React Native app. You hold customer USDC in a shared omnibus or hot wallet; end users do not sign on-chain transactions themselves.

For non-custodial React Native (user wallet signing via RAMPS_SIGN_TRANSACTION), use the React Native · Stellar (non-custodial) guide.

For the web iframe SDK (createRamps + onDepositAddress), see Web · Custodial cash-out.

Scope: Custodial cash-out (off-ramp) only. For custodial cash-in, use the Custodial cash-in guide. The WebView message contract is Embed the widget.

How it works:

  1. Your backend creates a session with customerIdentifier for the logged-in user.
  2. Your app opens the MoneyGram widget in a WebView and sends RAMPS_CONFIG with walletType: 'custodial'.
  3. When the user commits, the widget sends RAMPS_DEPOSIT_ADDRESS (not RAMPS_SIGN_TRANSACTION).
  4. Your app calls your internal transfer API, then replies with RAMPS_SIGN_SUCCESS and the on-chain txHash.
  5. The widget polls until confirmed and returns a reference number for cash pickup.

The widget and API are the same as web custodial. Only the postMessage bridge differs.


TopicDetails
Custody modeSet at onboarding (walletCustody: 'custodial'), cannot switch per session
customerIdentifierRequired in POST /v1/sessions: stable internal user ID (max 255 chars)
Omnibus walletcustodianCashOutWallet: USDC source for off-ramp; set in partner portal
Stellar memoInclude depositMemo as Memo.id (numeric). Memo.text fails deposit verification

See Web · Custodial cash-out for full session API examples and backend transfer orchestration.


TypeScript
async function createCustodialSession(userId: string) {  const res = await fetch('https://playground.xramps.moneygram.com/api/v1/sessions', {    method: 'POST',    headers: {      'Content-Type': 'application/json',      'x-api-key': process.env.MONEYGRAM_SK!,    },    body: JSON.stringify({      customerIdentifier: userId,      walletAddress: process.env.PARTNER_OMNIBUS_WALLET,      chain: 'stellar',    }),  })  if (!res.ok) throw new Error(`Session failed: ${res.status}`)  return res.json()}

Session TTL: 1 hour. Create a fresh session each time the user opens the widget.


Non-custodialCustodial
walletType: 'non-custodial'walletType: 'custodial'
wallet.address = user's G-addresswallet.address = your omnibus / hot wallet
Handle RAMPS_SIGN_TRANSACTIONHandle RAMPS_DEPOSIT_ADDRESS
Sign with user walletCall internal transfer API → return txHash

RAMPS_CONFIG (custodial)

On RAMPS_READY:

TypeScript
post('RAMPS_CONFIG', {  sessionToken: session.sessionToken,  wallet: {    address: PARTNER_OMNIBUS_WALLET,    chain: 'stellar',    asset: 'USDC',    walletType: session.walletType,  },  devConfig: {    mockMode: false,    apiBaseUrl: 'https://playground.xramps.moneygram.com/api',  },  transaction: {    type: 'off-ramp',    asset: 'USDC',  },})

TypeScript
case 'RAMPS_DEPOSIT_ADDRESS': {  try {    const res = await fetch(INTERNAL_TRANSFER_URL, {      method: 'POST',      headers: {        'Content-Type': 'application/json',        Authorization: `Bearer ${appAuthToken}`,      },    })    if (!res.ok) throw new Error(`Transfer failed (${res.status})`)    const { txHash } = await res.json()    if (typeof txHash !== 'string' || !txHash) throw new Error('Transfer returned no txHash')    post('RAMPS_SIGN_SUCCESS', { txHash, walletAddress: PARTNER_OMNIBUS_WALLET })  } catch (err) {    post('RAMPS_SIGN_ERROR', {      error: err instanceof Error ? err.message : 'Transfer failed',    })  }  break}

Do not authorize transfers from WebView-supplied address, amount, or memo alone. Your backend resolves the active Ramps transaction and re-reads authoritative values from GET /v1/transactions/:id/status.


Same idempotent orchestration as the Web custodial guide. Submit a Stellar USDC payment from your hot wallet with the memo from the Ramps API when present.