Apple Pay Wallet Order Tracking Demo

Learn how to provide order tracking to customers using Apple Pay.
Transactions made 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 APIs. Order Tracking with Apple Pay provides users with an itemized breakdown of purchased items along with any shipping or pickup information. Orders can be updated by the merchant on user device 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 editor 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 Show Transcript tab to view the transaction transcript.

To implement Order Tracking, you must first have set up your service to process Apple Pay transactions. See the main Apple Pay Demo page 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 editor 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, you may be a developer working on a shopping or logistics platform that serves many merchants, or you may be a developer implementing order creation on your site, but relying on a logistics partner for serving order updates to your customers.

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

Select the JavaScript API you want to explore.

Requirements

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

  • iOS devices running iOS 16.0 or later
  • Safari 14 on macOS 13.0 or later
  • Have a payment card provisioned in Wallet
  • Have the same 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 must send the initial order details to Wallet running on their device.

After the payment is processed 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, identified by the unique orderID.

Sending 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.

Below you can see an example implementation of this handler that includes the new payload data that needs to be included 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 alpha-numeric token of type DOMString.
        }
    }

    session.completePayment(data);
}
    

For more information see orderDetails.

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

Alternatively, if you rely on a third party logistics partner that will be generating the order payloads and sending updates to user on your behalf, refer to the documentation of your logistics partner to determine the correct value to specify for the webServiceURL.

Now that Wallet has obtained the webServiceURL from orderDetails via completePayment, Wallet makes a request to fetch the Order Package from the URL in this format:

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

In the GET request, the "your-web-service.com" is the webServiceURL specified in orderDetails. Wallet will send the authenticationToken that you generated for the order and included 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. The next section details how to build a distributable order package.

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 a 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 the detailed explanation of the schema.

You can use the JSON editor in the create an order section’s below to validate the order json against the JSON 2020-12 schema.

Here is an example of a manifest.json contents:

{
    "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.

Now, you have a distributable .order package you can send 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 Pay button to make a dummy 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

While the simple 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 to according to the following schema:

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

The request has an Authorization field in the header that contains the authenticationToken that was generated for the order for verification. The header field for Authorization is in the form AppleOrder {authenticationToken}.

The body of the 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. Your web service should store the association between all four fields to send updates to Wallet.

Take a look at the examples below to make a transaction for orders with the webServiceURL, and the authenticationToken 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.

Updating an order

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

When Wallet receives the notification, it makes a call to your web service requesting a list of order identifiers of 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 whatever the lastModified field value was provided by your web service last time Wallet made this request. If this is the first time Wallet makes the request, the value will be empty.

The web service should 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"
}
                        

Once Wallet receives the list of orders to fetch, it makes an individual request to fetch each order from

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

Once you have placed at least one sample updatable order in this session, it will be visible in the list below.

There are no orders in this session. Please 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 such as status, pickupAt, estimatedDeliveryAt, etc. Then, click 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 notification

    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 set to the orderTypeIdentifier specified in the initial order payload. The body of the notification is empty — Wallet will reach out to the associated webServiceURL to fetch the list of all recently updated orders for this merchant Order Type Identifier when it receives the notification as described above in the Updating an order section.

    In order to send the push notification, you need a few items from the Apple Developer APNs Portal:

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

    All APNs notifications must be sent over HTTP/2 and TLS 1.2 connections.

    For more information, see Sending Notification Requests to APNs.

    Unregistering from updates

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

    It’s the merchant’s responsibility to delete the device push token from their database. The request is made to:

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


    The request has an Authorization field in the header that contains the authenticationToken that was generated for the order for verification. The header field for Authorization is in the form 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.