Apple Pay Wallet Order Tracking Demo

Learn how to provide order tracking to customers using Apple Pay.
Transactions you make on this site don’t charge your card.

Overview

This page demonstrates the Order Tracking feature available in Apple Pay using the Payment Request API or the Apple Pay JS API. Order Tracking with Apple Pay provides users with an itemized breakdown of purchased items, along with any shipping or pickup information. The merchant can update orders users’ devices to reflect the latest order state, such as shipping or pickup fulfillments.

This is an interactive playground that shows examples for each step of implementing Order Tracking. You can modify the payloads in the code blocks throughout the page to customize the orders and explore how the changes impact the functionality.

This demo displays a transcript of server responses after each order creation and update. Click or tap the Show Transcript tab to view the transaction transcript.

To implement Order Tracking, you must first set up your service to process Apple Pay transactions. See Apple Pay Demo for detailed implementation guidance.

This demo generates source code that you can copy into your own project. Click or tap the Show Source tab to view the source code. The source code updates as you change values in the code blocks throughout the page. You can click or tap the Copy button inside the Show Source tab to copy the source code to your clipboard.

Implementation variations

As with baseline Apple Pay, you may be a developer who is implementing this functionality on your own site, working on a shopping or logistics platform that serves many merchants, or implementing order creation on your site, but relying on a logistics partner to publish order updates to your customers.

Depending on your use case, you need to implement all, or only a subset, of the APIs. If you’re planning to use a third party to serve your order updates to your customers, refer to your shopping platform or logistic partner documentation for integration instructions.

Select the API you want to explore.

Requirements

This demo uses Apple Pay JS 13. To run this demo, use:

  • iOS devices running iOS 16 or later
  • Safari 14 with macOS 13 or later
  • A payment card provisioned in Wallet
  • The same payment card and Apple ID across all devices

Create an order

As the merchant, you create the order when a customer purchases products on your website. When the customer authorizes the transaction with Apple Pay, you send the initial order details to Wallet running on their device.

After the payment processes for the transaction, Wallet receives initial order details that include the unique orderID and the webServiceURL. Wallet then calls the webServiceURL requesting the order package, which it identifies by the unique orderID.

Send order details to Wallet

When the customer initiates a transaction you, as the merchant, start an ApplePaySession. When the customer authorizes the payment as part of the session, the browser triggers the onpaymentauthorized event handler. In your implementation of this event handler, you, as the merchant, need to generate the initial order details and send them as part of the payload to the completePayment session handler function.

For more information, see orderDetails.

Below you can see an example implementation of this handler that includes the payload data to enable order tracking:

session = new ApplePaySession(version, request);

session.onpaymentauthorized = (payment) => {
    // ...
    // ... After merchant validation and payment request build
    // ...
    let paymentStatus = ApplePaySession.STATUS_SUCCESS // Can be "ApplePaySession.STATUS_SUCCESS" or "ApplePaySession.STATUS_FAILURE"
    let data = {
        status: paymentStatus,
        // Additional fields for order tracking
        orderDetails: {
            orderIdentifier: // The ID of the order of type DOMString.
            orderTypeIdentifier: // The order type ID of the order of type DOMString.
            webServiceURL: // The base URL of type DOMString to where Wallet can request for orders.
            authenticationToken: // Randomly generated alphanumeric token of type DOMString.
        }
    }

    session.completePayment(data);
}
    

If you’re a merchant implementing the Order Tracking functionality on your site (or a merchant platform that serves many merchants) and are planning to serve order updates to the user devices directly, point webServiceURL to a new API endpoint on your own domain and implement the Wallet Orders Web Service API.

Alternatively, if you rely on a third–party logistics partner to generate the order payloads and send updates to users on your behalf, refer to the documentation of your logistics partner to determine the correct value to specify for the webServiceURL.

When Wallet obtains the webServiceURL from orderDetails using completePayment, it makes a request to fetch the Order Package from the URL in the following format:

GET https://your-web-service.com/v1/orders/{orderTypeIdentifier}/{orderIdentifier}

In the example GET request, your-web-service.com is the webServiceURL you specify in orderDetails. Wallet sends the authenticationToken that you generate for the order and include in the orderDetails as the Authorization header with the request.

The web service needs to return an order package as a response to the request above.

For more information, see Retrieve the latest version of an order.

Build a distributable order package

An order package is a compressed zip archive that contains an order.json file with the detailed order information, a manifest.json file, localization string files, any media files, and a signature file.

See Creating the source for an order for a detailed explanation of the schema.

You can use the JSON editor in the Create an order section below to validate the order JSON against the JSON 2020-12 schema.

Here is an example of the contents of a manifest.json:

{
    "icon.png" : "2a1625e1e1b3b38573d086b5ec158f72f11283a0",
    "icon@2x.png" : "7321a3b7f47d1971910db486330c172a720c3e4b",
    "icon@3x.png" : "7321a3b7f47d1971910db486330c172a720c3e4b",
    "order.json" : "ef3f648e787a16ac49fff2c0daa8615e1fa15df9",
    "strip.png" : "25b737727194b5c7b26a86d57e859a054eada240",
    "en.lproj/logo.png" : "cff02680b9041b7bf637960f9f2384738c935347",
    "en.lproj/logo@2x.png" : "0e12af882204c3661fd937f6594c6b5ffc6b8a49",
    "en.lproj/logo@3x.png" : "1f103c8a07fb979ea33adfbfd031e26305fd616b",
    "en.lproj/order.strings" : "aaf7d9598f6a792755be71f492a3523d507bc212",
    "zh-Hans.lproj/logo.png" : "eca86d8a474ccd33978f6aaf98a564669d45c7ae",
    "zh-Hans.lproj/logo@2x.png" : "b6556bc2fa795d11262f17cdff04f80350398f5f",
    "zh-Hans.lproj/logo@3x.png" : "124f8381721b44b2b57bf33e30b8a9a2e0404bce",
    "zh-Hans.lproj/order.strings" : "b0b4499ba7369e4cc15bad45c251e7b9bbcad6a4",
}
                        

