Omnichannel icon

Order in store, pick up in store

Endless aisle: Order in store and pick up in store.

In this Endless Aisle retail use case, online items are ordered in a store, and authorized using a payment terminal. The order is then picked up at the shopper's preferred store. The payment is captured upon pickup. If not all ordered items become available for pickup at the same time, the shopper has to make several trips to the store and there will be corresponding partial captures.

This use case also covers a "mixed basket", where the shopper adds items that are available at the store to the ordered online items. This is possible both when ordering the online items, and when picking up the order. The payment for the in-store items is captured on the spot.

Requirements

Before you begin, take into account the following information.

Requirement Description
Integration type You must have both an ecommerce integration and a point-of-sale integration with Adyen.
Your systems It is essential to have (or create) a consolidated order/inventory management or ERP system. Or alternatively, you must have an orchestration layer that communicates with your various sub-systems and can consume webhook messages. This is because shoppers may return items to the store or to the warehouse, and both systems need to be able to update the inventory in case of a return.
Preparation We recommend familiarizing yourself with specific concepts so that you can make informed decisions about integration choices. See Considerations for details.

Shopper journey

From the shopper's perspective, this Endless Aisle retail use case is as follows.

In the store, it turns out that items that the shopper wants to purchase are not available at the location. Store staff helps the shopper to order the items online, and select the store where they want to pick up the order. If desired, the shopper can combine the online order with purchasing items from the store that do not need to be ordered. The shopper presents their card on the payment terminal.

When the order arrives at the selected store, the shopper is notified. The shopper goes to the store for pickup, and identifies by presenting their card on the payment terminal. The shopper is then handed the ordered goods. If desired, the shopper can combine picking up the online order with purchasing items that are available in the store.

The following diagram illustrates this shopper journey.

CmdyYXBoIExSCiAgICBBKChPcmRlcjxicj5pbiBzdG9yZSkpOjo6c3RlcFN0eWxlIC0tPiBCe0FkZDxicj5pdGVtcz99Ojo6c3RlcFN0eWxlCiAgICBCIC0tIFllcyAtLT4gQ1tQcmVzZW50PGJyPmNhcmQgb248YnI+dGVybWluYWxdOjo6c3RlcFN0eWxlCiAgICBCIC0tIE5vIC0tPiBDW1ByZXNlbnQ8YnI+Y2FyZCBvbjxicj50ZXJtaW5hbF06OjpzdGVwU3R5bGUKICAgIEMgLS0+IERbUmVjZWl2ZTxicj5ub3RpZmljYXRpb25dOjo6c3RlcFN0eWxlCiAgICBEIC0tPiBFW0dvIHRvIHN0b3JlPGJyPmZvciBwaWNrdXBdOjo6c3RlcFN0eWxlCiAgICBFIC0tPiBGe0FkZDxicj5pdGVtcz99Ojo6c3RlcFN0eWxlCiAgICBGIC0tIFllcyAtLT4gR1tQcmVzZW50PGJyPmNhcmQgb248YnI+dGVybWluYWxdOjo6c3RlcFN0eWxlCiAgICBGIC0tIE5vIC0tPiBHW1ByZXNlbnQ8YnI+Y2FyZCBvbjxicj50ZXJtaW5hbF06OjpzdGVwU3R5bGUKICAgIEcgLS0+IEgoKFJlY2VpdmUgaXRlbXM8YnI+YXQgcGlja3VwKSk6OjpmaW5hbFN0eWxlCgolJSBTdHlsZXMKICAgIGNsYXNzRGVmIHRvcFN0eWxlIGZpbGw6IzAwMCxzdHJva2U6IzAwMCxjb2xvcjojZmZmCiAgICBjbGFzc0RlZiBjYXRlZ29yeVN0eWxlIGZpbGw6IzQ0NCxzdHJva2U6IzMzMyxjb2xvcjojZmZmCiAgICBjbGFzc0RlZiBzdGVwU3R5bGUgZmlsbDojZmZmLHN0cm9rZTojMGFiZjUzLHN0cm9rZS13aWR0aDoycHgsY29sb3I6IzAwMAogICAgY2xhc3NEZWYgZmluYWxTdHlsZSBmaWxsOiMwYWJmNTMsc3Ryb2tlOiMwNzhkM2UsY29sb3I6IzAwMAo=

