PAY2S WOOCOMMERCE 1.3.10

Thêm nút Tải mã QR dưới ảnh trên mobile và desktop. Tải đúng ảnh gốc của ngân hàng đang chọn, không kèm lớp logo/hiệu ứng scan trên giao diện. Sau khi tải, người dùng có thể chọn ảnh trong ứng dụng ngân hàng nếu ứng dụng hỗ trợ.
Ảnh được tải qua backend shop để tránh giới hạn tải ảnh khác domain. Kiểm tra order key, ngân hàng và trạng thái còn chờ trước khi tải; không nhận URL tùy ý từ client. Chỉ trả ảnh PNG/JPEG hợp lệ, tối đa 2 MB.
Cập nhật bằng ZIP plugin. Nếu đã triển khai bản 1.3.9 thì không cần thay API, worker hay SQL thêm cho nút tải QR.
Đã kiểm tra desktop/mobile, đổi ngân hàng đổi link tải, byte ảnh tải đúng bản gốc, từ chối sai key/ngân hàng/đơn đã đóng và phản hồi không phải ảnh. Chưa thử tải trên thiết bị iOS/Android thật.

PAY2S WOOCOMMERCE 1.3.9 — TRUY VẤN TRẠNG THÁI BỔ SUNG IPN

CÀI ĐẶT
1. Cập nhật plugin bằng pay2s-gateway-1.3.9.zip, giữ cấu hình và key.
2. Cập nhật generalredirectt.js vào đúng nơi tiến trình Node đang phục vụ /api/generate-redirect, giữ nguyên .env/dependency/port rồi restart tiến trình đó. Thay đổi này giúp API ký bằng đúng key cửa hàng khi invoice có store_id. Nếu chỉ dùng key tài khoản chủ thì API hiện tại vẫn dùng được; khuyến nghị cập nhật để hỗ trợ đủ cả hai loại key.
3. Không cần migration SQL mới cho 1.3.9. Gói worker IPN trước đó nếu chưa triển khai vẫn có hướng dẫn SQL riêng, không liên quan bước cài này.
Không thay các file sendIPN/retryIPN bằng generalredirectt.js; đây là hai dịch vụ khác nhau.

LUỒNG
Trình duyệt vẫn hỏi backend shop mỗi 1 giây khi tab hiển thị. Nếu đơn chưa có kết quả, backend shop dùng token t lưu từ payUrl gọi HTTPS /api/generate-redirect phía Pay2S. Không đưa secret/access key mới vào JavaScript hoặc trả redirect ký từ Pay2S cho trình duyệt.
Mỗi đơn tối đa một truy vấn bổ sung trong khoảng 2 giây; khóa dùng chung giữa các PHP request để nhiều tab không gọi trùng. Request ngoài timeout 3 giây, lỗi thì chờ 10 giây trước khi thử lại, IPN vẫn hoạt động bình thường.
Chỉ success=true, paid=true với dữ liệu có chữ ký đúng, đúng shop, đúng order_id, số tiền, resultCode=0 và thời gian mới được dùng để xác nhận.
API pending, lỗi mạng, hết hạn hoặc chữ ký không khớp KHÔNG được coi là thất bại/đã thanh toán. Tiếp tục dùng IPN làm nguồn kết quả.

CHỐNG XỬ LÝ LẶP
API và IPN dùng chung hàm xác nhận cùng khóa MySQL theo đơn, tương thích bảng đơn WooCommerce/HPOS qua WC APIs.
API xác nhận trước: cập nhật đơn và phát hook/event như IPN. IPN tới sau chỉ ACK, ghi mốc nhận IPN/bổ sung transaction_id nếu còn thiếu; không chạy lại payment_complete/trừ kho/hook thành công.
Nếu khóa kết quả đang bận, IPN trả 503 để worker retry, không ACK giả. Hủy đơn cũng dùng chung khóa khi ghi kết quả WooCommerce.
Event ID giữ nguyên giữa IPN/API để bên nhận tracking chống trùng. Vẫn cần dedup phía đích; không bảo đảm exactly-once khi process bị kill giữa các thao tác WooCommerce/third-party hooks.
Giữ custom thông báo thành công và cấu hình thank-you. Mặc định hiện thành công tại trang như bản trước.

CHẨN ĐOÁN
Response pay2s_order_status có confirmation_source: status_api hoặc ipn. Console window.pay2sTiming cũng hiển thị nguồn này.
webhook_received_at_ms giữ tên cũ trong dữ liệu chẩn đoán, nghĩa là thời điểm nhận IPN. Nếu API xác nhận trước khi IPN tới thì trường này còn null, đó không phải lỗi.
MySQL cần hỗ trợ GET_LOCK/RELEASE_LOCK; đây là khóa theo connection, không thêm bảng/cột. Nếu quyền/môi trường không hỗ trợ, không bỏ qua khóa để cập nhật thanh toán.

ĐÃ KIỂM TRA
Phản hồi API đúng/sai chữ ký, sai shop/đơn/số tiền/thời gian, pending, cache và lỗi mạng, khóa bận, API xác nhận trước rồi IPN tới sau không phát/trừ kho lại; API Node ký owner/store và từ chối khi thiếu key cửa hàng. Hồi quy IPN, hủy và hóa đơn qua. Chưa gọi API production hay giao dịch thật.

HƯỚNG DẪN GIAO DIỆN/TRACKING TỪ BẢN TRƯỚC
PAY2S WOOCOMMERCE 1.3.8

CÀI ĐẶT
WordPress > Plugins > Add New > Upload Plugin > pay2s-gateway-1.3.8.zip, thay bản cũ. Giữ key và các cấu hình đã lưu. Xóa cache asset nếu giao diện chưa đổi.

