0

I have been tasked with creating a simple feature that allows the users to fill a form and create an apple wallet pass (.pkpass) for themselves. I have decided to use Pass2u.

My problem is, that after I generate the .pkpass file, I try to call the getPkpass, and it returns a stream in the body. I have no idea how to work with it, and have found a very confusing explanation involving some kind of a reader online. The goal is for the entire thing to work like this:

  1. client sends a POST request to the server
  2. Server recieves the POST, and sends another post to the pass2u api which creates the pass
  3. with the passId (server gets that as a response in step 2), the server now makes a GET request to the pass2u api, asking for the specific pass file
  4. The API returns the MIME Binary stream file to the server
  5. The server somehow processes it, and sends it as a response to the initial POST request (this was sent in step 1.)
  6. the client side downloads the file

I am asking for help with part 5. and part 6., since I have gotten to a point where I can create the file and retrieve the binary stream.

Here is the relevant server code:

const options = {
        method: "GET",
        headers: {
          "x-api-key": "myAPIkey",
          Accept: "application/vnd.apple.pkpass",
        },
      };
      fetch(
        `https://api.pass2u.net/v2/models/247901/passes/${response.data.passId}`,
        options
      )
        .then((response) => {
          console.log(response);
          res.send(response);
        })
        .catch(function (error) {
          console.log(
            "An error occured occured while sending the GET request to pass2u"
          );
          console.error(error);
        });

The client handles things as follows:

axios
        .post(
          'http://localhost:80/generatePkpass',
          {
            name: `${qr.name} ${qr.lastName}`,
            mobile: `${qr.phone}`,
            email: `${qr.email}`,
            qr: `${qr.output}`
          },
          { responseType: 'blob', timeout: 30000 }
        )
        .then((response) => {
          this.isGenerating = false
          console.log(response)

          console.log(response.data)

          const blobUrl = URL.createObjectURL(response.data)

          // Create an anchor element
          const anchor = document.createElement('a')

          // Set the href attribute to the blob URL
          anchor.href = blobUrl

          // Set the download attribute to specify the filename
          anchor.download = 'yourPkPass.pkpass'

          // Simulate a click on the anchor element
          anchor.click()

          // Clean up: revoke the temporary URL
          URL.revokeObjectURL(blobUrl)
          // const filename = 'yourpass.pkpass'

          // saveAs(response.data, filename)
        })

I know the client should not be handling this as a blob probably, but I still think there is a problem on the server.

Guys, thanks a lot in advance, it is 1 am here, and I am feeling so exhausted by this. I a beginner dev and this is my first task at a new company I work for. I feel super bad for not knowing this, but I was hired as a frontend developer, and never worked with binary strings my whole life.

First I had the GET request to the pass2u api in axios, but I changed it into fetch, which cleared things up a bit, but now I am still facing the same issue of being unable to send the pass to the client. I additionally tried handling it on the frontend as an arraybuffer, and it downloaded the files, however, I was unable to open them on safari

2
  • 1
    Why don't you just redirect to the pkpass file after it's created? At PassNinja - we return a URL that looks like i.getpass.es/p/asdfaer so our customers can send it directly to their customers.
    – grundyoso
    Feb 9 at 5:51
  • Otherwise you have to deal with making sure the response headers are correct (lookup "application/vnd.apple.pkpass") plus the liability of potentially screwing up the stream as you try to proxy the body from pass2u back to the browser.
    – grundyoso
    Feb 9 at 5:58

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.