Considerations

Before you set up a flow for this use case, there are a couple of points that you must be aware of or make a decision on.

Legal entity and location

In this use case, you use the payment terminal to authorize the online order.

If you want to process your Endless Aisle online transactions over a different merchant account than the regular in-person transactions, ask your Ayden Account Manager or Implementation Engineer about Merchant Account Sharing. With this, orders for both merchant accounts are processed on the same terminal, but kept separate. Enabling Merchant Account Sharing is subject to compliance approval. Terminals require a local legal entity.

If compliance approval is not given, you have other options to keep the transactions separate:

  • You can use separate terminals for regular in-store transactions and Endless Aisle transactions.
  • Or you can set up multiple stores under the same merchant account. This keeps the reporting simple.
  • Alternatively, instead of authorizing Endless Aisle online orders on a payment terminal, you can use Pay by Link payment links.

Reference:
Pay by Link

Capture settings

This use case requires specific procedures to capture the payment. You must enable and use manual capture, and contact our Support Team to enable multiple partial captures.

For the ordered items, the amount is initially authorized, but not captured. When the shopper picks up the items in the store, you make a manual capture request. If all items are picked up at the same time, you capture the full amount. If items are picked up at different times, you make a partial capture request for each pickup. If the shopper drops online items when picking up the order, you make a partial capture request for the reduced amount.

It depends on your other use cases whether it is best to enable manual capture for every payment, or in the API request for an individual payment.

Reference:
Enable manual capture, Partial manual capture, Capture a payment

Authorization expiry and late capture

After sending a notification that the order is ready for pickup and waiting for the shopper to collect the order, it is possible that the authorization has expired when you try to capture the payment. To deal with that, you have several options:

  • Implement authorization adjustments.
    You pre-authorize the order, and after a while send a /payments/{paymentPspReference}/amountUpdates request with the amount due, to renew the authorization. You can repeat this several times as needed, but each adjustment incurs costs.

    You need to choose between a synchronous flow or an asynchronous flow. In the synchronous flow you keep track of an adjustAuthorisationData blob that you pass from request to request. In the asynchronous flow you rely on webhooks to learn if the authorization adjustment succeeded.

    Authorization adjustment is also useful for:

    • Partial capture scenarios where only part of the order is picked up: after the partial capture you renew the authorization for a partial amount, to cover the items that will be picked up later.
    • Added in-store items at pickup, if you treat mixed baskets as one transaction: if the amount due increases substantially, you adjust the authorized amount upwards and then make a single capture request. Note that if the shopper drops online items when picking up the order you could adjust the amount down, but a partial capture request for a reduced amount is simpler and more cost-effective.

    Reference:
    Pre-authorization and authorization adjustment, Expiration of pre-authorizations

  • Use the Extend on capture feature.
    When you capture the payment, Adyen checks the status of the initial authorization. If the authorization has expired, we perform a new authorization request. This feature is supported for American Express, Mastercard, and Visa.

  • Implement tokenization.
    In your Terminal API payment request for the online items, you include tokenization parameters so that you receive a token and a shopper reference in the response. If at capture it turns out the initial authorization has expired, you make a new payment request to the Checkout API /payments endpoint. This request includes the token and shopper reference.

    Reference:
    Tokenization at the point of sale, Make an unscheduled card-on-file payment

Mixed baskets

If you want to support mixed baskets, where the shopper combines an online order with items that are available in the store, we recommend discussing your Adyen account structure and capture strategy with your Adyen implementation engineer or account manager.

