Open zackshapiro opened 5 years ago
Thinking about this more, maybe something is not calling the delegate methods that ask Shopify for shipping method options so that's why it's not showing up?
If you take a look at PaySession.swift
, on line 184, we create the PKPaymentRequest
. You're right, the shipping address is never transferred over from PaySession
into the request, as you've shown in the snippet above. If injecting the shipping contact in that method helps your case, we can certainly add it to the SDK.
Thanks @dbart01 . I've added it in my local, unlocked file:
func paymentRequestUsing(_ checkout: PayCheckout, currency: PayCurrency, merchantID: String) -> PKPaymentRequest
let request = PKPaymentRequest()
request.merchantIdentifier = merchantID
request.countryCode = currency.countryCode
request.currencyCode = currency.currencyCode
request.merchantCapabilities = .capability3DS
request.requiredBillingAddressFields = .all
request.requiredShippingAddressFields = .all
if #available(iOS 11.0, *) { // added this in, made no difference
request.requiredShippingContactFields = [.emailAddress, .name, .phoneNumber, .postalAddress]
} else {
// we don't support before 11
}
request.supportedNetworks = self.acceptedCardBrands.paymentNetworks
request.paymentSummaryItems = checkout.summaryItems(for: self.shopName)
let contact = PKContact()
var name = PersonNameComponents()
name.givenName = checkout.shippingAddress?.firstName
name.familyName = checkout.shippingAddress?.lastName
contact.name = name
let address = CNMutablePostalAddress()
address.street = checkout.shippingAddress!.addressLine1! + checkout.shippingAddress!.addressLine2!
address.city = checkout.shippingAddress!.city!
address.state = checkout.shippingAddress!.province!
address.postalCode = checkout.shippingAddress!.zip!
address.country = "USA"
address.isoCountryCode = "840"
contact.postalAddress = address
request.shippingContact = contact
but then the methods to get shipping info are never called. Any idea why? I can't find a guard that's triggered or anything like that
I commented out the request.shippingContact
line to look at the stack trace of where that's called from and it seems to originate inside of PassKit in PKPaymentAuthorizationController.paymentAuthorizationCoordinator
Not really sure how to debug this to get it working with the added shippingContact
Hi @dbart01, wanted to bump this up. Thanks
What methods are you expecting to be called and when? You are correct, all the callback come directly from PassKit
and pull information into the Apple Pay payment processing modal. As far as I know, there's no way to programatically invoke these methods manually.
Without setting the shippingContact
on the request
, didSelectShippingContact
is automatically called. For some reason though, setting that attribute causes it not to be called so I can't both set a user-generated address and charge the user checking out for shipping
I would imagine that logic is baked into PassKit
. Why is didSelectShippingContact
necessary to charge the user?
That's what causes the other shipping/contact-related delegate methods to be called that you've built in to PaySession
Since you know your pod best and I haven't been able to decipher why this is, do you know why adding the shippingContact
here is causing the other PaySession delegate methods not to fire?
Morning @dbart01, hope you had a good weekend. I'd really like to ship this feature this week if you have any insight into this or why it's not working with the Shopify PaySession delegate code, that'd be amazingly helpful. Thanks!
:wave: Hey @zackshapiro, are you still seeing this? We haven't been able to replicate the issue and need more information. Thanks!
I could not solve this issue. I want to fill the shipping address automatically when opening apple pay page. Is it possible?
@ksmks0921 This is possible, but you'll need to fork the repository, or submit a PR.
adding a shippingContact: shippingContact?
property onto the PaySession
and in the paymentRequestUsing
method, where they create the PKPaymentRequest
, set the correct property.
@TheiOSDude Hello, I did this but as @zackshapiro said their delegates (didRequestShippingRatesFor) don't get called anymore and this will cause an internal error.
For those who are facing the same problem, setting the delegate variable in PaySession to a strong variable as opposed to weak (public var delegate: PaySessionDelegate? instead of public weak var delegate: PaySessionDelegate?), adding the extra fields in paymentRequestUsing(), and modifying the authorize() func did the trick. It's not a perfect solution, but it worked for me for Apple Pay. Here is the code:
I have a flow where a user fills out an address form that we store in
UserDefaults
. Normal address fields, email, phone, first and last names. My goal is to pre-fill the Shipping Address on the Apple Pay prompt not with the primary shipping address attached to the user's default card, as it is currently coded into the Shopify SDK, but with my own user-generated address.I built myself a sample app where I can do this just fine like this:
Doing it this way, I have both the stubbed shipping address in the Apple Pay prompt as well as a shipping method.
- What is the expected behaviour?
Two expectations that both fail:
1) Before I call
paySession.authorize()
, when I'm constructing myPayCheckout
object, when I give it ashippingAddress
, I'd expect that address to show up as the Apple Pay shipping address in the modal but it doesn't.needsShipping
is marked as true when I create thePayCheckout
object and I've printed that address throughout the various methods that are called, the address I want to stub always shows in the logs but when the Apple Pay prompt comes up, the address tied to the primary card is always shown as the shipping.2) The other expectation that I had was to go into
func paymentRequestUsing(_ checkout: PayCheckout, currency: PayCurrency, merchantID: String) -> PKPaymentRequest
and set therequest.shippingContact
as I did in my sample app code. Doing that shows the correct user-entered address but the shipping method goes awayAlternatively, setting the
shippingAddress
to my user-entered value below infunc paymentAuthorizationController(_ controller: PKPaymentAuthorizationController, didAuthorizePayment payment: PKPayment, completion: @escaping (PKPaymentAuthorizationStatus) -> Void)
I thought might work, but also doesn't.I've hunted through the stack printing and stubbing and trying to get this to work. Seems like the address I provide to the
PayCheckout
should be honored all the way through and it's unclear why it's not. Any help would be great. Thanks3.6.0