Not sure what you mean by "recalling" the registration address. If there is a registration address, then Paypal may attempt to update it with its own data.
Searching for the setCustomerAddress function in the payment.php file, we can see that it is used 4 times, 3 times in the checkAndModifyAddress function and once outside of any other function, I assume during the execution of the payment.php file. (payment modules are not my strong suit so please bear with me)
In the checkAndModifyAddress function we have some scenarios, a few commented by the paypal module developers:
1. No customer addresses
<?php if (count($customer_addresses) == 0) { $paypal_address = setCustomerAddress($ppec, $customer); }
If the are no customers addresses, then the setCustomerAddress function is called without passing any address ID as the third argument (address id is null), this means a new address with the name "Paypal_Address" is created. If there are no addresses, then I don't know how we can recover the DNI field in this case however I believe this might be a rare occurrence, a "worst-case scenario" kind of thing.
2. Customer has at least one address, then we loop over the $customer_addresses array. The first comment states:
If a PayPal address already exists we use it to override new address from paypal
This part checks if there is already an address with the name "Paypal_Address", if so, the module will update it with the data from Paypal, however, when updating an address, unless properties are explicitly set to an empty string ( example: $address->dni = '' ), any additional address details that Paypal doesn't modify should remain. I have stated in my previous message that Paypal doesn't have a DNI value from its API so it doesn't touch the address' DNI property/field.
3. For the third usage, the second comment states:
We check if an address exists with the same country / city / street
So if there is a customer address that looks similar to the one the customer has on Paypal, it will update it, but the DNI field would still not be affected/removed.
4. The final usage in the checkAndModifyAddress function of setCustomerAddress is at the end, right before the address is created/updated via $paypal_address->save(). Here is the scenario where: the customer has addresses (at least one) and the we tried to look for an adddress named 'Paypal_Address' or that is similar to the address on Paypal but we haven't found a match. In this case, a new address is created based in the Paypal data, same as the first scenario.
This might be the cause of the problem you are facing, some customers may not use the same address they have on paypal and thus a new address with no DNI is created.
In this case, yes, you could use the first address in the array of addresses, something like this might work:
<?php // Potential fix in checkAndModifyAddress() function // Replace: if ($paypal_address == false) { $paypal_address = setCustomerAddress($ppec, $customer); } // With: if ($paypal_address == false) { $addressId = null; if (count($customer_addresses) !== 0) { $addressId = $customer_addresses[0]['id_address']; } $paypal_address = setCustomerAddress($ppec, $customer, $addressId); } // If you want to use the first address that HAS a DNI value, you can try this instead: if ($paypal_address == false) { $addressId = null; if (count($customer_addresses) !== 0) { foreach($customer_addresses as $customerAddr) { if ($customerAddr['dni']) { $addressId = $customerAddr['id_address']; break; } } // If no DNI found, still use the first address. if ($addressId === null) { $addressId = $customer_addresses[0]['id_address']; } } $paypal_address = setCustomerAddress($ppec, $customer, $addressId); }
Please use with caution! Preferably in a testing/dev environment.
5. The final usage is in the main execution of the payment.php file, here we have a few comments as well:
<?php //... if ((!$address || !$address->id) && $customer->id) { //If address does not exists, we create it $address = setCustomerAddress($ppec, $customer); $address->add(); } else if ($ppec->type != 'payment_cart') { //We used Express Checkout Shortcut => we override address $address = checkAndModifyAddress($ppec, $customer); }
Here is where things get a bit vague for me and I'm not exactly sure what is the scenario where the setCustomerAddress function is called, except for when the customer has no address, according to the comments. This is also the only bit of code where the checkAndModifyAddress function is called, when $ppec->type is anything but "payment_cart", maybe you can shed some light on this one.