ฉันเพิ่งเริ่มใช้ Drupal และต้องสร้างเกตเวย์การชำระเงินนอกสถานที่ (ด้วย Drupal Commerce 2) ทุกอย่างใช้งานได้ แต่บางครั้งก็ไม่ทำงาน
เซิร์ฟเวอร์ของผู้ให้บริการชำระเงินทางไกลส่งคำขอการแจ้งเตือนไปยังเซิร์ฟเวอร์ เกี่ยวกับสถานะของการชำระเงิน ดังนั้นฉันจึงมีทั้งสองอย่าง เมื่อกลับมา
และ เมื่อแจ้งเตือน
ในคลาส PaymentGateway
เนื่องจาก เมื่อกลับมา
ไม่รับประกันว่าจะถูกเรียก (ลูกค้าอาจปิดเบราว์เซอร์ ฯลฯ และผู้ให้บริการไม่จำเป็นต้องส่งเขากลับในกรณีของฉัน) แต่ เมื่อแจ้งเตือน
รับประกันว่าจะเรียกฉันสร้างและบันทึก การชำระเงิน
คัดค้านใน เมื่อแจ้งเตือน
, ไม่เข้า เมื่อกลับมา
, เมื่อชำระเงินเรียบร้อยแล้ว. (นี่คือสิ่งที่เอกสารแนะนำให้ทำ: https://docs.drupalcommerce.org/commerce2/developer-guide/payments/create-payment-gateway/off-site-gateways/handling-ipn)
รหัสของฉันจึงมีลักษณะดังนี้ (เป็นรหัสเทียมที่เรียบง่ายมาก ไม่รวมการตรวจสอบความถูกต้อง)
คลาส RedirectCheckout ขยาย OffsitePaymentGatewayBase ใช้ SupportsNotificationsInterface {
ฟังก์ชั่นสาธารณะ onReturn () {
$is_order_accepted = /* ตรวจสอบว่าผู้ให้บริการชำระเงินทางไกลยอมรับคำสั่งซื้อแล้ว */
ถ้า (!$is_order_accepted) {
โยน NeedsRedirectException ใหม่ ()
}
// ถ้าทุกอย่างดีแล้ว ไม่ต้องทำอะไร
}
ฟังก์ชั่นสาธารณะ onNotify () {
/** @var OrderInterface $คำสั่ง */
$order = /* โหลดคำสั่งซื้อที่มีการแจ้งเตือน */
$is_order_accepted = /* ตรวจสอบว่าผู้ให้บริการชำระเงินทางไกลยอมรับคำสั่งซื้อแล้ว */
ถ้า ($is_order_accepted) {
$payment = $payment_storage->สร้าง ();
$payment->save();
$order->setData('transaction_id', $transactionId);
$order->save(); // นี่คือสิ่งที่บางครั้งเขียนทับโดย onReturn() ฉันเชื่อ
}
}
}
โปรดทราบว่าฉันจำเป็นต้องบันทึกข้อมูลบางอย่างในคำสั่งซื้อ เมื่อคำสั่งซื้อได้รับการยอมรับ (ซึ่งไม่สามารถใช้งานได้เมื่อสร้างคำสั่งซื้อ เฉพาะเมื่อชำระเงินสำเร็จแล้วเท่านั้น)
เอกสารประกอบของ Drupal Commerce ระบุว่าคุณ "ไม่จำเป็น (และไม่ควร)" แตะที่คำสั่งซื้อ แต่ฉันต้องบันทึกข้อมูลเพิ่มเติมเกี่ยวกับคำสั่งซื้อที่ส่วนอื่นๆ ในระบบคาดว่าจะมีอยู่
สิ่งนี้มักจะได้ผล อย่างไรก็ตามทั้งสอง เมื่อกลับมา
และ เมื่อแจ้งเตือน
คำขอจากเซิร์ฟเวอร์ระยะไกลบางครั้งมาถึงในเวลาเดียวกัน ซึ่งฉันเชื่อว่านำไปสู่สภาวะการแย่งชิง
น่าเสียดายที่แม้ว่าฉันจะไม่ได้ทำอะไรตามคำสั่ง เมื่อกลับมา
ดูเหมือนว่าการค้าจะยังคงบันทึกคำสั่งซื้อ ฉันเชื่อว่าบางครั้งสิ่งนี้สามารถเขียนทับข้อมูลที่บันทึกไว้ในคำสั่งซื้อโดย เมื่อแจ้งเตือน
. ตัวอย่างเช่น:
เมื่อกลับมา
เริ่มทำงานและโหลดคำสั่งซื้อ (ดำเนินการโดยไลบรารีการค้าเอง ดังนั้นฉันจึงไม่สามารถทำอะไรเกี่ยวกับเรื่องนี้ได้)
- คำขอแจ้งเตือนมาถึงดังนั้น
เมื่อแจ้งเตือน
เริ่มทำงาน โหลดและบันทึกคำสั่งซื้อ และส่งคืน
- หลังจากนี้ ผ
เมื่อกลับมา
เมธอดส่งคืน ให้การควบคุมแก่ Commerce ซึ่งจะบันทึกคำสั่งซื้ออีกครั้ง เนื่องจากโหลดวัตถุคำสั่งซื้อมาก่อน เมื่อแจ้งเตือน
บันทึกมันเขียนทับอะไรก็ตาม เมื่อแจ้งเตือน
เขียนด้วยข้อมูลเก่า
(บางทีคำสั่งสนทนาอาจเป็นปัญหาได้เช่นกัน โดยที่ เมื่อแจ้งเตือน
สามารถเขียนทับข้อมูลใด ๆ ที่บันทึกไว้ในคำสั่งซื้อโดย Drupal Commerce ที่อยู่เบื้องหลัง หากมี ในระหว่าง เมื่อกลับมา
ขอ.)
มีวิธีจัดการที่ดีหรือไม่ เช่น หลีกเลี่ยงสภาพการแข่งขันเพื่อให้สามารถบันทึกข้อมูลการสั่งซื้อได้ เมื่อแจ้งเตือน
?
ฉันใช้ Drupal 8.6