Facebook Ads

Case study Facebook Ads: Vì sao SePay nhận tiền nhưng Meta Dataset thiếu Purchase?

Sơn Marketing
Sơn Marketing
Wed, 22 Jul 2026
Case study Facebook Ads: Vì sao SePay nhận tiền nhưng Meta Dataset thiếu Purchase?

Sự cố thực tế: hai học viên đã thanh toán khóa học qua SePay và hệ thống nghiệp vụ đã ghi nhận giao dịch, nhưng Meta Dataset lại thiếu sự kiện Purchase. Vấn đề không nằm ở việc ngân hàng chưa báo tiền; nó nằm ở đoạn nối giữa webhook thanh toán, trạng thái kích hoạt khóa học và Conversions API.

Bài case study Facebook Ads này mô tả cách Sơn Marketing truy ngược luồng dữ liệu, sửa cơ chế gửi Purchase và tạo khả năng phục hồi khi webhook được gửi lại. Toàn bộ thông tin nhận dạng học viên, mã đơn, khóa API và dữ liệu ghép nối đã được loại khỏi bài. Các con số bên dưới chỉ là thống kê sự kiện kỹ thuật cần thiết để chứng minh cơ chế hoạt động.

Kết quả sau sửa: log hệ thống ghi nhận 2 lần gửi Purchase thành công, 3 lần webhook trùng được đưa qua luồng phát lại an toàn và 1 lần hệ thống chủ động bỏ qua vì Purchase tương ứng đã được gửi. Không có giao dịch nào bị nhân đôi chỉ vì webhook được gọi lại.

Vì sao “đã nhận tiền” và “Meta đã nhận Purchase” là hai việc khác nhau?

Một lần học viên chuyển khoản thành công có thể đi qua ít nhất ba hệ thống độc lập:

  1. Ngân hàng và cổng thông báo thanh toán: xác nhận có tiền vào, số tiền, nội dung và mã tham chiếu.
  2. Hệ thống nghiệp vụ của website: đối chiếu đơn, kích hoạt quyền học, gửi email và lưu trạng thái giao dịch.
  3. Hệ thống đo lường quảng cáo: gửi Purchase lên Meta qua Conversions API để báo cáo và tối ưu.

Nếu bước hai thành công nhưng bước ba lỗi, học viên vẫn có khóa học còn Dataset vẫn thiếu Purchase. Ngược lại, nếu Meta nhận Purchase nhưng hệ thống chưa xác nhận tiền, báo cáo quảng cáo có thể đẹp hơn thực tế. Vì vậy Ads Manager hoặc Events Manager không được dùng làm sổ cái doanh thu.

Sự cố này xuất hiện sau khi website bổ sung SePay bên cạnh luồng thanh toán đã có. Luồng mới xử lý phần nhận tiền và kích hoạt, nhưng chưa có cùng mức bảo đảm rằng Purchase sẽ được gửi, ghi log và phục hồi ở mọi nhánh xử lý như luồng cũ.

Cách tìm nguyên nhân mà không đoán mò

Thay vì chỉ nhìn biểu đồ Dataset, quá trình kiểm tra đi từ nguồn sự thật tới từng điểm chuyển giao:

Câu hỏi Nguồn kiểm tra Kết quả cần phân biệt
Tiền đã vào chưa? Giao dịch SePay và dữ liệu đối soát Đã nhận tiền, đúng số tiền và đúng đơn
Khóa học đã kích hoạt chưa? Trạng thái đơn và quyền học Nghiệp vụ hoàn tất hay còn treo
Purchase đã được tạo chưa? Log chuyển đổi phía server Chưa gọi, gọi lỗi hay Meta đã nhận
Webhook có gọi lại không? Log webhook theo thời gian Lần đầu, bản phát lại hay bản trùng
Có nguy cơ đếm đôi không? Mã sự kiện ổn định và nhật ký đã gửi Cùng một giao dịch phải giữ cùng danh tính sự kiện