You have the following options for capturing the payment:

  • One transaction with multiple partial captures: this option requires that online and in-store items are processed under the same merchant account.

    • For a mixed basket when the shopper places the order, you authorize the full amount of both the online order and the point-of-sale items, and make a partial capture request for the in-store items. Later, you make one or more partial captures as the ordered items are picked up.
    • For a mixed basket when the shopper picks up the order, you adjust the authorized amount upwards for the added in-store items and then make a single capture request. This option requires that you used pre-authorization on the initial payment request.
  • Two separate transactions: you authorize the online order and capture the amount later as ordered items are picked up. For the in-store items, you make a separate payment request and capture the amount automatically, immediately or with a capture delay. This approach applies for mixed baskets both when the shopper places the order, and when the shopper picks up the order.

Reference:
Account structures for mixed baskets, Delayed automatic capture. Also see the references under "Capture" above.

Card recognition

At order pickup, you use a card acquisition request to find the shopper's order: the shopper presents their card or other payment instrument to the payment terminal. You then use the card alias or PAR from the response to look up the shopper and the order in your CRM system.

To use card acquisition in this way, you must enable receiving shopper identifying data in API responses, and you must store the card alias and/or the Payment Account Reference (PAR) in the shopper's profile.

If the shopper does not have a record in your CRM system yet at the time of ordering, the CRM must also support manual entry of shopper details and creation of a new CRM record.

Reference:
Card acquisition, Receive card and shopper identifiers, Card recognition.

Sale attribution

You need to decide beforehand on how you will attribute the sale: if items are online items but ordered and paid for in-store, is this an in-store sale or an ecommerce sale?

Refunds and discounts

If the shopper does not want an ordered item, the item may be returned to the store (during pickup or later), or to the warehouse. Both systems must be able to look up the PSP reference for the order and issue a (partial) referenced refund. You need to support both:

  • Terminal API referenced refunds from the POS to the terminal for returns brought to the store.
  • Checkout API referenced refunds for returns sent to the warehouse.

If discounts are offered over the phone or chat, customer service agents must be able to trigger partial referenced refunds as well.

Reference:
Terminal API partial referenced refund, Checkout API refund

API flow

There are several Adyen API requests involved in the described shopper journey, as shown in the following diagrams for:

  • The flow without mixed baskets and the flow with mixed baskets as a single transaction. These flows are very similar.
  • The flow with mixed baskets as separate transactions.

The next section, "Instructions", provides more details about the API flow.

No mixed basket or mixed basket as one transaction

