Reference
This section contains comprehensive reference materials to consult during your integration. Use these resources to lookup endpoints, debug errors, understand security concepts, and quickly reference data formats.
Complete Endpoints Catalog
This section provides a comprehensive reference of all Ealyx endpoints organized by type. Use this as your source of truth for which endpoints exist, what methods they use, and how to call them.
Ealyx API Endpoints (You Call These)
These are endpoints on the Ealyx API infrastructure that your backend calls. All endpoints use your configured {API_BASE_URL}:
| Endpoint | Method | Path | Trailing Slash | Purpose |
|---|---|---|---|---|
| Authentication | POST | {API_BASE_URL}/oauth2/token/ | ✓ YES | Authenticate and obtain OAuth tokens |
| Token Refresh | POST | {API_BASE_URL}/oauth2/token/ | ✓ YES | Refresh an expired access token |
| Get Merchants | GET | {API_BASE_URL}/core/merchants/ | ✓ YES | Retrieve merchant account information |
| Get Session | GET | {API_BASE_URL}/core/sessions/{session_hash} | ✓ YES | Get session and trade-in information |
| Get Trade-in Item | GET | {API_BASE_URL}/core/tradeinitems/{trade_in_id} | ✓ YES | Get specific trade-in valuation details |
| Register Purchase | POST | {API_BASE_URL}/register-purchase | ✗ NO | Register a trade-in when using other payment methods (e.g., credit card) instead of Ealyx Pay |
| Update Order | POST | {API_BASE_URL}/payments/orders/update | ✗ NO | Update order status (shipped, returned, etc.) |
Authentication: All endpoints require Authorization: Bearer {ACCESS_TOKEN} header (except Authentication which uses Basic Auth)
Your Backend Endpoints (EALYX Calls These)
These are endpoints you must implement on your merchant domain:
| Endpoint | Method | Path | Called By | Purpose |
|---|---|---|---|---|
| Shopper Data | GET | {MERCHANT_CALLBACKS_BASE}/shopper_data | SDK | Return customer and session data |
| Purchase Data | GET | {MERCHANT_CALLBACKS_BASE}/purchase_data | SDK | Return cart and order information |
| Webhook | POST | {MERCHANT_WEBHOOK_BASE}/order | Ealyx (server-to-server) | Receivepayment and order notifications |
Authentication: Webhook requires signature validation via X-Ealyx-Signature header (secret: {USER_ID}-{MERCHANT_ID})
Critical Details
Trailing Slash Rules (Strictly Required)
- WITH trailing slash (required, will fail without):
/oauth2/token/,/core/merchants/,/core/sessions/,/core/tradeinitems/ - WITHOUT trailing slash (required, will fail with):
/register-purchase,/payments/orders/update
Environment Switching
When moving from staging to production, only these change:
{API_BASE_URL}: https://api.stg.ealyx.tech → https://api.ealyx.tech
{ASSETS_URL}: https://cdn.stg.ealyx.tech → https://cdn.ealyx.tech
Credentials: (test credentials) → (production credentials)
Everything else stays the same. No code changes required, only update your configuration URLs.
Quick Switcher: Staging ↔ Production
Use this table when deploying from staging to production. Simply update your configuration with the production URLs:
One-Minute Migration Guide
| Component | Staging Value | Production Value | How to Change |
|---|---|---|---|
| API Base | https://api.stg.ealyx.tech | https://api.ealyx.tech | Remove .stg. from domain |
| Assets URL | https://cdn.stg.ealyx.tech | https://cdn.ealyx.tech | Remove .stg. from domain |
| Credentials | ealyx_test_* | Your production credentials | Update from Ealyx |
| CODE | (no changes) | (no changes) | Nothing to update in your code |
Example: Updating Your Configuration
Before (staging):
export API_BASE_URL="https://api.stg.ealyx.tech"
export ASSETS_URL="https://cdn.stg.ealyx.tech"
export CLIENT_ID="ealyx_test_xxx"
export CLIENT_SECRET="ealyx_test_yyy"
After (production):
export API_BASE_URL="https://api.ealyx.tech"
export ASSETS_URL="https://cdn.ealyx.tech"
export CLIENT_ID="your_prod_client_id"
export CLIENT_SECRET="your_prod_client_secret"
That's it! All your examples, scripts, and code using {API_BASE_URL}, etc. will automatically work with production.
Verification Checklist
After switching to production, verify:
- URLs no longer contain
.stg.anywhere - Credentials are production credentials (not test credentials)
- SSL/TLS is enabled (HTTPS, not HTTP)
- DNS records point to correct infrastructure
- Test a simple request:
curl -X GET "{API_BASE_URL}/core/merchants/" -H "Authorization: Bearer {ACCESS_TOKEN}" - Webhook URL is publicly accessible (test with curl from external machine)
- Monitor logs for any errors
For complete endpoint details (including trailing slash rules and environment switching), see Complete Endpoints Catalog above in the Reference section.
This section provides quick lookups for common tasks.
Frontend JavaScript API
Configuration
window.ealyxConfiguration = {
merchantId: '{MERCHANT_ID}',
browserCallbackBase: '{MERCHANT_CALLBACKS_BASE}',
confirmUrl: '{MERCHANT_SUCCESS_URL}',
products: 'valuations+ep1' // Default is just 'valuations'
};
import('{ASSETS_URL}/v1/main.js')
.then(module => {
window.Ealyx = module.Ealyx;
})
.catch(err => console.error('Error loading Ealyx:', err));
Event Listeners
window.addEventListener("ealyx-ready", handler);
function handler() {
// Valuation modal
window.Ealyx.openValuation();
window.Ealyx.addReadyToPlaceOrderListener(callback);
window.addEventListener("ealyx-valuation-updated", handlerValuationUpdate);
// Payment Control
window.Ealyx.updatePaymentSelected(isEalyxSelected);
window.Ealyx.openPayment();
}
Available SDK Events
The Ealyx SDK emits events throughout the integration lifecycle that you can listen to for custom logic:
| Event | When It Fires | Data Included |
|---|---|---|
ealyx-ready | SDK has loaded and initialized | None |
ealyx-valuation-updated | Valuation is updated | { message: "Ealyx Valuation Updated" } |
ealyx-payment-completed | Payment has been completed successfully | { message: "Ealyx Completed Payment" } |
ealyx-modal-closed | Valuation or payment modal is closed | { message: "Modal has been closed" } |
ealyxpay-payment-method-selected | Customer selects Ealyx Pay as payment method | Event data (payload from modal) |
ealyxpay-payment-method-unselected | Customer deselects Ealyx Pay | None |
ealyx-ready-to-place-order | Trade-in accepted, order can be created | { message: "Order can be created now" } |
ealyx-new-user-valuation-started | New user starts a valuation | { message: "User started a new valuation" } |
ealyx-purchase-updated | Purchase information is updated | { message: "Ealyx Purchase Updated" } |
Usage Examples:
// Listen for SDK ready
window.addEventListener("ealyx-ready", () => {
console.log("Ealyx SDK is ready to use");
window.Ealyx.openValuation();
});
// Listen for valuation updates
window.addEventListener("ealyx-valuation-updated", (event) => {
console.log("Valuation updated:", event.detail);
// Refresh UI with new valuation data
});
// Listen for payment completion
window.addEventListener("ealyx-payment-completed", (event) => {
console.log("Payment completed:", event.detail);
// Confirm order, show success page
});
// Listen for modal close
window.addEventListener("ealyx-modal-closed", (event) => {
console.log("Modal closed:", event.detail);
// Reset UI state
});
// Listen for ready to place order
window.addEventListener("ealyx-ready-to-place-order", (event) => {
console.log("Ready to place order:", event.detail);
// Trigger order creation on backend
fetch('/api/orders', { method: 'POST', body: JSON.stringify({...}) });
});
// Listen for new valuation started
window.addEventListener("ealyx-new-user-valuation-started", (event) => {
console.log("New valuation started:", event.detail);
// Track event for analytics
});
// Listen for purchase updates
window.addEventListener("ealyx-purchase-updated", (event) => {
console.log("Purchase updated:", event.detail);
// Refresh purchase display
});
Payment Option Details
const details = window.Ealyx?.paymentOptionDetailsFor('ep1');
// Returns: { mode, template_name, label, info, extra?, data? }
mode | Meaning | Action |
|---|---|---|
normal | Trade-in ready for EP1 | Show as selectable payment method |
popup | No valuation yet | Show option that opens valuation wizard when selected |
disable | EP1 not available | Show as disabled with explanation |
The response includes localized text fields:
label: Primary text for the payment method (e.g., "Pay €114.00 less with Ealyx Pay")info: Explanatory text for info popups/tooltipsextra: Secondary text for expanded payment method details (optional)
Note: The label is plain text but the info and extra fields may contain HTML tags, like <br> for line breaks, <strong> for bold text, etc. They will never be long or complex.
We strongly recommend using the standard texts but if you need to display the payment option in a custom way, you can use the template_name and data fields to get the raw values for custom rendering.
template_name: The name of the template to use for custom rendering. Contact Ealyx support to get up to date template list.data: Raw values for custom rendering:{ valuation, tradein, minimum, tradein_currency, cart_currency }
Disable sub-states (template_name when mode === 'disable'):
currency: Trade-in and cart currencies don't matchcart_below_limit: Cart too small for any trade-in useother_ok: Cart too small for EP1, but trade-in works with other payment methods
// Valuation Wizard
window.Ealyx.openValuation();
// Payment Control
window.Ealyx.updatePaymentSelected(isEalyxSelected);
window.Ealyx.openPayment();
Key Data Formats
All monetary values: Cents (e.g., €100.00 = 10000)
Cart Item:
{
"id": "item_id",
"name": "Product Name",
"description": "Description",
"url": "https://...",
"quantity": 1,
"price": 10000,
"tax": 2100,
"total": 12100
}
Note: For each item in cart:
price= unit price per item (before tax, before discounts)tax= tax for this itemtotal= (price * quantity) + tax = amount charged for this item
Cart Object:
{
"id": "cart_123",
"currency": "EUR",
"items": [...],
"price": 89999,
"tax": 18900,
"discounts": [
{
"id": "discount_1",
"name": "Summer Sale",
"total": 9000
}
],
"total": 99899
}
Important: Cart total calculation:
price= subtotal of all items (before tax, before discounts)tax= total tax amounttotal= price + tax - sum(discounts.total)In other words:
total= (price - discounts) + taxtotalINCLUDES tax, EXCLUDES discounts
Address:
{
"given_name": "John",
"family_name": "Doe",
"phone": "+1234567890",
"address": "123 Main St",
"city": "New York",
"state": "NY",
"country_code": "US",
"postal_code": "10001"
}
Authentication Headers
# Initial Login
Authorization: Basic base64({CLIENT_ID}:{CLIENT_SECRET})
# API Requests
Authorization: Bearer {ACCESS_TOKEN}
# Webhook Validation
X-Ealyx-Signature: hmac_sha256_hex
Update Type Values
shipped- Full order shipmentreturned- Full order returnpartial_shipment- Partial shipment with items listpartial_return- Partial return with items listcart_update- Cart modification with updated cart
Teaser Types & Placements
banner: Homepage, category pages, promotion bannersproduct-widget: Product detail pages, price displaycart-summary: Cart page, checkout summarythank-you: Order confirmation page
Troubleshooting & Quick Reference
| Issue | Possible Causes | Solution |
|---|---|---|
| Teasers not appearing | Frontend SDK not loaded or teaser placement incorrect | Check script tag and data attributes |
| Authentication failures | Invalid credentials or wrong endpoint | Verify CLIENT_ID, CLIENT_SECRET, and API URL |
| Webhook not received | Incorrect webhook URL or unreachable endpoint | Check webhook URL in Ealyx dashboard and ensure publicly accessible |
| Invalid signature | Wrong webhook secret (USER_ID-MERCHANT_ID) or request body integrity | Verify webhook secret format is USER_ID-MERCHANT_ID (from auth response) and use raw request body for HMAC calculation |
| Trade-in not found | Session hash mismatch or expired trade-in | Ensure consistent session hash generation |
| Order update failed | Wrong token scope or invalid order ID | Use token with 'updates' scope and verify order was sent to Ealyx |
| Payment modal not opening | Missing JavaScript event listeners or wrong payment method | Implement all three JavaScript components (select, intercept, listener) |