Complete E-commerce Checkout Flow
A comprehensive example showing a complete e-commerce checkout implementation.
Overview
This example demonstrates:
- Product catalog display
- Shopping cart management
- Customer creation
- Payment processing
- Order fulfillment
Server Setup
import express from "express";
import { createClient } from "@easylabs/node";
import dotenv from "dotenv";
dotenv.config();
const app = express();
app.use(express.json());
const easy = await createClient({
apiKey: process.env.EASY_API_KEY!,
});
1. Product Catalog
Get Products with Prices
app.get("/api/catalog", async (req, res) => {
try {
// Get all active products
const products = await easy.getProducts({ limit: 100 });
// Get prices for each product
const catalog = await Promise.all(
products.data.map(async (product) => {
const prices = await easy.getProductWithPrices(product.id);
return {
...product,
prices: prices.data,
};
}),
);
res.json({ catalog });
} catch (error: any) {
res.status(500).json({ error: error.message });
}
});
2. Shopping Cart
Client-side cart management (sent to server during checkout):
interface CartItem {
price_id: string;
quantity: number;
product_name: string;
unit_amount: number;
}
// Client-side cart state
const cart: CartItem[] = [
{
price_id: "price_123",
quantity: 2,
product_name: "Premium Widget",
unit_amount: 2999,
},
{
price_id: "price_456",
quantity: 1,
product_name: "Deluxe Service",
unit_amount: 4999,
},
];
3. Checkout Process
Checkout Endpoint
app.post("/api/checkout", async (req, res) => {
try {
const { customerData, paymentToken, cartItems, shippingAddress } = req.body;
// Validate cart items
if (!cartItems || cartItems.length === 0) {
return res.status(400).json({ error: "Cart is empty" });
}
// Process checkout
const result = await easy.checkout({
customer_creation: true,
customer_details: {
first_name: customerData.firstName,
last_name: customerData.lastName,
email: customerData.email,
phone: customerData.phone,
personal_address: shippingAddress,
},
source: {
type: "PAYMENT_CARD",
tokenId: paymentToken,
name: "Customer Card",
},
line_items: cartItems.map((item: any) => ({
price_id: item.price_id,
quantity: item.quantity,
})),
metadata: {
order_source: "web-checkout",
ip_address: req.ip,
user_agent: req.get("user-agent"),
},
});
// Send confirmation email (not shown)
// await sendOrderConfirmation(result.data);
res.status(201).json({
success: true,
order: {
id: result.data.id,
order_number: result.data.order_number,
total: result.data.total_cents,
customer_id: result.data.customer_id,
},
});
} catch (error: any) {
console.error("Checkout error:", error);
res.status(500).json({
success: false,
error: error.message,
});
}
});
Guest Checkout (Existing Customer)
app.post("/api/guest-checkout", async (req, res) => {
try {
const { customerId, paymentInstrumentId, cartItems } = req.body;
const result = await easy.checkout({
customer_creation: false,
identity_id: customerId,
source: paymentInstrumentId,
line_items: cartItems.map((item: any) => ({
price_id: item.price_id,
quantity: item.quantity,
})),
metadata: {
order_source: "returning-customer",
},
});
res.status(201).json({
success: true,
order: result.data,
});
} catch (error: any) {
res.status(500).json({
success: false,
error: error.message,
});
}
});
4. Order Management
Get Order Status
app.get("/api/orders/:id", async (req, res) => {
try {
const order = await easy.getOrder(req.params.id);
res.json(order);
} catch (error: any) {
res.status(404).json({ error: "Order not found" });
}
});
Customer Order History
app.get("/api/customers/:id/orders", async (req, res) => {
try {
const orders = await easy.getCustomerOrders(req.params.id, {
limit: 50,
offset: 0,
});
res.json(orders);
} catch (error: any) {
res.status(500).json({ error: error.message });
}
});
5. Order Fulfillment
Update Order Status
app.post("/api/orders/:id/fulfill", async (req, res) => {
try {
const { trackingNumber, carrier, status } = req.body;
const updated = await easy.updateOrderTags(req.params.id, {
fulfillment_status: status,
tracking_number: trackingNumber,
carrier: carrier,
shipped_at: new Date().toISOString(),
});
// Send shipping notification
// await sendShippingNotification(updated.data);
res.json(updated);
} catch (error: any) {
res.status(400).json({ error: error.message });
}
});
Complete Flow Example
import express from "express";
import { createClient } from "@easylabs/node";
const app = express();
app.use(express.json());
const easy = await createClient({
apiKey: process.env.EASY_API_KEY!,
});
// 1. Get product catalog
app.get("/api/catalog", async (req, res) => {
const products = await easy.getProducts();
const catalog = await Promise.all(
products.data.map(async (p) => {
const withPrices = await easy.getProductWithPrices(p.id);
return withPrices.data;
}),
);
res.json({ catalog });
});
// 2. Process checkout
app.post("/api/checkout", async (req, res) => {
const { customerData, paymentToken, cartItems } = req.body;
const result = await easy.checkout({
customer_creation: true,
customer_details: customerData,
source: {
type: "PAYMENT_CARD",
tokenId: paymentToken,
name: "Customer Card",
},
line_items: cartItems,
});
res.json({ success: true, order: result.data });
});
// 3. Get order
app.get("/api/orders/:id", async (req, res) => {
const order = await easy.getOrder(req.params.id);
res.json(order);
});
// 4. Fulfill order
app.post("/api/orders/:id/ship", async (req, res) => {
const updated = await easy.updateOrderTags(req.params.id, {
status: "shipped",
tracking: req.body.trackingNumber,
});
res.json(updated);
});
app.listen(3000);
Client-Side Integration
// Client-side checkout function
async function processCheckout(
customerData: any,
paymentToken: string,
cartItems: any[],
) {
const response = await fetch("/api/checkout", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
customerData,
paymentToken,
cartItems: cartItems.map((item) => ({
price_id: item.price_id,
quantity: item.quantity,
})),
shippingAddress: customerData.address,
}),
});
const result = await response.json();
if (result.success) {
// Redirect to success page
window.location.href = `/orders/${result.order.id}`;
} else {
// Handle error
console.error("Checkout failed:", result.error);
}
}