Tôi mới sử dụng Drupal và phải tạo một cổng thanh toán ngoài trang web (với Drupal Commerce 2). Tất cả đều hoạt động, nhưng đôi khi không.
Máy chủ của nhà cung cấp dịch vụ thanh toán từ xa gửi yêu cầu thông báo đến máy chủ, về trạng thái của khoản thanh toán, vì vậy tôi có cả hai onReturn
và onThông báo
trong lớp Cổng thanh toán.
Từ onReturn
không đảm bảo sẽ được gọi (khách hàng có thể đóng trình duyệt, v.v. và nhà cung cấp không nhất thiết phải gửi lại cho anh ta trong trường hợp của tôi), nhưng onThông báo
được đảm bảo để được gọi, tôi tạo và lưu Sự chi trả
đối tượng trong onThông báo
, không ở onReturn
, khi thanh toán xong. (Đây cũng là những gì tài liệu gợi ý để làm: https://docs.drupalcommerce.org/commerce2/developer-guide/payments/create-payment-gateway/off-site-gateways/handling-ipn)
Vì vậy, mã của tôi trông giống như thế này. (Đó là một mã giả rất đơn giản; kiểm tra xác thực không được bao gồm.)
class RedirectCheckout extends OffsitePaymentGatewayBase implements SupportsNotificationsInterface {
hàm công khai onReturn() {
$is_order_accepted = /* Kiểm tra nhà cung cấp dịch vụ thanh toán từ xa đã chấp nhận đơn đặt hàng */
nếu (!$is_order_accepted) {
ném NeedsRedirectException() mới
}
// Nếu tất cả đều tốt, không làm gì cả.
}
hàm công khai onNotify() {
/** @var OrderInterface $order */
$order = /* Tải đơn hàng sắp có thông báo */
$is_order_accepted = /* Kiểm tra nhà cung cấp dịch vụ thanh toán từ xa đã chấp nhận đơn đặt hàng */
nếu ($is_order_accepted) {
$thanh toán = $payment_storage->create();
$thanh toán->lưu();
$order->setData('transaction_id', $transactionId);
$order->save(); // Đây là những gì đôi khi bị ghi đè bởi onReturn(), tôi tin vậy.
}
}
}
Lưu ý rằng tôi cần lưu một số dữ liệu về đơn hàng, khi đơn hàng được chấp nhận (không có sẵn khi đơn hàng được tạo, chỉ khi thanh toán thành công).
Tài liệu Drupal Commerce nói rằng bạn "không cần (và không nên)" chạm vào đơn đặt hàng, nhưng tôi phải lưu một số dữ liệu bổ sung về đơn đặt hàng mà các bộ phận khác trên hệ thống dự kiến sẽ có ở đó.
Điều này thường hoạt động. Tuy nhiên, hai onReturn
và onThông báo
các yêu cầu từ máy chủ từ xa đôi khi đến gần như cùng một lúc, điều mà tôi tin rằng sẽ dẫn đến tình trạng chạy đua.
Thật không may, mặc dù tôi không làm gì với thứ tự trong onReturn
, Thương mại dường như vẫn giữ trật tự. Tôi tin rằng điều này đôi khi có thể ghi đè dữ liệu được lưu vào đơn đặt hàng bởi onThông báo
. Ví dụ:
onReturn
bắt đầu chạy và tải đơn đặt hàng (Việc này do chính thư viện thương mại thực hiện nên tôi không thể làm gì về việc này.)
- Yêu cầu thông báo đến, vì vậy
onThông báo
bắt đầu chạy, tải và lưu đơn đặt hàng, rồi trả về
- Sau này, các
onReturn
phương thức trả về, trả lại quyền kiểm soát cho Commerce, giúp lưu lại đơn đặt hàng; vì nó đã tải đối tượng đặt hàng trước đó onThông báo
đã lưu nó, nó ghi đè lên bất cứ điều gì onThông báo
đã viết với dữ liệu cũ
(Có lẽ thứ tự ngược lại cũng có thể có vấn đề, trong đó onThông báo
có thể ghi đè bất kỳ dữ liệu nào được Drupal Commerce lưu vào đơn đặt hàng ở hậu trường, nếu có, trong quá trình onReturn
yêu cầu.)
Có cách nào tốt để xử lý việc này không, ví dụ như giải quyết vấn đề về điều kiện chủng tộc để có thể lưu dữ liệu đơn hàng vào onThông báo
?
Tôi đang sử dụng Drupal 8.6.