0

paypal 模块尝试将 Paypal 返回的帐单信息(通常没有)映射到用户在结帐过程中输入的帐单信息。我喜欢在 NVP.php 模型中执行此操作的代码。

/**
     * Create billing and shipping addresses basing on response data
     * @param array $data
     */
    protected function _exportAddressses($data)
    {
        $address = new Varien_Object();
        Varien_Object_Mapper::accumulateByMap($data, $address, $this->_billingAddressMap);
        $address->setExportedKeys(array_values($this->_billingAddressMap));
        $this->_applyStreetAndRegionWorkarounds($address);
        $this->setExportedBillingAddress($address);

        // assume there is shipping address if there is at least one field specific to shipping
        if (isset($data['SHIPTONAME'])) {
            $shippingAddress = clone $address;
            Varien_Object_Mapper::accumulateByMap($data, $shippingAddress, $this->_shippingAddressMap);
            $this->_applyStreetAndRegionWorkarounds($shippingAddress);
            // PayPal doesn't provide detailed shipping name fields, so the name will be overwritten
            $shippingAddress->addData(array(
                'prefix'     => null,
                'firstname'  => $data['SHIPTONAME'],
                'middlename' => null,
                'lastname'   => null,
                'suffix'     => null,
            ));
            $this->setExportedShippingAddress($shippingAddress);
        }
    }

    /**
     * Adopt specified address object to be compatible with Magento
     *
     * @param Varien_Object $address
     */
    protected function _applyStreetAndRegionWorkarounds(Varien_Object $address)
    {
        // merge street addresses into 1
        if ($address->hasStreet2()) {
             $address->setStreet(implode("\n", array($address->getStreet(), $address->getStreet2())));
             $address->unsStreet2();
        }
        // attempt to fetch region_id from directory
        if ($address->getCountryId() && $address->getRegion()) {
            $regions = Mage::getModel('directory/country')->loadByCode($address->getCountryId())->getRegionCollection()
                ->addRegionCodeFilter($address->getRegion())
                ->setPageSize(1)
            ;
            foreach ($regions as $region) {
                $address->setRegionId($region->getId());
                $address->setExportedKeys(array_merge($address->getExportedKeys(), array('region_id')));
                break;
            }
        }
    }

有没有人成功地修改了这个过程以获取更完整的计费信息。我们需要能够向使用 Paypal 付款的客户发送“已付款”发票,因此我们需要捕获此信息。

4

1 回答 1

1

我已经破解了该问题的解决方法。这不是最干净的方式,但我可以在使用 PayPal 付款后将帐单地址数据保存在订单中。我花了 2 天的时间研究它,最后我只编写了几行代码。我用评论 #103 标记了我的解决方法。

类 Mage_Paypal_Model_Api_Nvp 的重写方法:

    protected function _importAddresses(array $to)
{
    // Original Code
    //$billingAddress  = ($this->getBillingAddress()) ? $this->getBillingAddress() : $this->getAddress();
    // Workaround #103
    if ($this->getBillingAddress())
    {
        $billingAddress = $this->getBillingAddress();
    }
    else
    {
        $chkout = Mage::getSingleton('checkout/session');
        $quote = $chkout->getQuote();
        $billingAddress = $quote->getBillingAddress();
        $billingAddress->setData($billingAddress->getOrigData());
        $session = Mage::getSingleton("core/session",  array("name"=>"frontend"));
        $session->setData("syn_paypal_original_billing_address", serialize($billingAddress->getOrigData()));
    }

    $shippingAddress = $this->getAddress();

    $to = Varien_Object_Mapper::accumulateByMap($billingAddress, $to, array_flip($this->_billingAddressMap));
    if ($regionCode = $this->_lookupRegionCodeFromAddress($billingAddress)) {
        $to['STATE'] = $regionCode;
    }
    if (!$this->getSuppressShipping()) {
        $to = Varien_Object_Mapper::accumulateByMap($shippingAddress, $to, array_flip($this->_shippingAddressMap));
        if ($regionCode = $this->_lookupRegionCodeFromAddress($shippingAddress)) {
            $to['SHIPTOSTATE'] = $regionCode;
        }
        $this->_importStreetFromAddress($shippingAddress, $to, 'SHIPTOSTREET', 'SHIPTOSTREET2');
        $this->_importStreetFromAddress($billingAddress, $to, 'STREET', 'STREET2');
        $to['SHIPTONAME'] = $shippingAddress->getName();
    }
    $this->_applyCountryWorkarounds($to);

    return $to;
}

并覆盖 Mage_Paypal_Model_Express_Checkout 中的方法:

    public function returnFromPaypal($token)
{
    $this->_getApi();
    $this->_api->setToken($token)
        ->callGetExpressCheckoutDetails();

    // import billing address
    $billingAddress = $this->_quote->getBillingAddress();
    $exportedBillingAddress = $this->_api->getExportedBillingAddress();

    // Workaround #103
    $session = Mage::getSingleton("core/session",  array("name"=>"frontend"));
    $dataOrg = unserialize($session->getData("syn_paypal_original_billing_address"));
    if (true === is_object($billingAddress))
    {
        foreach ($exportedBillingAddress->getExportedKeys() as $key) {
            if (array_key_exists($key, $dataOrg))
            {
                $billingAddress->setData($key, $dataOrg[$key]);
            }
        }
        $this->_quote->setBillingAddress($billingAddress);
    }

    // import shipping address
    $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();
}
于 2012-06-27T11:23:14.867 回答