Overview
This guide will help you integrate Vellosim’s eSIM API into your website, allowing customers to browse and purchase eSIM packages directly from your platform.Prerequisites
- Vellosim merchant account with API credentials
- Basic knowledge of JavaScript/TypeScript
- Web server or hosting platform
- HTTPS enabled (required for secure API calls)
Integration Steps
Step 1: Set Up Your Environment
First, set up environment variables for your API credentials:.env
Copy
VELLOSIM_API_KEY=your_api_key_here
VELLOSIM_BASE_URL=https://api.vellosim.com
Never expose your API key in client-side code. Always make API calls from your backend server.
Step 2: Create API Client
Create a server-side API client to handle Vellosim requests:Copy
// api/vellosim.js
const axios = require('axios');
class VellosimClient {
constructor(apiKey) {
this.client = axios.create({
baseURL: process.env.VELLOSIM_BASE_URL || 'https://api.vellosim.com',
headers: {
'X-API-Key': `apiKey}`,
'Content-Type': 'application/json'
}
});
}
async getRegions() {
const response = await this.client.get('/api/esim/regions');
return response.data;
}
async getPackages(regionCode, regionType) {
const response = await this.client.get('/api/esim/packages', {
params: { regionCode, regionType }
});
return response.data;
}
async getBalance() {
const response = await this.client.get('/api/wallet/balance');
return response.data;
}
async purchaseEsim(packageCode, paymentMethod, packageType) {
const response = await this.client.post('/api/esim/buy', {
packageCode,
paymentMethod,
packageType
});
return response.data;
}
async getOrders(page = 1, limit = 20, status = null, search = null) {
const params = { page, limit };
if (status) params.status = status;
if (search) params.search = search;
const response = await this.client.get('/api/esim/my-esims', { params });
return response.data;
}
async getOrder(esimId) {
const response = await this.client.get(`/api/esim/${esimId}`);
return response.data;
}
}
module.exports = new VellosimClient(process.env.VELLOSIM_API_KEY);
Step 3: Create API Routes
Set up backend routes to proxy requests to Vellosim:Copy
// routes/esim.js
const express = require('express');
const router = express.Router();
const vellosim = require('../api/vellosim');
// Get all regions
router.get('/regions', async (req, res) => {
try {
const regions = await vellosim.getRegions();
res.json(regions);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// Get packages by region
router.get('/packages', async (req, res) => {
try {
const { regionCode, regionType } = req.query;
const packages = await vellosim.getPackages(regionCode, regionType);
res.json(packages);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// Purchase eSIM
router.post('/purchase', async (req, res) => {
try {
const { packageCode, paymentMethod, packageType } = req.body;
const order = await vellosim.purchaseEsim(packageCode, paymentMethod, packageType);
res.json(order);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// Get user orders
router.get('/orders', async (req, res) => {
try {
const { page, limit, status, search } = req.query;
const orders = await vellosim.getOrders(page, limit, status, search);
res.json(orders);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
module.exports = router;
Step 4: Build Frontend Components
Create React components for your eSIM marketplace:React Component
Copy
// components/EsimMarketplace.jsx
import { useState, useEffect } from 'react';
export default function EsimMarketplace() {
const [regions, setRegions] = useState([]);
const [packages, setPackages] = useState([]);
const [selectedRegion, setSelectedRegion] = useState(null);
const [loading, setLoading] = useState(false);
useEffect(() => {
fetchRegions();
}, []);
const fetchRegions = async () => {
try {
const response = await fetch('/api/esim/regions');
const data = await response.json();
setRegions(data);
} catch (error) {
console.error('Failed to fetch regions:', error);
}
};
const fetchPackages = async (regionCode, regionType) => {
setLoading(true);
try {
const response = await fetch(
`/api/esim/packages?regionCode=${regionCode}®ionType=${regionType}`
);
const data = await response.json();
setPackages(data);
} catch (error) {
console.error('Failed to fetch packages:', error);
} finally {
setLoading(false);
}
};
const handleRegionSelect = (region) => {
setSelectedRegion(region);
fetchPackages(region.code, region.type);
};
const handlePurchase = async (packageCode) => {
try {
const response = await fetch('/api/esim/purchase', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
packageCode,
paymentMethod: 'wallet',
packageType: 'data'
})
});
const order = await response.json();
alert(`eSIM purchased successfully! Order ID: ${order.orderId}`);
} catch (error) {
console.error('Purchase failed:', error);
alert('Failed to purchase eSIM. Please try again.');
}
};
return (
<div className="esim-marketplace">
<h1>Choose Your eSIM</h1>
<div className="regions-grid">
{regions.map((region) => (
<button
key={region.code}
onClick={() => handleRegionSelect(region)}
className={selectedRegion?.code === region.code ? 'active' : ''}
>
{region.name}
</button>
))}
</div>
{loading && <p>Loading packages...</p>}
{packages.length > 0 && (
<div className="packages-grid">
{packages.map((pkg) => (
<div key={pkg.packageCode} className="package-card">
<h3>{pkg.name}</h3>
<p>Data: {pkg.data}</p>
<p>Validity: {pkg.validity} days</p>
<p className="price">${pkg.price}</p>
<button onClick={() => handlePurchase(pkg.packageCode)}>
Buy Now
</button>
</div>
))}
</div>
)}
</div>
);
}
Step 5: Add Styling
styles.css
Copy
.esim-marketplace {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
}
.regions-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 1rem;
margin: 2rem 0;
}
.regions-grid button {
padding: 1rem;
border: 2px solid #e5e7eb;
border-radius: 8px;
background: white;
cursor: pointer;
transition: all 0.2s;
}
.regions-grid button:hover {
border-color: #3b82f6;
transform: translateY(-2px);
}
.regions-grid button.active {
border-color: #3b82f6;
background: #eff6ff;
}
.packages-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 1.5rem;
margin-top: 2rem;
}
.package-card {
border: 1px solid #e5e7eb;
border-radius: 12px;
padding: 1.5rem;
background: white;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
.package-card h3 {
margin-top: 0;
color: #111827;
}
.package-card .price {
font-size: 1.5rem;
font-weight: bold;
color: #3b82f6;
margin: 1rem 0;
}
.package-card button {
width: 100%;
padding: 0.75rem;
background: #3b82f6;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
font-weight: 500;
}
.package-card button:hover {
background: #2563eb;
}
