@warriorteam/redai-zalo-sdk
Version:
Comprehensive TypeScript/JavaScript SDK for Zalo APIs - Official Account v3.0, ZNS with Full Type Safety, Consultation Service, Broadcast Service, Group Messaging with List APIs, Social APIs, Enhanced Article Management, Promotion Service v3.0 with Multip
231 lines • 10 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransactionService = void 0;
const common_1 = require("../types/common");
/**
* Service xử lý các API tin nhắn giao dịch của Zalo Official Account
*
* ĐIỀU KIỆN GỬI TIN GIAO DỊCH:
*
* 1. THỜI GIAN GỬI:
* - Chỉ được gửi trong vòng 24 giờ kể từ khi người dùng tương tác cuối cùng với OA
* - Tương tác bao gồm: gửi tin nhắn, nhấn button, gọi điện, truy cập website từ OA
*
* 2. NỘI DUNG TIN NHẮN:
* - Phải liên quan trực tiếp đến giao dịch thực tế
* - Bao gồm: xác nhận đơn hàng, thông báo thanh toán, cập nhật trạng thái giao hàng
* - Không được chứa nội dung quảng cáo, khuyến mãi
*
* 3. TẦN SUẤT GỬI:
* - Tối đa 3 tin nhắn giao dịch/ngày cho mỗi người dùng
* - Phải có khoảng cách ít nhất 1 giờ giữa các tin nhắn
*
* 4. ĐỊNH DẠNG:
* - Phải sử dụng template được Zalo phê duyệt trước
* - Template phải tuân thủ format chuẩn của tin giao dịch
*
* 5. NGƯỜI DÙNG:
* - Người dùng phải đã follow OA
* - Người dùng không được block OA
* - Người dùng phải có tương tác gần đây với OA
*
* 6. OFFICIAL ACCOUNT:
* - OA phải được xác minh (verified)
* - OA phải có quyền gửi tin giao dịch được Zalo cấp phép
* - OA không được vi phạm chính sách của Zalo
*
* LỖI THƯỜNG GẶP:
* - 1004: Người dùng chưa follow OA hoặc đã unfollow
* - 1005: Vượt quá thời gian 24 giờ từ lần tương tác cuối
* - 1006: Vượt quá giới hạn 3 tin/ngày
* - 1007: Template chưa được phê duyệt hoặc không hợp lệ
* - 1008: Nội dung tin nhắn vi phạm chính sách
*/
class TransactionService {
constructor(client) {
this.client = client;
this.transactionApiUrl = "https://openapi.zalo.me/v2.0/oa/message/transaction";
}
/**
* Gửi tin nhắn giao dịch
* @param accessToken Access token của Official Account
* @param recipient Thông tin người nhận
* @param message Nội dung tin nhắn giao dịch
* @returns Thông tin tin nhắn đã gửi
*/
async sendTransactionMessage(accessToken, recipient, message) {
try {
// Validate transaction message
this.validateTransactionMessage(message);
const request = {
recipient,
message,
};
const result = await this.client.apiPost(this.transactionApiUrl, accessToken, request);
if (result.error !== 0) {
throw new common_1.ZaloSDKError(result.message || "Failed to send transaction message", result.error, result);
}
if (!result.data) {
throw new common_1.ZaloSDKError("No response data received", -1);
}
return result.data;
}
catch (error) {
if (error instanceof common_1.ZaloSDKError) {
throw error;
}
throw new common_1.ZaloSDKError(`Failed to send transaction message: ${error.message}`, -1, error);
}
}
/**
* Gửi tin nhắn xác nhận đơn hàng
* @param accessToken Access token của Official Account
* @param recipient Thông tin người nhận
* @param orderInfo Thông tin đơn hàng
* @returns Thông tin tin nhắn đã gửi
*/
async sendOrderConfirmation(accessToken, recipient, orderInfo) {
try {
const message = {
type: "transaction",
attachment: {
type: "template",
payload: {
template_type: "transaction",
elements: [
{
title: `Xác nhận đơn hàng #${orderInfo.orderId}`,
subtitle: `Ngày đặt: ${orderInfo.orderDate}`,
default_action: {
type: "web_url",
url: `https://example.com/orders/${orderInfo.orderId}`,
},
buttons: [
{
type: "web_url",
title: "Xem chi tiết",
url: `https://example.com/orders/${orderInfo.orderId}`,
},
],
},
],
},
},
};
return this.sendTransactionMessage(accessToken, recipient, message);
}
catch (error) {
throw new common_1.ZaloSDKError(`Failed to send order confirmation: ${error.message}`, -1, error);
}
}
/**
* Gửi tin nhắn thông báo thanh toán
* @param accessToken Access token của Official Account
* @param recipient Thông tin người nhận
* @param paymentInfo Thông tin thanh toán
* @returns Thông tin tin nhắn đã gửi
*/
async sendPaymentNotification(accessToken, recipient, paymentInfo) {
try {
const statusText = {
success: "Thành công",
failed: "Thất bại",
pending: "Đang xử lý",
};
const message = {
type: "transaction",
attachment: {
type: "template",
payload: {
template_type: "transaction",
elements: [
{
title: `Thông báo thanh toán - ${statusText[paymentInfo.status]}`,
subtitle: `Đơn hàng #${paymentInfo.orderId} - ${paymentInfo.amount.toLocaleString("vi-VN")} VNĐ`,
default_action: {
type: "web_url",
url: `https://example.com/payments/${paymentInfo.orderId}`,
},
buttons: [
{
type: "web_url",
title: "Xem chi tiết",
url: `https://example.com/payments/${paymentInfo.orderId}`,
},
],
},
],
},
},
};
return this.sendTransactionMessage(accessToken, recipient, message);
}
catch (error) {
throw new common_1.ZaloSDKError(`Failed to send payment notification: ${error.message}`, -1, error);
}
}
/**
* Gửi tin nhắn cập nhật trạng thái giao hàng
* @param accessToken Access token của Official Account
* @param recipient Thông tin người nhận
* @param shippingInfo Thông tin giao hàng
* @returns Thông tin tin nhắn đã gửi
*/
async sendShippingUpdate(accessToken, recipient, shippingInfo) {
try {
const statusText = {
preparing: "Đang chuẩn bị hàng",
shipped: "Đã giao cho đơn vị vận chuyển",
in_transit: "Đang vận chuyển",
delivered: "Đã giao hàng thành công",
};
const message = {
type: "transaction",
attachment: {
type: "template",
payload: {
template_type: "transaction",
elements: [
{
title: `Cập nhật giao hàng - ${statusText[shippingInfo.status]}`,
subtitle: `Đơn hàng #${shippingInfo.orderId} - Mã vận đơn: ${shippingInfo.trackingNumber}`,
default_action: {
type: "web_url",
url: `https://example.com/tracking/${shippingInfo.trackingNumber}`,
},
buttons: [
{
type: "web_url",
title: "Theo dõi đơn hàng",
url: `https://example.com/tracking/${shippingInfo.trackingNumber}`,
},
],
},
],
},
},
};
return this.sendTransactionMessage(accessToken, recipient, message);
}
catch (error) {
throw new common_1.ZaloSDKError(`Failed to send shipping update: ${error.message}`, -1, error);
}
}
/**
* Validate transaction message format
* @param message Transaction message to validate
*/
validateTransactionMessage(message) {
if (!message.attachment) {
throw new common_1.ZaloSDKError("Transaction message must have attachment", -1);
}
if (!message.attachment.payload) {
throw new common_1.ZaloSDKError("Transaction message attachment must have payload", -1);
}
if (message.attachment.payload.template_type !== "transaction") {
throw new common_1.ZaloSDKError("Transaction message must use transaction template type", -1);
}
}
}
exports.TransactionService = TransactionService;
//# sourceMappingURL=transaction.service.js.map