6

Magento (v1.5) が、1 ページのチェックアウトでも定義されている配送ルールに基づいて、登録された Paypal ユーザーの国に基づいて配送を計算しないという問題があります。Paypal Express を使用する場合、Paypal にログインした後、ユーザーは注文を確認するために当社のサイトにリダイレクトされますが、配送オプションが選択されていない (または選択できない) ため、顧客は注文できません。

この解決策は私にはうまくいきません: http://www.magentocommerce.com/boards/viewthread/211273/

私が得るのは、「配送方法 申し訳ありませんが、現時点ではこの注文の見積もりはありません.」

ユーザーが「Place Order」を押しても何も起こりません。利用できる配送方法がないと静かに不平を言っているからです。(もちろん、利用可能な配送方法があり、通常のチェックアウトを通過すると自動的に選択されます).

他のフォーラム投稿も、カスタム テーマが問題の原因であることを示唆しています。カスタム テーマからすべての Paypal コンテンツを削除して、Magento が基本/既定のテンプレート ファイルとレイアウトを使用していることを確認しました。

アイデアはありますか?

4

2 に答える 2

4

Oscar Reales からの次のコードはうまくいきましたが、どこからダウンロードしたか思い出せません! もう 1 つの解決策は、Paypal Standard を使用することです。

/**
 * Overload of Mage_Paypal_Model_Express_Checkout to fix bug with user registration.
  *
  * Currently, when users choose "Register" in the buying process
  * And then choose "Paypal Express Checkout" as a method of payment,
  * User registration does not occur,
  * And the order is not assigned to the client, but remains "anonymous".
 * 
 * @see Mage_Paypal_Model_Express_Checkout
 * @see Mage_Checkout_Model_Type_Onepage
 * 
 * @author Oscar Reales <oreales@gmail.com>
 * @author Oscar Reales <oscar.reales@interactiv4.com>
 */
class Mg_Paypal_Model_Express_Checkout extends Mage_Paypal_Model_Express_Checkout
{

    /**
     * Update quote when returned from PayPal
     * @param string $token
     */
    public function returnFromPaypal($token)
    {
        $this->_getApi();
        $this->_api->setToken($token)
            ->callGetExpressCheckoutDetails();

        //modified
        //do not import the billing address from Paypal, we use the data that the user entered in the onsite Checkout
        /*$billingAddress = $this->_quote->getBillingAddress();
        $exportedBillingAddress = $this->_api->getExportedBillingAddress();
        foreach ($exportedBillingAddress->getExportedKeys() as $key) {
            $billingAddress->setDataUsingMethod($key, $exportedBillingAddress->getData($key));
        }*/

        //modified
        //do not import the shipping address from Paypal, we use the data that the user entered in the onsite Checkout
        /*$exportedShippingAddress = $this->_api->getExportedShippingAddress();
        if (!$this->_quote->getIsVirtual()) {
            $shippingAddress = $this->_quote->getShippingAddress();
            if ($shippingAddress) {
                if ($exportedShippingAddress) {
                    foreach ($exportedShippingAddress->getExportedKeys() as $key) {
                        $shippingAddress->setDataUsingMethod($key, $exportedShippingAddress->getData($key));
                    }
                    $shippingAddress->setCollectShippingRates(true);
                }

                // import shipping method
                $code = '';
                if ($this->_api->getShippingRateCode()) {
                    if ($code = $this->_matchShippingMethodCode($shippingAddress, $this->_api->getShippingRateCode())) {
                         // possible bug of double collecting rates :-/
                        $shippingAddress->setShippingMethod($code)->setCollectShippingRates(true);
                    }
                }
                $this->_quote->getPayment()->setAdditionalInformation(self::PAYMENT_INFO_TRANSPORT_SHIPPING_METHOD, $code);
            }
        }*/
        $this->_ignoreAddressValidation();

        // import payment info
        $payment = $this->_quote->getPayment();
        $payment->setMethod($this->_methodType);
        Mage::getSingleton('paypal/info')->importToPayment($this->_api, $payment);
        $payment->setAdditionalInformation(self::PAYMENT_INFO_TRANSPORT_PAYER_ID, $this->_api->getPayerId())
            ->setAdditionalInformation(self::PAYMENT_INFO_TRANSPORT_TOKEN, $token)
        ;
        $this->_quote->collectTotals()->save();
    }



