alexandercerutti / passkit-generator

The easiest way to generate custom Apple Wallet passes in Node.js
MIT License
893 stars 109 forks source link

Cannot open generated pass #209

Closed Fearix closed 4 months ago

Fearix commented 4 months ago

Hello, I have an online shop for event tickets and would now like to add the function that, in addition to the ticket as a PDF, the ticket is also sent as a Wallet Pass by email. When I tested this, I noticed that I couldn't open the ticket on the iPhone, nor on the Mac when I dragged it into the simulator's Wallet app (nothing happened).

After receiving the payment the following function in nodejs gets triggered:

async function generateApplePass(uuidString, eventData, phaseTitle, price, passPath) {

      const pass = await PKPass.from({
        model: "/home/backend/custom_modules/data/ticket.pass",
        certificates: {
          wwdr: fs.readFileSync(path.join(__dirname, 'data/certs', 'wwdr.pem')),
          signerCert: fs.readFileSync(path.join(__dirname, 'data/certs', 'signerCert.pem')),
          signerKey: fs.readFileSync(path.join(__dirname, 'data/certs', 'signerKey.pem')),
          signerKeyPassphrase: "..."
        },        
      }, 
        {
          description: `Ticket für ${eventData.title}`,
          serialNumber: uuidString,
        });

        pass.primaryFields.push({
          key: 'event',
          label: 'EVENT',
          value: eventData.title,
        });

        pass.secondaryFields.push(
          {
            key: 'phase',
            label: 'PHASE',
            value: phaseTitle,
          },
          {
            key: 'price',
            label: 'PREIS',
            value: `${price}€`,
          }
        );

        pass.auxiliaryFields.push(
          {
            "key": "date",
            "value": eventData.startDateTime,
            "label": "DATUM",
            "dateStyle": "PKDateStyleMedium",
            "timeStyle": "PKDateStyleShort",
            "ignoresTimeZone": true,
            "isRelative": false
          },
          {
            "key": "location",
            "value": getPassLocation(eventData),
            "label": "LOCATION",
          }
        );

        pass.setBarcodes({
          message: uuidString,
          format: 'PKBarcodeFormatQR',
          messageEncoding: 'iso-8859-1'
        });

        pass.setExpirationDate(new Date(eventData.endDateTime));
        pass.setRelevantDate(new Date(eventData.startDateTime));      

        const bufferData = pass.getAsBuffer();
        fs.writeFileSync(`cache/${passPath}`, bufferData);        
}

This is the content of my ticket.pass: icon icon@2x logo@2x logo pass.json

When I renamed the .pkpass file I received to .zip and extracted the contents, I got the following files. The content looks correct to me, but it is my first time working with passes: manifest.json icon icon@2x logo logo@2x pass.json

The folder also contains a signature file, but I can't upload it here.

I have already checked the .pkpass file with an online validator and got this result: Bildschirmfoto 2024-07-19 um 17 24 38

Does anybody know what I'm doing wrong? Thanks in advance

alexandercerutti commented 4 months ago

@Fearix Hi, I’m unable to look at you issue right now. I’ll look at it on Monday

alexandercerutti commented 4 months ago

Hi @Fearix, thanks for using passkit-generator. I had a bit of time to read your issue. Did you try to check if Console.app gives you any log? It is likely you are going to find things there, as when a pass doesn't open, it fails silently and logs things.

To debug, I created a guide in wiki that I cannot link you now because I'm from my phone.

Let me know.

Fearix commented 4 months ago

Thanks for the quick help @alexandercerutti. I was able to fix it by following the debugging instructions. Apparently Apple always requires a time zone for the ISO DateTime strings, which I was missing.

alexandercerutti commented 4 months ago

Glad you solved! May I ask you to leave a star on the project? 🌟