To sign the order package, see Sign and compress order package. You can then send the .order package to Wallet.

For more information, see Building a distributable order package.

Try it: Create an order

Modify the values of the different JSON payloads to simulate an order creation as part of a customer-initiated transaction. Click or tap Apple Pay button to create a sample transaction and see the order in Wallet on your test device.

Your browser doesn’t support Apple Pay on the web.
To try this demo, open this page in Safari.
(See Requirements.)

Register a device for updates

Although the sample examples above allow for static order receipts, you may want to provide updates to the user over the lifetime of the order. For example, you may want to update the order with shipping or pickup fulfillment status, shipping tracking number and status, or other information.

To support this use case, Wallet can register for update notifications. Wallet sends a registration request to the webServiceURL that you specify in the order.json.

Wallet builds the URL to send the subscription request according to the following schema:

POST https://your-web-service.com/v1/devices/{deviceIdentifier}/registrations/{orderTypeIdentifier}/{orderIdentifier}

The request includes an Authorization header that contains the authenticationToken that you initially generated for the order. The Authorization header field format is AppleOrder {authenticationToken}.

The body of the registration request contains the device-specific APNs pushToken that you will use to send notifications to Wallet. The pushToken is a unique key for app-device combination.

When your web service receives a device registration request, it should record the association of all four fields (orderIdentifier, deviceIdentifier, pushToken and authenticationToken) in order to send order updates to Wallet and manage device registration state.

Take a look at the examples below to make a transaction for orders with the webServiceURL and the authenticationToken fields present.

Try it: Create an order with status

Modify the values of the different JSON payloads to simulate updatable orders.


Your browser doesn’t support Apple Pay on the web.
To try this demo, open this page in Safari.
(See Requirements.)

For more information, see Register a device for update notifications.

Update an order

When the logistic provider or the merchant updates the order, the web service needs to send an APNs notification to notify Wallet that there are changes to the orders from the merchant.

When Wallet receives the notification, it makes a call to your web service requesting a list of order identifiers for orders associated with the device that have been modified since the last time Wallet and your web service communicated.

GET https://your-web-service.com/v1/devices/{deviceIdentifier}/registrations/{orderTypeIdentifier}?ordersModifiedSince={lastModified}

The ordersModifiedSince query parameter contains the lastModified field value that your web service provided the last time Wallet made this request. If this is the first time Wallet is making the request, the value is empty.

The web service needs to return a list of order identifiers that have been modified, and an updated lastModified value in the response body using the following schema:

{
    "orderIdentifiers": [
        "orderid1",
        "orderid2",
        "..."
    ],
    "lastModified": "new current timestamp or other identifier"
}
                        

After Wallet receives the list of orders to fetch, it makes an individual request to fetch each order from your web service using the following URL format:

GET https://your-web-service.com/v1/orders/{orderTypeIdentifier}/{orderIdentifier}

For more information, see Retrieve the registrations for a device.

Try it: Update sample orders

After you place at least one sample updatable order in this session, it is visible in the list below:

There are no orders in this session. Place an updatable order to edit and update it.

    After you select the order, scroll down to view the order JSON in the editor. You may modify fields like status, pickupAt, estimatedDeliveryAt, and so forth. Then click the Update button below the editor to send an APNs notification to Wallet, and see the order state change on your test device.


    Send APNs push notifications

    When the logistic provider or the merchant updates the order, they need to send an APNs notification using the pushToken associated with the order when Wallet registered for update notifications.

    The apns-topic for the push notification needs to be the orderTypeIdentifier that the initial order payload specifies. The body of the notification is empty — Wallet calls the associated webServiceURL to fetch the list of all recently updated orders for this merchant orderTypeIdentifier when it receives the push notification.

    To send the push notification, you need the following from the Apple Developer APNs Portal:

    kid : APNs Key ID (the certificate ID generated in Apple Developer Portal)
    iss : Issuer (the Team ID in Apple Developer Portal)
    auth-key : APNs Authentication Key (the certificate file generated in Apple Developer Portal)

    Send all APNs notifications over HTTP/2 and TLS 1.2 connections.

    For more information, see Sending Notification Requests to APNs.

    Unregister from updates

    When a user deletes an order in Wallet, or disables update notifications for an order, Wallet sends a request to the web service to unregister the device from any updates to that order.

    It’s your responsibility to delete the device identifier and push token from your database when you receive the unregistration request. Wallet makes the request to:

    DELETE https://your-web-service.com/v1/devices/{deviceIdentifier}/registrations/{orderTypeIdentifier}/{orderIdentifier}

    The request includes an Authorization header that contains the authenticationToken that you initially generated for the order. The Authorization header field format is AppleOrder {authenticationToken}.

    For more information, see Unregister a device from update notifications.

    Additional resources

    Ready to integrate Apple Pay into your website? Here are a few links you may find useful:

    Questions or feedback

    Check out our developer forums or reach out to us.