CnNlcXVlbmNlRGlhZ3JhbQogICAgcGFydGljaXBhbnQgU2hvcHBlcgogICAgcGFydGljaXBhbnQgRVJQCiAgICBwYXJ0aWNpcGFudCBQT1MKICAgIHBhcnRpY2lwYW50IEFkeWVuCgogICAgU2hvcHBlci0+PkVSUDogT3JkZXIgb25saW5lIGl0ZW1zCiAgICBvcHQgTWl4ZWQgYmFza2V0CiAgICAgICAgU2hvcHBlci0+PlBPUzogQWRkIGluLXN0b3JlIGl0ZW1zCiAgICBlbmQKICAgIFNob3BwZXItPj5QT1M6IEF1dGhvcml6ZSB0aGUgdHJhbnNhY3Rpb24KICAgIFBPUy0+PkFkeWVuOiBDYXJkIGFjcXVpc2l0aW9uIHJlcXVlc3QgZm9yIHdob2xlIGJhc2tldAogICAgQWR5ZW4tPj5QT1M6IENhcmQgYWNxdWlzaXRpb24gcmVzcG9uc2UKICAgIFBPUy0+PkVSUDogQWRkIHBpY2t1cCBzdG9yZSBhbmQgY29udGFjdCBkZXRhaWxzIHRvIG9yZGVyCiAgICBQT1MtPj5BZHllbjogVGVybWluYWwgQVBJIHBheW1lbnQgcmVxdWVzdCB3aXRoIG1hbnVhbCBjYXB0dXJlPGJyPk9wdGlvbmFsOiBwcmUtYXV0aG9yaXphdGlvbiBvciB0b2tlbml6YXRpb24KICAgIEFkeWVuLT4+UE9TOiBQYXltZW50IHJlc3BvbnNlCiAgICBvcHQgTWl4ZWQgYmFza2V0OiBJbi1zdG9yZSBpdGVtcyBhZGRlZAogICAgICAgIFBPUy0+PkFkeWVuOiBQYXJ0aWFsIG1hbnVhbCBjYXB0dXJlIG9mIGluLXN0b3JlIGl0ZW1zCiAgICAgICAgQWR5ZW4tPj5QT1M6IENhcHR1cmUgcmVzcG9uc2UKICAgIGVuZAogICAgRVJQLT4+U2hvcHBlcjogTm90aWZ5IG9yZGVyIHJlYWR5CiAgICBvcHQgRXh0ZW5kIGF1dGhvcml6YXRpb24gZm9yIG9ubGluZSBpdGVtcywgaWYgcHJlLWF1dGggd2FzIHVzZWQKICAgICAgICBFUlAtPj5BZHllbjogL3BheW1lbnRzL3twYXltZW50UHNwUmVmZXJlbmNlfS9hbW91bnRVcGRhdGVzIHJlcXVlc3QKICAgICAgICBBZHllbi0+PkVSUDogL2Ftb3VudFVwZGF0ZXMgcmVzcG9uc2UKICAgIGVuZAogICAgU2hvcHBlci0+PlBPUzogSWRlbnRpZnkgYXQgcGlja3VwCiAgICBQT1MtPj5BZHllbjogQ2FyZCBhY3F1aXNpdGlvbiByZXF1ZXN0CiAgICBBZHllbi0+PlBPUzogQ2FyZCBhY3F1aXNpdGlvbiByZXNwb25zZQogICAgUE9TLT4+QWR5ZW46IEVuYWJsZSBzZXJ2aWNlIHJlcXVlc3QgdG8gc3RvcCBjYXJkIGFjcXVpc2l0aW9uCiAgICBBZHllbi0+PlBPUzogRW5hYmxlIHNlcnZpY2UgcmVzcG9uc2UKICAgIG9wdCBNaXhlZCBiYXNrZXQ6IGFkanVzdCBhdXRob3JpemF0aW9uIGZvciBhZGRlZCBpbi1zdG9yZSBpdGVtcywgaWYgcHJlLWF1dGggd2FzIHVzZWQKICAgICAgICBTaG9wcGVyLS0+PlBPUzogQWRkIGluLXN0b3JlIGl0ZW1zCiAgICAgICAgUE9TLT4+QWR5ZW46IC9wYXltZW50cy97cGF5bWVudFBzcFJlZmVyZW5jZX0vYW1vdW50VXBkYXRlcyByZXF1ZXN0CiAgICAgICAgQWR5ZW4tPj5QT1M6IC9hbW91bnRVcGRhdGVzIHJlc3BvbnNlCiAgICBlbmQKICAgIFBPUy0+PkFkeWVuOiBNYW51YWwgY2FwdHVyZSBvZiB0aGUgZmluYWwgYW1vdW50IGR1ZQogICAgQWR5ZW4tPj5QT1M6IENhcHR1cmUgcmVzcG9uc2UKICAgIG9wdCBJZiBhdXRoIGV4cGlyZWQgYW5kIHBheW1lbnQgd2FzIHRva2VuaXplZCwgbWFrZSBwYXltZW50IHdpdGggdG9rZW4KICAgICAgICBQT1MtPj5BZHllbjogL3BheW1lbnRzIHJlcXVlc3QKICAgICAgICBBZHllbi0+PlBPUzogL3BheW1lbnRzIHJlc3BvbnNlCiAgICBlbmQKICAgIG9wdCBSZXR1cm4gdG8gc3RvcmUgbGF0ZXIsIGFmdGVyIHBpY2t1cAogICAgICAgIFNob3BwZXItLT4+UE9TOiBSZXR1cm4gaXRlbXMKICAgICAgICBQT1MtPj5BZHllbjogVGVybWluYWwgQVBJIHJlZnVuZCByZXF1ZXN0CiAgICAgICAgQWR5ZW4tPj5QT1M6IFJlZnVuZCByZXNwb25zZQogICAgZW5kCiAgICBvcHQgUmV0dXJuIHRvIHdhcmVob3VzZQogICAgICAgIFNob3BwZXItLT4+RVJQOiBSZXR1cm4gaXRlbXMKICAgICAgICBFUlAtPj5BZHllbjogQ2hlY2tvdXQgQVBJIHJlZnVuZCByZXF1ZXN0CiAgICAgICAgQWR5ZW4tPj5FUlA6IFJlZnVuZCByZXNwb25zZQogICAgZW5kCg==