Hai giao dịch bị thiếu có điểm chung là đi qua luồng SePay. Điều này giúp thu hẹp phạm vi kiểm tra. Tuy nhiên, “SePay có lỗi” vẫn là kết luận quá rộng: SePay đã hoàn thành việc thông báo tiền. Lỗi thực sự là tích hợp phía website chưa bảo đảm bước báo cáo Purchase sau khi nhận webhook.

Nguyên nhân gốc: xử lý webhook chưa có khả năng hoàn tất lại

Webhook thanh toán không phải một cuộc gọi chỉ xảy ra đúng một lần. Nhà cung cấp có thể gửi lại khi chưa nhận phản hồi, mạng có thể ngắt giữa chừng hoặc ứng dụng có thể hoàn tất một số bước rồi lỗi ở bước sau. Một thiết kế an toàn phải chấp nhận ít nhất các tình huống:

  • Webhook đến lần đầu và mọi bước đều thành công.
  • Giao dịch đã kích hoạt nhưng lệnh gửi Meta bị lỗi tạm thời.
  • Cùng một webhook đến thêm lần nữa.
  • Purchase đã gửi thành công nhưng website nhận lại thông báo trùng.
  • Cần gửi bù một giao dịch cũ mà không tạo thêm một Purchase mới.

Luồng SePay cũ từng dừng sớm khi thấy giao dịch đã được xử lý. Điều đó ngăn kích hoạt khóa học lần hai, nhưng đồng thời đóng luôn cơ hội hoàn tất bước CAPI nếu lần đầu dừng giữa chừng. Đây là dạng lỗi “nghiệp vụ đã xong, tác vụ phụ chưa xong” thường gặp ở hệ thống thanh toán.

Bản sửa gồm năm lớp bảo vệ

1. Hoàn tất nghiệp vụ cốt lõi trước cuộc gọi mạng

Trạng thái thanh toán và quyền học được xử lý trước. Cuộc gọi sang Meta là tác vụ mạng bên ngoài, có thể chậm hoặc lỗi; nó không được phép làm học viên mất quyền học dù tiền đã nhận. Cách tách này bảo vệ trải nghiệm khách hàng và làm rõ nguồn sự thật.

2. Tạo mã sự kiện ổn định cho mỗi giao dịch

Mỗi Purchase có một mã sự kiện được dẫn xuất ổn định từ giao dịch, thay vì sinh ngẫu nhiên ở mỗi lần thử. Khi cùng một đơn được gửi lại, danh tính sự kiện không đổi. Đây là nền tảng để chống trùng ở phía ứng dụng và hỗ trợ deduplication.

Meta nêu rằng event_nameevent_id được dùng để khử trùng giữa sự kiện browser và server. Meta cũng cho biết mã đơn hoặc mã giao dịch có thể làm cơ sở cho event_id, miễn là mỗi giao dịch có một mã riêng và hai nguồn dùng nhất quán. Hệ thống thực tế có thể biến đổi mã nội bộ trước khi sử dụng để không phơi bày dữ liệu không cần thiết.

3. Kiểm tra nhật ký trước khi gửi

Trước mỗi lần gọi CAPI, hệ thống kiểm tra xem Purchase với mã sự kiện đó đã được ghi nhận thành công chưa. Nếu có, luồng dừng ở trạng thái “đã gửi”, không tạo yêu cầu thứ hai. Nếu chưa có, hệ thống mới thử hoàn tất.

Lớp này khác với deduplication của Meta. Meta giúp gộp các sự kiện tương ứng ở phía nền tảng; nhật ký nội bộ giúp website biết chính nó đã làm gì và phục hồi có kiểm soát. Một hệ thống quan trọng nên có cả hai.

4. Cho phép webhook trùng đi qua nhánh phục hồi

Thay vì thấy “đã xử lý” rồi thoát ngay, webhook trùng được đưa qua một luồng an toàn: không cấp khóa học lại, không tạo giao dịch mới, nhưng vẫn kiểm tra xem Purchase hoặc tác vụ sau thanh toán đã hoàn tất chưa. Nếu đã hoàn tất, nó bỏ qua. Nếu còn thiếu, nó có thể gửi lại với cùng mã sự kiện.

