PassKit

pub package likes popularity pub points

Twitter Follow GitHub followers

🚧 API is subject to change! 🚧

PassKit allows you to work with Apple's PkPass and Order files. Those are the files that are usually managed via Apple Wallet. This is a pure Dart library and works with Flutter, on the web and on servers.

In order to show PassKit and Order files in Flutter, use the passkit_ui package, which includes ready made widgets.

Want to work with Apple's native PassKit APIs? Consider using apple_passkit.

Table of Content

Passes

What is PassKit?

Passes are a digital representation of information that might otherwise be printed on small pieces of paper or plastic. They let users take an action in the physical world. Passes can contain images and a barcode, and you can update passes using push notifications on iOS.

This technology consists of three main components:

  • A package format for creating passes.
  • A web service API for updating passes, implemented on your server.
  • An API used by your apps to interact with the user’s pass library.

A PkPass file looks something like this when rendered in the iOS Wallet app or via passkit_ui:

How to read a PassKit file?

import 'package:passkit/passkit.dart';

void main() {
  final passKitBytes = ... // get bytes for the PassKit from somewhere
  final pkPass = PkPass.fromBytes(passKitBytes);
}

How to get the latest version of a given PkPass?

import 'package:passkit/passkit.dart';

void main() {
  final passKitBytes = ... // get bytes for the PassKit from somewhere
  final pkPass = PkPass.fromBytes(passKitBytes);

  if(pkPass.isWebServiceAvailable) {
    final pkPassBytes = PassKitWebClient().getLatestVersion(pkPass);
  }
}

How to create a PassKit file?

Important

Follow the guide here to learn more about the signing process. This is a requirement before you can create a pass file.

Apple's documentation here explains which fields to set.

import 'package:passkit/passkit.dart';

void main() {
  final pass = PkPass(...);
  final binaryData = pass.write(
    certificatePem: File('pass_certificate.pem').readAsStringSync(),
    privateKeyPem: File('private_key.pem').readAsStringSync(),
  );
  File('pass.pkpass').writeAsBytesSync(binaryData);
}

There's a couple of convenience functions available to make the .pkpass creation easier:

If the resulting file doesn't work, please look into the troubleshooting guide.

shelf example

A Hello World like example with shelf looks something like this:

import 'package:shelf/shelf.dart';
import 'package:passkit/passkit.dart';

Response onRequest(Request request) {
  final pkPass = PkPass(...);
  final bytes = pkPass.write(
    certificatePem: File('passcertificate.pem').readAsStringSync(),
    privateKeyPem: File('passwordless_key.pem').readAsStringSync(),
  );

  return Response.ok(
    bytes,
    headers: {
      'Content-type': 'application/vnd.apple.pkpass',
      'Content-disposition': 'attachment; filename=pass.pkpass',
    },
  );
}
dart_frog example

A Hello World like example with dart_frog looks something like this:

import 'package:dart_frog/dart_frog.dart';
import 'package:passkit/passkit.dart';

Response onRequest(RequestContext context) {
  final pkPass = PkPass(...);
  final bytes = pkPass.write(
    certificatePem: File('passcertificate.pem').readAsStringSync(),
    privateKeyPem: File('passwordless_key.pem').readAsStringSync(),
  );

  return Response.bytes(
    body: bytes,
    headers: {
      'Content-type': 'application/vnd.apple.pkpass',
      'Content-disposition': 'attachment; filename=pass.pkpass',
    },
  );
}

Signature & Checksums

In case iOS runs into an issue with a PkPass it just shows a generic error message. This library is able to point out a more specific error, if a PkPass is malformatted, signed, or whatever.

Due to the closed source nature of the Apple Wallet software, there might be slight differences in this how the Wallet app and this package are working. If you run into such a problem, please create an issue.

Apple Wallet PassKit docs

Orders

What is order tracking?

When you support order tracking, Wallet can display information about an order a customer placed through your app or website, updating the information whenever the status of the order changes. You can help people start tracking their order right from your app or website and offer additional ways to add their order to Wallet.

When rendered, orders look something like this in the iOS Wallet app or via passkit_ui:

How to read an order file?

import 'package:passkit/passkit.dart';

void main() {
  final orderBytes = ... // get bytes for the PassKit from somewhere
  final order = PkOrder.fromBytes(orderBytes);
}

Apple Order Tracking docs

Closing notes

Unsupported or experimental functionality

Please feel encouraged to create PRs for the following features.

  • Push Notification update registration is only working on iOS due to it being an exclusive Apple thingy.
  • Localization: Existing, but still inconvenient to use. There might be issues due to localizations being UTF-16 formatted, but the library currently uses UTF-8 to read localizations.

Bugs and parsing issues

If you hit an issue with parsing, please create an issue and attach the pass or order file if possible.

Contributors

Thanks a lot to all the awesome contributors:

Contribute to this library, and you'll show up too.

We encourage you to contribute to this library. A good starting point is to look at these good first issues. Take a look at these issues if you're up for a challenge.

Libraries

passkit