Mixed basket as two transactions

We usually recommend delayed automatic capture for point-of-sale transactions. That is why the diagram shows automatic capture for the separate payment request related to the in-store items.

CnNlcXVlbmNlRGlhZ3JhbQogICAgcGFydGljaXBhbnQgU2hvcHBlcgogICAgcGFydGljaXBhbnQgRVJQCiAgICBwYXJ0aWNpcGFudCBQT1MKICAgIHBhcnRpY2lwYW50IEFkeWVuCgogICAgU2hvcHBlci0+PkVSUDogT3JkZXIgb25saW5lIGl0ZW1zCiAgICBub3RlIG92ZXIgU2hvcHBlciwgUE9TOiBNaXhlZCBiYXNrZXQKICAgIFNob3BwZXItPj5QT1M6IEFkZCBpbi1zdG9yZSBpdGVtcwogICAgU2hvcHBlci0+PlBPUzogQXV0aG9yaXplIHRyYW5zYWN0aW9uCiAgICBQT1MtPj5BZHllbjogQ2FyZCBhY3F1aXNpdGlvbiByZXF1ZXN0CiAgICBBZHllbi0+PlBPUzogQ2FyZCBhY3F1aXNpdGlvbiByZXNwb25zZQogICAgUE9TLT4+RVJQOiBBZGQgcGlja3VwIHN0b3JlIGFuZCBjb250YWN0IGRldGFpbHMgdG8gb3JkZXIKICAgIG5vdGUgb3ZlciBQT1MsIEFkeWVuOiBObyBjYXB0dXJlIHlldCBvZiBvbmxpbmUgaXRlbXMKICAgIFBPUy0+PkFkeWVuOiBUZXJtaW5hbCBBUEkgcGF5bWVudCByZXF1ZXN0IDEgZm9yIG9ubGluZSBpdGVtcyB3aXRoIG1hbnVhbCBjYXB0dXJlPGJyPk9wdGlvbmFsOiBwcmUtYXV0aG9yaXNhdGlvbiBvciB0b2tlbml6YXRpb24KICAgIEFkeWVuLT4+UE9TOiBQYXltZW50IHJlc3BvbnNlIDEKICAgIG5vdGUgb3ZlciBQT1MsIEFkeWVuOiBJbW1lZGlhdGUgb3IgZGVsYXllZCBhdXRvbWF0aWMgY2FwdHVyZSBvZiBpbi1zdG9yZSBpdGVtcwogICAgUE9TLT4+QWR5ZW46IFRlcm1pbmFsIEFQSSBQYXltZW50IHJlcXVlc3QgMiBmb3IgaW4tc3RvcmUgaXRlbXMKICAgIEFkeWVuLT4+UE9TOiBQYXltZW50IHJlc3BvbnNlIDIgd2l0aCBhdXRvbWF0aWMgY2FwdHVyZQogICAgRVJQLT4+U2hvcHBlcjogTm90aWZ5IG9yZGVyIHJlYWR5CiAgICBvcHQgRXh0ZW5kIGF1dGhvcml6YXRpb24gZm9yIG9ubGluZSBpdGVtcywgaWYgcHJlLWF1dGhvcml6YXRpb24gd2FzIHVzZWQKICAgICAgICBFUlAtPj5BZHllbjogL3BheW1lbnRzL3twYXltZW50UHNwUmVmZXJlbmNlfS9hbW91bnRVcGRhdGVzIHJlcXVlc3QKICAgICAgICBBZHllbi0+PkVSUDogL2Ftb3VudFVwZGF0ZXMgcmVzcG9uc2UKICAgIGVuZAogICAgU2hvcHBlci0+PlBPUzogSWRlbnRpZnkgYXQgcGlja3VwCiAgICBQT1MtPj5BZHllbjogQ2FyZCBhY3F1aXNpdGlvbiByZXF1ZXN0CiAgICBBZHllbi0+PlBPUzogQ2FyZCBhY3F1aXNpdGlvbiByZXNwb25zZQogICAgUE9TLT4+QWR5ZW46IEVuYWJsZSBzZXJ2aWNlIHJlcXVlc3QgdG8gc3RvcCBjYXJkIGFjcXVpc2l0aW9uCiAgICBBZHllbi0+PlBPUzogRW5hYmxlIHNlcnZpY2UgcmVzcG9uc2UKICAgIG5vdGUgb3ZlciBQT1MsIEFkeWVuOiBNYW51YWwgY2FwdHVyZSBvZiBvbmxpbmUgaXRlbXMKICAgIFBPUy0+PkFkeWVuOiBNYW51YWwgY2FwdHVyZSwgcGFydGlhbCBpZiBpdGVtcyBhcmUgZHJvcHBlZAogICAgQWR5ZW4tPj5QT1M6IENhcHR1cmUgcmVzcG9uc2UKICAgIG9wdCBJZiBhdXRoIGV4cGlyZWQgYW5kIHBheW1lbnQgd2FzIHRva2VuaXplZCwgbWFrZSBwYXltZW50IHdpdGggdG9rZW4KICAgICAgICBQT1MtPj5BZHllbjogL3BheW1lbnRzIHJlcXVlc3QKICAgICAgICBBZHllbi0+PlBPUzogL3BheW1lbnRzIHJlc3BvbnNlCiAgICBlbmQKICAgIFNob3BwZXItLT4+UE9TOiBBZGQgaW4tc3RvcmUgaXRlbXMgYXQgcGlja3VwCiAgICBub3RlIG92ZXIgUE9TLCBBZHllbjogSW1tZWRpYXRlIG9yIGRlbGF5ZWQgYXV0b21hdGljIGNhcHR1cmUgb2YgaW4tc3RvcmUgaXRlbXMKICAgIFBPUy0+PkFkeWVuOiBUZXJtaW5hbCBBUEkgUGF5bWVudCByZXF1ZXN0IGZvciBpbi1zdG9yZSBpdGVtcwogICAgQWR5ZW4tPj5QT1M6IFBheW1lbnQgcmVzcG9uc2Ugd2l0aCBhdXRvbWF0aWMgY2FwdHVyZQogICAgb3B0IFJldHVybiB0byBzdG9yZSBsYXRlciwgYWZ0ZXIgaW5pdGlhbCBwaWNrdXAKICAgICAgICBTaG9wcGVyLS0+PlBPUzogUmV0dXJuIGl0ZW1zCiAgICAgICAgUE9TLT4+QWR5ZW46IFRlcm1pbmFsIEFQSSByZWZ1bmQgcmVxdWVzdAogICAgICAgIEFkeWVuLT4+UE9TOiBSZWZ1bmQgcmVzcG9uc2UKICAgIGVuZAogICAgb3B0IFJldHVybiB0byB3YXJlaG91c2UKICAgICAgICBTaG9wcGVyLS0+PkVSUDogUmV0dXJuIGl0ZW1zCiAgICAgICAgRVJQLT4+QWR5ZW46IENoZWNrb3V0IEFQSSByZWZ1bmQgcmVxdWVzdAogICAgICAgIEFkeWVuLT4+RVJQOiBSZWZ1bmQgcmVzcG9uc2UKICAgIGVuZAo=

