Reference
Production checklist and troubleshooting
Go-live checklist, security rules, and common failure modes for Solana Ramps partners.
MoneyGram Ramps: Production checklist and troubleshooting
Shared checklist for Solana and Stellar widget partners (custodial and non-custodial, cash-in and cash-out).
Before going live:
Backend
- Secret key stored securely (environment variables, secrets manager)
- Session endpoint has rate limiting (prevent abuse)
- CORS configured to allow only your production domain
- Logging enabled for session creation and errors
- Monitoring alerts for high failure rates
Frontend
- Solana: mainnet USDC mint
EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v(SPL, not Token-2022). UsetokenAddressfrom the sign payload - Stellar: mainnet USDC issuer
GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN. Do not send the testnet issuer on mainnet - Stellar cash-out: settlement memo attached with
Memo.idwhen present. The user or hot wallet has enough XLM for the fee (and a USDC trustline on cash-in) - Production session API endpoint (not sandbox)
- Production credentials (keys starting with
ramps_pk_prod_, notsbox) - Cash-out:
onSignTransactionimplemented and tested on mainnet - Cash-in: widget URL
modeison-ramp(searchParams.set, not a secondmodeparameter); counter confirmation surfaced in your UI - Wallet connection state handled (prompt user to connect for cash-out; wallet address required to receive cash-in USDC)
- Error handling for all transaction failures
- Loading states during transaction signing (cash-out)
Security
- Never log session tokens, signatures, or user private data
- Content Security Policy allows iframe from MoneyGram domains
- XSS protection enabled
- HTTPS enforced (no mixed content)
User experience
- Mobile responsive (test on iOS Safari, Android Chrome)
- Clear error messages (not raw error codes)
- Transaction status polling after completion
- Help/support link visible if user has issues
Widget does not load
Symptoms: Blank iframe or loading spinner never resolves
Causes:
- Invalid session token: Check your backend is calling the session API correctly
- Domain not allowlisted: Contact MoneyGram to allowlist your domain
- CORS errors: Check browser console for blocked requests
- Content Security Policy: Ensure CSP allows iframes from MoneyGram domains
Fix:
// Check a session token is present. Never log the token itself.console.log('Session token present:', Boolean(sessionToken)) // Check for console errors// Open DevTools → Console → Look for CORS or CSP errors
Transaction signing fails (Solana)
Symptoms: Error after user clicks "Sign & Send"
Causes:
- User not authenticated: User has not signed in to the wallet
- Insufficient balance: User does not have enough USDC
- Wrong network: Wallet cluster does not match
tx.requiredNetwork - Invalid mint address: Hardcoded devnet mint, or Token-2022 USDC instead of the SPL mint in
tx.tokenAddress
Fix:
onSignTransaction: async (tx) => { if (!yourWallet.isConnected()) { throw new Error('Please sign in to your wallet') } if (!tx.tokenAddress) { throw new Error('Sign payload is missing tokenAddress') } // Match RPC to tx.requiredNetwork. Use tx.tokenAddress as the mint. // Compare amounts in base units (see toBaseUnits in the Web guide). Do not parseFloat(tx.amount). return await signAndSendUsdc(tx)}
Stellar cash-out is not detected
Symptoms: Funds leave the wallet, then the widget stays on confirming or check-deposit fails
Causes:
- Missing memo when the sign payload or
depositMemoincluded one - Wrong memo type:
Memo.textinstead ofMemo.id. The value is a numeric string (unsigned 64-bit) - Testnet issuer on mainnet:
GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5used whilerequiredNetworkismainnet. Mainnet USDC isGA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN - Insufficient XLM for the network fee, or no USDC trustline on a cash-in destination
Fix: Rebuild the payment with Memo.id when a memo is present, the issuer for requiredNetwork, and the exact amount string. Re-read GET /v1/transactions/:id/status and match depositAddress, depositMemo, and sendAmount before retrying check-deposit.
Session expired
Symptoms: Widget shows "Session expired" after user returns
Cause: Session tokens expire after 1 hour
Fix:
// Do not cache sessions// ❌ Badconst session = await fetchSession()localStorage.setItem('session', JSON.stringify(session)) // Expires! // ✅ Good - fetch fresh each timeasync function openWidget() { const session = await fetchSession() // Fresh session const ramps = createRamps({ sessionToken: session.sessionToken, // ... })}
Reference number not showing
Symptoms: Transaction completes but no reference number
Cause: Transaction succeeded on-chain but MoneyGram commit failed
Fix:
- Check transaction status via "View transaction" mode
- Contact MoneyGram support with transaction ID
- Check backend logs for commit errors
Documentation
- React Native guide: /developer/guides/react-native-solana
- Examples:
github.com/moneygram/xramps-examples(coming soon)
Contact
- Partner support, technical issues, and bug reports: Contact your MoneyGram partner manager