Tóm tắt
API Magento 2 (Adobe Commerce) cho phép tích hợp lập trình với các cửa hàng thương mại điện tử qua REST, SOAP, GraphQL với xác thực OAuth 1.0a và token. Bạn có thể truy cập sản phẩm, đơn hàng, khách hàng, kho hàng, v.v. với giới hạn tốc độ cấu hình. Bài hướng dẫn này tập trung vào cài đặt xác thực, thao tác CRUD, webhooks, điểm cuối tùy chỉnh và các chiến lược triển khai thực tế.
Giới thiệu
Adobe Commerce (Magento) vận hành hơn 250.000 cửa hàng thương mại điện tử, xử lý hơn 155 tỷ USD hàng năm. Đối với dev xây dựng tích hợp, ERP hoặc app di động, API Magento là công cụ thiết yếu để tự động hóa đồng bộ sản phẩm, đơn hàng, kho và dữ liệu khách hàng—giúp loại bỏ hàng chục giờ nhập liệu thủ công mỗi tuần.
Bài này hướng dẫn bạn toàn bộ quy trình tích hợp API Magento 2: xác thực OAuth 1.0a và token, sử dụng REST/SOAP/GraphQL, quản lý sản phẩm và đơn hàng, webhooks, phát triển API tùy chỉnh và triển khai sản xuất sẵn sàng.
💡 Apidog đơn giản hóa kiểm thử tích hợp API Magento: kiểm thử endpoint, xác thực luồng xác thực, kiểm tra phản hồi, debug lỗi, nhập spec API, mô phỏng response, chia sẻ kịch bản test với nhóm.
API Magento 2 là gì?
Magento 2 cung cấp 3 loại API:
- REST API: JSON, phù hợp web/app di động
- SOAP API: XML, dùng cho tích hợp doanh nghiệp
- GraphQL: Query-based, tối ưu frontend hiện đại
Các API cho phép thao tác:
- Sản phẩm, danh mục, kho
- Đơn hàng, hóa đơn, lô hàng
- Khách hàng, nhóm khách hàng
- Giỏ hàng, thanh toán
- Khuyến mãi, quy tắc giá
- Trang, block CMS
- Cấu hình cửa hàng
Các tính năng chính
| Tính năng | Mô tả |
|---|---|
| Nhiều giao thức | REST, SOAP, GraphQL |
| OAuth 1.0a | Truy cập an toàn bên thứ ba |
| Xác thực token | Token quản trị/tích hợp |
| Webhooks | Hoạt động bất đồng bộ qua hàng đợi |
| Giới hạn tốc độ | Cấu hình theo từng instance |
| Điểm cuối tùy chỉnh | Mở rộng API |
| Đa cửa hàng | Một API, nhiều store view |
So sánh API
| Loại API | Giao thức | Trường hợp sử dụng |
|---|---|---|
| REST | JSON | App di động, tích hợp |
| SOAP | XML | Doanh nghiệp (SAP, Oracle, ...) |
| GraphQL | GraphQL | Frontend, PWA |
Các phiên bản Magento
| Phiên bản | Trạng thái | Hết hỗ trợ |
|---|---|---|
| Magento 2.4.x | Hiện hành | Đang hoạt động |
| Adobe Commerce 2.4.x | Hiện hành | Đang hoạt động |
| Magento 1.x | Đã hết vòng đời | 06/2020 (Không sử dụng nữa) |
Bắt đầu: Thiết lập xác thực
Bước 1: Tạo tài khoản quản trị hoặc tích hợp
- Đăng nhập Magento Admin
- Đi tới System > Permissions > All Users
- Tạo user quản trị (token admin) HOẶC
- Vào System > Extensions > Integrations
- Tạo tích hợp mới (cho OAuth)
Bước 2: Chọn phương thức xác thực
| Phương thức | Tốt nhất cho | Thời gian sống token |
|---|---|---|
| Token quản trị | Tích hợp nội bộ | Cấu hình (mặc định 4h) |
| Token tích hợp | App bên thứ ba | Đến khi thu hồi |
| OAuth 1.0a | App marketplace | Đến khi thu hồi |
| Token khách hàng | App hướng khách hàng | Cấu hình |
Bước 3: Lấy token quản trị
const MAGENTO_BASE_URL = process.env.MAGENTO_BASE_URL;
const MAGENTO_ADMIN_USERNAME = process.env.MAGENTO_ADMIN_USERNAME;
const MAGENTO_ADMIN_PASSWORD = process.env.MAGENTO_ADMIN_PASSWORD;
const getAdminToken = async () => {
const response = await fetch(`${MAGENTO_BASE_URL}/rest/V1/integration/admin/token`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
username: MAGENTO_ADMIN_USERNAME,
password: MAGENTO_ADMIN_PASSWORD
})
});
if (!response.ok) throw new Error('Invalid admin credentials');
const token = await response.text();
return token;
};
// Sử dụng
const token = await getAdminToken();
console.log(`Admin token: ${token}`);
Lưu ý bảo mật: Lưu token vào biến môi trường hoặc kho an toàn.
# .env file
MAGENTO_BASE_URL="https://store.example.com"
MAGENTO_ADMIN_USERNAME="api_user"
MAGENTO_ADMIN_PASSWORD="secure_password_here"
MAGENTO_ACCESS_TOKEN="obtained_via_auth"
Bước 4: Tạo tích hợp (bên thứ ba)
- Vào System > Extensions > Integrations
- Click Add New Integration
- Điền:
- Tên: “My Integration”
- Email, Callback URL (cho OAuth), Identity Link URL (cho OAuth)
- Đặt API Permissions: chọn quyền cần (nên bật Sản phẩm, Đơn hàng, Khách hàng, Kho hàng)
- Lưu, Activate tích hợp, sao chép Access Token và Token Secret
Bước 5: Lấy token khách hàng
const getCustomerToken = async (email, password) => {
const response = await fetch(`${MAGENTO_BASE_URL}/rest/V1/integration/customer/token`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: email, password: password })
});
if (!response.ok) throw new Error('Invalid customer credentials');
const token = await response.text();
return token;
};
// Sử dụng
const customerToken = await getCustomerToken('customer@example.com', 'password123');
Bước 6: Thực hiện các cuộc gọi API đã xác thực
Tạo client API tái sử dụng:
const magentoRequest = async (endpoint, options = {}) => {
const token = await getAdminToken(); // hoặc lấy token đã lưu
const response = await fetch(`${MAGENTO_BASE_URL}/rest${endpoint}`, {
...options,
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
...options.headers
}
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Magento API Error: ${error.message}`);
}
return response.json();
};
// Sử dụng
const products = await magentoRequest('/V1/products');
console.log(`Found ${products.items.length} products`);
Quản lý sản phẩm
Lấy sản phẩm với bộ lọc
const getProducts = async (filters = {}) => {
const params = new URLSearchParams();
if (filters.search) {
params.append('searchCriteria[filterGroups][0][filters][0][field]', 'sku');
params.append('searchCriteria[filterGroups][0][filters][0][value]', `%${filters.search}%`);
params.append('searchCriteria[filterGroups][0][filters][0][conditionType]', 'like');
}
if (filters.priceFrom) {
params.append('searchCriteria[filterGroups][1][filters][0][field]', 'price');
params.append('searchCriteria[filterGroups][1][filters][0][value]', filters.priceFrom);
params.append('searchCriteria[filterGroups][1][filters][0][conditionType]', 'gteq');
}
params.append('searchCriteria[pageSize]', filters.limit || 20);
params.append('searchCriteria[currentPage]', filters.page || 1);
const response = await magentoRequest(`/V1/products?${params.toString()}`);
return response;
};
// Sử dụng
const products = await getProducts({ search: 'shirt', priceFrom: 20, limit: 50 });
products.items.forEach(product => {
console.log(`${product.sku}: ${product.name} - $${product.price}`);
});
Lấy một sản phẩm theo SKU
const getProduct = async (sku) => {
const response = await magentoRequest(`/V1/products/${sku}`);
return response;
};
// Sử dụng
const product = await getProduct('TSHIRT-001');
console.log(`Name: ${product.name}`);
console.log(`Price: $${product.price}`);
console.log(`Stock: ${product.extension_attributes?.stock_item?.qty}`);
Tạo sản phẩm mới
const createProduct = async (productData) => {
const product = {
product: {
sku: productData.sku,
name: productData.name,
attribute_set_id: productData.attributeSetId || 4,
type_id: 'simple',
price: productData.price,
status: productData.status || 1,
visibility: productData.visibility || 4,
weight: productData.weight || 1,
extension_attributes: {
stock_item: {
qty: productData.qty || 0,
is_in_stock: productData.qty > 0
}
},
custom_attributes: [
{ attribute_code: 'description', value: productData.description },
{ attribute_code: 'short_description', value: productData.shortDescription },
{ attribute_code: 'color', value: productData.color },
{ attribute_code: 'size', value: productData.size }
]
}
};
const response = await magentoRequest('/V1/products', {
method: 'POST',
body: JSON.stringify(product)
});
return response;
};
// Sử dụng
const newProduct = await createProduct({
sku: 'TSHIRT-NEW-001',
name: 'Premium Cotton T-Shirt',
price: 29.99,
qty: 100,
description: 'High-quality cotton t-shirt',
shortDescription: 'Premium cotton tee',
color: 'Blue',
size: 'M'
});
console.log(`Product created: ${newProduct.id}`);
Cập nhật sản phẩm
const updateProduct = async (sku, updates) => {
const product = { product: { sku: sku, ...updates } };
const response = await magentoRequest(`/V1/products/${sku}`, {
method: 'PUT',
body: JSON.stringify(product)
});
return response;
};
// Sử dụng
await updateProduct('TSHIRT-001', {
price: 24.99,
extension_attributes: {
stock_item: { qty: 150, is_in_stock: true }
}
});
Xóa sản phẩm
const deleteProduct = async (sku) => {
await magentoRequest(`/V1/products/${sku}`, { method: 'DELETE' });
console.log(`Product ${sku} deleted`);
};
Các loại sản phẩm
| Loại | Mô tả | Trường hợp sử dụng |
|---|---|---|
| Simple | Một SKU, không biến thể | Sản phẩm cơ bản |
| Configurable | Cha có biến thể con | Kích cỡ/màu sắc |
| Grouped | Bộ sản phẩm đơn giản | Gói sản phẩm |
| Virtual | Không vật lý | Dịch vụ, tải xuống |
| Bundle | Gói tùy chỉnh | Bộ tự lắp |
| Downloadable | Kỹ thuật số | Ebook, phần mềm |
Quản lý đơn hàng
Lấy đơn hàng với bộ lọc
const getOrders = async (filters = {}) => {
const params = new URLSearchParams();
if (filters.status) {
params.append('searchCriteria[filterGroups][0][filters][0][field]', 'status');
params.append('searchCriteria[filterGroups][0][filters][0][value]', filters.status);
params.append('searchCriteria[filterGroups][0][filters][0][conditionType]', 'eq');
}
if (filters.dateFrom) {
params.append('searchCriteria[filterGroups][1][filters][0][field]', 'created_at');
params.append('searchCriteria[filterGroups][1][filters][0][value]', filters.dateFrom);
params.append('searchCriteria[filterGroups][1][filters][0][conditionType]', 'gteq');
}
params.append('searchCriteria[pageSize]', filters.limit || 20);
params.append('searchCriteria[currentPage]', filters.page || 1);
const response = await magentoRequest(`/V1/orders?${params.toString()}`);
return response;
};
// Lấy các đơn hàng đang chờ xử lý từ 7 ngày trước
const orders = await getOrders({
status: 'pending',
dateFrom: '2026-03-18 00:00:00',
limit: 50
});
orders.items.forEach(order => {
console.log(`Order #${order.increment_id}: ${order.customer_email} - $${order.grand_total}`);
});
Lấy một đơn hàng theo ID
const getOrder = async (orderId) => {
const response = await magentoRequest(`/V1/orders/${orderId}`);
return response;
};
// Sử dụng
const order = await getOrder(12345);
console.log(`Order #${order.increment_id}`);
console.log(`Status: ${order.status}`);
console.log(`Total: $${order.grand_total}`);
console.log('Items:');
order.items.forEach(item => {
console.log(` - ${item.name} x ${item.qty_ordered}`);
});
Luồng trạng thái đơn hàng
đang chờ → đang xử lý → hoàn tất
→ đã hủy
→ đang giữ
→ chờ xét duyệt thanh toán
Cập nhật trạng thái đơn hàng
const updateOrderStatus = async (orderId, newStatus) => {
// Hủy đơn
await magentoRequest(`/V1/orders/${orderId}/cancel`, { method: 'POST' });
// Giữ đơn
await magentoRequest(`/V1/orders/${orderId}/hold`, { method: 'POST' });
// Bỏ giữ
await magentoRequest(`/V1/orders/${orderId}/unhold`, { method: 'POST' });
};
Tạo hóa đơn
const createInvoice = async (orderId, items = [], notify = true, appendComment = false, comment = null) => {
const invoice = {
capture: true,
last: true,
items: items
};
if (comment) {
invoice.comment = comment;
invoice.notify_customer = notify ? 1 : 0;
invoice.append_comment = appendComment ? 1 : 0;
}
const response = await magentoRequest(`/V1/order/${orderId}/invoice`, {
method: 'POST',
body: JSON.stringify(invoice)
});
return response;
};
// Sử dụng
const invoiceId = await createInvoice(12345, [], true, false, 'Thank you for your order!');
console.log(`Invoice created: ${invoiceId}`);
Tạo lô hàng
const createShipment = async (orderId, items = [], notify = true, appendComment = false, comment = null, tracks = []) => {
const shipment = {
items: items,
notify: notify ? 1 : 0,
append_comment: appendComment ? 1 : 0,
comment: comment,
tracks: tracks
};
const response = await magentoRequest(`/V1/order/${orderId}/ship`, {
method: 'POST',
body: JSON.stringify(shipment)
});
return response;
};
// Sử dụng
const shipmentId = await createShipment(12345, [], true, false, 'Your order has shipped!', [
{
track_number: '1Z999AA10123456784',
title: 'Tracking Number',
carrier_code: 'ups'
}
]);
console.log(`Shipment created: ${shipmentId}`);
Quản lý khách hàng
Lấy khách hàng
const getCustomers = async (filters = {}) => {
const params = new URLSearchParams();
if (filters.email) {
params.append('searchCriteria[filterGroups][0][filters][0][field]', 'email');
params.append('searchCriteria[filterGroups][0][filters][0][value]', filters.email);
params.append('searchCriteria[filterGroups][0][filters][0][conditionType]', 'eq');
}
params.append('searchCriteria[pageSize]', filters.limit || 20);
const response = await magentoRequest(`/V1/customers/search?${params.toString()}`);
return response;
};
// Sử dụng
const customers = await getCustomers({ email: 'customer@example.com' });
customers.items.forEach(customer => {
console.log(`${customer.firstname} ${customer.lastname} - ${customer.email}`);
});
Tạo khách hàng
const createCustomer = async (customerData) => {
const customer = {
customer: {
websiteId: customerData.websiteId || 1,
email: customerData.email,
firstname: customerData.firstname,
lastname: customerData.lastname,
middlename: customerData.middlename || '',
gender: customerData.gender || 0,
store_id: customerData.storeId || 0,
extension_attributes: {
is_subscribed: customerData.subscribed || false
}
},
password: customerData.password
};
const response = await magentoRequest('/V1/customers', {
method: 'POST',
body: JSON.stringify(customer)
});
return response;
};
// Sử dụng
const newCustomer = await createCustomer({
email: 'newcustomer@example.com',
firstname: 'John',
lastname: 'Doe',
password: 'SecurePass123!',
subscribed: true
});
console.log(`Customer created: ID ${newCustomer.id}`);
Quản lý kho hàng (MSI)
Lấy trạng thái kho hàng
const getStockStatus = async (sku) => {
const response = await magentoRequest(`/V1/products/${sku}/stockItems/1`);
return response;
};
// Sử dụng
const stock = await getStockStatus('TSHIRT-001');
console.log(`Qty: ${stock.qty}`);
console.log(`In Stock: ${stock.is_in_stock}`);
console.log(`Min Qty: ${stock.min_qty}`);
Cập nhật kho hàng
const updateStock = async (sku, qty, isInStock = null) => {
const stockItem = {
stockItem: {
qty: qty,
is_in_stock: isInStock !== null ? isInStock : qty > 0
}
};
const response = await magentoRequest(`/V1/products/${sku}/stockItems/1`, {
method: 'PUT',
body: JSON.stringify(stockItem)
});
return response;
};
// Sử dụng
await updateStock('TSHIRT-001', 100, true);
Webhooks và hoạt động bất đồng bộ
Thiết lập Webhooks
Magento không hỗ trợ webhooks gốc. Thay vào đó, bạn có thể:
- Thăm dò endpoint đơn hàng định kỳ:
const pollNewOrders = async (lastOrderId) => {
const orders = await getOrders({ dateFrom: new Date().toISOString() });
const newOrders = orders.items.filter(o => o.id > lastOrderId);
return newOrders;
};
- Sử dụng Adobe I/O Events (chỉ Adobe Commerce)
- Tự xây dựng module webhook: Hướng dẫn message queue
Giới hạn tốc độ
Hiểu về giới hạn tốc độ
- Mặc định: Không giới hạn, có thể cấu hình trong Admin
- Khuyến nghị: 100–1000 requests/phút
Cấu hình tại: Stores > Configuration > Services > Web API > Security
Xử lý giới hạn tốc độ
const makeRateLimitedRequest = async (endpoint, options = {}, maxRetries = 3) => {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await magentoRequest(endpoint, options);
return response;
} catch (error) {
if (error.message.includes('429') && attempt < maxRetries) {
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
} else {
throw error;
}
}
}
};
Danh sách kiểm tra triển khai sản xuất
- [ ] Dùng token tích hợp (không dùng tài khoản admin) ở môi trường production
- [ ] Lưu trữ token an toàn (DB mã hóa)
- [ ] Thực hiện giới hạn tốc độ, xếp hàng request
- [ ] Xử lý lỗi toàn diện
- [ ] Ghi log toàn bộ API call
- [ ] Có giải pháp webhook thay thế (polling hoặc Adobe I/O)
- [ ] Kiểm thử với dữ liệu thật
- [ ] Retry tự động khi request lỗi
Các trường hợp sử dụng thực tế
Tích hợp ERP
- Thách thức: Kho phải đồng bộ thủ công giữa ERP và Magento
- Giải pháp: Tích hợp API hai chiều mỗi 15 phút
- Kết quả: Kho real-time, không over-sell
Ứng dụng di động
- Thách thức: Cần trải nghiệm native tốt
- Giải pháp: API GraphQL duyệt sản phẩm, REST cho thanh toán
- Kết quả: Tăng 40% chuyển đổi mobile
Kết luận
Magento 2 API cung cấp đầy đủ công cụ thương mại điện tử:
- REST, SOAP, GraphQL endpoint
- Xác thực token cho tích hợp
- CRUD đủ cho sản phẩm, đơn hàng, khách hàng
- MSI quản lý kho nâng cao
- Giới hạn tốc độ cấu hình linh hoạt
- Apidog tối ưu kiểm thử API & cộng tác nhóm
Phần hỏi đáp
Làm cách nào để xác thực với API Magento?
Sử dụng token quản trị cho tích hợp nội bộ hoặc tạo Integration trong System > Extensions (cho OAuth). Token khách hàng cho app hướng khách.
Sự khác biệt giữa REST và GraphQL trong Magento là gì?
REST hỗ trợ đủ CRUD; GraphQL tối ưu cho frontend truy vấn nhanh, linh hoạt.
Làm cách nào để tạo sản phẩm qua API?
Gửi POST tới /V1/products với JSON sản phẩm gồm SKU, tên, giá, stock_item trong extension_attributes.
Tôi có thể nhận webhooks cho các đơn hàng mới không?
Magento không hỗ trợ webhooks gốc. Sử dụng polling, Adobe I/O Events (Adobe Commerce) hoặc module custom.
Làm cách nào để cập nhật số lượng kho hàng?
Gửi PUT tới /V1/products/{sku}/stockItems/1 với trường qty và is_in_stock.
Top comments (0)