Instructions

This section provides high-level instructions focusing on how to use the Adyen APIs and webhooks in the described shopper journey.

The code samples show the minimally required parameters. You can add more parameters.

Contact details

After the shopper has ordered the online items and selected a pickup store:

  1. Make a Terminal API CardAcquisitionRequest where the CardAcquisitionTransaction object contains the TotalAmount field with the purchase amount for the ordered items.

    If you support mixed baskets as a single transaction, use the total amount of the basket: the purchase amount for the ordered online items and any items from the store.
    If you support mixed baskets as two separate transactions, use only the amount of the ordered online items.

    Reference:
    Card acquisition

  2. When you receive the CardAcquisitionResponse, save the following information:

    • AdditionalResponse.PaymentAccountReference: the PAR, if present.
    • AdditionalResponse.alias: the card alias.
    • The TimeStamp and TransactionID from the POIData.POITransactionID object. You need these values later, when you (pre-)authorize the transaction.

    The following example shows the AdditionalResponse as a string of key-value pairs concatenated with an ampersand (&). It is possible you receive a Base64-encoded string instead, which you need to Base64 decode first.

  3. Use the card alias and/or PAR from the card acquisition response to look up the shopper's contact details in your ERP system. You need the contact details later, to send a notification when the order is ready for pickup.

  4. If the shopper is found in the ERP system, let the shop assistant verify the contact details with the shopper.
    Ensure the shop assistant can update this information in the ERP system, if needed.

  5. If the shopper is not found in the ERP system, add a record for the shopper to the ERP system with the card alias and/or PAR from the card acquisition response, and the other details that you need, specifically the contact details and the name of the shopper. You can collect those other details in various ways, for example:

    • The shop assistant asks the shopper for the details.
    • You collect the shopper's details on a secondary screen, for instance a tablet.
    • You use input requests to collect the shopper's details on the payment terminal.
  6. Make sure the pickup store location is included on the order.

