Reference

onTransactionCreated (RAMPS_TRANSACTION_CREATED)

Optional widget callback after validate succeeds (before commit): persist the stable Ramps transaction id, mgiTransactionId for webhook correlation, and reopen view mode if the user leaves mid-flow.

OptionalWeb · onTransactionCreatedRN · RAMPS_TRANSACTION_CREATED

RAMPS_TRANSACTION_CREATED

The widget posts RAMPS_TRANSACTION_CREATED once the Ramps transaction record exists: immediately after validate succeeds and Ramps returns a transactionId. It fires before commit, signing, deposit (cash-out), and completion.

It does not fire before validate. KYC and any required fields must complete first. Validate allocates the stable Ramps id; this event is how the widget surfaces that ID to your app.

Partners use this event to persist the stable Ramps transaction id early, so an interrupted flow still leaves enough state for view mode and support. Because the ID exists after validate but before commit, you can reopen the widget in view mode while the user is still in the flow (for example, after validate but before they finish commit or Sign & Send).

The payload also includes mgiTransactionId when validate bound a MoneyGram quote, so partners can map status webhooks to a pending credit or history row without an extra status call.

For history storage patterns and view mode, see Partner transaction history.

For transaction status and webhooks (all flows), see Transaction status & webhooks.

For custodial cash-in crediting, see Custodial cash-in.


StageRAMPS_TRANSACTION_CREATED
Before validate (quote, KYC, required fields)Does not fire
Validate succeeds (transactionId allocated)Fires once
EDD / KYC corrections and re-validate (same transaction)Does not fire again for the same id
Commit, Sign & Send, deposit, done screenDoes not fire again
View mode (reopen existing transaction)Does not fire again
TEXT
Quote → KYC → Validate succeeds → RAMPS_TRANSACTION_CREATED → Commit / Sign & Send → Done screen → RAMPS_TRANSACTION_COMPLETE                      │                        │                      └── id + mgiTransactionId are stable from here onward                      └── view mode works from here (status may still be validated / pending_kyc)

Delivery

SurfaceMechanism
Web SDKonTransactionCreated(transaction) callback on createRamps
React NativepostMessage with type: 'RAMPS_TRANSACTION_CREATED'
View modeDoes not fire again when reopening an existing transaction

The event fires at most once per transaction in the widget flow. It is not retried if the host misses it. Partners that require durable capture should also persist the ID at commit or poll status as a fallback.

onTransactionCreated is optional. Integrations that only listen for onComplete / RAMPS_TRANSACTION_COMPLETE continue to work.


Payload

Type: TransactionCreatedRecord (@ramps/types)

TypeScript
interface TransactionCreatedRecord {  /** Stable Ramps transaction ID. Same value as RAMPS_TRANSACTION_COMPLETE.id */  id: string  /**   * MoneyGram transaction ID for the quote backing this transaction.   * Use to correlate status webhooks. Omitted only if validate ran without an MGI ID.   */  mgiTransactionId?: string  /** 'cash-in' for on-ramp, 'cash-out' for off-ramp */  type: 'cash-in' | 'cash-out'  /** Always 'created' on this event */  status: 'created'  chain: 'solana' | 'stellar' | 'ethereum' | /* ... */  asset: 'USDC' | /* ... */  walletType: 'custodial' | 'non-custodial'  walletAddress: string  amount: number  /** ISO 8601 quote expiry. Past this the transaction cannot complete */  quoteExpiresAt?: string  /** ISO 8601 timestamp of this event */  createdAt: string   // Present when quote economics parsed successfully from the settled quote:  fees?: { mgi: number; partner: number; total: number; currency: string }  sendPrincipal?: number  destinationAmount?: number  destinationCurrency?: string  exchangeRate?: number}

Field notes

FieldCash-inCash-out
idRamps transaction ID for view mode and GET /statusSame
mgiTransactionIdMoneyGram ID for webhook correlationSame
type'cash-in''cash-out'
walletAddressDestination wallet (omnibus for custodial cash-in)Source wallet (omnibus for custodial cash-out)
amountUSDC amount the user receivesUSDC amount the user sends
referenceNumberNot present (assigned later at commit / completion)Not present at creation
fees.currencyFiat (counter currency)USDC

Quote economics (fees, sendPrincipal, etc.) are included only when every figure parses cleanly from the settled quote. If any value is missing or invalid, the whole economics block is omitted rather than sending partial numbers.


TEXT
Quote → KYC → Validate succeeds → RAMPS_TRANSACTION_CREATED → Commit → Done screen → RAMPS_TRANSACTION_COMPLETE                      │                      └── id + mgiTransactionId are stable from here onward
StageEvent
After validate (pre-commit)RAMPS_TRANSACTION_CREATED
After commit (confirmation code shown)RAMPS_TRANSACTION_COMPLETE
After user pays at storeNo widget event (poll status or webhook)
USDC delivered to omnibusGET /status?sync=true → completed

For custodial cash-in, there is no RAMPS_DEPOSIT_ADDRESS between creation and completion.


Persist mgiTransactionId and map it to customerIdentifier from your session when this event fires. Credit internal balances when status reaches completed (via webhook or poll).

See Custodial cash-in · Crediting pattern and Transaction status & webhooks.


Web example

TypeScript
createRamps({  sessionToken,  wallet: { address, chain: 'solana', asset: 'USDC', walletType },  transaction: { type: 'on-ramp' },   onTransactionCreated: (tx) => {    savePendingTransaction({      id: tx.id,      mgiTransactionId: tx.mgiTransactionId,      type: tx.type,           // 'cash-in'      amount: String(tx.amount),      status: 'created',      walletType: tx.walletType,      createdAt: Date.now(),    })  },   onComplete: (tx) => {    updateTransaction(tx.id, {      referenceNumber: tx.referenceNumber,      status: tx.status,    })  },})

TypeScript
case 'RAMPS_TRANSACTION_CREATED': {  const p = payload as TransactionCreatedRecord  await AsyncStorage.setItem(`mgi_tx_${p.id}`, JSON.stringify({    id: p.id,    mgiTransactionId: p.mgiTransactionId,    type: p.type,    amount: String(p.amount),    asset: p.asset,    status: 'created',    walletType: p.walletType,    createdAt: Date.now(),  }))  break}

Both events report the same id. Treat creation as an upsert and completion as an update:

TypeScript
// Key storage on id aloneconst key = `mgi_tx_${record.id}`
RAMPS_TRANSACTION_CREATEDRAMPS_TRANSACTION_COMPLETE
WhenAfter validate succeedsDone screen
status'created'Final status (e.g. 'completed', 'committed')
mgiTransactionIdPresent when validate bound a quoteNot present (use created event or status API)
referenceNumberAbsentPresent when MoneyGram has assigned one
quoteEconomics flattened onto payloadFull quote object on TransactionRecord
View mode inputYes (viewTransaction.id)N/A (do not expect re-fire in view mode)