@subiz/widget-v4 4.1.202 → 4.1.204

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/api.md +1224 -0
  2. package/compiled_src/chatbox/ChatButton.js +19 -16
  3. package/compiled_src/chatbox/MessageInput.js +1 -0
  4. package/compiled_src/chatbox/main.js +28 -3
  5. package/compiled_src/lib.js +14 -0
  6. package/compiled_src/store/api.js +36 -4
  7. package/compiled_src/store/store.js +20 -4
  8. package/compiled_src/util/event.test.js +38 -0
  9. package/dist/19e1c4525c1.app.js +1 -0
  10. package/dist/{19d8a41ce33.chat.html → 19e1c4525c1.chat.html} +1 -1
  11. package/dist/19e1c4525c1.chat.js +1 -0
  12. package/dist/{19d8a41ce33.form.html → 19e1c4525c1.form.html} +1 -1
  13. package/dist/19e1c4525c1.form.js +1 -0
  14. package/dist/{19d8a41ce33.index.html → 19e1c4525c1.index.html} +1 -1
  15. package/dist/{19d8a41ce33.library.html → 19e1c4525c1.library.html} +1 -1
  16. package/dist/19e1c4525c1.library.js +1 -0
  17. package/dist/{19d8a41ce33.preview.html → 19e1c4525c1.preview.html} +1 -1
  18. package/dist/19e1c4525c1.preview.js +1 -0
  19. package/dist/19e1c4525c1.webview.js +1 -0
  20. package/dist/HASH +1 -1
  21. package/dist/screenshoot.js +104 -22
  22. package/package.json +8 -8
  23. package/src/chatbox/ChatButton.js +20 -15
  24. package/src/chatbox/MessageInput.js +1 -0
  25. package/src/chatbox/main.js +24 -4
  26. package/src/lib.js +14 -0
  27. package/src/store/api.js +41 -3
  28. package/src/store/store.js +28 -19
  29. package/src/util/event.test.js +31 -0
  30. package/dist/19d8a41ce33.app.js +0 -1
  31. package/dist/19d8a41ce33.chat.js +0 -1
  32. package/dist/19d8a41ce33.form.js +0 -1
  33. package/dist/19d8a41ce33.library.js +0 -1
  34. package/dist/19d8a41ce33.preview.js +0 -1
  35. package/dist/19d8a41ce33.webview.js +0 -1
  36. package/examples/track.js +0 -41
  37. /package/dist/{19d8a41ce33.127.js → 19e1c4525c1.127.js} +0 -0
  38. /package/dist/{19d8a41ce33.132.js → 19e1c4525c1.132.js} +0 -0
  39. /package/dist/{19d8a41ce33.185.js → 19e1c4525c1.185.js} +0 -0
  40. /package/dist/{19d8a41ce33.27.js → 19e1c4525c1.27.js} +0 -0
  41. /package/dist/{19d8a41ce33.278.js → 19e1c4525c1.278.js} +0 -0
  42. /package/dist/{19d8a41ce33.339.js → 19e1c4525c1.339.js} +0 -0
  43. /package/dist/{19d8a41ce33.459.js → 19e1c4525c1.459.js} +0 -0
  44. /package/dist/{19d8a41ce33.490.js → 19e1c4525c1.490.js} +0 -0
  45. /package/dist/{19d8a41ce33.74.js → 19e1c4525c1.74.js} +0 -0
  46. /package/dist/{19d8a41ce33.997.js → 19e1c4525c1.997.js} +0 -0