(Pre-)authorization

  1. Make a Terminal API PaymentRequest with:

    • PaymentData.CardAcquisitionReference: an object with the TimeStamp and TransactionID returned in the POIData.POITransactionID object of the card acquisition response.

    • PaymentTransaction.AmountsReq: an object with the Currency and the RequestedAmount.
      If you support mixed baskets as a single transaction, use the total amount of the basket.
      If you support mixed baskets as two separate transactions, use only the amount of the ordered online items.

    • SaleToAcquirerData: a parameter with manualCapture set to true. Optionally you can add SaleToAcquirerData parameters to pre-authorize or tokenize the transactions, as a method to handle authorization expiry and late captures.

      Use one of the following formats to provide the SaleToAcquirerData value:

      • Option 1: A JSON object converted to a Base64-encoded string.
      • Option 2: Key-value pairs.

      Reference:
      Enable manual capture for a payment

  2. When you receive the payment response, save details from the following fields:

    • POITransactionID.TransactionID: save the transaction ID. This is provided in the format tenderReference.pspReference, for example, CW1r112876209163113.DXCD52AY3WUGXS93. The PSP reference is also provided in the AdditionalResponse.
      You need the PSP reference later, to extend or adjust the authorization, and to capture the payment. You also need the PSP reference if the shopper returns items to the warehouse.
      You need the full transaction ID if the shopper returns items to the store.

    • AdditionalResponse:

      • If you use synchronous authorization adjustment, save the adjustAuthorisationData. You need this data blob later, to extend or adjust the authorization.

      • If you use tokenization, save the token (recurring.recurringDetailReference or tokenization.storedPaymenMethodId) and the shopper reference (recurring.shopperReference or tokenization.shopperReferece).

    • POITransactionID.TimeStamp: save the payment date and time. You need the timestamp if the shopper returns items to the store.

  3. If you support mixed baskets as a single transaction, make a partial manual capture request for the in-store items. See the example below, under "In-store pickup".

  4. If you support mixed baskets as two separate transactions, make another Terminal API payment request for the in-store items.
    If your point-of-sale merchant account uses immediate or delayed capture by default (which we usually recommend), do not set manual capture in this payment request. Otherwise, see the exampleunder "In-store pickup", and make a separate manual capture request for the in-store items.

