In-person payments
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:
- Example request
- Example response
{
"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"
}
]
}
{
"id": "pmt_4u63jn9LyJyJBn1LLrlVlg",
"object": "payment",
"created_at": "2025-05-19T09:34:41.529984Z",
"account_id": "acc_5O2jndwBvLOkb3S3kerabf",
"reference": "876c7552-adab-494a-af9e-99722ae01ca4-with-fees",
"amount":
{
"currency": "EUR",
"quantity": "10.00"
},
"payment_rails":
{
"payment_device_id": "{payment_device_id}"
},
"checkout_status": "open"
}
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.
Interaction | Checkout status | Authorization status |
---|---|---|
POST /payments request | Open | - |
Payment device displays sale | Open | - |
Customer inserts card | Open | - |
Customer cancels sale on terminal | Failed | Declined |
Payment is authorized | Succeeded | Approved |
Payment is declined | Failed | Declined |
Payment device is busy processing another payment | Failed | - |
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.
Do not call the GET /payment endpoint more than once a second for a payment until you get a final status.
{
"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.
- Success
- Failed
{
"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"
}
}
{
"object": "event",
"webhook_endpoint_id": "webh_4WxqjT0YfsxXDeKPRiebwE",
"event_type": "payment.failed",
"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": "failed"
}
}
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 value | Test scenario | Checkout status |
---|---|---|
test_pos_approved_visa | Simulates a successful Visa payment. | Succeeded |
test_pos_approved_mastercard | Simulates a successful Mastercard payment. | Succeeded |
test_pos_declined_visa | Simulates a declined Visa payment. | Failed |
test_pos_declined_mastercard | Simulates a declined Mastercard payment. | Failed |
test_pos_device_busy | Simulates 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.