Development of White-Label Crypto Exchanger
White-label crypto exchanger is a ready-made instant cryptocurrency exchange platform that partner deploys under their own brand. Unlike exchange, exchanger doesn't require user registration for basic operations: enter destination address, send coins, get exchange. Attractive product for launch: low barrier to entry, clear business model.
White-Label Models
Three Business Models
Revenue share: platform processes transactions through own liquidity providers, partner gets % of each exchange. Zero operating costs for partner, but low margin (30-50% of platform margin).
License model: partner gets full source code or SaaS solution with admin panel, independently connects liquidity providers, sets margins. Full control, but needs technical team.
API + UI: white-label backend API, partner builds own UI. Maximum flexibility for technical partners.
What WL Package Includes
Core functionality:
- Exchange widget (embeddable) and standalone page
- Real-time rate calculation
- Support 100+ cryptocurrencies and tokens
- Multilingual localization
- Responsive design (mobile-first)
Admin panel:
- Manage trading pairs (enable/disable, set margin)
- Monitor transactions and manual intervention
- Customize KYC thresholds
- Affiliate/referral system
- Financial reporting
Brand customization:
- Logo, color scheme, fonts
- Custom domain with SSL
- Email templates in brand style
- SEO meta tags
Technical Architecture
Multi-Tenant Architecture
class TenantConfig(BaseModel):
tenant_id: str
domain: str
brand_name: str
logo_url: str
primary_color: str
secondary_color: str
# Trading settings
enabled_pairs: list[str]
default_markup_percent: float = 1.5
pair_markups: dict[str, float] = {} # Custom margin by pair
# KYC settings
kyc_required_above_usd: float = 1000
kyc_provider: str = 'sumsub'
# Liquidity providers (priority)
liquidity_providers: list[str] = ['changenow', 'simpleswap', 'internal']
# Payout wallet
payout_wallet: str
affiliate_rate: float = 0.0
Router middleware determines tenant by domain:
class TenantMiddleware:
async def __call__(self, request: Request, call_next):
host = request.headers.get('host', '').split(':')[0]
tenant = await self.tenant_registry.get_by_domain(host)
if not tenant:
return JSONResponse({'error': 'Unknown domain'}, status_code=404)
request.state.tenant = tenant
response = await call_next(request)
return response
Liquidity Providers
class ChangeNowProvider:
BASE_URL = "https://api.changenow.io/v2"
async def get_rate(
self,
from_currency: str,
to_currency: str,
amount: Decimal,
flow: str = 'standard'
) -> RateQuote | None:
try:
response = await self.http.get(
f"{self.BASE_URL}/exchange/estimated-amount",
params={
'fromCurrency': from_currency.lower(),
'toCurrency': to_currency.lower(),
'fromAmount': str(amount),
'flow': flow,
'type': 'direct',
},
headers={'x-changenow-api-key': self.api_key}
)
data = response.json()
return RateQuote(
provider='changenow',
to_amount=Decimal(str(data['toAmount'])),
rate=Decimal(str(data['toAmount'])) / amount,
min_amount=Decimal(str(data.get('minAmount', 0))),
expires_in_seconds=600
)
except Exception as e:
logger.error(f"ChangeNow rate error: {e}")
return None
Applying Tenant Markup
def apply_tenant_markup(
provider_quote: RateQuote,
tenant: TenantConfig,
pair: str
) -> AdjustedQuote:
"""Apply tenant markup on top of provider rate"""
markup_percent = tenant.pair_markups.get(pair, tenant.default_markup_percent)
markup_multiplier = 1 - (markup_percent / 100)
adjusted_to_amount = provider_quote.to_amount * Decimal(str(markup_multiplier))
return AdjustedQuote(
original_to_amount=provider_quote.to_amount,
displayed_to_amount=adjusted_to_amount,
markup_percent=markup_percent,
margin_amount=provider_quote.to_amount - adjusted_to_amount,
provider=provider_quote.provider
)
Embeddable Widget
Key advantage of white-label exchanger—can be embedded in any website:
<!-- Partner embeds on their website -->
<div id="crypto-exchanger"></div>
<script>
ExchangerWidget.init({
container: '#crypto-exchanger',
apiKey: 'partner_api_key_here',
fromCurrency: 'BTC',
toCurrency: 'USDT',
theme: 'dark',
primaryColor: '#FF6B00',
lang: 'ru',
onComplete: (txId) => {
console.log('Exchange created:', txId);
}
});
</script>
<script src="https://widget.yourexchanger.com/v2/widget.js"></script>
Widget loads from iframe or as JavaScript inject depending on security requirements. Iframe is isolated and safer, JavaScript inject allows deeper customization.
Monitoring and Alerts
class ExchangeMonitor:
async def check_stuck_orders(self):
"""Find transactions stuck without status update"""
stuck_threshold = timedelta(hours=2)
stuck_orders = await self.db.get_orders_by_status(
status='waiting',
older_than=stuck_threshold
)
for order in stuck_orders:
# Check status with provider
provider_status = await self.get_provider_status(order)
if provider_status.is_completed:
await self.complete_order(order, provider_status)
elif provider_status.is_failed:
await self.fail_order(order, provider_status.error)
else:
# Still waiting—alert operator
await self.alert_operator(order, f"Stuck for {stuck_threshold}")
Monitoring is critical: blockchain transactions delay, providers sometimes hang. Without auto-monitoring and manual exception handling—bad reputation and dissatisfied customers.
White-Label Pricing
| Tier | What's Included | Cost |
|---|---|---|
| Starter | SaaS + basic customization | $500-2,000/month |
| Business | Self-hosted + full source | $10,000-50,000 one-time |
| Enterprise | Custom development | from $50,000 |
Main vendors: ChangeNow WL, StealthEX WL, GodEx WL, SimpleSwap WL. Custom development justified for specific integration requirements or business logic.







