Classic-platform icon

Point of sale for platforms

Process point-of-sale payments on behalf of your account holders.

This page is for classic Adyen for Platforms integrations. If you are just starting your implementation, refer to our new integration guide instead.

Adyen for Platforms enables you to onboard account holders with point-of-sale (POS) integrations to accept in-person payments. To make this happen, you need to:

Requirements

Before you start processing point-of-sale payments for your account holders, you need to:

You can specify different currencies, MCCs, and payment methods for each country/region. We use this information to enable you to create stores based on the type of payments that must be processed in the store.

Subscribe to store notifications

When you add a store for an account holder, we send a notification to let you know the store has been set up. To ensure you receive this notification:

  1. Make a POST request to the Terminal API endpoint, specifying:

    • active: true.
    • description: Your text to recognize the notification subscription by.
    • An eventConfigs array with eventType: ACCOUNT_HOLDER_STORE_STATUS_CHANGE and includeMode: INCLUDE.
    • notifyURL: Endpoint on your server where you'll receive the notifications.
    • hmacSignatureKey: Use this parameter if you want us to protect notifications with HMAC signatures. It specifies the HMAC key that we'll use to calculate the HMAC signatures of the notifications we send to the notifyURL. On your end you'll need to verify the signatures of the incoming notifications.
    • notifyUsername and notifyPassword: Username and password that we need for basic authentication with the server where you'll receive the notifications.
    • sslProtocol: Protocol used to secure the communication, such as TLS or SSL.
  2. Make sure that your server accepts the notifications.

  3. Use the notificationId you receive in the response to test the notification.

Create a store for the account holder

Make sure our Support Team has enabled creating stores. If you haven't requested this yet, refer to the requirements.

Once our Support Team has enabled creating stores, you can start adding stores for your account holders.

To provide store details, include a storeDetails array when you create a new account holder or when you update an existing one:

  1. Make a POST request to one of the following endpoints:

    Situation Endpoint Specify
    There is no account holder for the sub-merchant yet. /createAccountHolder The usual parameters to create a business account holder, as well as businessDetails.taxId.
    You want to add a store to an existing account holder. /updateAccountHolder accountHolderCode: Your unique reference for the account holder. Include businessDetails.taxId, unless it is already present as part of businessDetails.
  2. In the request body, include an accountHolderDetails.storeDetails array, specifying:

    • address: The city, country, houseNumberOrName, postalCode, stateOrProvince, and street of the physical store where the account holder will process payments from.
    • fullPhoneNumber: The phone number of the store.
    • merchantAccount: The merchant account used for accepting payments.
    • merchantCategoryCode: The merchant category code (MCC) that classifies the business of the account holder.
    • storeName: The name of the account holder's store. This will be included in the shopper statement.
    • storeReference: Your unique reference for the account holder's store.

    The next example shows a /createAccountHolder request to create a new account holder with a store.

    The following example shows how to add a store to an existing account holder using an /updateAccountHolder call.

    The response contains various account holder details, including the storeDetails showing that the status of the store is Pending.

  3. Before processing point-of-sale (POS) payments, wait until you receive an ACCOUNT_HOLDER_STORE_STATUS_CHANGE notification showing that the new status of the store is Active.

Assign a terminal to the store

To process POS payments, the account holder's store needs to have one or more payment terminals. The process is as follows:

  1. Select a terminal and inform the account holder of the communication requirements.

  2. Order a terminal if you do not have the required terminal in your inventory.

  3. Assign the terminal from your inventory to the store of the account holder in one of the following ways:

    • Assign terminals using your Customer Area
      or
    • Assign terminals in bulk using API calls

      The advantage of using the Terminal Management API over the Customer Area, is that API calls enable you to automate assigning terminals and retrieving an overview of terminal assignments.

  4. Configure the terminals in the Customer Area, under Point of Sale > Terminal settings.

  5. Ship the terminal to the physical store address and instruct the account holder to board the terminal.

Split a payment

To split a point-of-sale payment, you can:

When you use a split configuration, Adyen evaluates the rules in the split configuration for all the transactions processed through the store. If you need to change the commission fees for specific transactions, you can send split instructions in the payment or capture API request. Any split instructions that you send through the API overrides the automatic split.

Make a split payment using the Terminal API

To split a POS payment, you make a Terminal API call. In the PaymentRequest you provide the split payment data in the SaleToAcquirerData, in key-value pair or Base64-encoded format. This credits payments directly to an account holder's account.

