Authorizing Apple Pay via non-Safari browser fails to decode merchant session.

When attempting to authorize an Apple Payment on an iOS 18 device using the scannable code in a non-Safari browser (i.e. Chrome), the payment sheet displays briefly, then dismisses.

This same exact implementation of Apple Pay on the Web works flawlessly in Safari, so this feels like a bug given that the merchant session works fine in Safari.

The following errors were found in my iOS device logs:

(PassbookUIService) Codable: Failed to decode Merchant Session Created: Error Domain=NSCocoaErrorDomain Code=4864 UserInfo={NSDebugDescription=<private>, NSCodingPath=<private>}

(PassbookUIService) Session 29592: Fatal Error: Failed to decode merchant session created`
Answered by dtrenz in 823762022

Update: My team was able to resolve this issue!

It turns out that our server was trying to type the opaque payment session response from Apple, instead of treating it like an opaque string and simply forwarding that raw string response down to the frontend, to be sent into completeMerchantValidation().

I'm experiencing the same problem in Firefox 134.0 (aarch64) on macOS 14.6.1 (Apple M1).

Console 1.1, shows these messages when connected to my iPhone 14 running iOS 18.1.1:

error	14:43:31.069080+0000	PassbookUIService	Codable: Failed to decode Merchant Session Created: Error Domain=NSCocoaErrorDomain Code=4864 UserInfo={NSCodingPath=<private>, NSDebugDescription=<private>}
error	14:43:31.069103+0000	PassbookUIService	Session 12311: Fatal Error: Failed to decode merchant session created

After installing the Apple Pay for iOS profile, the log messages from Console are more detailed:

error	13:38:31.786791+0000	PassbookUIService	Codable: Failed to decode Merchant Session Created: Swift.DecodingError.typeMismatch(Swift.UInt, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "messageBody", intValue: nil), CodingKeys(stringValue: "updateBody", intValue: nil), CodingKeys(stringValue: "merchantSession", intValue: nil), CodingKeys(stringValue: "epochTimestamp", intValue: nil)], debugDescription: "Expected to decode UInt but found a string instead.", underlyingError: nil))
error	13:38:31.786824+0000	PassbookUIService	Session 11150: Fatal Error: Failed to decode merchant session created

I've submitted FB16392549.

Accepted Answer

Update: My team was able to resolve this issue!

It turns out that our server was trying to type the opaque payment session response from Apple, instead of treating it like an opaque string and simply forwarding that raw string response down to the frontend, to be sent into completeMerchantValidation().

I should also note that the core issue may have been that some fields in the payment session that were numbers/int were incorrectly being typed as strings. Specifically, epochTimestamp and expiresAt.

While this may have been the specific issue, the solution was to simply not bother deserializing the payment session into a type and simply forward it to the frontend and, ultimately, to the Apple Pay SDK.

Authorizing Apple Pay via non-Safari browser fails to decode merchant session.
 
 
Q