Make Terminal Payments
The Terminal Payments API endpoints provide a way to initiate and complete payment actions through terminal devices.
Terminal payments are for card-present payments, where a customer taps or enters their credit card into a payment terminal. The payment terminal is configured to a backend payment processor that handles the payment details. POS Server – through specific payment features, such as Fortis Payments – integrates with the processor to perform the payment transactions.
As payment processors use different ways to access payment terminals, the POS API uses a standard method of working with the terminals. This method is:
- The caller starts a payment transaction through the
terminalPayment.start
endpoint. - The start endpoint will return one of three types of results:
- The payment, if the payment was immediately processed during the API call.
- An error, if the payment failed validation or was not successfully processed.
- A continuation, indicating that the caller must query for an updated payment status. The continuation includes the amount of time to wait before querying for the status.
- The caller must call the
terminalPayment.continue
endpoint to query the updated payment status, if a continuation was returned in the initial call. - Like the start endpoint, the continue endpoint will return one of three results:
- The payment, if the payment was successfully processed.
- An error, if the payment was not successfully processed.
- A continuation, indicating that the caller must re-query for an updated payment status.
- For a successful payment authorization, another call is required. The caller should call the
terminalPayment.capture
endpoint to capture the authorized payment. Again, the capture endpoint will return either the successful payment, an error, or a continuation.
Permissions
These endpoints require the following permissions:
MakeSaleTerminalPayment
to make a SALE (immediate) payment.MakeRefundTerminalPayment
to make a REFUND (immediate) payment.AuthorizeTerminalPayment
to make an AUTHORIZE payment authorization.CapturePayment
to capture a payment authorization.VoidPayment
to void a payment or payment authorization.ListPaymentTerminals
to view a list of payment terminals for the current location.
a) List Terminals
Return a list of payment terminals configured for the POS server location:
query MyQuery {
terminalPayment {
terminals {
id
name
}
}
}
The caller should should typically call this endpoint to retrieve a list of available terminals. This can be done in a settings page, for example, to allow a user to choose the terminal that will process payments.
b) Get Capabilities
Return the capabilities supported by the currently configured payment processor:
query MyQuery {
terminalPayment {
capabilities {
canAuthorize
canBlindRefund
canDirectRefund
refNoMaxLength
}
}
}
The caller should query this endpoint to determine the type of operations that are supported by the processor, to ensure that it only calls the operations that are supported. Payment processors may vary in their ability to perform the following types of operations:
- Whether they support payment authorization and capture;
- Whether they support blind refunds – refunds where the ID of the payment to refund is not known;
- Whether they support direct refunds – refunds where the ID of the payment to refund is known;
- The maximum field length of a payment’s
refNo
field.
c) Start Payment
Start a payment operation:
mutation MyMutation {
terminalPayment {
start(
startRequest: {
type: AUTHORIZE,
terminalId: "11ed07ba8af1eb32897e4482",
amount: "3.99",
correlationId: "abcdef",
refNo: "P1003",
sale: {
id: "1000",
seq: 1,
subTotal: "3.95",
tax: "0.04",
lines: {
sku: "GUM",
description: "Chewing gum",
unitPrice: "3.95",
quantity: 1,
uom: "EA",
commodityCode: null
}
}
}) {
terminalId
status
continuation {
code
retrySeconds
}
error {
type
message
providerMessage
isPaymentInUnknownState
}
payment {
id
saleId
refNo
requestedAmount
amount
tipAmount
authCode
}
}
}
}
This example shows a payment authorization, with start request type set to AUTHORIZE
. The requests for SALE
and REFUND
payment operations are identical, other than the type input parameter.
Refunds also optionally take a
refundPaymentId
parameter. If specified, the refund will be a direct refund against the identified payment transaction; if not specified, the refund is a blind refund.Consult the
capabilities
endpoint to determine which type(s) of refunds that the current payment processor supports. Payment processors may also differ on how they implement each type of refund.
Other Parameters
The endpoint also takes the following input parameters:
- A terminal ID indicating which terminal to scan/process the credit card.
- The amount of the payment.
- A reference number for the payment.
- This is typically the caller’s internal identifier for the payment.
- This value must be unique, as most payment processors will often validate it to help prevent duplicate payment transactions.
- Use the
capabilities
endpoint to query the maximum text length of this value.
- A sale object containing the details of the sale.
- While optional, it is highly recommended to provide this information as it enables benefits such a as Level 3 process integration.
- A correlation ID that can be used for logging.
- The caller should generate a unique value that can be used to identify the payment attempt.
- This value can be used to correlate log records across multiple systems, making it easier to identify potential problems.
- For example, the same ID can be used to identify the payment operation at the caller, within POS server, and within the payment processor itself.
Response
Like the other terminal payment endpoints, this endpoint returns either a payment value, an error value, or a continuation value. The caller should be prepared to handle any one of these states.
The following is an example of a continuation value response:
{
"data": {
"terminalPayment": {
"start": {
"terminalId": "11ed07ba8af1eb32897e4482",
"status": "CONTINUE",
"continuation": {
"code": "5cb5705a-1496-4997-8275-99c508b2c0ea",
"retrySeconds": 2
},
"error": null,
"payment": null
}
}
}
}
There are two values in the response that should be considered when calling the continue
endpoint:
- The
code
must be passed to the continue endpoint. - The
retrySeconds
indicates the the optimal time to wait (in seconds) before calling the endpoint.
d) Continue Payment
Polls the payment processor for updated status about a payment operation:
mutation MyMutation {
terminalPayment {
continue(
continueRequest: {
code: "5cb5705a-1496-4997-8275-99c508b2c0ea"
correlationId: "ghijkl",
sale: {
id: "1000",
seq: 1,
subTotal: "3.95",
tax: "0.04",
lines: {
sku: "GUM",
description: "Chewing gum",
unitPrice: "3.95",
quantity: 1,
uom: "EA",
commodityCode: null
}
}
})
{
terminalId
status
continuation {
code
retrySeconds
}
error {
type
message
providerMessage
isPaymentInUnknownState
}
payment {
id
saleId
refNo
requestedAmount
amount
tipAmount
authCode
}
}
}
}
The key parameter that you must pass is the continuation code
that was returned in the call to the start
endpoint.
Other Parameters
The endpoint also takes the following input parameters:
- A sale object containing the details of the sale.
- This should be the same sale information that you originally supplied to the
start
endpoint.
- This should be the same sale information that you originally supplied to the
- A correlation ID that can be used for logging.
- Like the other endpoints, the correlation ID is a unique value that can be used to identify the continuation operation in log records that are created across multiple systems.
Response:
Like the other terminal payment endpoints, this endpoint returns either a payment value, an error value, or a continuation value. The caller should be prepared to handle any one of these states.
A continuation call may return another continuation in the event that the payment operations is still being processed (e.g. waiting for input from the user). It may take several calls to the
continue
endpoint to complete the operation.
Upon a successful payment operation, the detailed payment information is returned in the response like the following:
{
"data": {
"terminalPayment": {
"continue": {
"terminalId": "11ed07ba8af1eb32897e4482",
"status": "OK",
"continuation": null,
"error": null,
"payment": {
"id": "11ed256a6ea7390aa07d5728",
"saleId": "1000",
"refNo": "P1003",
"requestedAmount": 3.99,
"amount": 3.99,
"tipAmount": 0,
"authCode": "256a6e"
}
}
}
}
}
e) Capture Payment
Capture (complete) a payment authorization:
mutation MyMutation {
terminalPayment {
capture(
captureRequest: {
id: "11ed256a6ea7390aa07d5728"
amount: "3.99"
correlationId: "mnopqr",
sale: {
id: "1000",
seq: 1,
subTotal: "3.95",
tax: "0.04",
lines: {
sku: "GUM",
description: "Chewing gum",
unitPrice: "3.95",
quantity: 1,
uom: "EA",
commodityCode: null
}
}
})
{
terminalId
status
continuation {
code
retrySeconds
}
error {
type
message
providerMessage
isPaymentInUnknownState
}
payment {
id
saleId
refNo
requestedAmount
amount
tipAmount
authCode
}
}
}
}
The key parameters that you must pass are the payment ID generated by the start
endpoint, and the amount of funds that you want to capture.
The amount of funds to capture should be less than or equal to the amount that was authorized in the original payment authorization.
Other Parameters
The endpoint also takes the following input parameters:
- A sale object containing the details of the sale.
- This should be the same sale information that you originally supplied to the
start
endpoint.
- This should be the same sale information that you originally supplied to the
- A correlation ID that can be used for logging.
- Like the other endpoints, the correlation ID is a unique value that can be used to identify the capture operation in log records that are created across multiple systems.
Response:
Like the other terminal payment endpoints, this endpoint returns either a payment value, an error value, or a continuation value. The caller should be prepared to handle any one of these states.
While it is not common, a payment processor may return a continuation for a capture operation. The caller must be able to support this type of scenario, and use the
continue
endpoint to poll for the status of the capture operation.
Upon a successful payment operation, the detailed payment information is returned in the response like the following:
{
"data": {
"terminalPayment": {
"capture": {
"terminalId": "11ed07ba8af1eb32897e4482",
"status": "OK",
"continuation": null,
"error": null,
"payment": {
"id": "11ed256a6ea7390aa07d5728",
"saleId": "1000",
"refNo": "P1003",
"requestedAmount": 3.99,
"amount": 3.99,
"tipAmount": 0,
"authCode": "256a6e"
}
}
}
}
}
f) Void Payment
Void (cancel) a payment or payment authorization:
mutation MyMutation {
terminalPayment {
void(
voidRequest: {
id: "11ed256a6ea7390aa07d5728",
correlationId: "stuvwx"
})
{
terminalId
status
continuation {
code
retrySeconds
}
error {
type
message
providerMessage
isPaymentInUnknownState
}
payment {
id
saleId
refNo
requestedAmount
amount
tipAmount
authCode
}
}
}
}
Voids are supported only for payments that are not posted yet in the payment processor. The endpoint will return an error if a void against a posted payment is attempted.
The key parameter that you must pass is the payment ID generated by the start
endpoint.
Other Parameters
The endpoint also takes the following input parameters:
- A correlation ID that can be used for logging.
- Like the other endpoints, the correlation ID is a unique value that can be used to identify the void operation in log records that are created across the caller, POS server and the payment processor.
Response:
Like the other terminal payment endpoints, this endpoint returns either a payment value, an error value, or a continuation value. The caller should be prepared to handle any one of these states.
While it is not common, a payment processor may return a continuation for a void operation. The caller must be able to support this type of scenario, and use the
continue
endpoint to poll for the status of the void operation.