获取 Paypal Express [Magento] 的完整账单地址

Posted

技术标签:

【中文标题】获取 Paypal Express [Magento] 的完整账单地址【英文标题】:Get Full Billing Address for Paypal Express [Magento] 【发布时间】:2012-06-04 21:51:28 【问题描述】:

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 付款的客户发送“已付款”发票,因此我们需要获取此信息。

【问题讨论】:

【参考方案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();

【讨论】:

大卫,你使用的是什么版本的 magento。我的代码看起来有点不同,我正在尝试确定您的代码是新的还是旧的。

以上是关于获取 Paypal Express [Magento] 的完整账单地址的主要内容,如果未能解决你的问题,请参考以下文章

如何获取新的 PayPal Express Checkout UI

如何使用 PayPal Express Checkout 集成(客户端 REST)获取交易 ID

paypal express checkout set paypal费用另加

PayPal Express Checkout - 错误 400 错误请求

如何消除 PayPal Express Checkout 以进行 Payflow 订单审查?

Paypal Express Checkout.js - 填充产品详细信息