2

Authorize.net Direct Post を支払い方法として使用するサイトを構築していますが、注文が正常に完了した後、カートが非アクティブ化されないという問題が発生しています。Mage_Authorizenet_Model_Directpost では、注文承認ステップの一環として、574 行で見積もりが無効化されていることを確認できました。

Mage::getModel('sales/quote')
    ->load($order->getQuoteId())
    ->setIsActive(false)
    ->save();

ただし、directpost.js では、Authorize.net が IFrame をロードし、returnQuote 関数が呼び出されると、_returnCustomerQuote 関数を呼び出す Mage_Authorizenet_Directpost_PaymentController の returnQuoteAction にリダイレクトされます。

if ($order->getId()) {
            $quote = Mage::getModel('sales/quote')
                ->load($order->getQuoteId());
            if ($quote->getId()) {
                $quote->setIsActive(1)
                    ->setReservedOrderId(NULL)
                    ->save();
                $this->_getCheckout()->replaceQuote($quote);
            }
            $this->_getDirectPostSession()->removeCheckoutOrderIncrementId($incrementId);
            $this->_getDirectPostSession()->unsetData('quote_id');
            if ($cancelOrder) {
                $order->registerCancellation($errorMsg)->save();
            }
        }

見積が再び有効に設定されていることに注意してください。注文がキャンセルされない限り、なぜ彼らがこれを行うのかわかりません。ここのロジックに何かが欠けているのではないかと考えています。ワンページ チェックアウトのカスタマイズと、実際の注文送信のカスタマイズを行いましたが、これに影響するものは見当たりません。Magento は、コール チェーンの後半で見積もりが無効になることを期待していますか? Authorize.net Direct Post がローカルに応答を中継しないため、コードをステップ実行できないため、これをデバッグするのは困難です。

提供できるヘルプをありがとう。

4

1 に答える 1

2

私が知る限り、Authorize.net からのリクエスト パラメータにエラー メッセージが含まれていれば、成功したとしても _returnCustomerQuote を呼び出すことができるようです。これは、Mage_Authorizenet_Directpost_PaymentController の redirectAction からのものです。

    if (!empty($redirectParams['success'])
        && isset($redirectParams['x_invoice_num'])
        && isset($redirectParams['controller_action_name'])
    ) {
        $this->_getDirectPostSession()->unsetData('quote_id');
        $params['redirect_parent'] = Mage::helper('authorizenet')->getSuccessOrderUrl($redirectParams);
    }
    if (!empty($redirectParams['error_msg'])) {
        $cancelOrder = empty($redirectParams['x_invoice_num']);
        $this->_returnCustomerQuote($cancelOrder, $redirectParams['error_msg']);
    }

しかし、私の状況では、access.log [結合] を見ると、/checkout/onepagegoing からのエントリがあることがわかりました/authorizenet/directpost_payment/returnQuote

しばらくの間私の髪を引っ張ってコードを掘り下げ、いくつかの調査を行った後、これは directpost.js の onLoadIframe にバインドされている loadIframe 関数のバグにすぎないように感じます。

     loadIframe : function() {
        if (this.paymentRequestSent) {
            switch (this.controller) {
                case 'onepage':
                    this.paymentRequestSent = false;
                    if (!this.hasError) {
                        this.returnQuote();
                    }
                    break;
                case 'sales_order_edit':
                case 'sales_order_create':
                    if (!this.orderRequestSent) {
                        this.paymentRequestSent = false;
                        if (!this.hasError) {
                            this.returnQuote();
                        } else {
                            this.changeInputOptions('disabled', false);
                            toggleSelectsUnderBlock($('loading-mask'), true);
                            $('loading-mask').hide();
                            enableElements('save');
                        }
                    }
                    break;
            }
            if (this.tmpForm) {
                document.body.removeChild(this.tmpForm);
            }
        }
    },

リダイレクトアクションがiframeを埋めたときに支払い要求が送信されたかどうかを確認しているようです。支払い要求が送信された場合、それが onepage コントローラーを使用していた場合、および応答にエラーがなかった場合は、見積もりを返し、それをアクティブのままにし、アイテムはカートに残ります...

それは私には意味がないので、this.hasError から強打を削除しました。注文後にカートがクリアされ、他に問題はないようです

今はこんな感じです、誰かに間違っていると言ってもらいたいです(マジで)。

loadIframe : function() {
    if (this.paymentRequestSent) {
        switch (this.controller) {
            case 'onepage':
                this.paymentRequestSent = false;
                if (this.hasError) {
                    this.returnQuote();
                }
                break;
            case 'sales_order_edit':
            case 'sales_order_create':
                if (!this.orderRequestSent) {
                    this.paymentRequestSent = false;
                    if (!this.hasError) {
                        this.returnQuote();
                    } else {
                        this.changeInputOptions('disabled', false);
                        toggleSelectsUnderBlock($('loading-mask'), true);
                        $('loading-mask').hide();
                        enableElements('save');
                    }
                }
                break;
        }
        if (this.tmpForm) {
            document.body.removeChild(this.tmpForm);
        }
    }
},

'sales_order_create' コントローラーの場合はこのようになりますが、今のところ Magento はそのままにしておきます。

于 2015-05-21T23:15:23.460 に答える