package/api.md ADDED
@@ -0,0 +1,1224 @@
1
+ # Subiz CDP Event API
2
+
3
+ Tài liệu này hướng dẫn website gửi sự kiện người dùng về Subiz CDP bằng client library đã được cài trên website.
4
+
5
+ ## Tổng quan
6
+
7
+ API chính để gửi sự kiện là:
8
+
9
+ ```js
10
+ subiz('event', 'product_viewed', {
11
+ product_id: 'pd2345',
12
+ sku: 's5345',
13
+ name: 'Bàn phím cơ không dây',
14
+ price: 1500000,
15
+ currency: 'VND',
16
+ })
17
+ ```
18
+
19
+ `subiz('event', ...)` trả về `Promise`.
20
+
21
+ ```js
22
+ subiz('event', 'add_to_cart', {
23
+ product_id: 'pd2345',
24
+ sku: 's5345',
25
+ quantity: 1,
26
+ price: 1500000,
27
+ currency: 'VND',
28
+ }).then(function (result) {
29
+ console.log('Đã gửi event', result)
30
+ }).catch(function (error) {
31
+ console.error('Không gửi được event', error)
32
+ })
33
+ ```
34
+
35
+ ## Cấu trúc event
36
+
37
+ ```js
38
+ subiz('event', 'event_name', {}, {event_source_id: 'evt_1234'})
39
+ ```
40
+
41
+ Chữ ký:
42
+
43
+ ```js
44
+ subiz('event', type, payload, options)
45
+ ```
46
+
47
+ | Tham số | Bắt buộc | Mô tả |
48
+ | --- | --- | --- |
49
+ | `type` | Có | Tên sự kiện. Dùng `snake_case`, chỉ gồm chữ thường, số và `_`, tối đa 64 ký tự. |
50
+ | `payload` | Không | Dữ liệu chi tiết của event. Giá trị là object JSON. |
51
+ | `options.event_source_id` | Không | ID duy nhất của event ở hệ thống của website, dùng để chống gửi trùng. |
52
+ | `options.event_time` | Không | Thời điểm event thực sự xảy ra. Dùng ISO 8601 có timezone, ví dụ `2026-05-23T10:30:00+07:00` hoặc `2026-05-23T03:30:00Z`. Nếu không gửi, Subiz dùng thời điểm nhận event. |
53
+
54
+ Ví dụ chống trùng event:
55
+
56
+ ```js
57
+ subiz('event', 'content_viewed', {
58
+ url: 'https://example.com/products/pd2345',
59
+ title: 'Bàn phím cơ không dây',
60
+ }, {event_source_id: 'evt_1234'})
61
+ ```
62
+
63
+ Ví dụ gửi event xảy ra trước thời điểm gửi:
64
+
65
+ ```js
66
+ subiz('event', 'order_completed', {
67
+ order_id: 'ord_99482',
68
+ total: 3000000,
69
+ currency: 'VND',
70
+ }, {
71
+ event_source_id: 'order_completed_ord_99482',
72
+ event_time: '2026-05-23T10:30:00+07:00',
73
+ })
74
+ ```
75
+
76
+ ## Chuẩn dữ liệu payload
77
+
78
+ `payload` phải là object JSON và chỉ nên chứa dữ liệu cần thiết để phân tích, chăm sóc khách hàng hoặc cá nhân hóa trải nghiệm.
79
+
80
+ Quy ước kiểu dữ liệu:
81
+
82
+ | Kiểu dữ liệu | Quy ước |
83
+ | --- | --- |
84
+ | String | Dùng UTF-8. Tránh gửi string quá dài; với nội dung tự do như message/comment, chỉ gửi khi thực sự cần cho nghiệp vụ. |
85
+ | Number | Dùng number JSON, không gửi số dưới dạng string nếu cần tính toán hoặc lọc theo khoảng. |
86
+ | Boolean | Dùng `true` hoặc `false`. |
87
+ | Date | Dùng chuỗi ngày ISO 8601 dạng `YYYY-MM-DD`, ví dụ `2026-05-23`. |
88
+ | Date-time | Dùng ISO 8601 có timezone, ví dụ `2026-05-23T10:30:00+07:00` hoặc `2026-05-23T03:30:00Z`. Nên ưu tiên UTC (`Z`) nếu hệ thống nguồn có thể xuất UTC. |
89
+ | Currency | Dùng mã tiền tệ ISO 4217 viết hoa, ví dụ `VND`, `USD`, `EUR`, `JPY`. |
90
+ | Amount | Dùng số theo đơn vị tiền thực tế, không dùng minor unit. Ví dụ `1500000` cho 1.500.000 VND và `19.99` cho 19.99 USD. |
91
+ | Object | Có thể lồng object, nhưng nên giữ cấu trúc nông và ổn định. Không gửi DOM node, class instance, function hoặc object có vòng lặp tham chiếu. |
92
+ | Array | Dùng cho danh sách cùng kiểu dữ liệu, ví dụ `items`. Mỗi item nên có schema ổn định giữa các lần gửi. |
93
+ | `null` | Chỉ dùng khi muốn thể hiện field có chủ đích nhưng chưa có giá trị. Nếu field không liên quan hoặc không có dữ liệu, nên bỏ field đó khỏi `payload`. |
94
+
95
+ Giới hạn khuyến nghị:
96
+
97
+ - `payload` nên nhỏ hơn 32 KB sau khi JSON stringify.
98
+ - Một event không nên gửi quá 100 item trong array. Với đơn hàng lớn, gửi các field tổng hợp trên event chính và đồng bộ chi tiết bằng luồng backend riêng nếu cần.
99
+ - Object lồng nhau không nên sâu quá 5 cấp.
100
+ - Tên field nên dùng `snake_case`, chỉ gồm chữ thường, số và `_`.
101
+ - Không dùng field có kiểu dữ liệu thay đổi giữa các event cùng loại, ví dụ lúc là string, lúc là object.
102
+
103
+ Xử lý dữ liệu cá nhân:
104
+
105
+ - Không gửi mật khẩu, OTP, token đăng nhập, refresh token, cookie, số thẻ thanh toán, CVV hoặc dữ liệu nhạy cảm không cần thiết.
106
+ - Nếu cần gửi email hoặc số điện thoại để định danh, chỉ gửi khi website đã có quyền sử dụng dữ liệu đó.
107
+ - Nếu chỉ cần phân tích mà không cần định danh trực tiếp, nên hash hoặc mask dữ liệu trước khi gửi. Ví dụ gửi `email_hash` thay vì `email`, hoặc `phone_masked: '******8935'` thay vì số điện thoại đầy đủ.
108
+ - Không gửi toàn bộ địa chỉ nếu chỉ cần phân tích theo vùng; ưu tiên các field ít nhạy cảm hơn như `province`, `city`, `country`.
109
+
110
+ ## Quy ước đặt tên
111
+
112
+ Tên event nên mô tả hành động đã xảy ra, ở dạng quá khứ hoặc trạng thái hoàn tất.
113
+
114
+ Nên dùng:
115
+
116
+ ```txt
117
+ product_viewed
118
+ product_searched
119
+ add_to_cart
120
+ checkout_started
121
+ order_completed
122
+ form_submitted
123
+ ```
124
+
125
+ Không nên dùng:
126
+
127
+ ```txt
128
+ ProductViewed
129
+ productViewed
130
+ product-viewed
131
+ view product
132
+ ```
133
+
134
+ ## Common fields
135
+
136
+ Subiz tự thu thập một số thông tin ngữ cảnh như URL hiện tại, referrer, thiết bị, trình duyệt, session và nguồn truy cập nếu có thể. Website vẫn có thể gửi các trường này trong `payload` khi muốn override hoặc bổ sung dữ liệu chính xác hơn.
137
+
138
+ Các field thường dùng:
139
+
140
+ | Trường | Mô tả |
141
+ | --- | --- |
142
+ | `url` | URL nơi event xảy ra. |
143
+ | `title` | Tiêu đề trang hoặc tên nội dung. |
144
+ | `referrer` | Trang giới thiệu người dùng tới URL hiện tại. |
145
+ | `utm_source` | UTM source nếu website muốn gửi chủ động. |
146
+ | `utm_medium` | UTM medium. |
147
+ | `utm_campaign` | UTM campaign. |
148
+ | `utm_content` | UTM content. |
149
+ | `utm_term` | UTM term. |
150
+ | `source` | Nguồn nội bộ của website, ví dụ `homepage`, `landing_page`, `email_campaign`. |
151
+
152
+ Ví dụ:
153
+
154
+ ```js
155
+ subiz('event', 'product_viewed', {
156
+ product_id: 'pd2345',
157
+ name: 'Bàn phím cơ không dây',
158
+ url: 'https://example.com/products/pd2345',
159
+ utm_campaign: 'summer_2026',
160
+ })
161
+ ```
162
+
163
+ ## Dữ liệu cá nhân
164
+
165
+ Chỉ gửi các thông tin cần thiết cho mục đích chăm sóc khách hàng, phân tích hành vi và cá nhân hóa trải nghiệm. Không gửi mật khẩu, mã OTP, thông tin thẻ thanh toán, token đăng nhập hoặc dữ liệu nhạy cảm không cần thiết vào `payload`.
166
+
167
+ Các field như `email`, `phone`, `fullname`, `customer_id`, `user_id` có thể được gửi khi website đã có quyền sử dụng dữ liệu đó trong hệ thống của mình.
168
+
169
+ ## Định danh khách hàng
170
+
171
+ ## Pageview
172
+
173
+ Dùng `pageview` khi website muốn ghi nhận lượt xem trang thủ công, đặc biệt trong Single Page App khi URL thay đổi nhưng browser không reload trang.
174
+
175
+ ```js
176
+ subiz('pageview', {
177
+ url: 'https://example.com/blog/cdp-architecture',
178
+ title: 'CDP Architecture',
179
+ referrer: 'https://google.com',
180
+ })
181
+ ```
182
+
183
+ `pageview` là wrapper của event `content_viewed`. Website nên dùng `subiz('pageview', ...)` thay vì tự gửi `content_viewed` cho các lượt xem trang thông thường.
184
+
185
+ Ví dụ cho Single Page App:
186
+
187
+ ```js
188
+ function onRouteChange(route) {
189
+ subiz('pageview', {
190
+ url: window.location.href,
191
+ title: document.title,
192
+ referrer: document.referrer,
193
+ })
194
+ }
195
+ ```
196
+
197
+ ## Cập nhật thông tin khách hàng
198
+
199
+ ```js
200
+ subiz('event', 'user_updated', {
201
+ email: 'alice@example.com',
202
+ phone: '85345345535',
203
+ fullname: 'Thanh',
204
+ })
205
+ ```
206
+
207
+ ## Thương mại điện tử
208
+
209
+ Các event bên dưới là ví dụ khuyến nghị. Website có thể gửi thêm custom event bằng cùng cấu trúc `subiz('event', type, payload)`.
210
+
211
+ Các field trong ví dụ không bắt buộc toàn bộ. Website nên gửi những field mình có và giữ tên field ổn định giữa các lần gửi. Giá trị tiền tệ dùng số theo đơn vị tiền thực tế, ví dụ `{price: 1500000, currency: 'VND'}`.
212
+
213
+ Quy ước ID:
214
+
215
+ | Trường | Mô tả |
216
+ | --- | --- |
217
+ | `product_id` | ID sản phẩm. Dùng cho event xảy ra trực tiếp trên một sản phẩm và trong từng item của giỏ hàng/đơn hàng. |
218
+ | `sku` | Mã SKU/biến thể sản phẩm nếu có. |
219
+ | `category_id` | ID danh mục sản phẩm. Không dùng `id` để đại diện cho danh mục. |
220
+ | `category_name` | Tên hiển thị của danh mục sản phẩm. |
221
+ | `cart_id` | ID giỏ hàng. Không dùng `id` để đại diện cho giỏ hàng. |
222
+ | `checkout_id` | ID phiên checkout. |
223
+ | `order_id` | ID đơn hàng. Không dùng `id` để đại diện cho đơn hàng. |
224
+ | `return_id` | ID yêu cầu đổi trả. |
225
+ | `refund_id` | ID giao dịch hoàn tiền. |
226
+
227
+ Quy ước tiền tệ:
228
+
229
+ | Trường | Mô tả |
230
+ | --- | --- |
231
+ | `price` | Đơn giá của một sản phẩm hoặc item. |
232
+ | `current_price` | Giá hiện tại của sản phẩm tại thời điểm event xảy ra. |
233
+ | `target_price` | Giá mong muốn khi user đăng ký nhận thông báo giảm giá. |
234
+ | `total` | Tổng tiền của giỏ hàng, checkout, đơn hàng, thanh toán hoặc hóa đơn. |
235
+ | `discount_amount` | Số tiền giảm giá. |
236
+ | `shipping_fee` | Phí vận chuyển. |
237
+ | `refund_amount` | Số tiền hoàn lại. |
238
+ | `estimated_value` | Giá trị ước tính của deal/cơ hội bán hàng. |
239
+ | `renewal_value` | Giá trị hợp đồng khi gia hạn. |
240
+ | `mrr_delta` | Chênh lệch doanh thu định kỳ hàng tháng sau khi nâng/hạ cấp hoặc thêm seat. |
241
+
242
+ Nên ưu tiên các event có thể dùng trực tiếp cho marketing segmentation, funnel và recommendation:
243
+
244
+ | Câu hỏi marketing | Event nên dùng |
245
+ | --- | --- |
246
+ | Sản phẩm nào đang hot trend? | `product_viewed`, `product_searched`, `add_to_wishlist`, `add_to_cart`, `order_completed` |
247
+ | User quan tâm sản phẩm nào nhưng chưa mua? | `product_viewed`, `add_to_wishlist`, `add_to_cart`, `checkout_started`, `order_completed` |
248
+ | User bỏ giỏ hàng? | `add_to_cart`, `checkout_started`; loại trừ user đã có `payment_completed` hoặc `order_completed` cùng `cart_id`/`checkout_id` |
249
+ | Sản phẩm nào có nhu cầu cao nhưng chuyển đổi thấp? | `product_viewed`, `product_inquired`, `add_to_cart`, `order_completed` |
250
+ | Sản phẩm nào đang thiếu hàng nhưng vẫn có nhu cầu? | `back_in_stock_subscribed`, `product_inquired`, `product_viewed` |
251
+ | User nào nhạy cảm với giá? | `price_drop_subscribed`, `coupon_applied`, `add_to_wishlist` |
252
+ | Campaign/coupon nào tạo doanh thu? | `coupon_applied`, `order_completed` |
253
+ | Sản phẩm nào hay bị trả/hủy? | `order_cancelled`, `order_refunded`, `return_requested` |
254
+
255
+ Để query marketing dễ hơn, các event liên quan đến một sản phẩm nên gửi ổn định các field `product_id`, `sku`, `name`, `category`, `brand` trong `payload`. Với `order_completed`, luôn gửi danh sách `items` và mỗi item nên có `product_id`, `sku`, `name`, `category`, `quantity`, `price`.
256
+
257
+ ### Xem sản phẩm
258
+
259
+ ```js
260
+ subiz('event', 'product_viewed', {
261
+ product_id: 'pd2345',
262
+ sku: 's5345',
263
+ name: 'Bàn phím cơ không dây',
264
+ category: 'electronics',
265
+ brand: 'Keychron',
266
+ price: 1500000,
267
+ currency: 'VND',
268
+ })
269
+ ```
270
+
271
+ ### Xem danh mục sản phẩm
272
+
273
+ ```js
274
+ subiz('event', 'product_category_viewed', {
275
+ category_id: 'cat_electronics',
276
+ category_name: 'Electronics',
277
+ url: 'https://example.com/categories/electronics',
278
+ })
279
+ ```
280
+
281
+ ### Xem danh sách sản phẩm
282
+
283
+ ```js
284
+ subiz('event', 'product_list_viewed', {
285
+ list_id: 'homepage_featured',
286
+ list_name: 'Sản phẩm nổi bật',
287
+ category: 'electronics',
288
+ items: [
289
+ {product_id: 'pd2345', sku: 's5345', name: 'Bàn phím cơ không dây', category: 'electronics', position: 1, price: 1500000},
290
+ {product_id: 'pd9876', sku: 's1234', name: 'Chuột không dây', category: 'electronics', position: 2, price: 450000},
291
+ ],
292
+ currency: 'VND',
293
+ })
294
+ ```
295
+
296
+ ### Tìm kiếm sản phẩm
297
+
298
+ ```js
299
+ subiz('event', 'product_searched', {
300
+ keyword: 'bàn phím cơ không dây',
301
+ category_filter: 'electronics',
302
+ sort_by: 'price_asc',
303
+ })
304
+ ```
305
+
306
+ ### Lọc hoặc sắp xếp sản phẩm
307
+
308
+ ```js
309
+ subiz('event', 'product_list_filtered', {
310
+ category: 'electronics',
311
+ filters: {
312
+ brand: ['logitech', 'keychron'],
313
+ price_min: 500000,
314
+ price_max: 2000000,
315
+ },
316
+ sort_by: 'price_asc',
317
+ result_count: 24,
318
+ })
319
+ ```
320
+
321
+ ### Hỏi về sản phẩm
322
+
323
+ ```js
324
+ subiz('event', 'product_inquired', {
325
+ product_id: 'pd2345',
326
+ sku: 's5345',
327
+ name: 'Bàn phím cơ không dây',
328
+ category: 'electronics',
329
+ brand: 'Keychron',
330
+ channel: 'zalo_oa',
331
+ inquiry_type: 'stock_check',
332
+ message: 'Bàn phím này còn sẵn hàng ở kho không shop?',
333
+ has_agent_replied: false,
334
+ agent_id: null,
335
+ })
336
+ ```
337
+
338
+ ### Đăng ký nhận thông báo còn hàng
339
+
340
+ ```js
341
+ subiz('event', 'back_in_stock_subscribed', {
342
+ product_id: 'pd2345',
343
+ sku: 's5345',
344
+ name: 'Bàn phím cơ không dây',
345
+ category: 'electronics',
346
+ brand: 'Keychron',
347
+ price: 1500000,
348
+ currency: 'VND',
349
+ })
350
+ ```
351
+
352
+ ### Đăng ký nhận thông báo giảm giá
353
+
354
+ ```js
355
+ subiz('event', 'price_drop_subscribed', {
356
+ product_id: 'pd2345',
357
+ sku: 's5345',
358
+ name: 'Bàn phím cơ không dây',
359
+ category: 'electronics',
360
+ brand: 'Keychron',
361
+ current_price: 1500000,
362
+ target_price: 1200000,
363
+ currency: 'VND',
364
+ })
365
+ ```
366
+
367
+ ### Thêm vào giỏ hàng
368
+
369
+ ```js
370
+ subiz('event', 'add_to_cart', {
371
+ cart_id: 'cart_12345',
372
+ product_id: 'pd2345',
373
+ sku: 's5345',
374
+ name: 'Bàn phím cơ không dây',
375
+ price: 1500000,
376
+ currency: 'VND',
377
+ quantity: 1,
378
+ category: 'electronics',
379
+ brand: 'Keychron',
380
+ })
381
+ ```
382
+
383
+ ### Xem giỏ hàng
384
+
385
+ ```js
386
+ subiz('event', 'cart_viewed', {
387
+ cart_id: 'cart_12345',
388
+ total: 3000000,
389
+ currency: 'VND',
390
+ cart_size: 2,
391
+ items: [
392
+ {product_id: 'pd2345', sku: 's5345', name: 'Bàn phím cơ không dây', category: 'electronics', quantity: 1, price: 1500000},
393
+ {product_id: 'pd9876', sku: 's1234', name: 'Chuột không dây', category: 'electronics', quantity: 1, price: 1500000},
394
+ ],
395
+ })
396
+ ```
397
+
398
+ ### Xóa khỏi giỏ hàng
399
+
400
+ ```js
401
+ subiz('event', 'remove_from_cart', {
402
+ cart_id: 'cart_12345',
403
+ product_id: 'pd2345',
404
+ sku: 's5345',
405
+ name: 'Bàn phím cơ không dây',
406
+ price: 1500000,
407
+ currency: 'VND',
408
+ quantity: 1,
409
+ category: 'electronics',
410
+ brand: 'Keychron',
411
+ })
412
+ ```
413
+
414
+ ### Thêm vào danh sách yêu thích
415
+
416
+ ```js
417
+ subiz('event', 'add_to_wishlist', {
418
+ product_id: 'pd2345',
419
+ sku: 's5345',
420
+ name: 'Bàn phím cơ không dây',
421
+ price: 1500000,
422
+ currency: 'VND',
423
+ category: 'electronics',
424
+ brand: 'Keychron',
425
+ })
426
+ ```
427
+
428
+ ### Xóa khỏi danh sách yêu thích
429
+
430
+ ```js
431
+ subiz('event', 'remove_from_wishlist', {
432
+ product_id: 'pd2345',
433
+ sku: 's5345',
434
+ name: 'Bàn phím cơ không dây',
435
+ price: 1500000,
436
+ currency: 'VND',
437
+ category: 'electronics',
438
+ brand: 'Keychron',
439
+ })
440
+ ```
441
+
442
+ ### Áp dụng mã giảm giá
443
+
444
+ ```js
445
+ subiz('event', 'coupon_applied', {
446
+ coupon_code: 'SUMMER2026',
447
+ discount_amount: 150000,
448
+ currency: 'VND',
449
+ cart_id: 'cart_12345',
450
+ })
451
+ ```
452
+
453
+ ### Xóa mã giảm giá
454
+
455
+ ```js
456
+ subiz('event', 'coupon_removed', {
457
+ coupon_code: 'SUMMER2026',
458
+ cart_id: 'cart_12345',
459
+ })
460
+ ```
461
+
462
+ ### Bắt đầu thanh toán
463
+
464
+ ```js
465
+ subiz('event', 'checkout_started', {
466
+ checkout_id: 'chk_556677',
467
+ cart_id: 'cart_12345',
468
+ total: 3000000,
469
+ currency: 'VND',
470
+ cart_size: 2,
471
+ })
472
+ ```
473
+
474
+ ### Thêm thông tin giao hàng
475
+
476
+ ```js
477
+ subiz('event', 'shipping_info_added', {
478
+ checkout_id: 'chk_556677',
479
+ shipping_method: 'standard',
480
+ shipping_fee: 30000,
481
+ currency: 'VND',
482
+ })
483
+ ```
484
+
485
+ ### Thêm thông tin thanh toán
486
+
487
+ ```js
488
+ subiz('event', 'payment_info_added', {
489
+ checkout_id: 'chk_556677',
490
+ payment_method: 'credit_card',
491
+ total: 3000000,
492
+ currency: 'VND',
493
+ })
494
+ ```
495
+
496
+ ### Khởi tạo thanh toán
497
+
498
+ ```js
499
+ subiz('event', 'payment_initiated', {
500
+ transaction_id: 'txn_12345',
501
+ checkout_id: 'chk_556677',
502
+ cart_id: 'cart_12345',
503
+ total: 3000000,
504
+ currency: 'VND',
505
+ })
506
+ ```
507
+
508
+ Nếu hệ thống đã tạo đơn trước bước thanh toán, có thể gửi thêm `order_id`. Nếu hệ thống chỉ tạo đơn sau khi thanh toán thành công, gửi `checkout_id` và `cart_id` trước, sau đó bổ sung `order_id` ở `payment_completed` hoặc `order_completed`.
509
+
510
+ ### Thanh toán thất bại
511
+
512
+ ```js
513
+ subiz('event', 'payment_failed', {
514
+ transaction_id: 'txn_12345',
515
+ checkout_id: 'chk_556677',
516
+ cart_id: 'cart_12345',
517
+ order_id: 'ord_99482',
518
+ total: 3000000,
519
+ currency: 'VND',
520
+ error_code: 'card_declined',
521
+ error_message: 'Thẻ bị từ chối',
522
+ })
523
+ ```
524
+
525
+ ### Hoàn tất thanh toán
526
+
527
+ ```js
528
+ subiz('event', 'payment_completed', {
529
+ transaction_id: 'txn_12345',
530
+ checkout_id: 'chk_556677',
531
+ cart_id: 'cart_12345',
532
+ order_id: 'ord_99482',
533
+ total: 3000000,
534
+ currency: 'VND',
535
+ status: 'success',
536
+ })
537
+ ```
538
+
539
+ ### Hoàn tất đơn hàng
540
+
541
+ ```js
542
+ subiz('event', 'order_completed', {
543
+ order_id: 'ord_99482',
544
+ checkout_id: 'chk_556677',
545
+ cart_id: 'cart_12345',
546
+ total: 3000000,
547
+ shipping_fee: 30000,
548
+ discount_amount: 0,
549
+ currency: 'VND',
550
+ payment_method: 'credit_card',
551
+ items: [
552
+ {product_id: 'pd2345', sku: 's5345', name: 'Bàn phím cơ không dây', category: 'electronics', quantity: 1, price: 1500000},
553
+ {product_id: 'pd9876', sku: 's1234', name: 'Chuột không dây', category: 'electronics', quantity: 1, price: 1500000},
554
+ ],
555
+ }, {event_source_id: 'order_completed_ord_99482'})
556
+ ```
557
+
558
+ ### Đặt hàng thất bại
559
+
560
+ ```js
561
+ subiz('event', 'order_failed', {
562
+ checkout_id: 'chk_556677',
563
+ error_code: 'out_of_stock',
564
+ error_message: 'Một sản phẩm trong giỏ hàng đã hết hàng',
565
+ total: 3000000,
566
+ currency: 'VND',
567
+ })
568
+ ```
569
+
570
+ ### Xác nhận đơn hàng
571
+
572
+ ```js
573
+ subiz('event', 'order_confirmed', {
574
+ order_id: 'ord_99482',
575
+ expected_delivery_date: '2026-05-15',
576
+ status: 'confirmed',
577
+ })
578
+ ```
579
+
580
+ ### Hủy đơn hàng
581
+
582
+ ```js
583
+ subiz('event', 'order_cancelled', {
584
+ order_id: 'ord_99482',
585
+ cancel_reason: 'customer_changed_mind',
586
+ })
587
+ ```
588
+
589
+ ### Hoàn tiền đơn hàng
590
+
591
+ ```js
592
+ subiz('event', 'order_refunded', {
593
+ order_id: 'ord_99482',
594
+ refund_id: 'rf_12345',
595
+ refund_amount: 3000000,
596
+ reason: 'customer_returned_items',
597
+ currency: 'VND',
598
+ }, {event_source_id: 'order_refunded_rf_12345'})
599
+ ```
600
+
601
+ ### Yêu cầu đổi trả
602
+
603
+ ```js
604
+ subiz('event', 'return_requested', {
605
+ order_id: 'ord_99482',
606
+ return_id: 'ret_12345',
607
+ reason: 'wrong_size',
608
+ items: [
609
+ {product_id: 'pd2345', sku: 's5345', name: 'Bàn phím cơ không dây', category: 'electronics', quantity: 1, price: 1500000},
610
+ ],
611
+ currency: 'VND',
612
+ })
613
+ ```
614
+
615
+ ### Hoàn tất đổi trả
616
+
617
+ ```js
618
+ subiz('event', 'return_completed', {
619
+ order_id: 'ord_99482',
620
+ return_id: 'ret_12345',
621
+ refund_amount: 1500000,
622
+ currency: 'VND',
623
+ })
624
+ ```
625
+
626
+ ### Bắt đầu giao hàng
627
+
628
+ ```js
629
+ subiz('event', 'order_shipped', {
630
+ order_id: 'ord_99482',
631
+ shipping_method: 'standard',
632
+ tracking_code: 'VNPOST_88374',
633
+ estimated_delivery_date: '2026-05-15',
634
+ })
635
+ ```
636
+
637
+ ### Giao hàng thành công
638
+
639
+ ```js
640
+ subiz('event', 'order_delivered', {
641
+ order_id: 'ord_99482',
642
+ tracking_code: 'VNPOST_88374',
643
+ })
644
+ ```
645
+
646
+ ### Đánh giá sản phẩm
647
+
648
+ ```js
649
+ subiz('event', 'product_reviewed', {
650
+ product_id: 'pd2345',
651
+ sku: 's5345',
652
+ name: 'Bàn phím cơ không dây',
653
+ category: 'electronics',
654
+ brand: 'Keychron',
655
+ rating: 5,
656
+ review_id: 'rv_12345',
657
+ has_comment: true,
658
+ })
659
+ ```
660
+
661
+ ### Chia sẻ sản phẩm
662
+
663
+ ```js
664
+ subiz('event', 'product_shared', {
665
+ product_id: 'pd2345',
666
+ sku: 's5345',
667
+ name: 'Bàn phím cơ không dây',
668
+ category: 'electronics',
669
+ brand: 'Keychron',
670
+ channel: 'facebook',
671
+ url: 'https://example.com/products/pd2345',
672
+ })
673
+ ```
674
+
675
+ ## Dịch vụ
676
+
677
+ ### Đặt lịch dịch vụ
678
+
679
+ ```js
680
+ subiz('event', 'service_booked', {
681
+ booking_id: 'bk_77362',
682
+ service_id: 'srv_massage_01',
683
+ scheduled_time: '2026-05-20T14:00:00Z',
684
+ })
685
+ ```
686
+
687
+ ### Hoàn thành dịch vụ
688
+
689
+ ```js
690
+ subiz('event', 'service_completed', {
691
+ booking_id: 'bk_77362',
692
+ service_id: 'srv_massage_01',
693
+ actual_duration_minutes: 65,
694
+ })
695
+ ```
696
+
697
+ ## Tương tác
698
+
699
+ ### Reaction
700
+
701
+ Dùng `reacted` khi người dùng thả hoặc gỡ reaction trên bất kỳ đối tượng nào: sản phẩm trên website, bài post, comment, tin nhắn, video, reel, story hoặc nội dung khác trên các kênh như Facebook, Instagram, WhatsApp, TikTok, Telegram.
702
+
703
+ | Trường | Bắt buộc | Mô tả |
704
+ | --- | --- | --- |
705
+ | `target_type` | Có | Loại đối tượng được reaction, ví dụ `product`, `post`, `comment`, `message`, `video`, `reel`, `story`. |
706
+ | `reaction` | Có | Loại reaction: `like`, `love`, `wow`, `haha`, `sorry`, `angry`, emoji như `👍`, `❤️`, hoặc giá trị reaction khác tùy nền tảng. |
707
+ | `action` | Không | Hành động với reaction: `add` (default) khi thả reaction, `remove` khi gỡ reaction. Nên dùng `action: 'remove'` thay vì `reaction: 'unlike'` nếu biết reaction cũ là gì. |
708
+ | `channel` | Không | Kênh xảy ra reaction, ví dụ `website`, `facebook`, `instagram`, `whatsapp`, `tiktok`, `telegram`. |
709
+
710
+ Ví dụ khách like sản phẩm trên website:
711
+
712
+ ```js
713
+ subiz('event', 'reacted', {
714
+ target_type: 'product',
715
+ reaction: 'like',
716
+ action: 'add',
717
+ channel: 'website',
718
+ product_id: 'pd2345',
719
+ sku: 's5345',
720
+ })
721
+ ```
722
+
723
+ Ví dụ khách gỡ like sản phẩm:
724
+
725
+ ```js
726
+ subiz('event', 'reacted', {
727
+ target_type: 'product',
728
+ reaction: 'like',
729
+ action: 'remove',
730
+ channel: 'website',
731
+ product_id: 'pd2345',
732
+ sku: 's5345',
733
+ })
734
+ ```
735
+
736
+ Ví dụ reaction trên post Facebook:
737
+
738
+ ```js
739
+ subiz('event', 'reacted', {
740
+ target_type: 'facebook_post',
741
+ reaction: 'love',
742
+ action: 'add',
743
+ channel: 'facebook',
744
+ post_id: '102345678901234',
745
+ page_id: '987654321012345',
746
+ })
747
+ ```
748
+
749
+ Ví dụ reaction trên tin nhắn Telegram:
750
+
751
+ ```js
752
+ subiz('event', 'reacted', {
753
+ target_type: 'message',
754
+ reaction: 'like',
755
+ action: 'add',
756
+ channel: 'telegram',
757
+ message_id: 'msg_778899',
758
+ })
759
+ ```
760
+
761
+ ### Gửi form
762
+
763
+ ```js
764
+ subiz('event', 'form_submitted', {
765
+ form_id: 'frm_newsletter_01',
766
+ form_name: 'Đăng ký nhận bản tin',
767
+ campaign_id: 'camp_summer_2026',
768
+ })
769
+ ```
770
+
771
+ ### Đăng nhập và đăng xuất
772
+
773
+ ```js
774
+ subiz('event', 'login')
775
+
776
+ subiz('event', 'logout')
777
+ ```
778
+
779
+ ### Giới thiệu khách hàng mới
780
+
781
+ ```js
782
+ subiz('event', 'customer_referred', {
783
+ referral_code: 'THANH2026',
784
+ referred_user_id: 'usr_new_999',
785
+ })
786
+ ```
787
+
788
+ ### Cập nhật khách hàng thân thiết
789
+
790
+ ```js
791
+ subiz('event', 'customer_loyalty_updated', {
792
+ action: 'earn',
793
+ points: 500,
794
+ current_tier: 'platinum',
795
+ })
796
+ ```
797
+
798
+ ## B2B và hợp đồng
799
+
800
+ Các event B2B nên giúp marketing và sales trả lời các câu hỏi như: lead nào có intent cao, công ty nào đang active, deal nào có khả năng close, chiến dịch nào tạo pipeline, khách hàng nào sắp renew hoặc có nguy cơ churn.
801
+
802
+ Nên giữ ổn định các field định danh như `company_id`, `company_name`, `contact_id`, `deal_id`, `contract_id`, `plan`, `industry`, `company_size`, `estimated_value`, `currency`.
803
+
804
+ | Câu hỏi marketing/sales | Event nên dùng |
805
+ | --- | --- |
806
+ | Lead nào vừa phát sinh? | `lead_created`, `form_submitted`, `customer_registered` |
807
+ | Lead nào có intent cao? | `demo_requested`, `meeting_booked`, `quote_requested`, `pricing_viewed` |
808
+ | Campaign nào tạo pipeline? | `lead_created`, `demo_requested`, `quote_requested`, `deal_created` |
809
+ | Deal nào đang tiến triển? | `deal_created`, `deal_stage_changed`, `proposal_sent`, `quote_requested` |
810
+ | Deal nào bị mất? | `deal_lost`, `contract_cancelled` |
811
+ | Khách hàng nào có khả năng mở rộng? | `subscription_upgraded`, `seat_added`, `feature_activated` |
812
+ | Khách hàng nào sắp renew? | `renewal_started`, `invoice_paid`, `contract_signed` |
813
+ | Khách hàng nào có nguy cơ churn? | `subscription_downgraded`, `invoice_failed`, `customer_churned` |
814
+
815
+ ### Tạo lead
816
+
817
+ ```js
818
+ subiz('event', 'lead_created', {
819
+ lead_id: 'lead_10293',
820
+ contact_id: 'ct_10293',
821
+ company_id: 'com_9981',
822
+ company_name: 'Tech Corp VN',
823
+ email: 'alice@techcorp.vn',
824
+ phone: '0987654321',
825
+ source: 'landing_page_summer',
826
+ campaign_id: 'camp_summer_2026',
827
+ industry: 'software',
828
+ company_size: '51-200',
829
+ })
830
+ ```
831
+
832
+ ### Đăng ký tài khoản
833
+
834
+ ```js
835
+ subiz('event', 'customer_registered', {
836
+ customer_id: 'usr_new_10293',
837
+ company_id: 'com_9981',
838
+ company_name: 'Tech Corp VN',
839
+ registration_method: 'google',
840
+ source: 'landing_page_summer',
841
+ is_verified: false,
842
+ })
843
+ ```
844
+
845
+ ### Xem trang giá
846
+
847
+ ```js
848
+ subiz('event', 'pricing_viewed', {
849
+ company_id: 'com_9981',
850
+ company_name: 'Tech Corp VN',
851
+ plan: 'business',
852
+ billing_cycle: 'annual',
853
+ url: 'https://example.com/pricing',
854
+ })
855
+ ```
856
+
857
+ ### Bắt đầu dùng thử
858
+
859
+ ```js
860
+ subiz('event', 'trial_started', {
861
+ trial_id: 'trial_12345',
862
+ company_id: 'com_9981',
863
+ company_name: 'Tech Corp VN',
864
+ plan: 'business',
865
+ start_date: '2026-05-12',
866
+ end_date: '2026-05-26',
867
+ source: 'pricing_page',
868
+ })
869
+ ```
870
+
871
+ ### Yêu cầu demo
872
+
873
+ ```js
874
+ subiz('event', 'demo_requested', {
875
+ demo_id: 'demo_12345',
876
+ contact_id: 'ct_10293',
877
+ company_id: 'com_9981',
878
+ company_name: 'Tech Corp VN',
879
+ plan_interest: 'business',
880
+ estimated_users: 50,
881
+ preferred_time: '2026-05-20T14:00:00Z',
882
+ })
883
+ ```
884
+
885
+ ### Đặt lịch họp
886
+
887
+ ```js
888
+ subiz('event', 'meeting_booked', {
889
+ meeting_id: 'mt_12345',
890
+ contact_id: 'ct_10293',
891
+ company_id: 'com_9981',
892
+ company_name: 'Tech Corp VN',
893
+ meeting_type: 'sales_demo',
894
+ scheduled_time: '2026-05-20T14:00:00Z',
895
+ owner_id: 'sale_001',
896
+ })
897
+ ```
898
+
899
+ ### Hoàn thành cuộc họp
900
+
901
+ ```js
902
+ subiz('event', 'meeting_completed', {
903
+ meeting_id: 'mt_12345',
904
+ contact_id: 'ct_10293',
905
+ company_id: 'com_9981',
906
+ company_name: 'Tech Corp VN',
907
+ meeting_type: 'sales_demo',
908
+ outcome: 'qualified',
909
+ next_step: 'send_proposal',
910
+ })
911
+ ```
912
+
913
+ ### Tạo deal
914
+
915
+ ```js
916
+ subiz('event', 'deal_created', {
917
+ deal_id: 'deal_556677',
918
+ company_id: 'com_9981',
919
+ company_name: 'Tech Corp VN',
920
+ stage: 'qualified',
921
+ estimated_value: 50000000,
922
+ currency: 'VND',
923
+ owner_id: 'sale_001',
924
+ source: 'demo_requested',
925
+ })
926
+ ```
927
+
928
+ ### Đổi trạng thái deal
929
+
930
+ ```js
931
+ subiz('event', 'deal_stage_changed', {
932
+ deal_id: 'deal_556677',
933
+ company_id: 'com_9981',
934
+ company_name: 'Tech Corp VN',
935
+ from_stage: 'qualified',
936
+ to_stage: 'proposal_sent',
937
+ estimated_value: 50000000,
938
+ currency: 'VND',
939
+ owner_id: 'sale_001',
940
+ })
941
+ ```
942
+
943
+ ### Gửi proposal
944
+
945
+ ```js
946
+ subiz('event', 'proposal_sent', {
947
+ proposal_id: 'pr_2026_05_01',
948
+ deal_id: 'deal_556677',
949
+ company_id: 'com_9981',
950
+ company_name: 'Tech Corp VN',
951
+ total: 48000000,
952
+ currency: 'VND',
953
+ valid_until: '2026-06-01',
954
+ })
955
+ ```
956
+
957
+ ### Yêu cầu báo giá
958
+
959
+ ```js
960
+ subiz('event', 'quote_requested', {
961
+ quote_id: 'qt_2026_05_01',
962
+ deal_id: 'deal_556677',
963
+ company_id: 'com_9981',
964
+ company_name: 'Tech Corp VN',
965
+ estimated_budget: 50000000,
966
+ currency: 'VND',
967
+ })
968
+ ```
969
+
970
+ ### Chấp nhận báo giá
971
+
972
+ ```js
973
+ subiz('event', 'quote_accepted', {
974
+ quote_id: 'qt_2026_05_01',
975
+ deal_id: 'deal_556677',
976
+ company_id: 'com_9981',
977
+ company_name: 'Tech Corp VN',
978
+ total: 48000000,
979
+ currency: 'VND',
980
+ })
981
+ ```
982
+
983
+ ### Từ chối báo giá
984
+
985
+ ```js
986
+ subiz('event', 'quote_rejected', {
987
+ quote_id: 'qt_2026_05_01',
988
+ deal_id: 'deal_556677',
989
+ company_id: 'com_9981',
990
+ company_name: 'Tech Corp VN',
991
+ reason: 'price_too_high',
992
+ total: 48000000,
993
+ currency: 'VND',
994
+ })
995
+ ```
996
+
997
+ ### Ký hợp đồng
998
+
999
+ ```js
1000
+ subiz('event', 'contract_signed', {
1001
+ contract_id: 'ctr_09876',
1002
+ deal_id: 'deal_556677',
1003
+ quote_id: 'qt_2026_05_01',
1004
+ company_id: 'com_9981',
1005
+ company_name: 'Tech Corp VN',
1006
+ total: 48000000,
1007
+ plan: 'business',
1008
+ billing_cycle: 'annual',
1009
+ start_date: '2026-06-01',
1010
+ end_date: '2027-05-31',
1011
+ currency: 'VND',
1012
+ }, {event_source_id: 'contract_signed_ctr_09876'})
1013
+ ```
1014
+
1015
+ ### Hủy hợp đồng
1016
+
1017
+ ```js
1018
+ subiz('event', 'contract_cancelled', {
1019
+ contract_id: 'ctr_09876',
1020
+ company_id: 'com_9981',
1021
+ company_name: 'Tech Corp VN',
1022
+ cancel_reason: 'budget_cut',
1023
+ cancelled_at: '2026-10-01',
1024
+ remaining_value: 24000000,
1025
+ currency: 'VND',
1026
+ })
1027
+ ```
1028
+
1029
+ ### Mất deal
1030
+
1031
+ ```js
1032
+ subiz('event', 'deal_lost', {
1033
+ deal_id: 'deal_556677',
1034
+ company_id: 'com_9981',
1035
+ company_name: 'Tech Corp VN',
1036
+ lost_reason: 'chose_competitor',
1037
+ estimated_value: 50000000,
1038
+ currency: 'VND',
1039
+ })
1040
+ ```
1041
+
1042
+ ### Hoàn thành onboarding
1043
+
1044
+ ```js
1045
+ subiz('event', 'onboarding_completed', {
1046
+ company_id: 'com_9981',
1047
+ company_name: 'Tech Corp VN',
1048
+ plan: 'business',
1049
+ onboarding_duration_days: 14,
1050
+ owner_id: 'cs_001',
1051
+ })
1052
+ ```
1053
+
1054
+ ### Kích hoạt tính năng quan trọng
1055
+
1056
+ ```js
1057
+ subiz('event', 'feature_activated', {
1058
+ company_id: 'com_9981',
1059
+ company_name: 'Tech Corp VN',
1060
+ feature_key: 'automation_workflow',
1061
+ plan: 'business',
1062
+ activated_by: 'usr_10293',
1063
+ })
1064
+ ```
1065
+
1066
+ ### Nâng cấp gói
1067
+
1068
+ ```js
1069
+ subiz('event', 'subscription_upgraded', {
1070
+ subscription_id: 'sub_12345',
1071
+ company_id: 'com_9981',
1072
+ company_name: 'Tech Corp VN',
1073
+ from_plan: 'starter',
1074
+ to_plan: 'business',
1075
+ mrr_delta: 3000000,
1076
+ currency: 'VND',
1077
+ })
1078
+ ```
1079
+
1080
+ ### Hạ cấp gói
1081
+
1082
+ ```js
1083
+ subiz('event', 'subscription_downgraded', {
1084
+ subscription_id: 'sub_12345',
1085
+ company_id: 'com_9981',
1086
+ company_name: 'Tech Corp VN',
1087
+ from_plan: 'business',
1088
+ to_plan: 'starter',
1089
+ mrr_delta: -3000000,
1090
+ reason: 'budget_cut',
1091
+ currency: 'VND',
1092
+ })
1093
+ ```
1094
+
1095
+ ### Thêm người dùng vào tài khoản
1096
+
1097
+ ```js
1098
+ subiz('event', 'seat_added', {
1099
+ subscription_id: 'sub_12345',
1100
+ company_id: 'com_9981',
1101
+ company_name: 'Tech Corp VN',
1102
+ seat_delta: 5,
1103
+ total_seats: 25,
1104
+ mrr_delta: 1500000,
1105
+ currency: 'VND',
1106
+ })
1107
+ ```
1108
+
1109
+ Trong đó `seat_delta` là số seat được thêm ở lần thay đổi này, còn `total_seats` là tổng số seat sau thay đổi.
1110
+
1111
+ ### Bắt đầu gia hạn
1112
+
1113
+ ```js
1114
+ subiz('event', 'renewal_started', {
1115
+ contract_id: 'ctr_09876',
1116
+ company_id: 'com_9981',
1117
+ company_name: 'Tech Corp VN',
1118
+ renewal_date: '2027-05-31',
1119
+ current_value: 48000000,
1120
+ currency: 'VND',
1121
+ })
1122
+ ```
1123
+
1124
+ ### Gia hạn thành công
1125
+
1126
+ ```js
1127
+ subiz('event', 'renewal_completed', {
1128
+ contract_id: 'ctr_09876',
1129
+ company_id: 'com_9981',
1130
+ company_name: 'Tech Corp VN',
1131
+ renewal_value: 60000000,
1132
+ start_date: '2027-06-01',
1133
+ end_date: '2028-05-31',
1134
+ currency: 'VND',
1135
+ }, {event_source_id: 'renewal_completed_ctr_09876_2027'})
1136
+ ```
1137
+
1138
+ ### Thanh toán hóa đơn thành công
1139
+
1140
+ ```js
1141
+ subiz('event', 'invoice_paid', {
1142
+ invoice_id: 'inv_12345',
1143
+ company_id: 'com_9981',
1144
+ company_name: 'Tech Corp VN',
1145
+ total: 48000000,
1146
+ billing_cycle: 'annual',
1147
+ currency: 'VND',
1148
+ }, {event_source_id: 'invoice_paid_inv_12345'})
1149
+ ```
1150
+
1151
+ ### Thanh toán hóa đơn thất bại
1152
+
1153
+ ```js
1154
+ subiz('event', 'invoice_failed', {
1155
+ invoice_id: 'inv_12345',
1156
+ company_id: 'com_9981',
1157
+ company_name: 'Tech Corp VN',
1158
+ total: 48000000,
1159
+ error_code: 'card_declined',
1160
+ currency: 'VND',
1161
+ })
1162
+ ```
1163
+
1164
+ ### Rời bỏ dịch vụ
1165
+
1166
+ ```js
1167
+ subiz('event', 'customer_churned', {
1168
+ company_id: 'com_9981',
1169
+ company_name: 'Tech Corp VN',
1170
+ churn_type: 'voluntary',
1171
+ reason: 'switched_to_competitor',
1172
+ lifetime_days: 345,
1173
+ lifetime_value: 25000000,
1174
+ currency: 'VND',
1175
+ })
1176
+ ```
1177
+
1178
+ ## Custom event
1179
+
1180
+ Website có thể gửi event riêng ngoài các ví dụ phía trên.
1181
+
1182
+ ```js
1183
+ subiz('event', 'coupon_copied', {
1184
+ coupon_code: 'SUMMER2026',
1185
+ campaign_id: 'camp_summer_2026',
1186
+ location: 'product_detail',
1187
+ })
1188
+ ```
1189
+
1190
+ Quy tắc:
1191
+
1192
+ - `type` phải dùng `snake_case`.
1193
+ - `type` chỉ gồm chữ thường, số và `_`.
1194
+ - `type` tối đa 64 ký tự.
1195
+ - `payload` nên là object JSON, không gửi function, DOM node hoặc object có vòng lặp tham chiếu.
1196
+ - Dùng `event_source_id` cho các event quan trọng như `order_completed`, `payment_completed`, `form_submitted` để tránh ghi nhận trùng.
1197
+
1198
+ ## Xử lý lỗi
1199
+
1200
+ Vì `subiz('event', ...)` trả về `Promise`, website có thể dùng `await` hoặc `.then/.catch`.
1201
+
1202
+ ```js
1203
+ async function sendOrderCompleted(order) {
1204
+ try {
1205
+ await subiz('event', 'order_completed', {
1206
+ order_id: order.id,
1207
+ total: order.total,
1208
+ currency: order.currency,
1209
+ items: order.items,
1210
+ }, {event_source_id: 'order_completed_' + order.id})
1211
+ } catch (error) {
1212
+ console.error('Không gửi được order_completed', error)
1213
+ }
1214
+ }
1215
+ ```
1216
+
1217
+ Với event không quan trọng, website có thể gửi theo kiểu fire-and-forget:
1218
+
1219
+ ```js
1220
+ subiz('event', 'product_viewed', {
1221
+ product_id: 'pd2345',
1222
+ name: 'Bàn phím cơ không dây',
1223
+ })
1224
+ ```