Shopify / mobile-buy-sdk-ios

Shopify’s Mobile Buy SDK makes it simple to sell physical products inside your mobile app. With a few lines of code, you can connect your app with the Shopify platform and let your users buy your products using Apple Pay or their credit card.
MIT License
452 stars 198 forks source link

PayPostalAddress / PayAddress country field is empty string #1092

Open tareksabry1337 opened 4 years ago

tareksabry1337 commented 4 years ago

Currently when checking out via ApplePay using PaySession and attempting to retrieve shipping rates it throws an error that shipping address is invalid, I thought it's my code or that I broke something, I then cloned the sample project and I tried to do a checkout with ApplePay but I have seen the exact same error.

Screen Shot 2020-06-30 at 9 38 27 AM

Upon further investigation and looking through the code I set a break point

Screen Shot 2020-06-30 at 9 38 27 AM

And inspecting the country property on address yields an empty string.

Screen Shot 2020-06-30 at 9 41 06 AM

Therefore causing the issue mentioned above.

Side Note: On my app I also have my own implementation of ApplePay aside from PaySession and I ran into the exact same issue except on my custom implementation when I got the PKPayment object I retrieved the isoCountryCode and converted to country name using Swift's native functions in order to overcome this issue.

This is also possible to overcome when request shipping rates because PayPostalAddress contains the "countryCode" property which can be converted to country name but PayAddress does not fill in countryCode making this an impossible obstacle to overcome unless I fork the SDK and use it locally.

xanderbuck commented 4 years ago

@tareksabry1337 I think I ran into this similar issue a while back. When you are creating the checkout, are you passing in the allowPartialAddresses Boolean flag as true?

This flag is needed for the Apple Pay because of Apple Pays security not actually passing the full address to the developer until the user has authorized the order. My suspicion is when your Apple Pay tries to validate the address, Apple Pay gives it a partial address which shopify uses to calculate shipping, but because you are not allowing partial addresses it fails.

This flag is used as such:

let input = Storefront.CheckoutCreateInput.create(lineItems: .value(lineItems), allowPartialAddresses: .value(true)

You then pass this input object to the checkCreateMutation:

static func mutation(checkoutInput: Storefront.CheckoutCreateInput) -> Storefront.MutationQuery {

        let mutation = Storefront.buildMutation { $0
            .checkoutCreate(input: checkoutInput) { $0
                .checkout { $0
                    .checkoutFragment()
                }
                .checkoutUserErrors { $0
                    .checkoutUserErrorFragment()
                }
            }
        }

        return mutation
    }
tareksabry1337 commented 4 years ago

@xanderbuck I'm aware of this limitation from Apple Pay and yes I have allowPartialAddresses to true, however what Apple blocks is Address Line 1 / First Name. Fields like city and country return in the address, in fact when debugging in my internal implementation of Apple Pay I found out it sometimes returns the country code and sometimes the country name, Shopify SDK however always uses the country name which does not return sometimes for some reason.

lorenzOliveto commented 3 years ago

I'm running int a similar problem, I'm in Italy and what I see is that PayAdress has Italia as its value, but whenever I try to pass it t a StoreFront.MailingAddressInput it tells me that the country is invalid because Shopify wants the country code (IT in this case). To overcome this I have to save the PayPostalAddress and use its country code instead of the one in PayAdress. Am I doing something wrong or this is the expected behavior?