To make the payment:

  1. Make a POST request to a Terminal API endpoint, specifying:

    • MessageHeader: the standard SaleToPOIRequest.MessageHeader object. Specify:

      Parameter Required Description
      ProtocolVersion -white_check_mark- 3.0
      MessageClass -white_check_mark- Service
      MessageCategory -white_check_mark- Payment
      MessageType -white_check_mark- Request
      ServiceID -white_check_mark- Your unique ID for this request, consisting of 1-10 alphanumeric characters. Must be unique within the last 48 hours for the terminal (POIID) being used.
      SaleID -white_check_mark- Your unique ID for the POS system component to send this request from.
      POIID -white_check_mark- The unique ID of the terminal to send this request to. Format: [device model]-[serial number].
    • PaymentRequest: The request body. This must include:

      Parameter Required Description
      SaleData.SaleTransactionID -white_check_mark- An object with:
      • TransactionID: your reference to identify a payment. We recommend using a unique value per payment. In your Customer Area and Adyen reports, this will show as the merchant reference for the transaction.
      • TimeStamp: date and time of the request in UTC format.
      SaleData.SaleToAcquirerData Provides the split payment data as concatenated key-value pairs separated by an ampersand (&) character, or in Base64-encoded format. See the tables below for details.
      PaymentTransaction.AmountsReq -white_check_mark- An object with:
      • Currency: the transaction currency.
      • RequestedAmount: the transaction amount.
    • To provide the split payment data in PaymentRequest.SaleData.SaleToAcquirerData, use the following fields:

      Field Description Example
      split.api Version of the Split API: 1. split.api=1
      split.totalAmount Amount to be split, in minor units. Must be equal to the transaction amount and to the sum of the split amounts. split.totalAmount=62000
      split.currencyCode Currency of the amount to be split. split.currencyCode=EUR
      split.nrOfItems Number of times you will split the payment. Must match the number of split items in the request. split.nrOfItems=2

      Specify each split as a split.item{item#} starting at 1split.item1split.item2, and so on. Each split item includes:

      Field Description Example
      split.item{item#}.amount Amount of the split, in minor units. split.item1.amount=60000 and split.item2.amount=2000
      split.item{item#}.type Split type. A type of MarketPlace or VAT sends the amount to the account specified. A type of Commission or PaymentFee sends the amount to your liable account. split.item1.type=MarketPlace and split.item2.type=Commission
      split.item{item#}.account Account that will receive the split. This is the accountCode of one of your account holder's accounts or your own liable account. You do not need to specify an account when split.type is Commission.  split.item1.account=8815628270908491
      split.item{item#}.reference The reference for that specific transaction split, which is returned in our reporting. Required if the split.type is MarketPlace.  

    The following example shows how to split a EUR 620.00 payment into EUR 600.00 to be paid into the account holder's account with accountCode 8815628270908491 and EUR 20.00 commission to be paid to the platform.

    The payment request is routed to the terminal, for the shopper to present their card and verify the payment. The payment is then sent to the Adyen payments platform for processing.

  2. Receive the payment result.

    If your integration uses asynchronous cloud communications, you must set up event notifications. We then send the Terminal API responses to your endpoint.

    If the payment is successful:

    • Approved is shown on the terminal display.
    • You receive a payment response containing:
      • POIData.POITransactionID.TransactionID: Transaction identifier for the payment in the format tenderReference.pspReference. For example, oLkO0012498220087000.981517998282382C.
      • PaymentResponse.Response.Result: Success
      • PaymentResponse.Response.AdditionalResponse: A base64 string. When decoded, this is a JSON object with additional transaction data.
      • PaymentReceipt: Object containing data you can use to generate a receipt.

You can also view the details of a payment in your Customer Area, under Transactions > Payments.

Split at capture using the API

Some platforms do not know the final split amounts at the moment the payment request is made. If this applies to your account holder's POS payments, you need to enable manual capture for POS payments and follow up each authorised Terminal API payment with a /payments/{paymentPspReference}/captures API call. Splitting at capture is also the procedure to use for tipping (gratuity) and partial payments.

Enabling manual capture for POS payments applies to all your point-of-sale account holders.

Proceed as follows to split at capture:

  1. From the transactionID field in the payment response, get the pspReference of the authorization you want to capture.

  2. To capture and split a payment at the same time, send a POST /payments/{paymentPspReference}/captures request, where paymentPspReference is the pspReference of the authorization you want to capture.

    In the body, include the splits array. For each item in the array, specify the following fields:

    Parameter Required Description
    account -white_check_mark- The account that will receive (or be charged) the split amount. This is the accountCode of your account holder's accounts or your liable balance account. You do not need to specify this field when type is Commission.
    amount.value -white_check_mark- The value of the split amount. You do not need to specify this field for transaction fees, since they are not known at the time of payment.
    type -white_check_mark- Defines the part of the payment you want to book to a specific account.
    Possible values:
    • Commission: books the commission to your platform's liable account.
    • MarketPlace: books the sale amount to the specified account.
    • PaymentFee: books the transaction fees to your platform's liable account.
    • VAT: books the value-added tax for the sale amount to the specified account.
    reference Required if type is MarketPlace Your reference for the split, which you can use to link the split to other operations and to reconcile payments. If the reference is not provided, the split is reported as part of the aggregated TransferBalance record in the Marketplace Payments accounting report.
    description Your description for that specific transaction split, which is returned in our reporting.

The example below shows how to capture a EUR 620.00 authorization with pspReference 981517998282382C, and split it into EUR 600.00 to be paid into the account holder's account with accountCode 8815628270908491 and EUR 20.00 commission to be paid to your liable account.

Check the result

API response

In the capture response, note the following:

  • paymentPspReference: the PSP reference of the authorization
  • pspReference: the PSP reference associated with this capture request. This is different from the PSP reference of the authorization.
  • status: received

Webhook

Wait for the CAPTURE webhook to learn the outcome of the request.

See also