Wallet Pass auto update web service using aws api gateway

1.4k views Asked by At

I am working on a web service to update Apple Wallet passes using AWS Lambda/API gateway/NodeJS. The Apple wallet hit the api to get update pass but each time I am getting following error:

encountered error: Received invalid pass data (The pass cannot be read because it isn’t valid.)

I have tried the same URL in the browser to get the pass. The pass is downloading every time and its opening a valid pass every time. But its not working when Apple wallet hit the URL. I have tried same URL in Postman it gives me base64 instead of binary data.

I have tried to achieve the same functionality with NodeJS and deployed on heroku, its working properly with Wallet(also gives binary in Postman). But I need to use AWS Lambda/API gateway/NodeJS.

I am not sure, if AWS changing something while delivering binary data.

Any help on this is appreciated.

1

There are 1 answers

1
Dan On

I just experienced this and spent hours trying to diagnose what was happening.

For anyone using AWS API Gateway & Lambda for their PassKit web service endpoints, there's a major "gotcha" (at least as of the date of my response) with how API Gateway's logic determines whether it needs to convert a response from base64 ==> binary.

If you inspect the request headers from Apple Wallet / PassKit, you'll see that the Accept header is */*.

API Gateway apparently iterates through the items in the request Accept header and determines if there is a match with any of the Binary Media Types you've defined under Your API Name > Settings. It will use the first match it finds and then, as you'd hope, convert the base64 string (from Lambda) to binary.

Here's the crazy part -- if you define application/vnd.apple.pkpass as one of your "please convert to binary" media types, requests from Apple Wallet / PassKit will not work. Why? Well, AWS (for whatever reason...) hasn't programmed */* to match any type ... it will literally only match */*.

As a result, the Accept header's */* will not match with application/vnd.apple.pkpass and your base64-encoded .pkpass response (from Lambda) will not be converted to binary, causing PassKit to choke + report errors.


TL;DR -- there is some goofiness with AWS API Gateway. To return PassKit pass data successfully, you need to add */* (not application/vnd.apple.pkpass) under Your API Name > Settings > Binary Media Types.