    /**
      * Override the parent because core code does not take into account whether the user
      * Has chosen to register or not. It makes no difference under checkout_method chosen by the user.
      * Simply: if the customer does not have a quote, the core code saves it as Guest, NOT_LOGGED_IN group
      * And saves the email in the billing Address along with the order.
      *
      * This behavior is not what we want. We save the customer if the user has
      * elected to register and not place the order as GUEST
     *
     * @param string $token
     * @param string $shippingMethodCode
     */
    public function place($token, $shippingMethodCode = null)
    {
        if ($shippingMethodCode) {
            $this->updateShippingMethod($shippingMethodCode);
        }

        //modified
        //check if the checkout method was chosen as a guest user or registering
        $isNewCustomer = false;
        switch ($this->_quote->getCheckoutMethod()) {
            case Mage_Checkout_Model_Type_Onepage::METHOD_GUEST:
                $this->_prepareGuestQuote();
                break;
            case Mage_Checkout_Model_Type_Onepage::METHOD_REGISTER:
                $this->_prepareNewCustomerQuote();
                $isNewCustomer = true;
                break;
        }
        //fin modification

        //modified
        //this code is no longer necessary with the previous change
        /*if (!$this->_quote->getCustomerId()) {
            $this->_quote->setCustomerIsGuest(true)
                ->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID)
                ->setCustomerEmail($this->_quote->getBillingAddress()->getEmail());
        }*/
        //fin modification

        $this->_ignoreAddressValidation();
        $this->_quote->collectTotals();
        $service = Mage::getModel('sales/service_quote', $this->_quote);
        $service->submitAll();
        $this->_quote->save();
        $this->_recurringPaymentProfiles = $service->getRecurringPaymentProfiles();
        // TODO: send recurring profile emails


        //modified
        //after saving the order and the customer, send relevant emails if this is a new customer
        if ($isNewCustomer) {
            try {
                $this->_involveNewCustomer();
            } catch (Exception $e) {
                Mage::logException($e);
            }
        }
        //fin modificacion

        $order = $service->getOrder();
        if (!$order) {
            return;
        }
        $this->_billingAgreement = $order->getPayment()->getBillingAgreement();

        // commence redirecting to finish payment, if paypal requires it
        if ($order->getPayment()->getAdditionalInformation(Mage_Paypal_Model_Express_Checkout::PAYMENT_INFO_TRANSPORT_REDIRECT)) {
            $this->_redirectUrl = $this->_config->getExpressCheckoutCompleteUrl($token);
        }

        switch ($order->getState()) {
            // even after placement paypal can disallow to authorize/capture, but will wait until bank transfers money
            case Mage_Sales_Model_Order::STATE_PENDING_PAYMENT:
                // TODO
                break;
            // regular placement, when everything is ok
            case Mage_Sales_Model_Order::STATE_PROCESSING:
            case Mage_Sales_Model_Order::STATE_COMPLETE:
            case Mage_Sales_Model_Order::STATE_PAYMENT_REVIEW:
                $order->sendNewOrderEmail();
                break;
        }
        $this->_order = $order;
    }


