Skip to main content

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

  1. Always handle errors: Wrap API calls in try-catch blocks to handle network errors and API failures gracefully.

  2. Use loading states: Provide feedback to users while API calls are in progress.

  3. Validate input: Validate customer data before sending it to the API.

  4. Store customer IDs: Keep track of customer IDs for future operations like creating payment instruments or processing payments.

  5. Use tags wisely: Leverage tags to add custom metadata that's specific to your business needs.

  6. 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);
}
}
}

Next Steps