Tôi cần phải ủy quyền, thực hiện một số cuộc gọi API của bên thứ 3 và dựa trên những gì trả về từ các cuộc gọi đó, hoặc nắm bắt hoặc hủy ủy quyền.
Hiện tại tôi đang sử dụng chỉ Authorize.net, nhưng tôi muốn điều này có thể cho càng nhiều cổng thanh toán càng tốt. Tôi có Authorize.net được đặt thành Chỉ ủy quyền. Người quan sát của tôi chạy trong sự kiện sales_order_payment_place_end.
Đây là những gì tôi đang làm trong trình quan sát của mình (chưa được tóm tắt, vẫn cần bằng chứng về khái niệm):
if(/*API calls return ok*/)
{
$observer->getPayment()->getMethod_instance()->capture($observer->getPayment(),$observer->getPayment()->getAmount());
}
else
{
Mage::dispatchEvent('Mainstreethost_MicrosOrder_Failure');
$observer->getPayment()->getMethod_instance()->cancel($observer->getPayment());
}
Khi tôi gọi chụp (), nó sẽ kiểm tra xem khoản thanh toán có được ủy quyền trước hay không, đó là những gì chúng tôi đang cố gắng thực hiện:
public function capture(Varien_Object $payment, $amount)
{
if ($amount <= 0) {
Mage::throwException(Mage::helper('paygate')->__('Invalid amount for capture.'));
}
$this->_initCardsStorage($payment);
if ($this->_isPreauthorizeCapture($payment)) {
$this->_preauthorizeCapture($payment, $amount);
} else if ($this->isPartialAuthorization($payment)) {
$this->_partialAuthorization($payment, $amount, self::REQUEST_TYPE_AUTH_CAPTURE);
} else {
$this->_place($payment, $amount, self::REQUEST_TYPE_AUTH_CAPTURE);
}
$payment->setSkipTransactionCreation(true);
return $this;
}
_isPreauthorizedCapture () cố gắng gán $ lastTransaction:
protected function _isPreauthorizeCapture($payment)
{
if ($this->getCardsStorage()->getCardsCount() <= 0) {
return false;
}
foreach($this->getCardsStorage()->getCards() as $card) {
$lastTransaction = $payment->getTransaction($card->getLastTransId());
if (!$lastTransaction
|| $lastTransaction->getTxnType() != Mage_Sales_Model_Order_Payment_Transaction::TYPE_AUTH
) {
return false;
}
}
return true;
}
$ lastTransaction luôn trả về false. Điều này là do $ thanh toán-> getTransaction () cuối cùng gọi _lookupTransaction ():
protected function _lookupTransaction($txnId, $txnType = false)
{
if (!$txnId) {
if ($txnType && $this->getId()) {
$collection = Mage::getModel('sales/order_payment_transaction')->getCollection()
->setOrderFilter($this->getOrder())
->addPaymentIdFilter($this->getId())
->addTxnTypeFilter($txnType)
->setOrder('created_at', Varien_Data_Collection::SORT_ORDER_DESC)
->setOrder('transaction_id', Varien_Data_Collection::SORT_ORDER_DESC);
foreach ($collection as $txn) {
$txn->setOrderPaymentObject($this);
$this->_transactionsLookup[$txn->getTxnId()] = $txn;
return $txn;
}
}
return false;
}
if (isset($this->_transactionsLookup[$txnId])) {
return $this->_transactionsLookup[$txnId];
}
$txn = Mage::getModel('sales/order_payment_transaction')
->setOrderPaymentObject($this)
->loadByTxnId($txnId);
if ($txn->getId()) {
$this->_transactionsLookup[$txnId] = $txn;
} else {
$this->_transactionsLookup[$txnId] = false;
}
return $this->_transactionsLookup[$txnId];
}
Bây giờ, phương thức này được gọi hai lần, một lần để ủy quyền và một lần khi tôi gọi chụp () trong trình quan sát. Cuộc gọi ủy quyền sẽ bỏ qua dòng này:
$txn = Mage::getModel('sales/order_payment_transaction')
->setOrderPaymentObject($this)
->loadByTxnId($txnId);
Và trả về một đối tượng giao dịch với dữ liệu null. Lý do tại sao điều này xảy ra?
Bởi vì phương thức loadObjectByTxnId () trong Mage_Sales_Model_Resource_Order_Payment_Transaction gán dữ liệu $ thành false:
public function loadObjectByTxnId(Mage_Sales_Model_Order_Payment_Transaction $transaction, $orderId, $paymentId,
$txnId)
{
$select = $this->_getLoadByUniqueKeySelect($orderId, $paymentId, $txnId);
$data = $this->_getWriteAdapter()->fetchRow($select);
$transaction->setData($data);
$this->unserializeFields($transaction);
$this->_afterLoad($transaction);
}
$ data là những gì hydrat hóa đối tượng lớp $ txn trong _lookupTransaction ()! Trong trường hợp bạn đang tự hỏi, đây là những gì truy vấn sql thực sự là:
SELECT `sales_payment_transaction`.* FROM `sales_payment_transaction` WHERE (order_id = '38') AND (payment_id = '38') AND (txn_id = '2217720876')
Cái bàn đó luôn trống không.
Nhưng chờ đã! Có quá nhiều thứ sẽ trở nên tồi tệ!
Trong cuộc gọi thứ hai (bắt cuộc gọi) đến _lookupTransaction (), điều này nếu bị ngắt:
if (isset($this->_transactionsLookup[$txnId])) {
return $this->_transactionsLookup[$txnId];
}
Nhưng giá trị đó là sai, có nghĩa là _isPreauthorizeCapture () trả về false và sau đó bắt () ném một lỗi, nói rằng tôi cần phải có số thẻ tín dụng.