5. Gửi đủ bối cảnh hợp lệ của sự kiện

Purchase phía server bao gồm tên sự kiện, thời điểm hành động thật, nguồn website, giá trị, tiền tệ, nội dung đơn và dữ liệu ghép nối hợp lệ khi có. Các thông tin như email hoặc số điện thoại phải được chuẩn hóa và băm theo yêu cầu trước khi truyền; bài viết này không công bố bất kỳ giá trị thật nào.

Với giao dịch gửi bù, thời gian sự kiện cần phản ánh thời điểm thanh toán thay vì thời điểm kỹ thuật viên bấm chạy lại. Tài liệu Meta cho phép event_time sớm hơn thời điểm gửi để hỗ trợ xử lý trễ, nhưng có giới hạn thời gian chấp nhận. Vì thế khắc phục phải được thực hiện sớm và có kiểm tra phản hồi, không nên để hàng tuần rồi mới đối soát.

Kết quả kiểm tra sau sửa

Dấu hiệu trong log đã ẩn danh Số lần Ý nghĩa
Purchase gửi thành công 2 Hai sự kiện cần phục hồi đã đi qua CAPI thành công
Webhook trùng được phát lại 3 Hệ thống không còn dừng trước bước kiểm tra hoàn tất
Bỏ qua vì Purchase đã gửi 1 Cơ chế idempotency ngăn một giao dịch tạo thêm sự kiện

Đây là kiểm tra kỹ thuật của luồng gửi, không có nghĩa Ads Manager bắt buộc phải hiển thị đúng cùng số đơn trong mọi cửa sổ báo cáo. Attribution còn phụ thuộc lượt tương tác quảng cáo, cửa sổ phân bổ, quyền riêng tư và khả năng ghép nối. Nguồn doanh thu chuẩn vẫn là dữ liệu thanh toán đã đối soát.

Ba số liệu phải đối soát riêng

  1. Số giao dịch đã thanh toán: lấy từ cổng thanh toán hoặc ngân hàng sau đối soát.
  2. Số Purchase đã gửi và được API chấp nhận: lấy từ nhật ký server, theo mã sự kiện duy nhất.
  3. Số Purchase được Meta phân bổ cho quảng cáo: lấy từ hệ thống quảng cáo theo cửa sổ attribution đã chọn.

Ba con số có liên quan nhưng không bắt buộc bằng nhau. Chỉ số đầu trả lời doanh nghiệp thu được bao nhiêu giao dịch. Chỉ số thứ hai trả lời tích hợp có truyền dữ liệu hay không. Chỉ số thứ ba trả lời Meta quy kết bao nhiêu giao dịch cho quảng cáo. Trộn ba lớp này là nguyên nhân của nhiều cuộc tranh luận “Facebook báo sai đơn”.

Checklist cho mọi tích hợp thanh toán → Meta

Thiết kế

  • Xác định nguồn sự thật của thanh toán và điều kiện chính xác để gọi Purchase.
  • Tách kích hoạt đơn khỏi cuộc gọi tới nền tảng quảng cáo.
  • Tạo mã sự kiện ổn định cho mỗi giao dịch.
  • Lưu trạng thái đã gửi, phản hồi API và số lần thử.
  • Không ghi khóa bí mật hoặc dữ liệu cá nhân thô vào log.

Xử lý webhook

  • Xác thực chữ ký hoặc khóa webhook trước khi tin payload.
  • Chỉ nhận giao dịch tiền vào và đối chiếu đúng số tiền.
  • Không giả định webhook chỉ đến một lần.
  • Không trả trạng thái thành công trước khi dữ liệu quan trọng đã được lưu.
  • Cho phép phát lại an toàn để hoàn tất tác vụ còn thiếu.

