Customer Management Example
This example demonstrates how to create, update, retrieve, and manage customers using the Easy React SDK.
Overview
The Easy SDK provides comprehensive customer management functionality including:
- Creating new customers
- Updating customer information
- Retrieving customer details
- Listing all customers
- Managing customer payment instruments
- Viewing customer orders
Complete Example
import React, { useState } from "react";
import { useEasy } from "@easylabs/react";
import type {
CustomerData,
PaymentInstrumentData,
OrderData,
} from "@easylabs/react";
function CustomerManager() {
const {
createCustomer,
updateCustomer,
getCustomer,
getCustomers,
getCustomerPaymentInstruments,
getCustomerOrders,
} = useEasy();
const [customer, setCustomer] = useState<CustomerData | null>(null);
const [customers, setCustomers] = useState<CustomerData[]>([]);
const [paymentInstruments, setPaymentInstruments] = useState<
PaymentInstrumentData[]
>([]);
const [orders, setOrders] = useState<OrderData[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
// Create a new customer
const createNewCustomer = async () => {
setLoading(true);
setError(null);
try {
const result = await createCustomer({
first_name: "Alice",
last_name: "Wilson",
email: "[email protected]",
phone: "+1234567890",
personal_address: {
line1: "456 Oak St",
city: "Another City",
state: "NY",
postal_code: "67890",
country: "US",
},
tags: {
source: "web-form",
campaign: "summer-2024",
},
});
setCustomer(result.data);
console.log("Customer created:", result.data);
} catch (err) {
setError(
err instanceof Error ? err.message : "Failed to create customer",
);
console.error("Error creating customer:", err);
} finally {
setLoading(false);
}
};
// Update customer information
const updateCustomerInfo = async (customerId: string) => {
setLoading(true);
setError(null);
try {
const result = await updateCustomer(customerId, {
phone: "+0987654321",
tags: {
...customer?.tags,
updated: new Date().toISOString(),
verified: true,
},
});
setCustomer(result.data);
console.log("Customer updated:", result.data);
} catch (err) {
setError(
err instanceof Error ? err.message : "Failed to update customer",
);
console.error("Error updating customer:", err);
} finally {
setLoading(false);
}
};
// Get a single customer by ID
const loadCustomer = async (customerId: string) => {
setLoading(true);
setError(null);
try {
const result = await getCustomer(customerId);
setCustomer(result.data);
console.log("Customer loaded:", result.data);
} catch (err) {
setError(err instanceof Error ? err.message : "Failed to load customer");
console.error("Error loading customer:", err);
} finally {
setLoading(false);
}
};
// Get all customers with pagination
const loadAllCustomers = async () => {
setLoading(true);
setError(null);
try {
const result = await getCustomers({
limit: 10,
offset: 0,
});
setCustomers(result.data);
console.log("Customers loaded:", result.data);
} catch (err) {
setError(err instanceof Error ? err.message : "Failed to load customers");
console.error("Error loading customers:", err);
} finally {
setLoading(false);
}
};
// Get customer's payment instruments
const loadCustomerPaymentMethods = async (customerId: string) => {
setLoading(true);
setError(null);
try {
const result = await getCustomerPaymentInstruments(customerId);
setPaymentInstruments(result.data);
console.log("Payment instruments:", result.data);
} catch (err) {
setError(
err instanceof Error
? err.message
: "Failed to load payment instruments",
);
console.error("Error loading payment instruments:", err);
} finally {
setLoading(false);
}
};
// Get customer's orders
const loadCustomerOrders = async (customerId: string) => {
setLoading(true);
setError(null);
try {
const result = await getCustomerOrders(customerId, {
limit: 10,
offset: 0,
});
setOrders(result.data);
console.log("Orders:", result.data);
} catch (err) {
setError(err instanceof Error ? err.message : "Failed to load orders");
console.error("Error loading orders:", err);
} finally {
setLoading(false);
}
};
return (
<div className="customer-manager">
<h2>Customer Management</h2>
{error && (
<div className="error-message" role="alert">
{error}
</div>
)}
{/* Create Customer Section */}
<section>
<h3>Create New Customer</h3>
<button onClick={createNewCustomer} disabled={loading}>
{loading ? "Creating..." : "Create Customer"}
</button>
</section>
{/* Customer Details Section */}
{customer && (
<section>
<h3>Customer Details</h3>
<div className="customer-info">
<p>
<strong>ID:</strong> {customer.id}
</p>
<p>
<strong>Name:</strong> {customer.first_name} {customer.last_name}
</p>
<p>
<strong>Email:</strong> {customer.email}
</p>
<p>
<strong>Phone:</strong> {customer.phone}
</p>
{customer.personal_address && (
<div>
<p>
<strong>Address:</strong>
</p>
<p>{customer.personal_address.line1}</p>
{customer.personal_address.line2 && (
<p>{customer.personal_address.line2}</p>
)}
<p>
{customer.personal_address.city},{" "}
{customer.personal_address.state}{" "}
{customer.personal_address.postal_code}
</p>
<p>{customer.personal_address.country}</p>
</div>
)}
{customer.tags && (
<div>
<p>
<strong>Tags:</strong>
</p>
<pre>{JSON.stringify(customer.tags, null, 2)}</pre>
</div>
)}
</div>
<div className="customer-actions">
<button
onClick={() => updateCustomerInfo(customer.id)}
disabled={loading}
>
Update Customer
</button>
<button
onClick={() => loadCustomerPaymentMethods(customer.id)}
disabled={loading}
>
Load Payment Methods
</button>
<button
onClick={() => loadCustomerOrders(customer.id)}
disabled={loading}
>
Load Orders
</button>
</div>
</section>
)}
{/* Payment Instruments Section */}
{paymentInstruments.length > 0 && (
<section>
<h3>Payment Instruments</h3>
<ul>
{paymentInstruments.map((instrument) => (
<li key={instrument.id}>
<strong>{instrument.name || "Unnamed"}</strong>
<span> - Type: {instrument.instrument_type}</span>
<span> - Enabled: {instrument.enabled ? "Yes" : "No"}</span>
{instrument.instrument_type === "PAYMENT_CARD" &&
instrument.card_brand && (
<span> - Brand: {instrument.card_brand}</span>
)}
</li>
))}
</ul>
</section>
)}
{/* Orders Section */}
{orders.length > 0 && (
<section>
<h3>Customer Orders</h3>
<ul>
{orders.map((order) => (
<li key={order.id}>
<strong>Order ID:</strong> {order.id}
<span> - Status: {order.status}</span>
<span> - Amount: ${(order.total_amount / 100).toFixed(2)}</span>
<span>
{" "}
- Date: {new Date(order.created_at).toLocaleDateString()}
</span>
</li>
))}
</ul>
</section>
)}
{/* All Customers Section */}
<section>
<h3>All Customers</h3>
<button onClick={loadAllCustomers} disabled={loading}>
{loading ? "Loading..." : "Load All Customers"}
</button>
{customers.length > 0 && (
<ul>
{customers.map((cust) => (
<li key={cust.id}>
<button onClick={() => loadCustomer(cust.id)}>
{cust.first_name} {cust.last_name} ({cust.email})
</button>
</li>
))}
</ul>
)}
</section>
</div>
);
}
export default CustomerManager;
API Methods
createCustomer
Creates a new customer in the system.
const result = await createCustomer({
first_name: string;
last_name: string;
email: string;
phone?: string;
personal_address?: {
line1: string;
line2?: string;
city: string;
state: string;
postal_code: string;
country: string;
};
tags?: Record<string, unknown>;
});
Response: ApiResponse<CustomerData>
updateCustomer
Updates an existing customer's information.
const result = await updateCustomer(customerId, {
phone?: string;
personal_address?: Partial<Address>;
tags?: Record<string, unknown>;
// Any other customer fields to update
});
Response: ApiResponse<CustomerData>
getCustomer
Retrieves a single customer by ID.
const result = await getCustomer(customerId);
Response: ApiResponse<CustomerData>
getCustomers
Retrieves a list of all customers with pagination.
const result = await getCustomers({
limit?: number; // Default: 20
offset?: number; // Default: 0
});
Response: ApiResponse<CustomerData[]>
getCustomerPaymentInstruments
Retrieves all payment instruments for a specific customer.
const result = await getCustomerPaymentInstruments(customerId);
Response: ApiResponse<PaymentInstrumentData[]>
getCustomerOrders
Retrieves all orders for a specific customer with pagination.
const result = await getCustomerOrders(customerId, {
limit?: number; // Default: 20
offset?: number; // Default: 0
});
Response: ApiResponse<OrderData[]>
Key Features
Tags and Metadata
Customers support custom tags for organizing and tracking additional information:
await createCustomer({
first_name: "John",
last_name: "Doe",
email: "[email protected]",
tags: {
source: "website",
campaign: "spring-sale-2024",
customer_type: "premium",
referral_code: "FRIEND20",
},
});
Address Management
Store customer addresses for billing and shipping:
await updateCustomer(customerId, {
personal_address: {
line1: "123 Main St",
line2: "Apt 4B",
city: "New York",
state: "NY",
postal_code: "10001",
country: "US",
},
});
Pagination
When retrieving lists of customers or orders, use pagination for better performance:
// Get first page
const page1 = await getCustomers({ limit: 20, offset: 0 });
// Get second page
const page2 = await getCustomers({ limit: 20, offset: 20 });
// Get third page
const page3 = await getCustomers({ limit: 20, offset: 40 });
Best Practices
-
Always handle errors: Wrap API calls in try-catch blocks to handle network errors and API failures gracefully.
-
Use loading states: Provide feedback to users while API calls are in progress.
-
Validate input: Validate customer data before sending it to the API.
-
Store customer IDs: Keep track of customer IDs for future operations like creating payment instruments or processing payments.
-
Use tags wisely: Leverage tags to add custom metadata that's specific to your business needs.
-
Paginate large lists: When dealing with many customers, use pagination to improve performance and user experience.
Error Handling
try {
const result = await createCustomer({
first_name: "Jane",
last_name: "Doe",
email: "[email protected]",
});
console.log("Success:", result.data);
} catch (error) {
if (error instanceof Error) {
// Handle specific error cases
if (error.message.includes("email")) {
console.error("Invalid email address");
} else if (error.message.includes("API request failed")) {
console.error("Server error, please try again");
} else {
console.error("Unexpected error:", error.message);
}
}
}