This page is part of the Payments Library Guides. Prefer direct API calls instead? See REST API Guides.
View on GitHub
Clone the complete example project
Server-Side: Create Session
Your server creates a session with the Orchestra API and returns the token to the client.Copy
const express = require('express');
const app = express();
// eWallet account IDs from environment variables
const eWalletAccounts = {
cardPay: process.env.EWALLET_CARDPAY_ACCOUNT_ID,
googlePay: process.env.EWALLET_GOOGLEPAY_ACCOUNT_ID,
applePay: process.env.EWALLET_APPLEPAY_ACCOUNT_ID,
payPal: process.env.EWALLET_PAYPAL_ACCOUNT_ID,
};
// Build array of only the configured account IDs
// Note: This helper is for the example's flexibility. In practice, you would
// simply list your eWallet account names directly in the request, e.g.:
// allowedeWalletAccountIds: ['my-cardpay-account', 'my-paypal-account']
function getConfiguredEWalletAccountIds() {
return Object.values(eWalletAccounts).filter(Boolean);
}
app.post('/api/create-session', async (req, res) => {
const response = await fetch('https://api.orchestrasolutions.com/EWalletOperations', {
method: 'POST',
headers: {
'X-Api-Key': process.env.ORCHESTRA_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
operation: 'CHARGE',
paymentGatewayAccountId: process.env.PAYMENT_GATEWAY_ACCOUNT_ID,
allowedeWalletAccountIds: getConfiguredEWalletAccountIds(),
allowedBrands: ['VISA', 'MASTERCARD', 'AMEX'],
currencyCode: 'USD',
countryCode: 'US',
amount: 49.99,
mode: 'TEST'
})
});
const data = await response.json();
res.json({ sessionToken: data.token });
});
app.listen(3000);
Client-Side: HTML
Create container elements for each payment method you want to display:Copy
<!DOCTYPE html>
<html>
<head>
<title>Checkout</title>
</head>
<body>
<h1>Complete Your Purchase</h1>
<p>Total: $<span id="amount">49.99</span></p>
<!-- Each payment method needs its own container -->
<div id="card-button"></div>
<div id="gpay-button"></div>
<div id="applepay-button"></div>
<div id="paypal-button"></div>
<div id="result"></div>
<script src="https://cdn.jsdelivr.net/npm/bluetime-ewallet@latest/dist/index.js"></script>
<script src="checkout.js"></script>
</body>
</html>
Client-Side: JavaScript
Initialize the library and render payment buttons:Copy
// checkout.js
let engine = null;
async function initPayment() {
// 1. Get session token from your server
const response = await fetch('/api/create-session', { method: 'POST' });
const { sessionToken } = await response.json();
// 2. Initialize the engine
engine = new eWallet.Engine(sessionToken);
// 3. Check which payment methods are available
const available = await engine.checkAvailability();
console.log('Available payment methods:', available);
// 4. Build list of buttons to display
const allButtons = [
{ name: 'CardPay', domEntitySelector: '#card-button' },
{ name: 'GooglePay', domEntitySelector: '#gpay-button' },
{ name: 'ApplePay', domEntitySelector: '#applepay-button' },
{ name: 'PayPal', domEntitySelector: '#paypal-button' }
];
const buttons = allButtons.filter(btn => available.includes(btn.name));
// 5. Render the buttons
engine.payBy(buttons, handleResult, { color: 'Dark', text: 'Pay' });
}
async function handleResult(result) {
const resultEl = document.getElementById('result');
// User cancelled
if (!result) {
resultEl.textContent = 'Payment cancelled';
return;
}
// Parse the result token
const [data, success] = engine.parseResultToken(result.token);
console.log('Payment result:', data);
// Check if payment succeeded
if (!data.clientSuccess) {
resultEl.textContent = 'Payment failed: ' + (data.clientErrorMessage || 'Unknown error');
return;
}
// Handle PSP charge results (CardPay, GooglePay, ApplePay)
if (data.upgChargeResults) {
if (data.upgChargeResults.operationResultCode === 'Success') {
resultEl.innerHTML = `
<strong>Payment successful!</strong><br>
Gateway: ${data.upgChargeResults.gatewayName}<br>
Reference: ${data.upgChargeResults.gatewayReference}<br>
Amount: ${data.upgChargeResults.amount} ${data.upgChargeResults.currency}
`;
} else {
resultEl.textContent = 'Payment declined: ' + (data.upgChargeResults.operationResultDescription || data.upgChargeResults.operationResultCode);
return;
}
}
// Handle direct charge results (PayPal, BankPay)
if (data.directChargeResults) {
if (data.directChargeResults.success) {
resultEl.innerHTML = '<strong>Payment successful!</strong><br>Provider: PayPal';
} else {
resultEl.textContent = 'Payment failed: ' + data.directChargeResults.message;
return;
}
}
// Server-side validation (recommended for production)
try {
const validationResponse = await fetch('/api/validate-payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ resultToken: result.token })
});
if (validationResponse.ok) {
const validationResult = await validationResponse.json();
console.log('Server validation:', validationResult);
}
} catch (error) {
console.warn('Could not reach server for validation:', error.message);
}
}
// Start when page loads
document.addEventListener('DOMContentLoaded', initPayment);
Server-Side: Validate Results
After a successful payment, validate the result token with Orchestra to confirm the payment:Copy
app.post('/api/validate-payment', async (req, res) => {
const { resultToken } = req.body;
const response = await fetch('https://api.orchestrasolutions.com/EWalletOperations/validateResults', {
method: 'POST',
headers: {
'X-Api-Key': process.env.ORCHESTRA_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify(resultToken)
});
const validationResult = await response.json();
if (validationResult.clientSuccess) {
// Payment confirmed - fulfill the order
res.json({ success: true, data: validationResult });
} else {
res.json({ success: false, error: validationResult.clientErrorMessage });
}
});