JSON-RPC API Reference
This document describes the JSON-RPC API methods supported by the Teya Unified EPOS SDK.
Table of Contents
Methods
- initialize
- setup
- setupAuthAndStore
- getTerminals
- linkTerminal
- clearDeviceLink
- clearUserAuth
- makePaymentAndSubscribe
- unsubscribeAll
- cancelPayment
- refundPayment
- makeUnreferencedRefund
- printCustomTemplate
- printCustomImage
- zipLogs
- openTab
- listTabs
- getTab
- closeTab
- respondToBillRequest
- respondWithError
- subscribeTabEvents
- unsubscribeTabEvents
- setPayAtTableEnabledOnStore
Common Definitions
initialize
Initializes the PosLink integration.
PosLink is a Teya Cloud service designed to handle payment requests and deliver
push notifications to the terminal linked by the user during the "setup" method call.
During the first successful "setup" method call, the user will also be required
to log in to their Teya account.
Request
{
"jsonrpc": "2.0",
"method": "initialize",
"params": {
"requesterId": "com.company.eposapp",
"requesterVersion": "1.0.0",
"isProductionEnv": true,
"clientId": "<your client id>",
"clientSecret": "<your client secret>",
"eposInstanceId": "<store or merchant>-<epos device id>",
"initialUserAccessToken": "<some user access token>"
},
"id": "30db5978-22c6-306c-a737-052260426f45"
}
isProductionEnv.isProductionEnv.Response
{
"jsonrpc": "2.0",
"result": {
"type": "initialize->ack",
"integrationsAppVersion": "1.1.0",
"integrations_app_version": "1.1.0"
},
"id": "30db5978-22c6-306c-a737-052260426f45"
}
integrationsAppVersion under the snake_case key integrations_app_version, kept for backwards compatibility. New integrations should read integrationsAppVersion; this key will be removed in v2.setup
Sets up the PosLink integration.
If there's no device linked info or no authentication saved in the SDK, it will show Teya UI
to help the user authenticate to their Teya account and/or link to their Teya payment device.
If no device is linked or authentication data is missing, the SDK will display the Teya UI
to guide the user through authentication and device linking. This process typically occurs
only during the initial setup or after invoking clearDeviceLink or clearUserAuth.
In such cases, the UI will prompt the user to complete the necessary steps.
Request
{
"jsonrpc": "2.0",
"method": "setup",
"id": "a0f84894-2ce8-33cf-93c0-fa6cc684007d"
}
Response
{
"jsonrpc": "2.0",
"result": {
"type": "setup->onResponse",
"response": "SUCCESS",
"debugErrorMessage": "Invalid client",
"store": {
"id": "store-id",
"name": "My store",
"address": {
"city": "London",
"country": "United Kingdom",
"streetAddressLine1": "123 High Street",
"streetAddressLine2": "Floor 2",
"zipcode": "EC1A 1BB"
}
},
"terminal": {
"id": "terminal-123",
"name": "Terminal 1",
"serialNumber": "SN123456789"
}
},
"id": "a0f84894-2ce8-33cf-93c0-fa6cc684007d"
}
Response setup result.Store store to which the epos is linked to. Present always in cases of "SUCCESS".Terminal terminal to which the epos is linked to. Present always in cases of "SUCCESS".Responseenum values (used onresponse)`Response` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-setupresult-response).
Storeclass parameters (used onstore)`Store` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-setup-store).
Terminalclass parameters (used onterminal)`Terminal` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-setup-terminal).
setupAuthAndStore
Like "setup" method but skips terminal selection step. That step should still
be done by using "linkTerminal" method before calling any method that requires a linked
terminal.
Request
{
"jsonrpc": "2.0",
"method": "setupAuthAndStore",
"id": "ec82c29e-5726-3d8a-9f19-59b5e7e19fd6"
}
Response
Like "setup->onResponse" but will not include the terminal info on successful setup, since
that step is skipped for "setupAuthAndStore" method.
{
"jsonrpc": "2.0",
"result": {
"type": "setupAuthAndStore->onResponse",
"response": "SUCCESS",
"debugErrorMessage": "Invalid client",
"store": {
"id": "store-id",
"name": "My store",
"address": {
"city": "London",
"country": "United Kingdom",
"streetAddressLine1": "123 High Street",
"streetAddressLine2": "Floor 2",
"zipcode": "EC1A 1BB"
}
}
},
"id": "ec82c29e-5726-3d8a-9f19-59b5e7e19fd6"
}
Response setup result.Store store to which the epos is linked to. Present always in cases of "SUCCESS".Responseenum values (used onresponse)`Response` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-setupresult-response).
Storeclass parameters (used onstore)`Store` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-setup-store).
getTerminals
Retrieves the list of terminals associated with the currently linked store.
Request
{
"jsonrpc": "2.0",
"method": "getTerminals",
"params": {
"forceRefresh": true
},
"id": "4d23d20b-c80a-3bf2-8d45-c18cd2387c27"
}
Response
{
"jsonrpc": "2.0",
"result": {
"type": "getTerminals->onResult",
"terminals": [
{
"id": "terminal-123",
"name": "Terminal 1",
"serialNumber": "SN123456789"
}
],
"failureReason": "NETWORK_ERROR",
"debugErrorMessage": "Socket timeout has expired"
},
"id": "4d23d20b-c80a-3bf2-8d45-c18cd2387c27"
}
Terminalclass parameters (used onterminals)`Terminal` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-setup-terminal).
| Name | Description |
|---|---|
SETUP_NOT_COMPLETED |
The SDK has not been successfully set up. Call setup first. |
NETWORK_ERROR |
A network error occurred when communicating with the server. |
OTHER |
An unexpected error occurred, check debugErrorMessage for details. |
linkTerminal
Links to a terminal from the current store with the given terminalId, or shows the terminal selection UI if terminalId is null.
Request
{
"jsonrpc": "2.0",
"method": "linkTerminal",
"params": {
"terminalId": "terminal-id"
},
"id": "46c830d1-2a55-34f3-a4d9-3bc93be6ab61"
}
Response
{
"jsonrpc": "2.0",
"result": {
"type": "linkTerminal->onResult",
"terminal": {
"id": "terminal-123",
"name": "Terminal 1",
"serialNumber": "SN123456789"
},
"failureReason": "INVALID_TERMINAL_ID",
"debugErrorMessage": "Internal server error"
},
"id": "46c830d1-2a55-34f3-a4d9-3bc93be6ab61"
}
Terminalclass parameters (used onterminal)`Terminal` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-setup-terminal).
| Name | Description |
|---|---|
SETUP_NOT_COMPLETED |
The SDK has not been successfully set up. Call setup first. |
USER_CANCELED |
The user canceled the terminal linking process. |
INVALID_TERMINAL_ID |
The provided terminal ID is invalid or does not belong to the currently linked store. |
NETWORK_ERROR |
A network error occurred when communicating with the server. |
OTHER |
An unexpected error occurred, check debugErrorMessage for details. |
clearDeviceLink
Removes the linked device information.
To link a new device, setup must be called again.
Request
{
"jsonrpc": "2.0",
"method": "clearDeviceLink",
"id": "fec6c8fe-181b-3988-a101-438909e17d09"
}
Response
{
"jsonrpc": "2.0",
"result": {
"type": "clearDeviceLink->ack"
},
"id": "fec6c8fe-181b-3988-a101-438909e17d09"
}
clearUserAuth
Removes the stored authentication information.
To authenticate, setup must be called again.
Request
{
"jsonrpc": "2.0",
"method": "clearUserAuth",
"id": "ef0c42f6-b60e-3850-89ac-d24e7b3c5517"
}
Response
{
"jsonrpc": "2.0",
"result": {
"type": "clearUserAuth->ack"
},
"id": "ef0c42f6-b60e-3850-89ac-d24e7b3c5517"
}
makePaymentAndSubscribe
Initiates a communication with the Payment app to make a payment.
TIP NOTE:
If you provide a tip, it will be included in the total amount you pass.
The tip is not added on top of amount, it is part of it.
For example:
amount = 100
tip = 20
In this case:
- The total payment is £1.00 (100 in minor units).
- £0.20 (20 in minor units) is considered the tip.
NOTES:
transactionIdshould be unique to the store the user is linked to. Meaning, for a given store id,
there should not be two transaction ids with the same value.
Request
{
"jsonrpc": "2.0",
"method": "makePaymentAndSubscribe",
"params": {
"transactionId": "my-transaction-unique-id",
"amount": 420,
"currency": "GBP",
"useTeyaDefaultUi": true,
"tip": 99,
"purchaseData": {
"lineItems": [
{
"product": {
"name": "Apple",
"description": "a description",
"externalProductId": "SKU-31241",
"category": "food",
"unit": "pcs",
"unitGrossPrice": 120,
"unitNetPrice": 100,
"taxRate": 2050,
"taxType": "Vat",
"taxCode": "VAT_STANDARD"
},
"purchaseLineType": "Product",
"quantity": 2,
"lineDiscountAmount": 100,
"lineTaxAmount": 40,
"lineTotalAmount": 200
}
],
"discountItems": [
{
"code": "DISC1234",
"description": "a description",
"amount": 100
}
]
},
"tabContext": {
"tabId": "ORDER-2026-001",
"terminalId": "term-001",
"type": "FULL",
"method": "CARD"
}
},
"id": "963a1259-6157-367d-a082-e88d8cd1229e"
}
amount how much the tip was, it will not change the charged amount.subscribeTabEvents->onPayRequested event. Set this when settling a tab (fully or partially); leave null for regular payments.VAT_STANDARD, VAT_REDUCED).| Name |
|---|
Vat |
VatExempt |
| Name |
|---|
Product |
Service |
Digital |
Tip |
Adjustment |
Shipping |
TabPaymentTypeenum values (used ontype)`TabPaymentType` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-tabs-tabpaymenttype).
TabPaymentMethodenum values (used onmethod)`TabPaymentMethod` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-tabs-tabpaymentmethod).
Response
This Response is streamed, meaning you will get multiple of these over time for a singlemakePaymentAndSubscribe call. However, only the final one will include the "id"
in the json-rpc object. Others can be matched via transactionId.
Represents a payment state change event during a payment and subscription operation.
This class provides details about the state of the payment transaction, its associated metadata,
and the reasons for the state, if applicable.
{
"jsonrpc": "2.0",
"result": {
"type": "makePaymentAndSubscribe->onPaymentStateChanged",
"transactionId": "tx-123",
"amount": 1000,
"tip": 200,
"currency": "GBP",
"gatewayPaymentId": "payment-123",
"state": "SUCCESSFUL",
"inProgressState": "WAITING_FOR_CARD_ENTRY",
"isFinal": true,
"reason": "CANCELED_BY_USER",
"metadata": {
"card": {
"last4": "1234",
"issuingCountry": "GB",
"brand": "VISA",
"type": "DEBIT"
},
"entryMode": "EMV_CONTACTLESS",
"verificationMethod": "ONLINE_PIN",
"applicationId": "A0000000012345",
"merchantAcquiringId": "MID12345",
"responseCode": "00",
"authorisationCode": "123ABC",
"dcc": {
"conversionFee": "2.5%",
"disclaimer": "I accept to pay in GBP",
"exchangeRate": "0.8650",
"transactionAmount": 8500,
"transactionCurrency": "GBP"
}
},
"transactionTimestamp": 1733241600000,
"debugErrorMessage": "Invalid request"
},
"id": "963a1259-6157-367d-a082-e88d8cd1229e"
}
makePaymentAndSubscribe call.tip and amount.PaymentState.IN_PROGRESS state, see InProgressState.PaymentStateReason.PaymentStateenum values (used onstate)`PaymentState` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-payments-paymentstate).
| Name | Description |
|---|---|
SENT_TO_PAYMENT_APP |
The payment details have been sent to the Teya payment app. |
RECEIVED |
The payment details have been successfully received by the payment app. |
WAITING_FOR_CARD_ENTRY |
Waiting for the customer to start card entry (insert, swipe, or tap). |
TIP_SELECTION |
Awaiting the customer's interaction regarding tipping. |
CARD_PRESENTED |
The payment app detected that a card has been presented by the customer. |
PIN_ENTRY |
The customer is required to enter their PIN. This typically follows card presentation when PIN is required. |
INSERT_CARD |
The customer is required to insert their card to proceed. |
DCC_SELECTION |
Waiting for the customer's selection regarding Dynamic Currency Conversion (DCC). |
REMOVE_CARD |
The customer is required to remove their card from the device. |
APP_SELECTION |
The customer is selecting a card application on the device. |
MOTO_FORM_SHOWN |
The operator is typing the card details by hand (manual / keyed entry, used for MOTO payments). Only delivered over the version-3 read; older reads surface WAITING_FOR_CARD_ENTRY instead. |
UNKNOWN |
An unknown sub-state. Fallback used for unexpected/new states not recognized by this SDK version. |
| Name |
|---|
PROCESSING_FAILED_DECLINED_ONLINE |
PROCESSING_FAILED_DECLINED_OFFLINE |
PROCESSING_FAILED_TIMEOUT |
PROCESSING_FAILED_CONNECTION_ERROR |
PROCESSING_FAILED_COMM_TIMEOUT |
PROCESSING_FAILED_CARD_PROCESSING_ERROR |
UNKNOWN |
CANCELED_BY_EPOS |
CANCELED_BY_USER |
EXPIRED |
TERMINAL_UNREACHABLE |
NOTIFICATION_EXPIRED |
SUPERSEDED_BY_NEW_TRANSACTION |
FEATURE_NOT_ACTIVATED_UNREFERENCED_REFUNDS |
TRANSACTION_ALREADY_IN_PROGRESS |
UNSUPPORTED_CURRENCY |
COMMUNICATION_FAILED_NETWORK |
COMMUNICATION_FAILED_UNEXPECTEDLY |
COMMUNICATION_FAILED_AUTH_REQUIRED |
Metadataclass parameters (used onmetadata)`Metadata` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-payments-metadata).
unsubscribeAll
Stops all notification events of makePaymentAndSubscribe->onPaymentStateChanged
related to ongoing payment with transactionId and dismisses the Teya UI, if present.
Request
{
"jsonrpc": "2.0",
"method": "unsubscribeAll",
"params": {
"transactionId": "my-transaction-id"
},
"id": "b20b1a66-974e-3784-8166-a79106f065a1"
}
Response
{
"jsonrpc": "2.0",
"result": {
"type": "unsubscribeAll->ack"
},
"id": "b20b1a66-974e-3784-8166-a79106f065a1"
}
cancelPayment
Cancels the ongoing payment request. This is a best effort call, meaning that the Teya
payment app may ignore this request, if, for example, it is too late to cancel it.
This does NOT cancel the subscribers from getting new state changes, in fact,
the listeners will still be the way users can check if this request actually took effect.
NOTICE that even if the result is positive, it does not mean that the payment will get
cancelled in the end.
Request
{
"jsonrpc": "2.0",
"method": "cancelPayment",
"params": {
"transactionId": "my-transaction-id"
},
"id": "f0af9f6b-6137-3025-9dc4-7c57ad668242"
}
Response
{
"jsonrpc": "2.0",
"result": {
"type": "cancelPayment->onResult",
"result": "CANCELLING_PAYMENT",
"debugErrorMessage": "Invalid request"
},
"id": "f0af9f6b-6137-3025-9dc4-7c57ad668242"
}
| Name | Description |
|---|---|
PAYMENT_NOT_YET_CREATED |
Payment not yet created, but communication to create it is under way. Retry when state changes to NEW. |
CANCELLING_PAYMENT |
This is the successful result. It means the system is attempting to cancel the payment request. The payment app may still ignore the cancellation request, if it happens too late in the process. |
PAYMENT_ALREADY_FINISHED |
The payment was already finished, nothing to cancel. |
NETWORK_ERROR |
There was a network error when attempting to communicate with the server. |
UNEXPECTED_SERVER_COMMUNICATION_ERROR |
There was an unexpected error when attempting to communicate with the server. |
UNKNOWN_TRANSACTION_ID |
Id is not a known ongoing transaction that can be cancelled. |
refundPayment
Refunds the payment for a given gatewayPaymentId previously returned viamakePaymentAndSubscribe->onPaymentStateChanged.
Request
{
"jsonrpc": "2.0",
"method": "refundPayment",
"params": {
"gatewayPaymentId": "tr_kxmw734nbfkj3723kndf",
"amount": 320,
"currency": "GBP",
"allocatedLineItems": [
{
"externalProductId": "SKU-31241",
"allocatedQuantity": 2,
"allocatedLineTotal": 200,
"allocatedTax": 100
}
]
},
"id": "df54e7a4-dfa3-31a8-93dc-4c4b15bcddf5"
}
Response
{
"jsonrpc": "2.0",
"result": {
"type": "refundPayment->onResult",
"gatewayRefundId": "refund-123",
"result": "SUCCESS",
"debugErrorMessage": "Invalid request"
},
"id": "df54e7a4-dfa3-31a8-93dc-4c4b15bcddf5"
}
| Name |
|---|
SUCCESS |
INVALID_AMOUNT_OR_PAYMENT_ID |
AMOUNT_EXCEEDS_ALLOWED |
DECLINED |
NETWORK_ERROR |
CANCELLED |
FAILED |
makeUnreferencedRefund
Initiates an unreferenced refund: a card-present credit to the card presented at the card machine,
not tied to any original sale. The customer taps their card to receive the money back.
Unlike refundPayment, which refunds a specific previous payment by its gatewayPaymentId, this
starts a brand new card-present transaction and reuses the same state machine asmakePaymentAndSubscribe, so it streams makeUnreferencedRefund->onPaymentStateChanged events.
IMPORTANT: Because there is no original transaction to validate against, these refunds are subject
to additional fraud screening, so they may be declined. Prefer refundPayment when you have the
original payment id.
Request
{
"jsonrpc": "2.0",
"method": "makeUnreferencedRefund",
"params": {
"transactionId": "my-refund-unique-id",
"amount": 420,
"currency": "GBP",
"useTeyaDefaultUi": true
},
"id": "914c6c8f-8e44-30c5-a613-e998094a8b71"
}
Response
This Response is streamed, meaning you will get multiple of these over time for a singlemakeUnreferencedRefund call. However, only the final one will include the "id" in the json-rpc
object. Others can be matched via transactionId.
Represents a refund state change event during an unreferenced refund operation. It shares the
same state machine as MakePaymentStateChange, so it reuses the InProgressState andPaymentStateReason enums.
{
"jsonrpc": "2.0",
"result": {
"type": "makeUnreferencedRefund->onPaymentStateChanged",
"transactionId": "tx-123",
"amount": 1000,
"currency": "GBP",
"gatewayRefundId": "refund-123",
"state": "SUCCESSFUL",
"inProgressState": "WAITING_FOR_CARD_ENTRY",
"isFinal": true,
"reason": "CANCELED_BY_USER",
"metadata": {
"card": {
"last4": "1234",
"issuingCountry": "GB",
"brand": "VISA",
"type": "DEBIT"
},
"entryMode": "EMV_CONTACTLESS",
"verificationMethod": "ONLINE_PIN",
"applicationId": "A0000000012345",
"merchantAcquiringId": "MID12345",
"responseCode": "00",
"authorisationCode": "123ABC",
"dcc": {
"conversionFee": "2.5%",
"disclaimer": "I accept to pay in GBP",
"exchangeRate": "0.8650",
"transactionAmount": 8500,
"transactionCurrency": "GBP"
}
},
"transactionTimestamp": 1733241600000,
"debugErrorMessage": "Invalid request"
},
"id": "914c6c8f-8e44-30c5-a613-e998094a8b71"
}
makeUnreferencedRefund call.amount.PaymentState.PaymentStateenum values (used onstate)`PaymentState` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-payments-paymentstate).
InProgressStateenum values (used oninProgressState)`InProgressState` is the same enum used by `makePaymentAndSubscribe` - [see its values ↗](#makepaymentandsubscribe-response-inprogressstate).
PaymentStateReasonenum values (used onreason)`PaymentStateReason` is the same enum used by `makePaymentAndSubscribe` - [see its values ↗](#makepaymentandsubscribe-response-reason). A refund attempted while the feature is switched off for the store reports `FEATURE_NOT_ACTIVATED_UNREFERENCED_REFUNDS`.
Metadataclass parameters (used onmetadata)`Metadata` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-payments-metadata).
printCustomTemplate
Represents a request to print a custom receipt template on the Teya card machine.
Request
{
"jsonrpc": "2.0",
"method": "printCustomTemplate",
"params": {
"rows": [
{
"rowType": "table",
"table": {
"headerCells": [
{
"element": {
"text": "Some text",
"bold": true,
"align": "CENTER"
},
"weight": 0.5
}
],
"rows": [
{
"cells": [
{
"text": "Some text",
"bold": true,
"align": "CENTER"
}
]
}
]
}
}
]
},
"id": "e5c962c8-c01e-3a09-8ad3-65737c09bfb9"
}
ReceiptRowsealed type (used onrows)`ReceiptRow` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-printing-receiptrow).
Response
Represents the change in the state of a printing operation.
{
"jsonrpc": "2.0",
"result": {
"type": "printCustom*->onPrintingStateChanged",
"receiptId": "a7b8c9d0-1e2f-4a5b-8c9d-0e1f2a3b4c5d",
"status": "CONNECTING_TO_PRINTER",
"printFailure": "OUT_OF_PAPER",
"errorMessage": "Some more info about the reason for error"
},
"id": "e5c962c8-c01e-3a09-8ad3-65737c09bfb9"
}
PrintStatus.PENDING.PrintStatusenum values (used onstatus)`PrintStatus` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-printstatedetailschange-printstatus).
PrintFailureenum values (used onprintFailure)`PrintFailure` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-printstatedetailschange-printfailure).
printCustomImage
Represents a method for printing a custom image.
Request
{
"jsonrpc": "2.0",
"method": "printCustomImage",
"params": {
"imageFullPath": "Users/Some/Path/ToTheFile/receipt.png"
},
"id": "fb25135f-51ff-387e-a13a-1114a8d829e5"
}
Response
Represents the change in the state of a printing operation.
{
"jsonrpc": "2.0",
"result": {
"type": "printCustom*->onPrintingStateChanged",
"receiptId": "a7b8c9d0-1e2f-4a5b-8c9d-0e1f2a3b4c5d",
"status": "CONNECTING_TO_PRINTER",
"printFailure": "OUT_OF_PAPER",
"errorMessage": "Some more info about the reason for error"
},
"id": "fb25135f-51ff-387e-a13a-1114a8d829e5"
}
PrintStatus.PENDING.PrintStatusenum values (used onstatus)`PrintStatus` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-printstatedetailschange-printstatus).
PrintFailureenum values (used onprintFailure)`PrintFailure` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-printstatedetailschange-printfailure).
zipLogs
Zips all log files collected from the Teya SDK application and returns a path for the newly
created zip file.
Request
{
"jsonrpc": "2.0",
"method": "zipLogs",
"id": "0ff0d1e5-d9ef-3c74-809a-b108e1235bf7"
}
Response
{
"jsonrpc": "2.0",
"result": {
"type": "zipLogs->response",
"zipPath": "path/to/the/logs.zip"
},
"id": "0ff0d1e5-d9ef-3c74-809a-b108e1235bf7"
}
openTab
Opens a new tab - registers a table/order with POSLink so payment terminals can discover it.
Pay at Table lets hospitality staff pull a tab's bill onto a Teya terminal and take payment.
The ePOS owns the tab; POSLink keeps a lightweight record for terminal orchestration.
Request
{
"jsonrpc": "2.0",
"method": "openTab",
"params": {
"tabId": "ORDER-2026-001",
"tabName": "Table 5",
"currency": "GBP"
},
"id": "b8ba60ff-b96f-3932-923f-ac0565218005"
}
Response
{
"jsonrpc": "2.0",
"result": {
"type": "openTab->onResult",
"tab": {
"tabId": "ORDER-2026-001",
"tabName": "Table 5",
"status": "PAYING",
"totalAmount": 5000,
"totalPaid": 2500,
"remaining": 2500,
"currency": "GBP",
"showingBillTerminalId": "term-001",
"billFileId": "bill-file-001",
"paymentRequests": [
{
"eposTransactionId": "tx-123",
"status": "SUCCESSFUL",
"amount": 2500,
"currency": "GBP",
"tip": 200,
"method": "CARD",
"type": "SPLIT",
"createdAtEpochMillis": 1733241600000,
"updatedAtEpochMillis": 1733241700000,
"transactionTimestampEpochMillis": 1733241650000,
"metadata": {
"card": {
"last4": "1234",
"issuingCountry": "GB",
"brand": "VISA",
"type": "DEBIT"
},
"entryMode": "EMV_CONTACTLESS",
"verificationMethod": "ONLINE_PIN",
"applicationId": "A0000000012345",
"merchantAcquiringId": "MID12345",
"responseCode": "00",
"authorisationCode": "123ABC",
"dcc": {
"conversionFee": "2.5%",
"disclaimer": "I accept to pay in GBP",
"exchangeRate": "0.8650",
"transactionAmount": 8500,
"transactionCurrency": "GBP"
}
}
}
],
"createdAtEpochMillis": 1733241600000,
"updatedAtEpochMillis": 1733241700000
},
"failureReason": "NETWORK_ERROR",
"debugErrorMessage": "Socket timeout"
},
"id": "b8ba60ff-b96f-3932-923f-ac0565218005"
}
Tabclass parameters (used ontab)`Tab` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-tabs-tab).
TabOperationFailureReasonenum values (used onfailureReason)`TabOperationFailureReason` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-tabs-taboperationfailurereason).
listTabs
Lists tabs for the linked store, one cursor-paginated page at a time.
Request
{
"jsonrpc": "2.0",
"method": "listTabs",
"params": {
"statuses": [
"OPEN"
],
"after": "cursor-abc",
"before": "cursor-xyz",
"limit": 50
},
"id": "30194f0c-9a27-39be-a9fb-4070ccefcbee"
}
OPEN, PAYING, PAUSED). Pass COMPLETED/CLOSED to include archived tabs.nextCursor. Mutually exclusive with before.prevCursor. Mutually exclusive with after.| Name | Description |
|---|---|
OPEN |
Registered and available for terminals. |
PAYING |
A terminal is processing payment(s). |
PAUSED |
A split payment was interrupted. |
COMPLETED |
All payments done, remaining is zero. |
CLOSED |
Removed from the active list. |
Response
{
"jsonrpc": "2.0",
"result": {
"type": "listTabs->onResult",
"page": {
"items": [
{
"tabId": "ORDER-2026-001",
"tabName": "Table 5",
"status": "OPEN",
"totalAmount": 5000,
"totalPaid": 0,
"remaining": 5000,
"currency": "GBP",
"showingBillTerminalId": "term-001"
}
],
"nextCursor": "cursor-next",
"prevCursor": "cursor-prev"
},
"failureReason": "NETWORK_ERROR",
"debugErrorMessage": "Socket timeout"
},
"id": "30194f0c-9a27-39be-a9fb-4070ccefcbee"
}
TabStatusenum values (used onstatus)`TabStatus` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-tabs-tabstatus).
TabOperationFailureReasonenum values (used onfailureReason)`TabOperationFailureReason` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-tabs-taboperationfailurereason).
getTab
Gets full details for a specific tab, including payment history.
Request
{
"jsonrpc": "2.0",
"method": "getTab",
"params": {
"tabId": "ORDER-2026-001"
},
"id": "2558074f-f328-34fc-bc9e-eadc730f2a74"
}
Response
{
"jsonrpc": "2.0",
"result": {
"type": "getTab->onResult",
"tab": {
"tabId": "ORDER-2026-001",
"tabName": "Table 5",
"status": "PAYING",
"totalAmount": 5000,
"totalPaid": 2500,
"remaining": 2500,
"currency": "GBP",
"showingBillTerminalId": "term-001",
"billFileId": "bill-file-001",
"paymentRequests": [
{
"eposTransactionId": "tx-123",
"status": "SUCCESSFUL",
"amount": 2500,
"currency": "GBP",
"tip": 200,
"method": "CARD",
"type": "SPLIT",
"createdAtEpochMillis": 1733241600000,
"updatedAtEpochMillis": 1733241700000,
"transactionTimestampEpochMillis": 1733241650000,
"metadata": {
"card": {
"last4": "1234",
"issuingCountry": "GB",
"brand": "VISA",
"type": "DEBIT"
},
"entryMode": "EMV_CONTACTLESS",
"verificationMethod": "ONLINE_PIN",
"applicationId": "A0000000012345",
"merchantAcquiringId": "MID12345",
"responseCode": "00",
"authorisationCode": "123ABC",
"dcc": {
"conversionFee": "2.5%",
"disclaimer": "I accept to pay in GBP",
"exchangeRate": "0.8650",
"transactionAmount": 8500,
"transactionCurrency": "GBP"
}
}
}
],
"createdAtEpochMillis": 1733241600000,
"updatedAtEpochMillis": 1733241700000
},
"failureReason": "NETWORK_ERROR",
"debugErrorMessage": "Socket timeout"
},
"id": "2558074f-f328-34fc-bc9e-eadc730f2a74"
}
Tabclass parameters (used ontab)`Tab` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-tabs-tab).
TabOperationFailureReasonenum values (used onfailureReason)`TabOperationFailureReason` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-tabs-taboperationfailurereason).
closeTab
Closes a tab, removing it from the active list. Should be called once payment is complete.
POSLink also auto-closes tabs with no activity for 24 hours.
Request
{
"jsonrpc": "2.0",
"method": "closeTab",
"params": {
"tabId": "ORDER-2026-001"
},
"id": "69957d53-3fca-347f-8c64-72d083bb4114"
}
Response
Result of a closeTab call. A null failureReason means the tab was closed successfully.
{
"jsonrpc": "2.0",
"result": {
"type": "closeTab->onResult",
"failureReason": "NETWORK_ERROR",
"debugErrorMessage": "Socket timeout"
},
"id": "69957d53-3fca-347f-8c64-72d083bb4114"
}
TabOperationFailureReasonenum values (used onfailureReason)`TabOperationFailureReason` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-tabs-taboperationfailurereason).
respondToBillRequest
Responds to a subscribeTabEvents->onShowBillRequested event by sending the bill details to
POSLink. The requesting terminal both displays the bill on-screen and can print it on receipt
paper, so the supplied template/image should be designed to render legibly in both contexts.
Request
{
"jsonrpc": "2.0",
"method": "respondToBillRequest",
"params": {
"tabId": "ORDER-2026-001",
"terminalId": "term-001",
"totalAmount": 5000,
"currency": "GBP",
"printModel": [
{
"rowType": "table",
"table": {
"headerCells": [
{
"element": {
"text": "Some text",
"bold": true,
"align": "CENTER"
},
"weight": 0.5
}
],
"rows": [
{
"cells": [
{
"text": "Some text",
"bold": true,
"align": "CENTER"
}
]
}
]
}
}
]
},
"id": "2c63095d-5f1b-36ff-9a88-9322ecc510c6"
}
printCustomTemplate. Ignored when billImagePath is set.printModel is not sent.ReceiptRowsealed type (used onprintModel)`ReceiptRow` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-printing-receiptrow).
Response
Result of a respondToBillRequest call. A null failureReason means POSLink accepted the bill.
{
"jsonrpc": "2.0",
"result": {
"type": "respondToBillRequest->onResult",
"failureReason": "TOTAL_LESS_THAN_PAID",
"debugErrorMessage": "Socket timeout"
},
"id": "2c63095d-5f1b-36ff-9a88-9322ecc510c6"
}
| Name | Description |
|---|---|
NO_LINKED_STORE |
No store is currently linked. Run setup (or setupAuthAndStore) first. |
NETWORK_ERROR |
A network error occurred when communicating with the server. |
TOTAL_LESS_THAN_PAID |
The new total is lower than the amount already paid for the tab. |
TAB_IN_WRONG_STATE |
The tab can no longer accept this bill (show-bill TTL expired, tab not found, tab CLOSED/COMPLETED, or terminal-id mismatch). |
UNEXPECTED_ERROR |
An unexpected error occurred; check debugErrorMessage for details. |
respondWithError
Rejects a terminal-initiated request (a bill request or a pay request) by sending an error to
POSLink. The requesting terminal displays message and returns to its table list.
Request
{
"jsonrpc": "2.0",
"method": "respondWithError",
"params": {
"tabId": "ORDER-2026-001",
"terminalId": "term-001",
"errorCode": "TABLE_NOT_FOUND",
"message": "Table 5 was not found"
},
"id": "3982d2f9-7426-36d4-b26a-e97c79cd6d72"
}
| Name | Description |
|---|---|
TABLE_NOT_FOUND |
The tab/order no longer exists on the ePOS. |
BILL_ALREADY_SETTLED |
The bill was already settled outside Pay at Table. |
EPOS_ERROR |
Generic ePOS-side failure with no more specific category. |
REQUEST_REJECTED |
The ePOS explicitly rejects the request (e.g. a policy decision). |
Response
Result of a respondWithError call. A null failureReason means POSLink accepted the rejection.
{
"jsonrpc": "2.0",
"result": {
"type": "respondWithError->onResult",
"failureReason": "NETWORK_ERROR",
"debugErrorMessage": "Socket timeout"
},
"id": "3982d2f9-7426-36d4-b26a-e97c79cd6d72"
}
TabOperationFailureReasonenum values (used onfailureReason)`TabOperationFailureReason` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-tabs-taboperationfailurereason).
subscribeTabEvents
Subscribes to the tab event stream for the linked store.
This is a streamed call. Tab events arrive as JSON-RPC notifications (messages with no id),
each carrying one of these results in its result.type:
subscribeTabEvents->onShowBillRequested- a terminal asks to display a tab's bill.subscribeTabEvents->onPayRequested- a terminal initiates a payment on a tab.subscribeTabEvents->onPaymentProgress- an intermediate payment progress update.subscribeTabEvents->onPaymentCompleted- a single payment on a tab reached a final state.subscribeTabEvents->onTabPaused- a terminal paused a split payment.subscribeTabEvents->onTabResumed- a paused tab resumed.subscribeTabEvents->onTabCompleted- a tab's outstanding balance reached zero.subscribeTabEvents->onBillHidden- the terminal showing a bill exited without paying.subscribeTabEvents->onConnectionStateChange- the stream's connection state changed.
The response section below shows one representative event; the others share the same envelope.
The stream ends with a single final response - carrying the original request id and asubscribeTabEvents->onConnectionStateChange result with state: DISCONNECTED - when the store
link is cleared or unsubscribeTabEvents is called.
Only one subscription may be active at a time; calling subscribeTabEvents again while one is
live is rejected with an invalid-state error.
Request
{
"jsonrpc": "2.0",
"method": "subscribeTabEvents",
"id": "8802ec5a-d114-34c9-8abe-d0ac74aca8b1"
}
Response
The terminal currently showing a tab's bill exited without paying (or timed out).
{
"jsonrpc": "2.0",
"result": {
"type": "subscribeTabEvents->onBillHidden",
"tabId": "ORDER-2026-001"
},
"id": "8802ec5a-d114-34c9-8abe-d0ac74aca8b1"
}
unsubscribeTabEvents
Stops the active tab event stream started by subscribeTabEvents. The streamedsubscribeTabEvents call then completes with its final DISCONNECTED response. A no-op if no
subscription is active.
Request
{
"jsonrpc": "2.0",
"method": "unsubscribeTabEvents",
"id": "33362d8f-a522-38ab-8fee-5b28b8dcb738"
}
Response
Acknowledges that the tab event stream was stopped.
{
"jsonrpc": "2.0",
"result": {
"type": "unsubscribeTabEvents->ack"
},
"id": "33362d8f-a522-38ab-8fee-5b28b8dcb738"
}
setPayAtTableEnabledOnStore
Enables or disables Pay at Table at the store level for the currently linked store.
Sets a store-wide capability flag. When enabled, every terminal in the store can surface PAT
entry points; when disabled those entry points are hidden the next time staff attempt them.
Each terminal keeps its own local opt-out toggle (default ON) - this call does not change that.
Disabling is an entry-point gate only: any PAT session already in progress on a terminal runs
to completion. Propagation to terminals is best-effort and asynchronous; a successful result
means POSLink accepted the store-level setting.
Request
{
"jsonrpc": "2.0",
"method": "setPayAtTableEnabledOnStore",
"params": {
"enable": true
},
"id": "f6e65960-6606-3656-84e4-dbfe41fe946a"
}
true to enable PAT for the store, false to disable it.Response
Result of a setPayAtTableEnabledOnStore call. A null failureReason means POSLink accepted
the new setting.
{
"jsonrpc": "2.0",
"result": {
"type": "setPayAtTableEnabledOnStore->onResult",
"failureReason": "NETWORK_ERROR",
"debugErrorMessage": "Socket timeout"
},
"id": "f6e65960-6606-3656-84e4-dbfe41fe946a"
}
TabOperationFailureReasonenum values (used onfailureReason)`TabOperationFailureReason` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-tabs-taboperationfailurereason).
General Definitions
PrintFailure
| Name |
|---|
NETWORK_ERROR |
BUSY |
OUT_OF_PAPER |
OVERHEATED |
COVER_OPEN |
LOW_BATTERY |
OTHER |
PrintStatus
| Name |
|---|
PENDING |
CONNECTING_TO_PRINTER |
PRINTING |
PRINTED |
FAILED |
Response
| Name | Description |
|---|---|
SUCCESS |
setup was successful |
CANCELED |
setup flow UI was canceled by the user |
SERVER_ERROR |
setup failed unexpectedly from a server error, check debugErrorMessage for details |
Payments Definitions
Metadata
| Name |
|---|
VISA |
MAESTRO |
MASTERCARD |
UNION_PAY |
JCB |
DINERS |
AMEX |
OTHER |
| Name |
|---|
DEBIT |
CREDIT |
PREPAID |
CHARGE |
PRIVATE |
DEFERRED_DEBIT |
UNKNOWN |
| Name |
|---|
E_COM |
EMV_PIN |
CONTACT_ICC |
EMV_CONTACTLESS |
KEYED |
MAGSTRIPE_SWIPED |
ON_FILE |
MAGSTRIPE_FALLBACK |
| Name |
|---|
NONE |
ELECTRONIC_SIGNATURE |
ON_DEVICE |
MANUAL |
SIGNATURE |
OFFLINE_PIN |
ONLINE_PIN |
OFFLINE_PIN_PLUS_SIGNATURE |
SECURED_ELECTRONIC_COMMERCE |
PaymentState
| Name | Description |
|---|---|
PENDING |
Initial temporary state of the payment. It will be the local state until we get the response of the payment creation. |
NEW |
Temporary state which means the payment request has been created. This state is set when the payment request is created on the server successfully. PosLink will have sent a push notification to the Teya payment app at this point. |
IN_PROGRESS |
Temporary state which means we got acknowledgement from the Teya payment app that the payment is in progress. This state is set when the Teya payment app updates the state to IN_PROGRESS in the backend. At this point, the reading card screen would be shown in the Teya app. |
CANCELLING |
Temporary state which means the system is trying to cancel the payment. It is possible that the payment will not be cancelled and moved back to IN_PROGRESS or SUCCESSFUL / PROCESSING_FAILED. This state is set when the cancelPayment succeeds and the server got the request to cancel. |
CANCELED |
Final state which means the payment was cancelled. |
SUCCESSFUL |
Final state which means the payment was successful. |
PROCESSING_FAILED |
Final state which means the payment was not successful. Check reason for why that may have happened. |
COMMUNICATION_FAILED |
Final state which means there was a communication failure either when trying to create the payment or when trying to get state updates. If we got PENDING -> COMMUNICATION_FAILED it means the payment was never created (or for state reason PaymentStateReason.COMMUNICATION_FAILED_NETWORK specifically, we may not know if the payment was created or not). If we got any state other than PENDING -> COMMUNICATION_FAILED it means the updating flow failed unexpectedly. (state reason will be PaymentStateReason.COMMUNICATION_FAILED_UNEXPECTEDLY) or PaymentStateReason.COMMUNICATION_FAILED_AUTH_REQUIRED - in which case you should setup PosLink again after clearing the auth info) |
Printing Definitions
Align
| Name |
|---|
LEFT |
CENTER |
RIGHT |
ReceiptRow
This is a sealed type with discriminator rowType.
On json object, specify the wanted type with, for example: "rowType" : "divider"
The following table shows the possible types:
| rowType | Type |
|---|---|
divider |
Divider |
item |
object (class: Item) |
items |
object (class: Items) |
spacer |
Spacer |
table |
object (class: Table) |
RowElementsealed type (used onitem)`RowElement` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-printing-rowelement).
RowElementsealed type (used onitems)`RowElement` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-printing-rowelement).
Textclass parameters (used onelement)`Text` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-printing-rowelement-text).
Textclass parameters (used oncells)`Text` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-printing-rowelement-text).
RowElement
This is a sealed type with discriminator elementType.
On json object, specify the wanted type with, for example: "elementType" : "image"
The following table shows the possible types:
| elementType | Type |
|---|---|
image |
object (class: Image) |
qrCode |
object (class: QrCode) |
text |
object (class: Text) - definition ↗ |
Align.LEFT.Alignenum values (used onalign)`Align` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-printing-align).
Align.LEFT.Alignenum values (used onalign)`Align` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-printing-align).
Textclass parameters (used onRowElement.text)`Text` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-printing-rowelement-text).
Text
Align.LEFT.Alignenum values (used onalign)`Align` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-printing-align).
Setup Definitions
Store
Terminal
Tabs Definitions
Tab
TabStatusenum values (used onstatus)`TabStatus` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-tabs-tabstatus).
PaymentStateenum values (used onstatus)`PaymentState` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-payments-paymentstate).
TabPaymentMethodenum values (used onmethod)`TabPaymentMethod` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-tabs-tabpaymentmethod).
TabPaymentTypeenum values (used ontype)`TabPaymentType` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-tabs-tabpaymenttype).
Metadataclass parameters (used onmetadata)`Metadata` is a shared type - [check its definition ↗](#def-com-teya-unifiedepssdk-rpcmodels-payments-metadata).
TabOperationFailureReason
| Name | Description |
|---|---|
NO_LINKED_STORE |
No store is currently linked. Run setup (or setupAuthAndStore) first. |
NETWORK_ERROR |
A network error occurred when communicating with the server. |
UNEXPECTED_ERROR |
An unexpected error occurred; check debugErrorMessage for details. |
TabPaymentMethod
| Name | Description |
|---|---|
CARD |
Card payment taken on the terminal. |
CASH |
Cash recorded on the terminal (tracked only, no card action). |
TabPaymentType
| Name | Description |
|---|---|
FULL |
Paying the full outstanding amount in a single transaction. |
SPLIT |
Paying a portion of the bill (one payer in a split). |
TabStatus
| Name | Description |
|---|---|
OPEN |
Registered and available for terminals. |
PAYING |
A terminal is processing payment(s). |
PAUSED |
A split payment was interrupted. |
COMPLETED |
All payments done, remaining is zero. |
CLOSED |
Removed from the active list. |
UNKNOWN |
Status not recognised by this SDK version. |