Đo lường

  • Gửi đúng event time, action source, value và currency.
  • Dùng dữ liệu ghép nối hợp lệ, tối thiểu cần thiết và xử lý đúng quy định.
  • Kiểm tra trùng giữa browser Pixel và server CAPI.
  • Đối soát hằng ngày giữa thanh toán, log CAPI và Dataset.
  • Cảnh báo khi có giao dịch đã hoàn tất nhưng chưa có log Purchase thành công sau một khoảng thời gian xác định.

Những cách sửa có vẻ nhanh nhưng không an toàn

Gửi lại Purchase với mã ngẫu nhiên. Cách này có thể làm giao dịch xuất hiện, nhưng mỗi lần bấm lại có nguy cơ thành một Purchase mới. Sửa đúng là giữ mã sự kiện ổn định và kiểm tra nhật ký.

Bắn Purchase ngay khi người dùng mở trang cảm ơn. Trang có thể được tải lại hoặc được mở khi giao dịch chưa đối soát. Với chuyển khoản, sự kiện nên gắn với xác nhận thanh toán phía server.

Coi webhook trùng là lỗi và bỏ toàn bộ. Trùng lặp là hành vi bình thường của cơ chế retry. Điều cần làm là khiến xử lý có tính idempotent, không phải cấm retry.

Chỉ kiểm tra Events Manager. Events Manager cho biết Meta nhận dữ liệu gì, nhưng không cho biết đầy đủ tiền đã vào hay quyền học đã cấp. Luôn cần đối chiếu từ hệ thống nghiệp vụ.

Đọc tiếp theo lộ trình

Nếu bạn chưa rõ vai trò từng thành phần, hãy đọc trước bài Meta Pixel, Dataset và Conversions API khác nhau thế nào. Bài Facebook Ads báo 30 đơn, website chỉ có 20 giải thích thêm sự khác biệt giữa ghi nhận kỹ thuật và attribution.

Để học theo thứ tự từ nền tảng tới đo lường và dữ liệu chuyển đổi, xem lộ trình học Facebook Ads.

Xem khóa học Facebook Ads Chuyển Đổi Vàng, chương trình thật và các bài mở học thử

Nguồn tham khảo chính thức

Kết luận

Sự cố không phải “SePay không gửi tiền” hay “Facebook tự mất đơn”. SePay đã thông báo giao dịch; website đã hoàn tất nghiệp vụ; mắt xích thiếu bảo đảm là bước báo cáo Purchase sau webhook. Bản sửa đúng không chỉ gửi bù hai sự kiện, mà còn biến luồng thành một quy trình có thể phát lại: cùng giao dịch, cùng mã sự kiện, kiểm tra trạng thái trước khi gửi và không kích hoạt trùng.

Đó cũng là bài học quan trọng nhất cho Facebook Ads: dữ liệu chuyển đổi tốt không bắt đầu từ một nút trong Events Manager. Nó bắt đầu từ cách doanh nghiệp định nghĩa giao dịch thật, thiết kế luồng hệ thống và duy trì đối soát giữa tiền, đơn và sự kiện quảng cáo.

AI

Tóm lược bởi Trợ giảng AI

Đang chuẩn bị tóm lược nội dung…
Thuật ngữ AI
Đang phân tích...
case study Facebook Ads SePay Meta Dataset thiếu Purchase Facebook Conversions API webhook thanh toán tracking Facebook Ads
Sơn Marketing
Về tác giả

Sơn Marketing

12 năm kinh nghiệm Facebook, Google Ads. Founder Tientoi - tối ưu kinh doanh online bền vững.

Chuyên ngành Truyền thông Marketing - ĐH Kinh tế Quốc dân.Khởi nghiệp từ năm 3 đại học với dự án tiếng Anh khởi nghiệp Evergreen.Thành lập nhiều dự án phi lợi nhuận: 1st Hanoi (hỗ trợ khách du lịch tới Hà Nội), KTXfree (dạy tiếng Anh cho sinh viên trong KTX), Bookmates (Câu lạc bộ yêu thích đọc sách).Xuất bản sách: Quảng cáo như không quảng cáo, Marketing 7…

0 Bình luận

Để lại bình luận

Xem ảnh lớn
Chat tư vấn ngay!
Zalo Chat 0899666898