Why missing built-in on-ramp hurts conversion?
Imagine: a user wants to buy ETH with euros right inside your mobile wallet. Without a built-in on-ramp, they leave for a third-party exchange, and conversion drops by 40%. Mercuryo is a European provider with an FCA license supporting 100+ countries. Fees: 2.95–3.95% for cards, 1.5% for SEPA. We integrate Mercuryo into your app: widget in 2–3 days or custom API. Statistically, a built-in on-ramp boosts retention by 25% and increases revenue per purchase by 30%.
How to choose integration mode: widget or API?
Widget — WebView or browser. Fast integration, Mercuryo handles KYC and payment page. Suitable for MVP and standard wallets. API — full UI control, requires business verification with Mercuryo and technical alignment. Used when a unique payment form is needed. Most wallets choose widget — it covers 90% of scenarios.
| Criteria | Widget | API |
|---|---|---|
| Integration speed | 1–2 days | 2–4 weeks |
| UI control | Minimal (colors, language) | Full custom |
| KYC/AML | Handled by Mercuryo | Can integrate own system |
| Server requirements | HMAC signature + Webhook | Signature, token exchange, order handling |
| Recommendation | MVP, general-purpose wallets | Exchanges, white-label solutions |
How to generate a signature for the Mercuryo widget?
Mercuryo requires an HMAC-SHA512 signature from the string {walletAddress}{secret}:
// Server side: address signing import CryptoKit let input = "\(walletAddress)\(mercuryoSecret)" let key = SymmetricKey(data: Data(mercuryoSecret.utf8)) let mac = HMAC<SHA512>.authenticationCode(for: Data(input.utf8), using: key) let signature = Data(mac).map { String(format: "%02x", $0) }.joined() Without a correct signature, the widget opens with an error. The signature is computed server-side and passed to the app as part of the URL.
What to do if the signature is invalid?
Check: does the secret match between your server and Mercuryo panel? Is the correct wallet address passed? Does the string contain extra characters? Signature error is the most common issue on the first widget launch.
Opening the widget
// Android — Chrome Custom Tabs with Mercuryo widget val params = buildString { append("widget_id=${mercuryoWidgetId}") append("&type=buy") append("¤cy=ETH") append("&network=ETHEREUM") append("&address=${userWalletAddress}") append("&signature=${serverGeneratedSignature}") append("&fiat_currency=EUR") append("&redirect_url=${URLEncoder.encode("myapp://mercuryo-complete", "UTF-8")}") append("&theme=dark") append("&lang=ru") } val widgetUrl = "https://exchange.mercuryo.io/?$params" CustomTabsIntent.Builder() .setColorScheme(CustomTabsIntent.COLOR_SCHEME_DARK) .build() .launchUrl(context, Uri.parse(widgetUrl)) The network parameter is critical
Mercuryo differentiates network and token separately. currency=USDC&network=ETHEREUM — USDC on Ethereum. currency=USDC&network=POLYGON — USDC on Polygon. Wrong network — user gets crypto on a different address (if addresses match format) or transaction fails. List of supported pairs: GET https://api.mercuryo.io/v1.6/public/currencies-buy — current reference.
Popular network table
| Token | Network | Chain ID | Status |
|---|---|---|---|
| ETH | Ethereum | 1 | Active |
| USDC | Ethereum | 1 | Active |
| USDC | Polygon | 137 | Active |
| BNB | BSC | 56 | Active |
| AVAX | Avalanche C | 43114 | Active |
Callback and verification
After purchase completion, Mercuryo redirects to redirect_url with parameters status (succeeded, failed, pending) and transaction_id. A webhook on the backend is more reliable than a deeplink. We recommend setting up an endpoint that receives POST requests with a JSON body containing status and verification signature. Implement retries and idempotency for guaranteed delivery.
Security and Compliance
When integrating on-ramp, it is important to comply with App Store Review Guidelines. For iOS, use Universal Links for redirect_url so users return to the app after purchase. On Android, use App Links. Also ensure correct App Transport Security (ATS) configuration for iOS. If the app collects tracking data, request ATT (App Tracking Transparency) permission before opening the widget. Mercuryo has its own KYC/AML procedures, but your app must properly handle verification statuses.
Our process
- Discovery — analyze requirements, choose integration mode.
- Design — define architecture: server-side signature, callback handling.
- Implementation — connect widget or API, configure parameters.
- Testing — test all scenarios: successful purchase, errors, callback, and via TestFlight for iOS.
- Deployment — publish to App Store / Google Play, set up monitoring.
What's included
- Integration documentation and signature scheme.
- Implementation of server endpoint for signature generation.
- Widget or API setup tailored to your app design.
- Handling deeplinks and webhooks for status updates.
- Mercuryo test account and KYC consultation.
- 2 weeks support after launch.
Estimates and timeline
Timeline: from 2 to 14 days depending on integration mode (widget 2–3 days, API up to 2 weeks). Pricing is individual. Get a consultation on Mercuryo integration — we'll assess your project and propose the optimal solution. Contact us to speed up time-to-market.
Experience: 5+ years integrating fintech solutions, 50+ projects with on-ramp providers. Source: Mercuryo Widget SDK documentation (mercuryo.io).