CẤU HÌNH
WooCommerce > Cài đặt > Thanh toán > Pay2S:
- Cách hiển thị thanh toán: Chuyển sang Pay2S hoặc Thanh toán ngay trên website.
- Sau khi thanh toán thành công: Hiện thông báo thành công ngay tại trang thanh toán (mặc định) hoặc Chuyển tới trang cảm ơn tùy chọn.
- URL trang cảm ơn tùy chọn: HTTPS đầy đủ. Chỉ URL hợp lệ đã chọn tùy chọn custom mới tự chuyển trang sau thành công. Mỗi phiên lưu cấu hình lúc tạo; phiên cũ vẫn theo URL tùy chọn đã lưu nếu có.

LUỒNG TẠI WEBSITE
Tạo đơn > QR và thông tin chuyển khoản > IPN xác nhận tiền > ẩn QR, hiện bảng Thanh toán thành công ngay tại chỗ > phát event cho GTM.
Mặc định KHÔNG tự chuyển trang khi thành công. Có liên kết Xem chi tiết đơn hàng để khách chủ động mở trang WooCommerce, lấy tệp tải xuống hoặc xem thông tin đơn.
Nếu chọn URL cảm ơn riêng: thông báo/event thành công trước, chuyển sau 1,5 giây.
Luồng chuyển sang Pay2S vẫn giữ trang trung gian phát event tạo đơn; không thay đổi thành tích hợp CAPI.

GIAO DIỆN
Dropdown chọn ngân hàng có logo, một QR mỗi lần; QR và hướng dẫn ở trái, số tiền và thông tin sao chép ở phải. Mobile xếp một cột.
Hiệu ứng scan nhẹ, icon Pay2S nhỏ ở giữa. Tắt chuyển động nếu thiết bị yêu cầu giảm chuyển động.
Không hiển thị đếm ngược hết hạn giả: API tạo thanh toán chưa có trường expiry rõ ràng cho plugin dùng. Tự kiểm tra trạng thái mỗi 1 giây sau phản hồi trước khi tab hiển thị, tối đa 30 phút mỗi lần mở; việc dừng polling không có nghĩa phiên hết hạn/thất bại.

HỦY ĐƠN
Popup xác nhận trong giao diện. Backend kiểm tra order key/nonce rồi gọi /v1/gateway/api/cancel-checkout của Pay2S với token phiên.
Chỉ hủy WooCommerce khi Pay2S xác nhận. Cổng thanh toán cần hỗ trợ endpoint và token có ký còn hạn. Nếu lỗi, không giả báo đã hủy.
Hủy thành công phát event thất bại reason_code=ORDER_CANCELLED, ẩn QR và chuyển về trang kết quả hủy WooCommerce sau 3 giây (giữ hành vi bản 1.3.5).

TRACKING
Xem TRACKING-GTM.txt. pay2s_payment_success phát SAU KHI bảng thành công đã hiện, cùng trang và cùng domain shop.
Meta Pixel/GTM phải được shop cài trên trang thanh toán. Plugin phát dataLayer/CustomEvent và PHP hooks, không tự gửi Pixel/CAPI.
Không ánh xạ Purchase cho cả event success lẫn alias confirmed. Chỉ một trigger cho một chuyển đổi.
Khách đóng trang thì browser không nhận event; tích hợp server qua PHP hook nếu cần CAPI, queue/retry và dedup tại nơi nhận.
Loại trừ URL query pay2s_order và /wc-api/ khỏi cache CDN/plugin cache. Không công khai URL có order key.

KIỂM TRA
Qua kiểm tra backend checkout/IPN/hủy, hồi quy hóa đơn, browser desktop/mobile dropdown/sao chép/dialog, thành công ở nguyên trang và bảng kết quả hiện trước event. Chưa thử thanh toán thật, Pixel thật hoặc mọi theme WooCommerce.

TĂNG TỐC 1.3.8
- Poll trạng thái mỗi 1 giây sau phản hồi trước, không gửi chồng request.
- Tab ẩn tạm dừng; quay lại kiểm tra ngay nếu không có request đang chạy.
- Khi lỗi mạng/API, giãn retry từ 3 tới tối đa 15 giây; phản hồi thành công trở về 1 giây. Không phát event thất bại vì lỗi mạng.
- Dừng sau khi có kết quả thanh toán/hủy. Thời gian webhook và mạng vẫn ảnh hưởng tốc độ thực tế.

CHẨN ĐOÁN
F12 > Network > pay2s_order_status > Response:
webhook_received_at_ms: thời điểm shop nhận IPN hợp lệ đầu tiên cho kết quả hiện tại (Unix milliseconds); đơn cũ chưa có hoặc chưa nhận IPN sẽ là null.
server_time_ms: thời điểm shop trả kết quả kiểm tra.
F12 > Console > window.pay2sTiming:
request_duration_ms: thời gian gọi API ở trình duyệt.
webhook_to_status_ms: độ chênh giữa nhận IPN và phản hồi kiểm tra, tính cùng đồng hồ server. Nếu mở lại đơn cũ thì đây là tuổi của kết quả, không phải thời gian trễ ban đầu.
Không suy ra được ngân hàng chuyển tiền -> Pay2S gửi webhook chỉ bằng các mốc này; cần đối chiếu log phía Pay2S khi webhook_received_at_ms còn null.
Đã kiểm tra chu kỳ 1 giây, tạm dừng/tiếp tục khi đổi tab, không gửi chồng request và giữ kết quả thành công tại trang. Chưa đo latency production.

1.3.8: IPN hợp lệ đã xử lý trả HTTP 200 và success=true, kể cả kết quả hủy. Worker nhận ACK đúng và không retry chỉ vì nội dung message khác nhau. Callback sai chữ ký/đơn/số tiền vẫn không ACK thành công.
