Skip to main content

In-person payments

BETA

In-person payments are currently in beta. Contact your Rootline point of contact for more information.

Rootline's In-person payments offering is cloud-based, so that you don't have to rely on a local network. The payment device needs to be connected to the internet using wifi or 4G/5G. Just like for online payments, you initiate an in-person payment from your server by calling the Payments API. The payment's status changes are communicated through webhook events. Additionally, you can use the GET /payments to retrieve the latest status.

Start a payment

To start a payment you need to provide the payment_device_id in the payment_rails of the /payments request. The payment will have checkout_status=open and the payment request is sent to the payment device. At this point, the customer will interact with the payment device to complete the payment. Here's an example of how to create a payment:

{
"account_id": "{platform_account_id}",
"processing_account_id": "{client_merchant_account_id}",
"payment_rails": {
"payment_device_id": "{payment_device_id}"
},
"reference": "your-reference",
"amount":
{
"currency": "EUR",
"quantity": "10.00"
},
"splits":
[
{
"account_id": "[client_merchant_account_id]",
"amount":
{
"currency": "EUR",
"quantity": "10.00"
},
"reference": "your-reference"
}
]
}

Receiving updates

The payment acceptance process takes place on the device. To keep your system up-to-date, please subscribe to the payment webhook events. For more detailed information on the authorization stages, you can subscribe to the authorization webhook events. Additionally, the GET /payments can be used to retrieve the latest status at any point in the process.

InteractionCheckout statusAuthorization status
POST /payments requestOpen-
Payment device displays saleOpen-
Customer inserts cardOpen-
Customer cancels sale on terminalFailedDeclined
Payment is authorizedSucceededApproved
Payment is declinedFailedDeclined
Payment device is busy processing another paymentFailed-

GET the payment

To fetch the payment status after a redirect, you use our GET /payments/{payment_id} call. From the response leverage the checkout_status and authorizations to determine the payment status.

Acceptable request per second

Do not call the GET /payment endpoint more than once a second for a payment until you get a final status.

The response to the GET /payment/{payment_id}
{
"id": "pmt_4ywyzcDHlXkc3xMVOp2Zu4",
"object": "payment",
"created_at": "2025-02-14T09:49:53.853335Z",
"account_id": "acc_5BTNdeSEmsHml77iazsI0r",
"reference": "your-reference",
"amount":
{
"currency": "EUR",
"quantity": "10.00"
},
"payment_rails":
{
"payment_device_id": "{payment_device_id}",
"payment_method": "visa"
},
"checkout_status": "succeeded",
"authorizations":
[
{
"id": "auth_4ywyzcDHlXkc3xMVOp2Zu6",
"object": "authorization",
"created_at": "2025-02-17T12:24:22.006529Z",
"amount":
{
"currency": "EUR",
"quantity": "10.00"
},
"status": "approved",
"payment_rails":
{
"payment_device_id": "{payment_device_id}",
"payment_method": "visa"
}
}
]
}

Webhooks

Rootline sends you webhook events to inform you about the outcome of a payment. You can receive webhook events for any status change mentioned here. To learn more about our webhook events, please read our section about webhooks.

Webhook event for a succeeded payment
{
"object": "event",
"webhook_endpoint_id": "webh_4WxqjT0YfsxXDeKPRiebwE",
"event_type": "payment.succeeded",
"event_time": "2025-02-14T09:49:52.123235Z",
"livemode": false,
"api_version": "2024-04-23",
"payment":
{
"id": "pmt_4ywyzcDHlXkc3xMVOp2Zu4",
"object": "payment",
"created_at": "2025-02-14T09:49:52.123235Z",
"account_id": "your-platform-account-id",
"reference": "your-reference",
"amount":
{
"currency": "EUR",
"quantity": "10.00"
},
"payment_rails":
{
"payment_device_id": "{payment_device_id}",
"payment_method": "visa"
},
"checkout_status": "succeeded"
}
}

Tipping

If you support tipping in your application, you can include the tip into the payment amount when creating the payment with Rootline. In the /payments request, the amount should be the total amount including tip. For example, if the original payment amount is €20.00 and the tip amount is €4.00, the amount in the /payments request should become €24.00.
You can route tips to a dedicated tipping account using the splits array.

Example payments request with tipping

{
"account_id": "{platform_account_id}",
"processing_account_id": "{client_merchant_account_id}",
"payment_rails":
{
"payment_device_id": "{payment_device_id}"
},
"reference": "your-reference",
"amount":
{
"currency": "EUR",
"quantity": "24.00"
},
"splits":
[
{
"account_id": "[client_merchant_account_id]",
"amount":
{
"currency": "EUR",
"quantity": "20.00"
},
"reference": "your-reference"
},
{
"account_id": "[tipping_account_id]",
"amount":
{
"currency": "EUR",
"quantity": "4.00"
},
"reference": "your-tip-reference"
}
]
}

Failure reasons

An In-person payment request can fail for several reasons:

  • The device is not connected to the internet
  • The device is busy processing another payment request
  • The store attendant or customer canceled the payment or the customer didn't provide their card within the timeout period
  • The card issuer declined the payment

When a payment reaches checkout_status "failed", check the authorizations object to find the decline_details for more information about reason the payment failed.

Depending on the failure you can initiate a new payment if applicable.

Testing

The In-person payments integration can be tested without physical hardware. Rootline offers the following test scenarios that can be provided in the reference field of the /payments request.

Reference valueTest scenarioCheckout status
test_pos_approved_visaSimulates a successful Visa payment.Succeeded
test_pos_approved_mastercardSimulates a successful Mastercard payment.Succeeded
test_pos_declined_visaSimulates a declined Visa payment.Failed
test_pos_declined_mastercardSimulates a declined Mastercard payment.Failed
test_pos_device_busySimulates the payment device unable to handle the payments request as its processing another payment.Failed

The checkout status will be communicated through both webhooks and by calling the GET /payments endpoint.

To simulate a payment you also need a payment_device_id, reach out to your Rootline point of contact for more information.