Opencart 3: Paypal Commerce Platform Missing Billing Address on Order

If you are using Paypal Commerce Platform for Opencart, you may come across an issue where only the name and country appear as the payment address.

This is because paypal does not return a payer’s address with the CAPTURE APPROVED response:

Array
(
    [id] => XXXXX
    [intent] => CAPTURE
    [status] => APPROVED
    [payment_source] => Array
        (
            [paypal] => Array
                (
                    [email_address] => XXXXXXXXXXXXXXXXX
                    [account_id] => XXXXX
                    [name] => Array
                        (
                            [given_name] => John
                            [surname] => Doe
                        )

                    [phone_type] => HOME
                    [phone_number] => Array
                        (
                            [national_number] => XXXXXXXXXXXXXXXXX
                        )

                    [address] => Array
                        (
                            [country_code] => GB
                        )

                )

        )

    [purchase_units] => Array
        (
            [0] => Array
                (
                    [reference_id] => default
                    [amount] => Array
                        (
                            [currency_code] => GBP
                            [value] => 3.99
                            [breakdown] => Array
                                (
                                    [item_total] => Array
                                        (
                                            [currency_code] => GBP
                                            [value] => 1
                                        )

                                    [tax_total] => Array
                                        (
                                            [currency_code] => GBP
                                            [value] => 2.99
                                        )

                                )

                        )

                    [payee] => Array
                        (
                            [email_address] => XXXXXXXXXXXXXXXXX
                            [merchant_id] => XXXXX
                        )

                    [items] => Array
                        (
                            [0] => Array
                                (
                                    [name] => Test product
                                    [unit_amount] => Array
                                        (
                                            [currency_code] => GBP
                                            [value] => 1
                                        )

                                    [quantity] => 1
                                    [sku] => Test product
                                    [url] => https://domain.co.uk/test-product
                                )

                        )

                    [shipping] => Array
                        (
                            [name] => Array
                                (
                                    [full_name] => John Doe
                                )

                            [address] => Array
                                (
                                    [address_line_1] => The Street
                                    [address_line_2] =>  
                                    [admin_area_2] => Town
                                    [admin_area_1] => County
                                    [postal_code] => Postcode
                                    [country_code] => GB
                                )

                        )

                )

        )

    [payer] => Array
        (
            [name] => Array
                (
                    [given_name] => John
                    [surname] => Doe
                )

            [email_address] => XXXXXXXXXXXXXXXXX
            [payer_id] => XXXXX
            [phone] => Array
                (
                    [phone_type] => HOME
                    [phone_number] => Array
                        (
                            [national_number] => XXXXXXXXXXXXXXXXX
                        )

                )

            [address] => Array
                (
                    [country_code] => GB
                )

        )

    [create_time] => 2022-11-05T15:15:33Z
    [links] => Array
        (
            [0] => Array
                (
                    [href] => https://api.paypal.com/v2/checkout/orders/XXXXXXXXXXXXXXXXX
                    [rel] => self
                    [method] => GET
                )

            [1] => Array
                (
                    [href] => https://api.paypal.com/v2/checkout/orders/XXXXXXXXXXXXXXXXX
                    [rel] => update
                    [method] => PATCH
                )

            [2] => Array
                (
                    [href] => https://api.paypal.com/v2/checkout/orders/XXXXXXXXXXXXXXXXX/capture
                    [rel] => capture
                    [method] => POST
                )

        )

)

If we look further into the issue and find the code that’s processing the response in /catalog/controller/extension/module/paypal_smart_button.php, we can see that the developers are setting the address fields but they are blank.

By looking at the PayPal API developer documentation, we can see that the customer’s billing details were previously available via payer object and got deprecated. The details moved to payment_source.paypal which is present in the response but is missing the desired fields. (presuming they were removed by default to protect customer privacy)

Further searching the web suggests that its possible to contact paypal and ask them to include the address in the response, in which case you may be able to use the data as so:
$this->session->data['payment_address']['address_1'] = (isset($paypal_order_info['payment_source']['paypal']['address']['address_line_1']) ? $paypal_order_info['payment_source']['paypal']['address']['address_line_1'] : '');
$this->session->data['payment_address']['address_2'] = (isset($paypal_order_info['payment_source']['paypal']['address']['address_line_2']) ? $paypal_order_info['payment_source']['paypal']['address']['address_line_2'] : '');
$this->session->data['payment_address']['city'] = '';
$this->session->data['payment_address']['postcode'] = (isset($paypal_order_info['payment_source']['paypal']['address']['postal_code']) ? $paypal_order_info['payment_source']['paypal']['address']['postal_code'] : '');
$this->session->data['payment_address']['country'] = (isset($paypal_order_info['payment_source']['paypal']['address']['country_code']) ? $paypal_order_info['payment_source']['paypal']['address']['country_code'] : '');
$this->session->data['payment_address']['country_id'] = (isset($paypal_order_info['payment_source']['paypal']['address']['country_code']) ? $paypal_order_info['payment_source']['paypal']['address']['country_code'] : '');

If you can’t get the details from PayPal but need the customer’s address populated to fix any possible issues with extensions that rely on it etc, it may be an idea to capture the address on the order confirmation page, or populate it with the shipping address instead.

$this->session->data['payment_address']['address_1'] = (isset($paypal_order_info['purchase_units'][0]['shipping']['address']['address_line_1']) ? $paypal_order_info['purchase_units'][0]['shipping']['address']['address_line_1'] : '');
$this->session->data['payment_address']['address_2'] = (isset($paypal_order_info['purchase_units'][0]['shipping']['address']['address_line_2']) ? $paypal_order_info['purchase_units'][0]['shipping']['address']['address_line_2'] : '');
$this->session->data['payment_address']['city'] = (isset($paypal_order_info['purchase_units'][0]['shipping']['address']['admin_area_2']) ? $paypal_order_info['purchase_units'][0]['shipping']['address']['admin_area_2'] : '');
$this->session->data['payment_address']['postcode'] = (isset($paypal_order_info['purchase_units'][0]['shipping']['address']['postal_code']) ? $paypal_order_info['purchase_units'][0]['shipping']['address']['postal_code'] : '');

Leave a Comment