    /**
     * Prepare quote for guest checkout order submit
     *
     * @see Mage_Checkout_Model_Type_Onepage::_prepareGuestQuote()
     *
     * @return Mg_Paypal_Model_Express_Checkout
     */
    protected function _prepareGuestQuote()
    {
        $quote = $this->_quote;
        $quote->setCustomerId(null)
            ->setCustomerEmail($quote->getBillingAddress()->getEmail())
            ->setCustomerIsGuest(true)
            ->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID);
        return $this;
    }


    /**
     * Prepare quote for customer registration and customer order submit
     * 
     * @see Mage_Checkout_Model_Type_Onepage::_prepareNewCustomerQuote()
     *
     */
    protected function _prepareNewCustomerQuote()
    {
        $quote      = $this->_quote;
        $billing    = $quote->getBillingAddress();
        $shipping   = $quote->isVirtual() ? null : $quote->getShippingAddress();

        //$customer = Mage::getModel('customer/customer');
        $customer = $quote->getCustomer();
        /* @var $customer Mage_Customer_Model_Customer */
        $customerBilling = $billing->exportCustomerAddress();
        $customer->addAddress($customerBilling);
        $billing->setCustomerAddress($customerBilling);
        $customerBilling->setIsDefaultBilling(true);
        if ($shipping && !$shipping->getSameAsBilling()) {
            $customerShipping = $shipping->exportCustomerAddress();
            $customer->addAddress($customerShipping);
            $shipping->setCustomerAddress($customerShipping);
            $customerShipping->setIsDefaultShipping(true);
        } elseif ($shipping) {
            $customerBilling->setIsDefaultShipping(true);
        }
        /**
         * @todo integration with dynamica attributes customer_dob, customer_taxvat, customer_gender
         */
        if ($quote->getCustomerDob() && !$billing->getCustomerDob()) {
            $billing->setCustomerDob($quote->getCustomerDob());
        }

        if ($quote->getCustomerTaxvat() && !$billing->getCustomerTaxvat()) {
            $billing->setCustomerTaxvat($quote->getCustomerTaxvat());
        }

        if ($quote->getCustomerGender() && !$billing->getCustomerGender()) {
            $billing->setCustomerGender($quote->getCustomerGender());
        }

        Mage::helper('core')->copyFieldset('checkout_onepage_billing', 'to_customer', $billing, $customer);
        $customer->setPassword($customer->decryptPassword($quote->getPasswordHash()));
        $customer->setPasswordHash($customer->hashPassword($customer->getPassword()));
        $quote->setCustomer($customer)
            ->setCustomerId(true);
    }


    /**
     * Involve new customer to system
     * 
     * @see Mage_Checkout_Model_Type_Onepage::_involveNewCustomer()
     *
     * @return Mg_Paypal_Model_Express_Checkout
     */
    protected function _involveNewCustomer()
    {
        $customer = $this->_quote->getCustomer();
        if ($customer->isConfirmationRequired()) {
            $customer->sendNewAccountEmail('confirmation');
            $url = Mage::helper('customer')->getEmailConfirmationUrl($customer->getEmail());
            Mage::getSingleton('customer/session')->addSuccess(
                Mage::helper('customer')->__('Account confirmation is required. Please, check your e-mail for confirmation link. To resend confirmation email please <a href="%s">click here</a>.', $url)
            );
        } else {
            $customer->sendNewAccountEmail();
            Mage::getSingleton('customer/session')->loginById($customer->getId());
        }
        return $this;
    }



    /**
      *  we extend it simply because it is defined as private in the parent
      *  And if nothing changes, we have the obligation to extend to
     */
    private function _ignoreAddressValidation()
    {
        $this->_quote->getBillingAddress()->setShouldIgnoreValidation(true);
        if (!$this->_quote->getIsVirtual()) {
            $this->_quote->getShippingAddress()->setShouldIgnoreValidation(true);
        }
    }


}
于 2012-03-03T13:29:41.703 に答える
3

私は3つの問題を見つけましたが、最終的にはこれが機能するようになりました(賞金は十分に費やされました:))。それらがすべてどこから来たのかはわかりませんが、Magentoのアップグレードとこのモジュールのさまざまなテンプレートの変更に関係しているのではないかと思われます。最初の問題はこの行でした:

<?php if (!($_shippingRateGroups = $this->getShippingRates())): ?>

どちらを読む必要があります:

<?php if (!($_shippingRateGroups = $this->getShippingRateGroups())): ?>

2番目の問題は、$this->getUrlいくつかの場所で繰り返される機能でした。これを完全に削除し、URLをハードコーディングしました。

最後に、$this->getCurrentShippingRate関数は現在のレートを返していませんでした。getCurrentShippingRate関数を次のように変更しapp/code/core/Mage/Paypal/Block/Express/Review.phpました。

public function getCurrentShippingRate()
{
    $this->_address = $this->_quote->getShippingAddress();
    return $this->_address->getShippingMethod();
    //return $this->_currentShippingRate;
}
于 2012-03-02T12:46:25.057 に答える