Authorization extension (optional)

At one or more moments before or after you notify the shopper that the order is ready for pickup, you may need to extend the authorization. This ensures you can still capture the payment later, when the shopper arrives at the store to pick up the order.

Reference:
Expiration of pre-authorizations,
Authorization adjustment

In-store pickup

When the shopper arrives at the pickup location to collect the order:

  1. To find the shopper's order based on the card that was used to authorize the order:

    1. Make a Terminal API CardAcquisitionRequest with an empty CardAcquisitionTransaction object.

      Reference:
      Card acquisition

    2. When you receive the CardAcquisitionResponse, find the shopper's order in your ERP system using the following information from the response.AdditionalResponse:

      • PaymentAccountReference: the PAR, if present.
      • alias: the card alias

      The following example shows the AdditionalResponse as a string of key-value pairs concatenated with an ampersand (&). It is possible you receive a Base64-encoded string instead, which you need to Base64 decode first.

    3. When you have found the order, finish the card acquisition by making an EnableServiceRequest to stop the flow.
      Consider including a DisplayOutput object with an explanatory message for the shopper, as shown in the following example.

      Reference:
      Finish with a cancellation

  2. Optional, if you used pre-authorization and you support mixed baskets as one transaction:

    If the shopper adds in-store items that significantly increase the amount due, make a POST /payments/{paymentPspReference}/amountUpdates request to adjust the authorization amount.

    The following examples show how to adjust the amount for the authorization with PSP reference DXCD52AY3WUGXS93 up from USD 124.66 to USD 214.03 for added in-store items with a value of USD 89.37.

  3. Make a manual capture request for the amount due:

    Send a POST request to the /payments/{paymentPspReference}/captures endpoint, where paymentPspReference is the PSP reference from the (pre-)authorization response.

    In your request, include:

    Parameter Required Description
    merchantAccount Required The name of your merchant account that is used to process the payment. This depends on how you attribute the sale.
    amount.value Required The amount in minor units (without a decimal point) being captured. If you made any /amountUpdates requests, this is the amount from your last authorization update.

    You need to make a partial capture for a smaller amount in these cases:

    • The whole order is available at pickup but the shopper does not want some of the ordered items.
    • Only part of the order is available and being picked. If you used pre-authorization: after the partial capture, you can adjust the authorization to a partial amount that covers the items that will be picked up at a later time.
  4. The following example shows a capture request for the authorization with PSP reference DXCD52AY3WUGXS93 for USD 124.66.

  5. Check the CAPTURE webhook event message for any issue with the capture.

    A response with success false and reason Transaction is expired means the authorization expired. If you tokenized the original Terminal API payment request, you can make a Checkout API /payments request with the token.

  6. If you treat mixed baskets as two separate transactions, make a separate Terminal API payment request for the in-store items that the shopper wants to purchase.

Later returns, after pickup

  1. If the shopper returns one or more of the delivered items, issue a refund using the Terminal API if the items are returned in-store, or using the Checkout API if the items returned to the warehouse.

See also