diff --git a/restapi/restendpoints.md b/restapi/restendpoints.md
index 7938554..d25c7d6 100644
--- a/restapi/restendpoints.md
+++ b/restapi/restendpoints.md
@@ -749,41 +749,61 @@ curl -X GET \
-## Endpoints Not Requiring a Payment Terminal
+## Device Control Commands
-The following endpoints operate entirely through the Cloud API and do **not** require a connected payment terminal.
+> **Note:**
+> The following commands are available for all devices running Android SDK version 7.1006.0 or later.
----
+Command Endpoint Format
-### Tip Adjustment
+All device control commands follow this endpoint structure:
+```https://cloud.handpoint.io/devices/{deviceType}/{serialNumber}/{command}```
+Where:
+- `{deviceType}` is the type of the device (e.g., PAXIM30)
+- `{serialNumber}` is the serial number of the device (e.g., 1640013848)
+- `{command}` is the specific command to execute
-`TipAdjustment`
+Common Parameters
-POST endpoint used to execute a tip adjustment operation.
+All commands share these common parameters:
-A tip adjustment operation allows merchants to adjust the tip amount of a sale transaction before the batch of transactions is settled by the processor at the end of the day. Note: This functionality is only available for the restaurant industry in the United States and the processors currently supporting this functionality are TSYS and VANTIV.
+| Parameter | Notes |
+| ----------- | ----------- |
+| `Header: ApiKeyCloud` Required
*String* | Api key used to authenticate the merchant. (UNIQUE per Merchant) |
+| `Header: Content-Type` Required
*String* | Must be set to `application/json` |
-Note: If two tip adjustments are sent for the same original transaction, only the second one will be taken into account. Each new tip adjustment will override the previous one. A tip adjustment will be rejected if the original transaction has already been batched out by the acquirer.
+Common Response Codes
-**Parameters**
+| Response Code | Description |
+|--------------|-------------|
+| 202 | Request accepted, command will be executed |
+| 403 | Authentication failed |
+| 422 | Invalid request |
+| 400 | Invalid parameter value (when applicable) |
-| Parameter | Notes |
-| ----------- | ----------- |
-| `Header: ApiKeyCloud` Required
*String* | Api key used to authenticate the merchant. (UNIQUE per Merchant) |
-| `Path parameter: guid` Required
*String* | The guid of the transaction to be adjusted. |
-| `Request Body: Tip Adjustment` Required
[TipAdjustment](restobjects.md#tip-adjustment) | Object containing the tip amount (as a *String* in MAJOR units, e.g. `"5.25"`) and currency of the tip adjustment. |
+---
-**Returns**
+:::caution
+For the Commands to work properly, the Handpoint Payments App **MUST** be in **Integrated Mode** (enabled via **Handpoint TMS** and controlled by the merchant in the **Handpoint Payments App** Settings).
+:::
+### Set Unattended Mode
-| Response | Response Code |
-| ----------- | ----------- |
-| **OK** | Response code 200. |
-| **BadRequest** | Response code 400. |
+`POST /devices/{deviceType}/{serialNumber}/set-unattended-mode`
+Enables or disables unattended mode on the device.
+Unattended mode will disable the Bottom navigation bar containing the Home, back, recent buttons.
+The Payment screen will be the only visible screen in the Handpoint Payments App. (Settings, Hisotry and Analytic tabs will not be accessible)
-**Code Example**
+
+**Request Body Parameters**
+
+| Parameter | Type | Description |
+|-----------|------|-------------|
+| `status` | boolean | `true` to enable unattended mode, `false` to disable |
+
+**Example Request**
**Requests**
@@ -791,12 +811,13 @@ Note: If two tip adjustments are sent for the same original transaction, only th
```shell
-curl --location --request POST 'https://cloud.handpoint.com/transactions/ff6da784-8b57-11ed-9891-ebe2a88ff071/tip-adjustment' \
---header 'ApiKeyCloud: MeRcHaNt-ApI-KeY' \
---header 'Content-Type: application/json' \
---data-raw '{
- "amount": "5.25" //5 => 5.00
-}'
+curl -X POST \
+ -H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "status": false
+ }' \
+ "https://cloud.handpoint.io/devices/PAXIM30/0000000000/set-unattended-mode"
```
@@ -805,59 +826,49 @@ curl --location --request POST 'https://cloud.handpoint.com/transactions/ff6da78
**Responses**
-
+
-```json
-{
- "statusMessage": "tip adjusted"
-}
-```
+No response body is returned.
-
+
```json
{
- "error": {
- "statusCode": 400,
- "name": "BadRequestError",
- "message": "Invalid guid [fake-guid]"
- }
+ "error": {
+ "statusCode": 400,
+ "name": "BadRequestError",
+ "message": {
+ "error": 1002,
+ "message": "No device listening at the other end of the secure channel"
+ }
+ }
}
```
-
-### Get Card Token {#transactionsguidtoken}
-
-`DeferredTokenization`
-
-GET endpoint used to retrieve a card token from a previously completed transaction. This operation, known as **deferred tokenization**, allows merchants to obtain a card token without requiring tokenization to be enabled at the time of the original transaction. The returned `cardToken` can be used for subsequent operations such as cardholder identification or MOTO payments. See the supported transaction types below.
+### Set Locale
-:::note
-Deferred tokenization is supported for the following transaction types: `sale`, `refund`, `preAuthorizationCapture`, `moToSale` and `moToRefund`. Other transaction types will return a `400` error.
-:::
+`POST /devices/{deviceType}/{serialNumber}/set-locale`
-:::warning
-Tokenization requests must be made within **12 months** of the original transaction. Requests for transactions older than 12 months will not be processed.
-:::
+Sets the locale of the target device.
-**Parameters**
+**Request Body Parameters**
-| Parameter | Notes |
-| ----------- | ----------- |
-| `Header: ApiKeyCloud` Required
*String* | Api key used to authenticate the merchant. (UNIQUE per Merchant) |
-| `Path parameter: guid` Required
*String* | The GUID of the completed card-present transaction from which to retrieve the token. |
+| Parameter | Type | Description |
+|-----------|--------|-----------------------------------------------------------------------------|
+| `locale` | string | IETF BCP 47 language tag (e.g., `en_US`). Two-letter language and country code.|
-**Returns**
+**Response Codes**
-| Response | Response Code |
-| ----------- | ----------- |
-| [DeferredTokenizationResponse](restobjects.md#deferredTokenizationResponse) | Response code 200. |
-| **BadRequest** | Response code 400. Returned when the transaction type is not eligible for deferred tokenization. |
+| Code | Description |
+|------|---------------------------------------------|
+| 202 | The request is accepted and will be executed|
+| 403 | Authentication failed |
+| 422 | Invalid request |
-**Code Example**
+**Example Request**
**Requests**
@@ -865,11 +876,13 @@ Tokenization requests must be made within **12 months** of the original transact
```shell
-curl -X GET \
- -H "ApiKeyCloud: MeRcHaNt-ApIkEy" \
- -H "Content-Type: application/json" \
- "https://cloud.handpoint.com/transactions/75413c40-21db-11f1-991b-6f80eaf25911/token" (production)
- "https://cloud.handpoint.io/transactions/75413c40-21db-11f1-991b-6f80eaf25911/token" (development)
+curl -X POST \
+ -H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "locale": "en_CA"
+ }' \
+ "https://cloud.handpoint.io/devices/PAXIM30/0000000000/set-locale"
```
@@ -878,264 +891,132 @@ curl -X GET \
**Responses**
-
+
-```json
-{
- "agreementNumber": "123456789010102",
- "cardToken": "665630867",
- "cardTokenizationGuid": "7df78050-21dc-11f1-991b-6f80eaf25911",
- "expiryDateMMYY": "0927",
- "httpStatus": "200",
- "maskedCardNumber": "************3555",
- "serverDateTime": "20260317083711509",
- "transactionReference": "75413c40-21db-11f1-991b-6f80eaf25911"
-}
-```
+No response body is returned.
-
+
```json
{
"error": {
- "details": {
- "body": {
- "error": {
- "errorCode": "3112",
- "errorGuid": "624d05e0-21dd-11f1-991b-6f80eaf25911",
- "httpStatus": "403",
- "reason": "Transaction type is not eligible for deferred tokenization"
- }
- },
- "status": 403
- },
- "message": "Viscus operation failed",
+ "statusCode": 400,
"name": "BadRequestError",
- "statusCode": 400
+ "message": {
+ "error": 1002,
+ "message": "No device listening at the other end of the secure channel"
+ }
}
}
```
-
---
-### Reversal
+### Set Password Protected
-:::info
-*Depending on the acquirer* Only applies to reversals that don't require the card to be presented.
-:::
+`POST /devices/{deviceType}/{serialNumber}/set-password-protected`
-This endpoint allows to Cancel/Void/Reverse a previous transaction without a reader.
+Enables or disables password protection on the device.
-**Parameters**
+**Request Body Parameters**
-| Parameter | Notes |
-| ----------- | ----------- |
-| `Header: ApiKeyCloud` Required
*String* | Api key used to authenticate the merchant. (UNIQUE per Merchant) |
-| `Body: originalGuid` Required
*String* | The GUID of the previously completed transaction to reverse. |
-| `Body: amount` Optional
*String* | Decimal amount in String, ISO 4217; Required for partial-reversals. *Only if your acquirer supports partial-reversals*. |
-| `Body: currency` Optional
*String* | Required for partial-reversals *Only if your acquirer supports partial-reversals*. |
-| `Body: messageReasonCode` Optional
*String* | default: CUSTOMER_CANCELLATION. See [allowed values](restapi/restobjects.md#messageReasonCode)|
+| Parameter | Type | Description |
+|-----------|---------|-----------------------------------------------------|
+| `status` | boolean | `true` to enable password protection, `false` to disable |
-**Returns**
+**Response Codes**
-| Response | Response Code |
-| ----------- | ----------- |
-| [DeferredTokenizationResponse](restobjects.md#deferredTokenizationResponse) | Response code 200. |
-| **BadRequest** | Response code 400. Returned when the transaction type is not eligible for deferred tokenization. |
+| Code | Description |
+|------|---------------------------------------------|
+| 202 | The request is accepted and will be executed|
+| 403 | Authentication failed |
+| 422 | Invalid request |
-**Code Example**
+**Example Request**
**Requests**
-
+
```shell
-curl --location --request POST 'https://cloud.handpoint.io/reversal' \
---header 'ApiKeyCloud: MeRcHaNt-ApI-KeY' \
---header 'Content-Type: application/json' \
---data-raw '{
- "originalGuid": "bb6e0b90-420f-11f1-b809-51c9c7fda18b"
-}'
+curl -X POST \
+ -H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
+ -H "Content-Type: application/json" \
+ -d '{
+ "status": true
+ }' \
+ "https://cloud.handpoint.io/devices/PAXIM30/0000000000/set-password-protected"
```
+
-
+**Responses**
-```shell
-curl --location --request POST 'https://cloud.handpoint.io/reversal' \
---header 'ApiKeyCloud: MeRcHaNt-ApI-KeY' \
---header 'Content-Type: application/json' \
---data-raw '{
- "originalGuid": "bb6e0b90-420f-11f1-b809-51c9c7fda18b",
- "amount": "15.00",
- "currency": "EUR"
-}'
-```
+
+
-
+No response body is returned.
-
-
-```shell
-curl --location --request POST 'https://cloud.handpoint.io/reversal' \
---header 'ApiKeyCloud: MeRcHaNt-ApI-KeY' \
---header 'Content-Type: application/json' \
---data-raw '{
- "originalGuid": "bb6e0b90-420f-11f1-b809-51c9c7fda18b",
- "messageReasonCode": "TIMEOUT_WAITING_FOR_RESPONSE"
-}'
-```
-
-
-
-
-**Responses**
-
-
-
-
-```json
-{
- "agreementNumber": "123456789010102",
- "cardToken": "665630867",
- "cardTokenizationGuid": "7df78050-21dc-11f1-991b-6f80eaf25911",
- "expiryDateMMYY": "0927",
- "httpStatus": "200",
- "maskedCardNumber": "************3555",
- "serverDateTime": "20260317083711509",
- "transactionReference": "75413c40-21db-11f1-991b-6f80eaf25911"
-}
-```
-
-
-
+
+
```json
{
"error": {
- "details": {
- "body": {
- "error": {
- "errorCode": "3112",
- "errorGuid": "624d05e0-21dd-11f1-991b-6f80eaf25911",
- "httpStatus": "403",
- "reason": "Transaction type is not eligible for deferred tokenization"
- }
- },
- "status": 403
- },
- "message": "Viscus operation failed",
+ "statusCode": 400,
"name": "BadRequestError",
- "statusCode": 400
+ "message": {
+ "error": 1002,
+ "message": "No device listening at the other end of the secure channel"
+ }
}
}
```
-
---
-:::info
-Pre-authorization operations are only available for acquirers that support pre-authorization flows. Contact your Handpoint relationship manager to confirm support for your acquirer.
-:::
-
-Pre-authorization operations allow you to **manage open pre-authorizations** remotely via Cloud API. A pre-authorization reserves funds on a card without charging them; the increase and capture endpoints let you adjust or finalize that reservation without requiring a physical payment terminal.
-
-Cloud API currently supports the following pre-authorization operations:
-
-- `POST /preauthorization/increase` — increases (or decreases, with `subtract: "1"`) the authorized amount of an open pre-authorization.
-- `POST /preauthorization/capture` — finalizes (captures) an open pre-authorization, charging the captured amount.
-
-All request and response payloads are defined in the corresponding [Pre-authorization objects](restobjects#preauthorization).
-
----
-
-### Preauthorization Increase / Decrease
-
-`PreauthIncrease`
-
-`POST /preauthorization/increase` is used to **modify the authorized amount** of an existing open pre-authorization. The operation is linked to the original pre-authorization via `originalGuid`.
-
-Pass `subtract: "1"` to decrease the authorized amount instead of increasing it.
+### Reboot
-#### Parameters
+`POST /devices/{deviceType}/{serialNumber}/reboot`
-| Parameter | Notes |
-| --------- | ----- |
-| `Header: ApiKeyCloud` Required | Cloud API key used to authenticate the merchant. |
-| `Request Body: PreauthIncreaseRequest` Required | [PreauthIncreaseRequest](restobjects#preauthIncreaseRequest) object containing the original pre-authorization GUID and the amount delta. |
+Reboots the device with an optional force parameter.
-Typical fields in the request body (see [PreauthIncreaseRequest](restobjects#preauthIncreaseRequest) for full details):
+**Request Body Parameters**
-- `originalGuid` Required – GUID of the original pre-authorization transaction.
-- `increaseAmount` Required – Amount delta to apply (for example, `"10.00"`).
-- `tipAmount` Optional – Tip amount to add (for example, `"2.00"`).
-- `subtract` Optional – Pass `"1"` to decrease the authorized amount instead of increasing it.
-- `customerReference` Optional – Integrator-defined reference, forwarded as-is to the gateway.
+| Parameter | Type | Description |
+|-----------|---------|-----------------------------------------------------------------------------|
+| `force` | boolean | `true` to force reboot even during transaction, `false` to check status first|
-#### Returns
+**Response Codes**
-| Result | Notes |
-| ------ | ----- |
-| `200` | Pre-authorization increase accepted. Response body is a parsed gateway object. |
-| `400` | Business rule error from the gateway (for example, unknown `originalGuid` or pre-authorization no longer open). Returned as `BadRequestError` with `error.code` and `error.details`. |
-| `403` | Forbidden — the API key does not belong to a merchant. Partner keys are not accepted by this endpoint. |
-| `422` | Payload validation error (`VALIDATION_FAILED`) — `originalGuid` or `increaseAmount` is missing. |
+| Code | Description |
+|------|---------------------------------------------|
+| 202 | The request is accepted and will be executed|
+| 403 | Authentication failed |
+| 422 | Invalid request |
-**Code Example**
+**Example Request**
**Requests**
-
-
-```shell
-curl -X POST \
- -H "Content-Type: application/json" \
- -H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
- -d '{
- "originalGuid": "0c9d9df0-48ec-11eb-81a1-470a19c80d3a",
- "increaseAmount": "10.00"
- }' \
- "https://cloud.handpoint.io/preauthorization/increase"
-```
-
-
-
+
```shell
curl -X POST \
- -H "Content-Type: application/json" \
-H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
- -d '{
- "originalGuid": "0c9d9df0-48ec-11eb-81a1-470a19c80d3a",
- "increaseAmount": "5.00",
- "subtract": "1"
- }' \
- "https://cloud.handpoint.io/preauthorization/increase"
-```
-
-
-
-
-```shell
-curl -X POST \
-H "Content-Type: application/json" \
- -H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
-d '{
- "originalGuid": "0c9d9df0-48ec-11eb-81a1-470a19c80d3a",
- "increaseAmount": "10.00",
- "tipAmount": "2.00",
- "customerReference": "table-12-increase"
+ "force": false
}' \
- "https://cloud.handpoint.io/preauthorization/increase"
+ "https://cloud.handpoint.io/devices/PAXIM30/0000000000/reboot"
```
@@ -1144,146 +1025,144 @@ curl -X POST \
**Responses**
-
+
-```json
-{
- "httpStatus": 200,
- "customFields": {
- "tenderType": "Credit",
- "issuerResponseCode": "200"
- },
- "acquirerTid": "0821599465",
- "actionCode": "0000",
- "agreementNumber": "123456789010102",
- "approvalCode": "010119",
- "batchNumber": "1",
- "cardTypeName": "VISA",
- "currency": "USD",
- "expiryDateMMYY": "1027",
- "holdAmount": "102.00",
- "issuerResponseCode": "00",
- "issuerResponseText": "COMPLETED",
- "maskedCardNumber": "************0936",
- "nonce": "1776156307790",
- "originalAmount": "1.00",
- "preAuthorizationGuid": "664ec4c0-37e6-11f1-bc66-3114cb76dabf",
- "serverDateTime": "20260414094416641",
- "terminalDateTime": "20260414094416433",
- "transNumber": "000001",
- "increaseAmount": "100.00",
- "preAuthorizationIncreaseGuid": "80b2e710-37e6-11f1-bc66-3114cb76dabf"
-}
-```
+No response body is returned.
-
+
```json
{
"error": {
"statusCode": 400,
"name": "BadRequestError",
- "message": "Original pre-auth is voided, not approved or already captured",
- "code": "3211",
- "details": {
- "errorCode": "3211",
- "errorGuid": "e8b35da0-37ea-11f1-bc66-3114cb76dabf",
- "httpStatus": 403,
- "reason": "Original pre-auth is voided, not approved or already captured"
+ "message": {
+ "error": 1002,
+ "message": "No device listening at the other end of the secure channel"
}
}
}
```
-
-
-
-
-```json
-{
- "error": {
- "statusCode": 422,
- "name": "UnprocessableEntityError",
- "message": "The request body is invalid.",
- "code": "VALIDATION_FAILED",
- "details": [
- {
- "path": "",
- "code": "required",
- "message": "must have required property 'increaseAmount'",
- "info": { "missingProperty": "increaseAmount" }
- }
- ]
- }
-}
-```
-
---
-### Preauthorization Capture
-
-`PreauthCapture`
-
-`POST /preauthorization/capture` is used to **finalize (capture) an open pre-authorization**, charging the `capturedAmount` to the cardholder. Once captured, the pre-authorization is settled and the held funds are transferred.
+### Set Screen Brightness
-#### Parameters
+`POST /devices/{deviceType}/{serialNumber}/set-screen-brightness`
-| Parameter | Notes |
-| --------- | ----- |
-| `Header: ApiKeyCloud` Required | Cloud API key used to authenticate the merchant. |
-| `Request Body: PreauthCaptureRequest` Required | [PreauthCaptureRequest](restobjects#preauthCaptureRequest) object containing the original pre-authorization GUID and the amount to capture. |
+Sets the screen brightness levels.
-Typical fields in the request body (see [PreauthCaptureRequest](restobjects#preauthCaptureRequest) for full details):
+**Request Body Parameters**
-- `originalGuid` Required – GUID of the original pre-authorization transaction.
-- `capturedAmount` Required – Amount to capture and charge (for example, `"120.00"`).
-- `tipAmount` Optional – Tip amount to include in the captured total (for example, `"5.00"`).
-- `customerReference` Optional – Integrator-defined reference, forwarded as-is to the gateway.
+| Parameter | Type | Description |
+|--------------------------|---------|------------------------------------|
+| `minimumBrightnessLevel` | integer | Value between 0 and 100 |
+| `maximumBrightnessLevel` | integer | Value between 0 and 100 |
-#### Returns
+**Response Codes**
-| Result | Notes |
-| ------ | ----- |
-| `200` | Pre-authorization capture accepted. Response body is a parsed gateway object. |
-| `400` | Business rule error from the gateway (for example, unknown `originalGuid`, pre-authorization already captured, or captured amount exceeds authorized amount). Returned as `BadRequestError` with `error.code` and `error.details`. |
-| `403` | Forbidden — the API key does not belong to a merchant. Partner keys are not accepted by this endpoint. |
-| `422` | Payload validation error (`VALIDATION_FAILED`) — `originalGuid` or `capturedAmount` is missing. |
+| Code | Description |
+|------|---------------------------------------------|
+| 202 | The request is accepted and will be executed|
+| 403 | Authentication failed |
+| 422 | Invalid request |
+| 400 | Value is outside the valid range |
-**Code Example**
+**Example Request**
**Requests**
-
+
```shell
curl -X POST \
- -H "Content-Type: application/json" \
-H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
+ -H "Content-Type: application/json" \
-d '{
- "originalGuid": "0c9d9df0-48ec-11eb-81a1-470a19c80d3a",
- "capturedAmount": "120.00"
+ "minimumBrightnessLevel": 20,
+ "maximumBrightnessLevel": 100
}' \
- "https://cloud.handpoint.io/preauthorization/capture"
+ "https://cloud.handpoint.io/devices/PAXIM30/0000000000/set-screen-brightness"
```
-
+
+
+**Responses**
+
+
+
+
+No response body is returned.
+
+
+
+
+```json
+{
+ "error": {
+ "statusCode": 400,
+ "name": "BadRequestError",
+ "message": {
+ "error": 1002,
+ "message": "No device listening at the other end of the secure channel"
+ }
+ }
+}
+```
+
+
+
+---
+
+### Set Reboot Time
+
+:::note
+This feature is only enabled for production devices.
+:::
+
+`POST /devices/{deviceType}/{serialNumber}/set-reboot-time`
+
+Sets the daily reboot time for the device. The actual reboot will occur at a random minute within the specified hour.
+
+**Request Body Parameters**
+
+| Parameter | Type | Description |
+|-----------|---------|-----------------------------------------------------|
+| `hour` | integer | Hour of the day (0-23) when device should reboot |
+
+:::tip
+If hour is set to 22, the device will reboot at a random time between 22:01 and 22:59.
+:::
+
+**Response Codes**
+
+| Code | Description |
+|------|---------------------------------------------|
+| 202 | The request is accepted and will be executed|
+| 403 | Authentication failed |
+| 422 | Invalid request |
+| 400 | Value is outside the valid range |
+
+**Example Request**
+
+**Requests**
+
+
+
```shell
curl -X POST \
- -H "Content-Type: application/json" \
-H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
+ -H "Content-Type: application/json" \
-d '{
- "originalGuid": "0c9d9df0-48ec-11eb-81a1-470a19c80d3a",
- "capturedAmount": "120.00",
- "tipAmount": "5.00",
- "customerReference": "hotel-folio-4422"
+ "hour": 22
}' \
- "https://cloud.handpoint.io/preauthorization/capture"
+ "https://cloud.handpoint.io/devices/PAXIM30/0000000000/set-reboot-time"
```
@@ -1292,144 +1171,77 @@ curl -X POST \
**Responses**
-
+
-```json
-{
- "httpStatus": 200,
- "customFields": {
- "tenderType": "Credit",
- "RRN": "513815902180",
- "issuerResponseCode": "200"
- },
- "acquirerTid": "0821599465",
- "actionCode": "0000",
- "agreementNumber": "123456789010102",
- "approvalCode": "010119",
- "batchNumber": "1",
- "cardTypeName": "VISA",
- "currency": "USD",
- "expiryDateMMYY": "1027",
- "holdAmount": "102.00",
- "issuerResponseCode": "00",
- "issuerResponseText": "COMPLETED",
- "maskedCardNumber": "************0936",
- "nonce": "1776156307790",
- "originalAmount": "1.00",
- "preAuthorizationGuid": "664ec4c0-37e6-11f1-bc66-3114cb76dabf",
- "serverDateTime": "20260414094532102",
- "terminalDateTime": "20260414094532085",
- "transNumber": "000001",
- "capturedAmount": "100.00",
- "preAuthorizationCaptureGuid": "adad5660-37e6-11f1-9d29-81969834b189"
-}
-```
+No response body is returned.
-
+
+
```json
{
- "error": {
- "statusCode": 422,
- "name": "UnprocessableEntityError",
- "message": "The request body is invalid.",
- "code": "VALIDATION_FAILED",
- "details": [
- {
- "path": "",
- "code": "required",
- "message": "must have required property 'capturedAmount'",
- "info": { "missingProperty": "capturedAmount" }
- }
- ]
- }
+ "error": {
+ "statusCode": 400,
+ "name": "BadRequestError",
+ "message": {
+ "error": 1002,
+ "message": "No device listening at the other end of the secure channel"
+ }
+ }
}
```
-## **MOTO Operations**
-`MOTO (Mail Order / Telephone Order)` operations can also be processed **without a payment reader**, using information
-that is already stored in the gateway (tokens and references to previous transactions).
-
-These endpoints are intended for MOTO scenarios where the merchant does **not** need to collect or handle sensitive
-card data (PAN, expiry date, CVV) in their own systems:
-
-- `/moto/sale` performs a sale using a **previously generated card token** (`cardToken`) that represents card details stored in the gateway.
-- `/moto/refund` performs a refund of a **previous operation**, using the card associated with that original operation (`originalGuid`).
-- `/moto/reversal` performs a reversal (void) of a **previous operation**, passing only its identifier (`originalGuid`).
-
-:::tip
-Unlike the standard MOTO operations that use `/transactions` and a physical terminal, these endpoints:
-
-- Do **not** require `serial_number` or `terminal_type`.
-- Do **not** receive raw card data in the request.
-- Rely on `cardToken` and `originalGuid` to reference card information already stored in the gateway.
-:::
+## Endpoints Not Requiring a Payment Terminal
-All request and response payloads are defined in the corresponding [Moto objects](restobjects#moto).
+The following endpoints operate entirely through the Cloud API and do **not** require a connected payment terminal.
---
-### MOTO Sale
+### Tip Adjustment
-`MotoSale`
-`POST /moto/sale` is used to perform a **MOTO sale without a payment reader**, using a **card token** (`cardToken`)
-that was generated previously (for example, by a `saleAndTokenizeCard` operation).
+`TipAdjustment`
-The card details are *not* sent in the request; they are resolved by the gateway using the `cardToken`.
+POST endpoint used to execute a tip adjustment operation.
-Typical flow:
+A tip adjustment operation allows merchants to adjust the tip amount of a sale transaction before the batch of transactions is settled by the processor at the end of the day. Note: This functionality is only available for the restaurant industry in the United States and the processors currently supporting this functionality are TSYS and VANTIV.
-1. A card is captured securely in a previous flow, for example through the [`/transactions`](restendpoints#transactions) endpoint using a
- `saleAndTokenizeCard` operation.
-2. The gateway returns a `cardToken` (e.g. `665630867`).
-3. The integrator can later perform one or more MOTO sales using that `cardToken`, without handling PAN/CVV again.
+Note: If two tip adjustments are sent for the same original transaction, only the second one will be taken into account. Each new tip adjustment will override the previous one. A tip adjustment will be rejected if the original transaction has already been batched out by the acquirer.
-#### Parameters
+**Parameters**
-| Parameter | Notes |
-| --------- | ----- |
-| `Header: ApiKeyCloud` Required | Cloud API key used to authenticate the merchant. |
-| `Request Body: MotoSaleRequest` Required | [MotoSaleRequest](restobjects#motoSaleRequest) object containing `cardToken`, `amount`, `currency` and optional merchant references. |
+| Parameter | Notes |
+| ----------- | ----------- |
+| `Header: ApiKeyCloud` Required
*String* | Api key used to authenticate the merchant. (UNIQUE per Merchant) |
+| `Path parameter: guid` Required
*String* | The guid of the transaction to be adjusted. |
+| `Request Body: Tip Adjustment` Required
[TipAdjustment](restobjects.md#tip-adjustment) | Object containing the tip amount (as a *String* in MAJOR units, e.g. `"5.25"`) and currency of the tip adjustment. |
-Typical fields in the request body (see [MotoSaleRequest](restobjects#motoSaleRequest) for full details):
+**Returns**
-- `cardToken` Required – Token representing the card stored in the gateway (e.g. `"665630867"`).
-- `amount` Required – String amount in MAJOR units (e.g. `"20.00"` for 20.00). Must be a positive integer string.
-- `currency` Required – 3-character ISO 4217 currency code (e.g. `"EUR"`).
-- Optional references for reconciliation: `customerReference`, `transactionReference`, etc.
-#### Returns
+| Response | Response Code |
+| ----------- | ----------- |
+| **OK** | Response code 200. |
+| **BadRequest** | Response code 400. |
-| Result | Notes |
-| ------ | ----- |
-| `200` | Sale successfully processed. The response body is a `motoSaleResponse` [Moto Transaction Response](restobjects#motoTransactionResponse) with the authorization result (approved/declined), authorization code, masked card details, acquirer TID, timestamps, etc. |
-| `400` | Business rule error from the payment gateway (for example, CVV required, card token failure). Returned as `BadRequestError`, with `error.code` and `error.details` containing the gateway error code and description. |
-| `422` | Payload validation error (`VALIDATION_FAILED`) when required fields are missing or do not match the schema (invalid amount (must be a positive integer string in minor units), currency length, etc.). |
-| `5xx` | Internal error or gateway unavailability. The final outcome may be unknown and may require reconciliation. |
-#### Code Example
+**Code Example**
**Requests**
-
+
```shell
-curl -X POST \
- -H "Content-Type: application/json" \
- -H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
- -d '{
- "amount": "20.00", // 20 => 20.00
- "currency": "EUR",
- "cardToken": "665630867",
- "customerReference": "order-12345",
- "transactionReference": "b7b2360d-3e9e-4b62-9a3a-2e6ef6c5cd01"
- }' \
- "https://cloud.handpoint.io/moto/sale"
+curl --location --request POST 'https://cloud.handpoint.com/transactions/ff6da784-8b57-11ed-9891-ebe2a88ff071/tip-adjustment' \
+--header 'ApiKeyCloud: MeRcHaNt-ApI-KeY' \
+--header 'Content-Type: application/json' \
+--data-raw '{
+ "amount": "5.25" //5 => 5.00
+}'
```
@@ -1438,69 +1250,23 @@ curl -X POST \
**Responses**
-
+
```json
{
- "error": {
- "statusCode": 400,
- "name": "BadRequestError",
- "message": "CVV required",
- "code": "3107",
- "details": {
- "errorGuid": "dae59b20-cf71-11f0-b588-a122fae316de",
- "errorCode": "3107",
- "description": "CVV required",
- "httpStatus": 400
- }
- }
+ "statusMessage": "tip adjusted"
}
```
-:::note
-A very common cause of **3107** is having "CVV/CV2 input mandatory" enabled for Card Not Present.
-:::
-
-
+
```json
{
"error": {
- "code": "5252",
- "details": {
- "description": "Card token failure",
- "errorCode": "5252",
- "errorGuid": "10a3d120-cf75-11f0-95b2-770b7d1d8e67",
- "httpStatus": 404
- },
- "message": "Card token failure",
+ "statusCode": 400,
"name": "BadRequestError",
- "statusCode": 400
- }
-}
-```
-
-
-
-
-```json
-{
- "error": {
- "code": "VALIDATION_FAILED",
- "details": [
- {
- "code": "required",
- "info": {
- "missingProperty": "amount"
- },
- "message": "must have required property 'amount'",
- "path": ""
- }
- ],
- "message": "The request body is invalid. See error object `details` property for more info.",
- "name": "UnprocessableEntityError",
- "statusCode": 422
+ "message": "Invalid guid [fake-guid]"
}
}
```
@@ -1508,60 +1274,47 @@ A very common cause of **3107** is having "CVV/CV2 input mandatory" enabled for
----
-
-### MOTO Refund
-
-`MotoRefund`
-
-`POST /moto/refund` is used to perform a **MOTO refund without a payment reader**.
+### Get Card Token {#transactionsguidtoken}
-The refund is **linked** to a previous MOTO sale via `originalGuid`, and the gateway reuses the card associated with that
-original transaction. No card data is passed in the refund request.
+`DeferredTokenization`
-#### Parameters
+GET endpoint used to retrieve a card token from a previously completed transaction. This operation, known as **deferred tokenization**, allows merchants to obtain a card token without requiring tokenization to be enabled at the time of the original transaction. The returned `cardToken` can be used for subsequent operations such as cardholder identification or MOTO payments. See the supported transaction types below.
-| Parameter | Notes |
-| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------- |
-| `Header: ApiKeyCloud` Required | Cloud API key used to authenticate the merchant. |
-| `Request Body: MotoRefundRequest` Required | [MotoRefundRequest](restobjects#motoRefundRequest) object containing `originalGuid`, `amount`, `currency` and optional merchant references. |
+:::note
+Deferred tokenization is supported for the following transaction types: `sale`, `refund`, `preAuthorizationCapture`, `moToSale` and `moToRefund`. Other transaction types will return a `400` error.
+:::
-Typical fields (see [MotoRefundRequest](restobjects#motoRefundRequest) for full details):
+:::warning
+Tokenization requests must be made within **12 months** of the original transaction. Requests for transactions older than 12 months will not be processed.
+:::
-* `originalGuid` Required – GUID of the original sale to be refunded (e.g. `"1a41d9f0-cf72-11f0-95b2-770b7d1d8e67"`).
-* `amount` Required – String amount to be refunded in MAJOR units (e.g. `"5.00"` for $5.00). Must be a positive integer string.
-* `currency` Required – 3-character ISO 4217 code (e.g. `"EUR"`, `"USD"`).
-* Optional: `customerReference`, `transactionReference`.
+**Parameters**
-Supports full and partial refunds, depending on acquirer configuration.
+| Parameter | Notes |
+| ----------- | ----------- |
+| `Header: ApiKeyCloud` Required
*String* | Api key used to authenticate the merchant. (UNIQUE per Merchant) |
+| `Path parameter: guid` Required
*String* | The GUID of the completed card-present transaction from which to retrieve the token. |
-#### Returns
+**Returns**
-| Result | Notes |
-| ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `200` | Refund successfully processed. The response body is a `motoRefundResponse` [Moto Transaction Response](restobjects#motoTransactionResponse) including `guid`, `originalGuid`, `amount`, `currency`, `maskedCardNumber`, `approvalCode`, `issuerResponseText`, etc. |
-| `400` | Business rule error from the payment gateway (for example, currency mismatch, refund amount greater than the original sale). Returned as `BadRequestError`, with `error.code` and `error.details` describing the gateway error. |
-| `422` | Payload validation error (`VALIDATION_FAILED`) when required fields are missing or invalid (missing `originalGuid`, invalid amount, invalid currency format, etc.). |
+| Response | Response Code |
+| ----------- | ----------- |
+| [DeferredTokenizationResponse](restobjects.md#deferredTokenizationResponse) | Response code 200. |
+| **BadRequest** | Response code 400. Returned when the transaction type is not eligible for deferred tokenization. |
-#### Code Example
+**Code Example**
**Requests**
-
+
```shell
-curl -X POST \
- -H "Content-Type: application/json" \
- -H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
- -d '{
- "originalGuid": "1a41d9f0-cf72-11f0-95b2-770b7d1d8e67",
- "amount": "5.00", // 5 => 5.00
- "currency": "EUR",
- "customerReference": "refund-98765",
- "transactionReference": "a1fe8db5-69a4-4b4d-a704-94ac2570f9b0"
- }' \
- "https://cloud.handpoint.io/moto/refund"
+curl -X GET \
+ -H "ApiKeyCloud: MeRcHaNt-ApIkEy" \
+ -H "Content-Type: application/json" \
+ "https://cloud.handpoint.com/transactions/75413c40-21db-11f1-991b-6f80eaf25911/token" (production)
+ "https://cloud.handpoint.io/transactions/75413c40-21db-11f1-991b-6f80eaf25911/token" (development)
```
@@ -1570,107 +1323,118 @@ curl -X POST \
**Responses**
-
+
```json
{
- "error": {
- "code": "3210",
- "details": {
- "description": "Original and linked currency do not match",
- "errorCode": "3210",
- "errorGuid": "35a2b220-cf7a-11f0-b588-a122fae316de",
- "httpStatus": 400
- },
- "message": "Original and linked currency do not match",
- "name": "BadRequestError",
- "statusCode": 400
- }
+ "agreementNumber": "123456789010102",
+ "cardToken": "665630867",
+ "cardTokenizationGuid": "7df78050-21dc-11f1-991b-6f80eaf25911",
+ "expiryDateMMYY": "0927",
+ "httpStatus": "200",
+ "maskedCardNumber": "************3555",
+ "serverDateTime": "20260317083711509",
+ "transactionReference": "75413c40-21db-11f1-991b-6f80eaf25911"
}
```
-
+
```json
{
- "error": {
- "code": "3209",
- "details": {
- "description": "The requested refund amount is greater than the initial sale amount",
- "errorCode": "3209",
- "errorGuid": "e72ea940-cf7a-11f0-b588-a122fae316de",
- "httpStatus": 400
- },
- "message": "The requested refund amount is greater than the initial sale amount",
- "name": "BadRequestError",
- "statusCode": 400
- }
+ "error": {
+ "details": {
+ "body": {
+ "error": {
+ "errorCode": "3112",
+ "errorGuid": "624d05e0-21dd-11f1-991b-6f80eaf25911",
+ "httpStatus": "403",
+ "reason": "Transaction type is not eligible for deferred tokenization"
+ }
+ },
+ "status": 403
+ },
+ "message": "Viscus operation failed",
+ "name": "BadRequestError",
+ "statusCode": 400
+ }
}
```
-
-
-
-Missing `originalGuid`, missing `amount`, invalid `currency` length, or invalid `amount` pattern — returned as `422 VALIDATION_FAILED` with one or more entries in `error.details`.
-
---
-### MOTO Reversal
+### Reversal
+
+:::info
+*Depending on the acquirer* Only applies to reversals that don't require the card to be presented.
+:::
+
+This endpoint allows to Cancel/Void/Reverse a previous transaction without a reader.
-`MotoReversal`
+**Parameters**
-`POST /moto/reversal` is used to **reverse (void)** a previous MOTO operation processed via the no-reader MOTO endpoints.
+| Parameter | Notes |
+| ----------- | ----------- |
+| `Header: ApiKeyCloud` Required
*String* | Api key used to authenticate the merchant. (UNIQUE per Merchant) |
+| `Body: originalGuid` Required
*String* | The GUID of the previously completed transaction to reverse. |
+| `Body: amount` Optional
*String* | Decimal amount in String, ISO 4217; Required for partial-reversals. *Only if your acquirer supports partial-reversals*. |
+| `Body: currency` Optional
*String* | Required for partial-reversals *Only if your acquirer supports partial-reversals*. |
+| `Body: messageReasonCode` Optional
*String* | default: CUSTOMER_CANCELLATION. See [allowed values](restapi/restobjects.md#messageReasonCode)|
-The request is linked to the original sale via `originalGuid`. No card data is sent; the gateway uses the original
-transaction information.
+**Returns**
-Reversals are typically used to cancel a MOTO sale shortly after authorization, subject to acquirer rules.
+| Response | Response Code |
+| ----------- | ----------- |
+| [DeferredTokenizationResponse](restobjects.md#deferredTokenizationResponse) | Response code 200. |
+| **BadRequest** | Response code 400. Returned when the transaction type is not eligible for deferred tokenization. |
-#### Parameters
+**Code Example**
-| Parameter | Notes |
-| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
-| `Header: ApiKeyCloud` Required | Cloud API key used to authenticate the merchant. |
-| `Request Body: MotoReversalRequest` Required | [MotoReversalRequest](restobjects#motoReversalRequest) object referencing the original MOTO transaction (`originalGuid`) and including the reversal `amount` and `currency`. |
+**Requests**
-Typical fields (see [MotoReversalRequest](restobjects#motoReversalRequest) for full details):
+
+
-* `originalGuid` Required – GUID of the original sale to be reversed.
-* `amount` Required – String amount to reverse in MAJOR units (e.g. `"20.00"` for $20.00). Must be a positive integer string.
-* `currency` Optional – 3-character ISO 4217 code; if provided, must respect `minLength = 3`, `maxLength = 3` and may need to match the original transaction’s currency.
-* Optional merchant references: `customerReference`, `transactionReference`.
+```shell
+curl --location --request POST 'https://cloud.handpoint.io/reversal' \
+--header 'ApiKeyCloud: MeRcHaNt-ApI-KeY' \
+--header 'Content-Type: application/json' \
+--data-raw '{
+ "originalGuid": "bb6e0b90-420f-11f1-b809-51c9c7fda18b"
+}'
+```
-#### Returns
+
-| Result | Notes |
-| ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `200` | Reversal accepted and processed. Response body is a `motoReversalResponse` [Moto Transaction Response](restobjects#motoTransactionResponse) indicating whether the reversal was approved, with fields such as `guid`, `originalGuid`, `issuerResponseCode`, `issuerResponseText`, `f25`, etc. |
-| `400` | Business rule error from the payment gateway (for example, unknown `originalGuid`, reversal not allowed). Returned as `BadRequestError`, with `error.code` and `error.details` describing the gateway error (for example, code `3153`). |
-| `422` | Payload validation error (`VALIDATION_FAILED`) when required fields are missing or invalid (missing `originalGuid`, missing `amount`, invalid `currency`, invalid `amount` pattern). |
+
-#### Code Example
+```shell
+curl --location --request POST 'https://cloud.handpoint.io/reversal' \
+--header 'ApiKeyCloud: MeRcHaNt-ApI-KeY' \
+--header 'Content-Type: application/json' \
+--data-raw '{
+ "originalGuid": "bb6e0b90-420f-11f1-b809-51c9c7fda18b",
+ "amount": "15.00",
+ "currency": "EUR"
+}'
+```
-**Requests**
+
-
-
+
```shell
-curl -X POST \
- -H "Content-Type: application/json" \
- -H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
- -d '{
- "originalGuid": "b28bdb10-cf87-11f0-b588-a122fae316de",
- "amount": "20.00", //20 => 20.00 || 2000 => 2000.00
- "currency": "EUR",
- "customerReference": "void-001",
- "transactionReference": "4d7b1a2c-5bfd-4a30-9b6f-123456789abc"
- }' \
- "https://cloud.handpoint.io/moto/reversal"
+curl --location --request POST 'https://cloud.handpoint.io/reversal' \
+--header 'ApiKeyCloud: MeRcHaNt-ApI-KeY' \
+--header 'Content-Type: application/json' \
+--data-raw '{
+ "originalGuid": "bb6e0b90-420f-11f1-b809-51c9c7fda18b",
+ "messageReasonCode": "TIMEOUT_WAITING_FOR_RESPONSE"
+}'
```
@@ -1679,161 +1443,201 @@ curl -X POST \
**Responses**
-
+
```json
{
- "type": "motoReversalResponse",
- "httpStatus": 200,
- "amount": "20.00",
- "currency": "EUR",
- "guid": "3f7772a0-cf88-11f0-b588-a122fae316de",
- "originalGuid": "b28bdb10-cf87-11f0-b588-a122fae316de",
- "issuerResponseCode": "00",
- "issuerResponseText": "Successful",
- "maskedCardNumber": "************3555",
- "f25": "4000"
+ "agreementNumber": "123456789010102",
+ "cardToken": "665630867",
+ "cardTokenizationGuid": "7df78050-21dc-11f1-991b-6f80eaf25911",
+ "expiryDateMMYY": "0927",
+ "httpStatus": "200",
+ "maskedCardNumber": "************3555",
+ "serverDateTime": "20260317083711509",
+ "transactionReference": "75413c40-21db-11f1-991b-6f80eaf25911"
}
```
-
+
```json
{
- "error": {
- "code": "3153",
- "details": {
- "description": "Unable to find message to reverse.",
- "errorCode": "3153",
- "errorGuid": "633a4370-cf88-11f0-b588-a122fae316de",
- "httpStatus": 404
- },
- "message": "Unable to find message to reverse.",
- "name": "BadRequestError",
- "statusCode": 400
- }
+ "error": {
+ "details": {
+ "body": {
+ "error": {
+ "errorCode": "3112",
+ "errorGuid": "624d05e0-21dd-11f1-991b-6f80eaf25911",
+ "httpStatus": "403",
+ "reason": "Transaction type is not eligible for deferred tokenization"
+ }
+ },
+ "status": 403
+ },
+ "message": "Viscus operation failed",
+ "name": "BadRequestError",
+ "statusCode": 400
+ }
}
```
-
-
-
-Missing `originalGuid`, missing `amount`, invalid `currency` length, or invalid `amount` pattern — returned as `422 VALIDATION_FAILED` with one or more entries in `error.details`.
-
-## Batch Operations Beta {#batch-operations}
+---
:::info
-Batch Operations are not available for all acquirers. Contact your Handpoint relationship manager to find out if this feature is supported for your acquirer.
+Pre-authorization operations are only available for acquirers that support pre-authorization flows. Contact your Handpoint relationship manager to confirm support for your acquirer.
:::
-Batch operations allow you to remotely **manage batches on a specific payment terminal** using Cloud API.
-
-These endpoints are typically used in scenarios where the acquirer or merchant workflow is batch-based (for example,
-daily settlement batches per terminal).
-
-Cloud API currently supports the following batch operations:
-
-- `POST /batch/close` — requests the **closure of a batch** for a given terminal (`deviceType`, `serialNumber`) and `batchNumber`.
-- `POST /batch/summary` — retrieves a **summary of a batch** for a given terminal (`deviceType`, `serialNumber`) and `batchNumber`.
-- `POST /batch/detail` — retrieves **batch detail** (including a list of transactions) for a given terminal (`deviceType`, `serialNumber`) and `batchNumber` (and optional `rrn`).
+Pre-authorization operations allow you to **manage open pre-authorizations** remotely via Cloud API. A pre-authorization reserves funds on a card without charging them; the increase and capture endpoints let you adjust or finalize that reservation without requiring a physical payment terminal.
+Cloud API currently supports the following pre-authorization operations:
-All request and response payloads are defined in the corresponding [Batch objects](restobjects#batch).
+- `POST /preauthorization/increase` — increases (or decreases, with `subtract: "1"`) the authorized amount of an open pre-authorization.
+- `POST /preauthorization/capture` — finalizes (captures) an open pre-authorization, charging the captured amount.
-:::info
-In MOTO scenarios, the `deviceType` and `serialNumber` fields can refer to a **virtual terminal** (`VT`) instead of a physical device. Use `VT` as the `deviceType` and the serial number of the virtual terminal assigned to the merchant. The serial number of the virtual terminal can be retrieved from the response of the [/initialize](restendpoints#initialize) endpoint.
-:::
+All request and response payloads are defined in the corresponding [Pre-authorization objects](restobjects#preauthorization).
---
-### Close Batch
-
-`BatchClose`
+### Preauthorization Increase / Decrease
-`POST /batch/close` is used to request **closure of a batch** for a specific payment terminal, identified by its
-`deviceType` and `serialNumber`, and a `batchNumber`.
+`PreauthIncrease`
-Typical use cases:
+`POST /preauthorization/increase` is used to **modify the authorized amount** of an existing open pre-authorization. The operation is linked to the original pre-authorization via `originalGuid`.
-- End-of-day batch closure triggered from a back-office or back-office job.
-- Manual batch close as part of a support or reconciliation process.
+Pass `subtract: "1"` to decrease the authorized amount instead of increasing it.
#### Parameters
| Parameter | Notes |
| --------- | ----- |
| `Header: ApiKeyCloud` Required | Cloud API key used to authenticate the merchant. |
-| `Request Body: BatchCloseRequest` Required | [BatchCloseRequest](restobjects#batchCloseRequest) object containing `deviceType`, `serialNumber` and `batchNumber`. |
+| `Request Body: PreauthIncreaseRequest` Required | [PreauthIncreaseRequest](restobjects#preauthIncreaseRequest) object containing the original pre-authorization GUID and the amount delta. |
-Typical fields in the request body (see [BatchCloseRequest](restobjects#batchCloseRequest) for full details):
+Typical fields in the request body (see [PreauthIncreaseRequest](restobjects#preauthIncreaseRequest) for full details):
-- `deviceType` Required – Terminal model identifier (for example, `"PAXA920MAX"`).
-- `serialNumber` Required – Serial number of the payment terminal (for example, `"2740013262"`).
-- `batchNumber` Required – Identifier of the batch to close (for example, `"1"`).
+- `originalGuid` Required – GUID of the original pre-authorization transaction.
+- `increaseAmount` Required – Amount delta to apply (for example, `"10.00"`).
+- `tipAmount` Optional – Tip amount to add (for example, `"2.00"`).
+- `subtract` Optional – Pass `"1"` to decrease the authorized amount instead of increasing it.
+- `customerReference` Optional – Integrator-defined reference, forwarded as-is to the gateway.
#### Returns
| Result | Notes |
| ------ | ----- |
-| `200` | Batch close request accepted. The response body is a [BatchCloseResponse](restobjects#batchCloseResponse) with the batch number, a unique `closeBatchGuid`, timestamps and an issuer-style response code/text. |
-| `400` | Business rule error or generic gateway error. Returned as `BadRequestError`, with `error.code`, `error.message` and `error.details` describing the problem. |
-| `422` | Payload validation error (`VALIDATION_FAILED`) when required fields are missing or do not match the schema (for example, missing `batchNumber`). |
-| `5xx` | Internal error or service unavailability. The final outcome of the batch close may be unknown and may require reconciliation or a retry at a later time. |
+| `200` | Pre-authorization increase accepted. Response body is a parsed gateway object. |
+| `400` | Business rule error from the gateway (for example, unknown `originalGuid` or pre-authorization no longer open). Returned as `BadRequestError` with `error.code` and `error.details`. |
+| `403` | Forbidden — the API key does not belong to a merchant. Partner keys are not accepted by this endpoint. |
+| `422` | Payload validation error (`VALIDATION_FAILED`) — `originalGuid` or `increaseAmount` is missing. |
**Code Example**
**Requests**
-
+
```shell
curl -X POST \
-H "Content-Type: application/json" \
-H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
-d '{
- "deviceType": "PAXA920MAX",
- "serialNumber": "2740013262",
- "batchNumber": "1"
+ "originalGuid": "0c9d9df0-48ec-11eb-81a1-470a19c80d3a",
+ "increaseAmount": "10.00"
}' \
- "https://cloud.handpoint.io/batch/close"
+ "https://cloud.handpoint.io/preauthorization/increase"
```
-
+
```shell
curl -X POST \
-H "Content-Type: application/json" \
-H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
-d '{
- "deviceType": "PAXA920MAX",
- "serialNumber": "2740013262"
+ "originalGuid": "0c9d9df0-48ec-11eb-81a1-470a19c80d3a",
+ "increaseAmount": "5.00",
+ "subtract": "1"
}' \
- "https://cloud.handpoint.io/batch/close"
+ "https://cloud.handpoint.io/preauthorization/increase"
+```
+
+
+
+
+```shell
+curl -X POST \
+ -H "Content-Type: application/json" \
+ -H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
+ -d '{
+ "originalGuid": "0c9d9df0-48ec-11eb-81a1-470a19c80d3a",
+ "increaseAmount": "10.00",
+ "tipAmount": "2.00",
+ "customerReference": "table-12-increase"
+ }' \
+ "https://cloud.handpoint.io/preauthorization/increase"
+```
+
+
+
+
+**Responses**
+
+
+
+
+```json
+{
+ "httpStatus": 200,
+ "customFields": {
+ "tenderType": "Credit",
+ "issuerResponseCode": "200"
+ },
+ "acquirerTid": "0821599465",
+ "actionCode": "0000",
+ "agreementNumber": "123456789010102",
+ "approvalCode": "010119",
+ "batchNumber": "1",
+ "cardTypeName": "VISA",
+ "currency": "USD",
+ "expiryDateMMYY": "1027",
+ "holdAmount": "102.00",
+ "issuerResponseCode": "00",
+ "issuerResponseText": "COMPLETED",
+ "maskedCardNumber": "************0936",
+ "nonce": "1776156307790",
+ "originalAmount": "1.00",
+ "preAuthorizationGuid": "664ec4c0-37e6-11f1-bc66-3114cb76dabf",
+ "serverDateTime": "20260414094416641",
+ "terminalDateTime": "20260414094416433",
+ "transNumber": "000001",
+ "increaseAmount": "100.00",
+ "preAuthorizationIncreaseGuid": "80b2e710-37e6-11f1-bc66-3114cb76dabf"
+}
```
-
-
-**Responses**
-
-
-
+
```json
{
- "batchNumber": "1",
- "closeBatchGuid": "14431ad0-d0dc-11f0-9ed0-695d1a368668",
- "closedAt": "20251204064010281",
- "customerReference": {},
- "httpStatus": "200",
- "issuerResponseCode": "00",
- "issuerResponseText": "ACCEPTED"
+ "error": {
+ "statusCode": 400,
+ "name": "BadRequestError",
+ "message": "Original pre-auth is voided, not approved or already captured",
+ "code": "3211",
+ "details": {
+ "errorCode": "3211",
+ "errorGuid": "e8b35da0-37ea-11f1-bc66-3114cb76dabf",
+ "httpStatus": 403,
+ "reason": "Original pre-auth is voided, not approved or already captured"
+ }
+ }
}
```
@@ -1843,20 +1647,18 @@ curl -X POST \
```json
{
"error": {
+ "statusCode": 422,
+ "name": "UnprocessableEntityError",
+ "message": "The request body is invalid.",
"code": "VALIDATION_FAILED",
"details": [
{
+ "path": "",
"code": "required",
- "info": {
- "missingProperty": "batchNumber"
- },
- "message": "must have required property 'batchNumber'",
- "path": ""
+ "message": "must have required property 'increaseAmount'",
+ "info": { "missingProperty": "increaseAmount" }
}
- ],
- "message": "The request body is invalid. See error object `details` property for more info.",
- "name": "UnprocessableEntityError",
- "statusCode": 422
+ ]
}
}
```
@@ -1864,72 +1666,69 @@ curl -X POST \
-### Batch Summary
-
-`BatchSummary`
+---
-`POST /batch/summary` is used to retrieve a **summary of a batch** for a specific payment terminal, identified by its
-`deviceType`, `serialNumber`, and `batchNumber`.
+### Preauthorization Capture
-Typical use cases:
+`PreauthCapture`
-- Back-office reconciliation after a batch close.
-- Reporting and dashboards that need batch-level totals (number of transactions, net amount, status).
-- Support tools that need to check the status of a batch on a given terminal.
+`POST /preauthorization/capture` is used to **finalize (capture) an open pre-authorization**, charging the `capturedAmount` to the cardholder. Once captured, the pre-authorization is settled and the held funds are transferred.
#### Parameters
| Parameter | Notes |
| --------- | ----- |
| `Header: ApiKeyCloud` Required | Cloud API key used to authenticate the merchant. |
-| `Request Body: BatchSummaryRequest` Required | [BatchSummaryRequest](restobjects#batchSummaryRequest) object containing `deviceType`, `serialNumber` and `batchNumber`. |
+| `Request Body: PreauthCaptureRequest` Required | [PreauthCaptureRequest](restobjects#preauthCaptureRequest) object containing the original pre-authorization GUID and the amount to capture. |
-Typical fields in the request body (see [BatchSummaryRequest](restobjects#batchSummaryRequest) for full details):
+Typical fields in the request body (see [PreauthCaptureRequest](restobjects#preauthCaptureRequest) for full details):
-- `deviceType` Required – Terminal model identifier (for example, `"PAXA920MAX"`).
-- `serialNumber` Required – Serial number of the payment terminal (for example, `"2740013262"`).
-- `batchNumber` Required – Identifier of the batch whose summary is being requested (for example, `"1"`).
+- `originalGuid` Required – GUID of the original pre-authorization transaction.
+- `capturedAmount` Required – Amount to capture and charge (for example, `"120.00"`).
+- `tipAmount` Optional – Tip amount to include in the captured total (for example, `"5.00"`).
+- `customerReference` Optional – Integrator-defined reference, forwarded as-is to the gateway.
#### Returns
| Result | Notes |
| ------ | ----- |
-| `200` | Batch summary successfully retrieved. The response body is a [BatchSummaryResponse](restobjects#batchSummaryResponse) with batch status, transaction counts, net amount and optional custom fields. |
-| `400` | Business / lookup error (for example, the batch cannot be summarised for the given terminal). Returned as `BadRequestError`, with `error.code`, `error.message` and optional `error.details`. |
-| `422` | Payload validation error (`VALIDATION_FAILED`) when required fields are missing or do not match the schema (for example, missing `batchNumber`). |
-| `5xx` | Internal error or service unavailability. The batch itself is not modified; the integrator may retry later or reconcile through other means. |
+| `200` | Pre-authorization capture accepted. Response body is a parsed gateway object. |
+| `400` | Business rule error from the gateway (for example, unknown `originalGuid`, pre-authorization already captured, or captured amount exceeds authorized amount). Returned as `BadRequestError` with `error.code` and `error.details`. |
+| `403` | Forbidden — the API key does not belong to a merchant. Partner keys are not accepted by this endpoint. |
+| `422` | Payload validation error (`VALIDATION_FAILED`) — `originalGuid` or `capturedAmount` is missing. |
**Code Example**
**Requests**
-
+
```shell
curl -X POST \
-H "Content-Type: application/json" \
-H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
-d '{
- "deviceType": "PAXA920MAX",
- "serialNumber": "2740013262",
- "batchNumber": "1"
+ "originalGuid": "0c9d9df0-48ec-11eb-81a1-470a19c80d3a",
+ "capturedAmount": "120.00"
}' \
- "https://cloud.handpoint.io/batch/summary"
+ "https://cloud.handpoint.io/preauthorization/capture"
```
-
+
```shell
curl -X POST \
-H "Content-Type: application/json" \
-H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
-d '{
- "deviceType": "PAXA920MAX",
- "serialNumber": "2740013262"
+ "originalGuid": "0c9d9df0-48ec-11eb-81a1-470a19c80d3a",
+ "capturedAmount": "120.00",
+ "tipAmount": "5.00",
+ "customerReference": "hotel-folio-4422"
}' \
- "https://cloud.handpoint.io/batch/summary"
+ "https://cloud.handpoint.io/preauthorization/capture"
```
@@ -1942,129 +1741,140 @@ curl -X POST \
```json
{
- "batchNumber": "1",
- "batchStatus": "CLOSED",
- "batchSummaryGuid": "61573ba0-08ac-11f1-b002-eb225f134f40",
- "customFields": {
- "entry": [
- {
- "key": "salesCount",
- "value": "155"
- },
- {
- "key": "refundsCount",
- "value": "3"
- },
- {
- "key": "issuerBatchCloseLocalTimestamp",
- "value": "2025-12-05T11:00:00"
- }
- ]
- },
- "httpStatus": "200",
- "issuerResponseCode": "00",
- "issuerResponseText": "DATA RETRIEVED",
- "netAmount": "245.00",
- "transactionCount": "158"
+ "httpStatus": 200,
+ "customFields": {
+ "tenderType": "Credit",
+ "RRN": "513815902180",
+ "issuerResponseCode": "200"
+ },
+ "acquirerTid": "0821599465",
+ "actionCode": "0000",
+ "agreementNumber": "123456789010102",
+ "approvalCode": "010119",
+ "batchNumber": "1",
+ "cardTypeName": "VISA",
+ "currency": "USD",
+ "expiryDateMMYY": "1027",
+ "holdAmount": "102.00",
+ "issuerResponseCode": "00",
+ "issuerResponseText": "COMPLETED",
+ "maskedCardNumber": "************0936",
+ "nonce": "1776156307790",
+ "originalAmount": "1.00",
+ "preAuthorizationGuid": "664ec4c0-37e6-11f1-bc66-3114cb76dabf",
+ "serverDateTime": "20260414094532102",
+ "terminalDateTime": "20260414094532085",
+ "transNumber": "000001",
+ "capturedAmount": "100.00",
+ "preAuthorizationCaptureGuid": "adad5660-37e6-11f1-9d29-81969834b189"
}
```
-Key fields:
-
-* `batchStatus` – Current status of the batch (for example, `"CLOSED"`).
-* `transactionCount` – Total number of transactions in the batch.
-* `netAmount` – Net amount for the batch in major units as a string (for example, `"245.00"`).
-* `customFields.entry` – Optional list of key/value pairs with acquirer-specific metrics (for example, `salesCount`, `refundsCount`, `issuerBatchCloseLocalTimestamp`).
-
-
```json
{
"error": {
+ "statusCode": 422,
+ "name": "UnprocessableEntityError",
+ "message": "The request body is invalid.",
"code": "VALIDATION_FAILED",
"details": [
{
+ "path": "",
"code": "required",
- "info": {
- "missingProperty": "batchNumber"
- },
- "message": "must have required property 'batchNumber'",
- "path": ""
+ "message": "must have required property 'capturedAmount'",
+ "info": { "missingProperty": "capturedAmount" }
}
- ],
- "message": "The request body is invalid. See error object `details` property for more info.",
- "name": "UnprocessableEntityError",
- "statusCode": 422
+ ]
}
}
```
-
-### Batch Detail
+## **MOTO Operations**
-`BatchDetail`
-A Batch Detail allows the user to retrieve information about a specific batch (including a list of transacctions) included in the batch for a specific payment terminal.
+`MOTO (Mail Order / Telephone Order)` operations can also be processed **without a payment reader**, using information
+that is already stored in the gateway (tokens and references to previous transactions).
-`POST /batch/detail` is used to retrieve information about a specific batch (including a list of transacctions) included in the batch for a specific payment terminal, identified by its
-`deviceType`, `serialNumber`, `batchNumber` and `RRN`.
+These endpoints are intended for MOTO scenarios where the merchant does **not** need to collect or handle sensitive
+card data (PAN, expiry date, CVV) in their own systems:
+
+- `/moto/sale` performs a sale using a **previously generated card token** (`cardToken`) that represents card details stored in the gateway.
+- `/moto/refund` performs a refund of a **previous operation**, using the card associated with that original operation (`originalGuid`).
+- `/moto/reversal` performs a reversal (void) of a **previous operation**, passing only its identifier (`originalGuid`).
+
+:::tip
+Unlike the standard MOTO operations that use `/transactions` and a physical terminal, these endpoints:
+
+- Do **not** require `serial_number` or `terminal_type`.
+- Do **not** receive raw card data in the request.
+- Rely on `cardToken` and `originalGuid` to reference card information already stored in the gateway.
+:::
+
+All request and response payloads are defined in the corresponding [Moto objects](restobjects#moto).
+
+---
+
+### MOTO Sale
+
+`MotoSale`
+
+`POST /moto/sale` is used to perform a **MOTO sale without a payment reader**, using a **card token** (`cardToken`)
+that was generated previously (for example, by a `saleAndTokenizeCard` operation).
+
+The card details are *not* sent in the request; they are resolved by the gateway using the `cardToken`.
+
+Typical flow:
+
+1. A card is captured securely in a previous flow, for example through the [`/transactions`](restendpoints#transactions) endpoint using a
+ `saleAndTokenizeCard` operation.
+2. The gateway returns a `cardToken` (e.g. `665630867`).
+3. The integrator can later perform one or more MOTO sales using that `cardToken`, without handling PAN/CVV again.
#### Parameters
| Parameter | Notes |
| --------- | ----- |
-| `Header: ApiKeyCloud` Required | Cloud API key used to authenticate the merchant. |
-| `Request Body: BatchDetailRequest` Required | [BatchDetailRequest](restobjects#batchDetailRequest) object containing `deviceType`, `serialNumber`, `batchNumber` and `rrn`. |
+| `Header: ApiKeyCloud` Required | Cloud API key used to authenticate the merchant. |
+| `Request Body: MotoSaleRequest` Required | [MotoSaleRequest](restobjects#motoSaleRequest) object containing `cardToken`, `amount`, `currency` and optional merchant references. |
-Typical fields in the request body (see [BatchDetailRequest](restobjects#batchDetailRequest) for full details):
+Typical fields in the request body (see [MotoSaleRequest](restobjects#motoSaleRequest) for full details):
-- `deviceType` Required – Terminal model identifier (for example, `"PAXA920MAX"`).
-- `serialNumber` Required – Serial number of the payment terminal (for example, `"2740013262"`).
-- `batchNumber` Required – Identifier of the batch whose summary is being requested (for example, `"1"`).
-- `rrn` Optional – Retrieval Reference Number, unique number assigned by the acquirer (for example, `"123"`).
+- `cardToken` Required – Token representing the card stored in the gateway (e.g. `"665630867"`).
+- `amount` Required – String amount in MAJOR units (e.g. `"20.00"` for 20.00). Must be a positive integer string.
+- `currency` Required – 3-character ISO 4217 currency code (e.g. `"EUR"`).
+- Optional references for reconciliation: `customerReference`, `transactionReference`, etc.
#### Returns
| Result | Notes |
| ------ | ----- |
-| `200` | Batch detail successfully retrieved. The response body is a [BatchDetailResponse](restobjects#batchDetailResponse) with batch status and optional details fields. |
-| `400` | Business / lookup error (for example, the batch cannot be summarised for the given terminal). Returned as `BadRequestError`, with `error.code`, `error.message` and optional `error.details`. |
-| `422` | Payload validation error (`VALIDATION_FAILED`) when required fields are missing or do not match the schema (for example, missing `batchNumber`). |
-| `5xx` | Internal error or service unavailability. The batch itself is not modified; the integrator may retry later or reconcile through other means. |
-
-**Code Example**
-
-**Requests**
-
-
-
+| `200` | Sale successfully processed. The response body is a `motoSaleResponse` [Moto Transaction Response](restobjects#motoTransactionResponse) with the authorization result (approved/declined), authorization code, masked card details, acquirer TID, timestamps, etc. |
+| `400` | Business rule error from the payment gateway (for example, CVV required, card token failure). Returned as `BadRequestError`, with `error.code` and `error.details` containing the gateway error code and description. |
+| `422` | Payload validation error (`VALIDATION_FAILED`) when required fields are missing or do not match the schema (invalid amount (must be a positive integer string in minor units), currency length, etc.). |
+| `5xx` | Internal error or gateway unavailability. The final outcome may be unknown and may require reconciliation. |
-```shell
-curl -X POST \
- -H "Content-Type: application/json" \
- -H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
- -d '{
- "deviceType": "PAXA920MAX",
- "serialNumber": "2740013262",
- "batchNumber": "1"
- }' \
- "https://cloud.handpoint.io/batch/detail"
-```
+#### Code Example
-
-
+**Requests**
+
+
+
```shell
curl -X POST \
-H "Content-Type: application/json" \
-H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
-d '{
- "deviceType": "PAXA920MAX",
- "serialNumber": "2740013262"
+ "amount": "20.00", // 20 => 20.00
+ "currency": "EUR",
+ "cardToken": "665630867",
+ "customerReference": "order-12345",
+ "transactionReference": "b7b2360d-3e9e-4b62-9a3a-2e6ef6c5cd01"
}' \
- "https://cloud.handpoint.io/batch/detail"
+ "https://cloud.handpoint.io/moto/sale"
```
@@ -2073,43 +1883,48 @@ curl -X POST \
**Responses**
-
+
```json
{
- "httpStatus": "200",
- "batchNumber": "1",
- "closedAt": "20260213135114884",
- "issuerResponseCode": "00",
- "issuerResponseText": "Batch detail retrieved",
- "details": [
- {
- "transactionType": "SALE",
- "amount": "100.00",
- "batchDetailElementGuid": "2fac8676-396a-4cf1-a5ab-650f3f79e923"
- },
- {
- "transactionType": "SALE",
- "retrievalReferenceNumber": "RRN08236",
- "amount": "50.00",
- "batchDetailElementGuid": "dcb718ef-59f0-4de8-b414-41048782aff9"
- },
- {
- "transactionType": "REFUND",
- "retrievalReferenceNumber": "RRN08237",
- "amount": "25.00",
- "batchDetailElementGuid": "d1a7ef06-c429-4a57-a07b-b461482bcafa"
+ "error": {
+ "statusCode": 400,
+ "name": "BadRequestError",
+ "message": "CVV required",
+ "code": "3107",
+ "details": {
+ "errorGuid": "dae59b20-cf71-11f0-b588-a122fae316de",
+ "errorCode": "3107",
+ "description": "CVV required",
+ "httpStatus": 400
}
- ],
- "batchDetailGuid": "10360390-08e4-11f1-8bbe-a982e87fcbf2",
- "batchStatus": "CLOSED"
+ }
}
```
-Key fields:
+:::note
+A very common cause of **3107** is having "CVV/CV2 input mandatory" enabled for Card Not Present.
+:::
-* `batchStatus` – Current status of the batch (for example, `"CLOSED"`).
-* `details.entry` – Optional list with transaction info (for example, `transactionType`, `amount`, `retrievalReferenceNumber`, `batchDetailElementGuid`).
+
+
+
+```json
+{
+ "error": {
+ "code": "5252",
+ "details": {
+ "description": "Card token failure",
+ "errorCode": "5252",
+ "errorGuid": "10a3d120-cf75-11f0-95b2-770b7d1d8e67",
+ "httpStatus": 404
+ },
+ "message": "Card token failure",
+ "name": "BadRequestError",
+ "statusCode": 400
+ }
+}
+```
@@ -2122,9 +1937,9 @@ Key fields:
{
"code": "required",
"info": {
- "missingProperty": "batchNumber"
+ "missingProperty": "amount"
},
- "message": "must have required property 'batchNumber'",
+ "message": "must have required property 'amount'",
"path": ""
}
],
@@ -2138,76 +1953,60 @@ Key fields:
+---
-## Device Control Commands
-
-> **Note:**
-> The following commands are available for all devices running Android SDK version 7.1006.0 or later.
-
-Command Endpoint Format
-
-All device control commands follow this endpoint structure:
-```https://cloud.handpoint.io/devices/{deviceType}/{serialNumber}/{command}```
-
-Where:
-- `{deviceType}` is the type of the device (e.g., PAXIM30)
-- `{serialNumber}` is the serial number of the device (e.g., 1640013848)
-- `{command}` is the specific command to execute
-
-Common Parameters
-
-All commands share these common parameters:
-
-| Parameter | Notes |
-| ----------- | ----------- |
-| `Header: ApiKeyCloud` Required
*String* | Api key used to authenticate the merchant. (UNIQUE per Merchant) |
-| `Header: Content-Type` Required
*String* | Must be set to `application/json` |
+### MOTO Refund
-Common Response Codes
+`MotoRefund`
-| Response Code | Description |
-|--------------|-------------|
-| 202 | Request accepted, command will be executed |
-| 403 | Authentication failed |
-| 422 | Invalid request |
-| 400 | Invalid parameter value (when applicable) |
+`POST /moto/refund` is used to perform a **MOTO refund without a payment reader**.
----
+The refund is **linked** to a previous MOTO sale via `originalGuid`, and the gateway reuses the card associated with that
+original transaction. No card data is passed in the refund request.
-:::caution
-For the Commands to work properly, the Handpoint Payments App **MUST** be in **Integrated Mode** (enabled via **Handpoint TMS** and controlled by the merchant in the **Handpoint Payments App** Settings).
-:::
+#### Parameters
-### Set Unattended Mode
+| Parameter | Notes |
+| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------- |
+| `Header: ApiKeyCloud` Required | Cloud API key used to authenticate the merchant. |
+| `Request Body: MotoRefundRequest` Required | [MotoRefundRequest](restobjects#motoRefundRequest) object containing `originalGuid`, `amount`, `currency` and optional merchant references. |
-`POST /devices/{deviceType}/{serialNumber}/set-unattended-mode`
+Typical fields (see [MotoRefundRequest](restobjects#motoRefundRequest) for full details):
-Enables or disables unattended mode on the device.
-Unattended mode will disable the Bottom navigation bar containing the Home, back, recent buttons.
-The Payment screen will be the only visible screen in the Handpoint Payments App. (Settings, Hisotry and Analytic tabs will not be accessible)
+* `originalGuid` Required – GUID of the original sale to be refunded (e.g. `"1a41d9f0-cf72-11f0-95b2-770b7d1d8e67"`).
+* `amount` Required – String amount to be refunded in MAJOR units (e.g. `"5.00"` for $5.00). Must be a positive integer string.
+* `currency` Required – 3-character ISO 4217 code (e.g. `"EUR"`, `"USD"`).
+* Optional: `customerReference`, `transactionReference`.
+Supports full and partial refunds, depending on acquirer configuration.
-**Request Body Parameters**
+#### Returns
-| Parameter | Type | Description |
-|-----------|------|-------------|
-| `status` | boolean | `true` to enable unattended mode, `false` to disable |
+| Result | Notes |
+| ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `200` | Refund successfully processed. The response body is a `motoRefundResponse` [Moto Transaction Response](restobjects#motoTransactionResponse) including `guid`, `originalGuid`, `amount`, `currency`, `maskedCardNumber`, `approvalCode`, `issuerResponseText`, etc. |
+| `400` | Business rule error from the payment gateway (for example, currency mismatch, refund amount greater than the original sale). Returned as `BadRequestError`, with `error.code` and `error.details` describing the gateway error. |
+| `422` | Payload validation error (`VALIDATION_FAILED`) when required fields are missing or invalid (missing `originalGuid`, invalid amount, invalid currency format, etc.). |
-**Example Request**
+#### Code Example
**Requests**
-
+
```shell
curl -X POST \
- -H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
-H "Content-Type: application/json" \
+ -H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
-d '{
- "status": false
+ "originalGuid": "1a41d9f0-cf72-11f0-95b2-770b7d1d8e67",
+ "amount": "5.00", // 5 => 5.00
+ "currency": "EUR",
+ "customerReference": "refund-98765",
+ "transactionReference": "a1fe8db5-69a4-4b4d-a704-94ac2570f9b0"
}' \
- "https://cloud.handpoint.io/devices/PAXIM30/0000000000/set-unattended-mode"
+ "https://cloud.handpoint.io/moto/refund"
```
@@ -2216,130 +2015,107 @@ curl -X POST \
**Responses**
-
-
-No response body is returned.
-
-
-
+
```json
{
- "error": {
- "statusCode": 400,
- "name": "BadRequestError",
- "message": {
- "error": 1002,
- "message": "No device listening at the other end of the secure channel"
- }
- }
+ "error": {
+ "code": "3210",
+ "details": {
+ "description": "Original and linked currency do not match",
+ "errorCode": "3210",
+ "errorGuid": "35a2b220-cf7a-11f0-b588-a122fae316de",
+ "httpStatus": 400
+ },
+ "message": "Original and linked currency do not match",
+ "name": "BadRequestError",
+ "statusCode": 400
+ }
}
```
-
-
-
-### Set Locale
-
-`POST /devices/{deviceType}/{serialNumber}/set-locale`
-
-Sets the locale of the target device.
-
-**Request Body Parameters**
-
-| Parameter | Type | Description |
-|-----------|--------|-----------------------------------------------------------------------------|
-| `locale` | string | IETF BCP 47 language tag (e.g., `en_US`). Two-letter language and country code.|
-
-**Response Codes**
-
-| Code | Description |
-|------|---------------------------------------------|
-| 202 | The request is accepted and will be executed|
-| 403 | Authentication failed |
-| 422 | Invalid request |
-
-**Example Request**
-
-**Requests**
-
-
-
-
-```shell
-curl -X POST \
- -H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
- -H "Content-Type: application/json" \
- -d '{
- "locale": "en_CA"
- }' \
- "https://cloud.handpoint.io/devices/PAXIM30/0000000000/set-locale"
-```
-
-
-
-
-**Responses**
-
-
-
-
-No response body is returned.
-
+
```json
{
- "error": {
- "statusCode": 400,
- "name": "BadRequestError",
- "message": {
- "error": 1002,
- "message": "No device listening at the other end of the secure channel"
- }
- }
+ "error": {
+ "code": "3209",
+ "details": {
+ "description": "The requested refund amount is greater than the initial sale amount",
+ "errorCode": "3209",
+ "errorGuid": "e72ea940-cf7a-11f0-b588-a122fae316de",
+ "httpStatus": 400
+ },
+ "message": "The requested refund amount is greater than the initial sale amount",
+ "name": "BadRequestError",
+ "statusCode": 400
+ }
}
```
+
+
+
+
+Missing `originalGuid`, missing `amount`, invalid `currency` length, or invalid `amount` pattern — returned as `422 VALIDATION_FAILED` with one or more entries in `error.details`.
+
---
-### Set Password Protected
+### MOTO Reversal
-`POST /devices/{deviceType}/{serialNumber}/set-password-protected`
+`MotoReversal`
-Enables or disables password protection on the device.
+`POST /moto/reversal` is used to **reverse (void)** a previous MOTO operation processed via the no-reader MOTO endpoints.
-**Request Body Parameters**
+The request is linked to the original sale via `originalGuid`. No card data is sent; the gateway uses the original
+transaction information.
-| Parameter | Type | Description |
-|-----------|---------|-----------------------------------------------------|
-| `status` | boolean | `true` to enable password protection, `false` to disable |
+Reversals are typically used to cancel a MOTO sale shortly after authorization, subject to acquirer rules.
-**Response Codes**
+#### Parameters
-| Code | Description |
-|------|---------------------------------------------|
-| 202 | The request is accepted and will be executed|
-| 403 | Authentication failed |
-| 422 | Invalid request |
+| Parameter | Notes |
+| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
+| `Header: ApiKeyCloud` Required | Cloud API key used to authenticate the merchant. |
+| `Request Body: MotoReversalRequest` Required | [MotoReversalRequest](restobjects#motoReversalRequest) object referencing the original MOTO transaction (`originalGuid`) and including the reversal `amount` and `currency`. |
-**Example Request**
+Typical fields (see [MotoReversalRequest](restobjects#motoReversalRequest) for full details):
+
+* `originalGuid` Required – GUID of the original sale to be reversed.
+* `amount` Required – String amount to reverse in MAJOR units (e.g. `"20.00"` for $20.00). Must be a positive integer string.
+* `currency` Optional – 3-character ISO 4217 code; if provided, must respect `minLength = 3`, `maxLength = 3` and may need to match the original transaction’s currency.
+* Optional merchant references: `customerReference`, `transactionReference`.
+
+#### Returns
+
+| Result | Notes |
+| ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `200` | Reversal accepted and processed. Response body is a `motoReversalResponse` [Moto Transaction Response](restobjects#motoTransactionResponse) indicating whether the reversal was approved, with fields such as `guid`, `originalGuid`, `issuerResponseCode`, `issuerResponseText`, `f25`, etc. |
+| `400` | Business rule error from the payment gateway (for example, unknown `originalGuid`, reversal not allowed). Returned as `BadRequestError`, with `error.code` and `error.details` describing the gateway error (for example, code `3153`). |
+| `422` | Payload validation error (`VALIDATION_FAILED`) when required fields are missing or invalid (missing `originalGuid`, missing `amount`, invalid `currency`, invalid `amount` pattern). |
+
+#### Code Example
**Requests**
-
+
```shell
curl -X POST \
- -H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
-H "Content-Type: application/json" \
+ -H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
-d '{
- "status": true
+ "originalGuid": "b28bdb10-cf87-11f0-b588-a122fae316de",
+ "amount": "20.00", //20 => 20.00 || 2000 => 2000.00
+ "currency": "EUR",
+ "customerReference": "void-001",
+ "transactionReference": "4d7b1a2c-5bfd-4a30-9b6f-123456789abc"
}' \
- "https://cloud.handpoint.io/devices/PAXIM30/0000000000/set-password-protected"
+ "https://cloud.handpoint.io/moto/reversal"
```
@@ -2348,65 +2124,142 @@ curl -X POST \
**Responses**
-
+
-No response body is returned.
+```json
+{
+ "type": "motoReversalResponse",
+ "httpStatus": 200,
+ "amount": "20.00",
+ "currency": "EUR",
+ "guid": "3f7772a0-cf88-11f0-b588-a122fae316de",
+ "originalGuid": "b28bdb10-cf87-11f0-b588-a122fae316de",
+ "issuerResponseCode": "00",
+ "issuerResponseText": "Successful",
+ "maskedCardNumber": "************3555",
+ "f25": "4000"
+}
+```
-
+
```json
{
- "error": {
- "statusCode": 400,
- "name": "BadRequestError",
- "message": {
- "error": 1002,
- "message": "No device listening at the other end of the secure channel"
- }
- }
+ "error": {
+ "code": "3153",
+ "details": {
+ "description": "Unable to find message to reverse.",
+ "errorCode": "3153",
+ "errorGuid": "633a4370-cf88-11f0-b588-a122fae316de",
+ "httpStatus": 404
+ },
+ "message": "Unable to find message to reverse.",
+ "name": "BadRequestError",
+ "statusCode": 400
+ }
}
```
+
+
+
+
+Missing `originalGuid`, missing `amount`, invalid `currency` length, or invalid `amount` pattern — returned as `422 VALIDATION_FAILED` with one or more entries in `error.details`.
+
+## Batch Operations Beta {#batch-operations}
+
+:::info
+Batch Operations are not available for all acquirers. Contact your Handpoint relationship manager to find out if this feature is supported for your acquirer.
+:::
+
+Batch operations allow you to remotely **manage batches on a specific payment terminal** using Cloud API.
+
+These endpoints are typically used in scenarios where the acquirer or merchant workflow is batch-based (for example,
+daily settlement batches per terminal).
+
+Cloud API currently supports the following batch operations:
+
+- `POST /batch/close` — requests the **closure of a batch** for a given terminal (`deviceType`, `serialNumber`).
+- `POST /batch/summary` — retrieves a **summary of a batch** for a given terminal (`deviceType`, `serialNumber`) and `batchNumber`.
+- `POST /batch/detail` — retrieves **batch detail** (including a list of transactions) for a given terminal (`deviceType`, `serialNumber`) and `batchNumber` (and optional `rrn`).
+
+
+All request and response payloads are defined in the corresponding [Batch objects](restobjects#batch).
+
+:::info
+In MOTO scenarios, the `deviceType` and `serialNumber` fields can refer to a **virtual terminal** (`VT`) instead of a physical device. Use `VT` as the `deviceType` and the serial number of the virtual terminal assigned to the merchant. The serial number of the virtual terminal can be retrieved from the response of the [/initialize](restendpoints#initialize) endpoint.
+:::
+
---
-### Reboot
+### Close Batch
-`POST /devices/{deviceType}/{serialNumber}/reboot`
+`BatchClose`
-Reboots the device with an optional force parameter.
+`POST /batch/close` is used to request **closure of a batch** for a specific payment terminal, identified by its
+`deviceType` and `serialNumber`, and optionally a `batchNumber`.
-**Request Body Parameters**
+Typical use cases:
-| Parameter | Type | Description |
-|-----------|---------|-----------------------------------------------------------------------------|
-| `force` | boolean | `true` to force reboot even during transaction, `false` to check status first|
+- End-of-day batch closure triggered from a back-office or back-office job.
+- Manual batch close as part of a support or reconciliation process.
-**Response Codes**
+#### Parameters
-| Code | Description |
-|------|---------------------------------------------|
-| 202 | The request is accepted and will be executed|
-| 403 | Authentication failed |
-| 422 | Invalid request |
+| Parameter | Notes |
+| --------- | ----- |
+| `Header: ApiKeyCloud` Required | Cloud API key used to authenticate the merchant. |
+| `Request Body: BatchCloseRequest` Required | [BatchCloseRequest](restobjects#batchCloseRequest) object containing `deviceType`, `serialNumber` and `batchNumber`. |
-**Example Request**
+Typical fields in the request body (see [BatchCloseRequest](restobjects#batchCloseRequest) for full details):
+
+- `deviceType` Required – Terminal model identifier (for example, `"PAXA920MAX"`).
+- `serialNumber` Required – Serial number of the payment terminal (for example, `"2740013262"`).
+- `batchNumber` Optional – Identifier of the batch to close (for example, `"1"`), if not specified, the current open batch for that Terminal will be closed.
+
+#### Returns
+
+| Result | Notes |
+| ------ | ----- |
+| `200` | Batch close request accepted. The response body is a [BatchCloseResponse](restobjects#batchCloseResponse) with the batch number, a unique `closeBatchGuid`, timestamps and an issuer-style response code/text. |
+| `400` | Business rule error or generic gateway error. Returned as `BadRequestError`, with `error.code`, `error.message` and `error.details` describing the problem. |
+| `422` | Payload validation error (`VALIDATION_FAILED`) when required fields are missing or do not match the schema (for example, missing `serialNumber`). |
+| `5xx` | Internal error or service unavailability. The final outcome of the batch close may be unknown and may require reconciliation or a retry at a later time. |
+
+**Code Example**
**Requests**
-
+
```shell
curl -X POST \
+ -H "Content-Type: application/json" \
-H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
+ -d '{
+ "deviceType": "PAXA920MAX",
+ "serialNumber": "2740013262",
+ "batchNumber": "1"
+ }' \
+ "https://cloud.handpoint.io/batch/close"
+```
+
+
+
+
+```shell
+curl -X POST \
-H "Content-Type: application/json" \
+ -H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
-d '{
- "force": false
+ "deviceType": "PAXA920MAX",
+ "serialNumber": "2740013262"
}' \
- "https://cloud.handpoint.io/devices/PAXIM30/0000000000/reboot"
+ "https://cloud.handpoint.io/batch/close"
```
@@ -2415,68 +2268,135 @@ curl -X POST \
**Responses**
-
+
-No response body is returned.
+```json
+{
+ "batchNumber": "1",
+ "closeBatchGuid": "14431ad0-d0dc-11f0-9ed0-695d1a368668",
+ "closedAt": "20251204064010281",
+ "customerReference": {},
+ "httpStatus": "200",
+ "issuerResponseCode": "00",
+ "issuerResponseText": "ACCEPTED"
+}
+```
-
+
```json
{
- "error": {
- "statusCode": 400,
- "name": "BadRequestError",
- "message": {
- "error": 1002,
- "message": "No device listening at the other end of the secure channel"
+ "httpStatus": "200",
+ "customerReference": {},
+ "customFields": {
+ "entry": {
+ "key": "issuerBatchCloseLocalTimestamp",
+ "value": "2026-05-07T10:02:12"
}
- }
+ },
+ "batchNumber": "1",
+ "closeBatchGuid": "d1988a50-49fb-11f1-b64d-2969d719a012",
+ "closedAt": "20260507100212859",
+ "issuerResponseCode": "00",
+ "issuerResponseText": "ACCEPTED",
+ "batchStatus": "CLOSED"
+}
+```
+
+
+
+
+```json
+{
+ "error": {
+ "code": "VALIDATION_FAILED",
+ "details": [
+ {
+ "code": "required",
+ "info": {
+ "missingProperty": "batchNumber"
+ },
+ "message": "must have required property 'batchNumber'",
+ "path": ""
+ }
+ ],
+ "message": "The request body is invalid. See error object `details` property for more info.",
+ "name": "UnprocessableEntityError",
+ "statusCode": 422
+ }
}
```
+
----
+### Batch Summary
-### Set Screen Brightness
+`BatchSummary`
+
+`POST /batch/summary` is used to retrieve a **summary of a batch** for a specific payment terminal, identified by its
+`deviceType`, `serialNumber`, and `batchNumber`.
+
+Typical use cases:
+
+- Back-office reconciliation after a batch close.
+- Reporting and dashboards that need batch-level totals (number of transactions, net amount, status).
+- Support tools that need to check the status of a batch on a given terminal.
-`POST /devices/{deviceType}/{serialNumber}/set-screen-brightness`
+#### Parameters
-Sets the screen brightness levels.
+| Parameter | Notes |
+| --------- | ----- |
+| `Header: ApiKeyCloud` Required | Cloud API key used to authenticate the merchant. |
+| `Request Body: BatchSummaryRequest` Required | [BatchSummaryRequest](restobjects#batchSummaryRequest) object containing `deviceType`, `serialNumber` and `batchNumber`. |
-**Request Body Parameters**
+Typical fields in the request body (see [BatchSummaryRequest](restobjects#batchSummaryRequest) for full details):
-| Parameter | Type | Description |
-|--------------------------|---------|------------------------------------|
-| `minimumBrightnessLevel` | integer | Value between 0 and 100 |
-| `maximumBrightnessLevel` | integer | Value between 0 and 100 |
+- `deviceType` Required – Terminal model identifier (for example, `"PAXA920MAX"`).
+- `serialNumber` Required – Serial number of the payment terminal (for example, `"2740013262"`).
+- `batchNumber` Required – Identifier of the batch whose summary is being requested (for example, `"1"`).
-**Response Codes**
+#### Returns
-| Code | Description |
-|------|---------------------------------------------|
-| 202 | The request is accepted and will be executed|
-| 403 | Authentication failed |
-| 422 | Invalid request |
-| 400 | Value is outside the valid range |
+| Result | Notes |
+| ------ | ----- |
+| `200` | Batch summary successfully retrieved. The response body is a [BatchSummaryResponse](restobjects#batchSummaryResponse) with batch status, transaction counts, net amount and optional custom fields. |
+| `400` | Business / lookup error (for example, the batch cannot be summarised for the given terminal). Returned as `BadRequestError`, with `error.code`, `error.message` and optional `error.details`. |
+| `422` | Payload validation error (`VALIDATION_FAILED`) when required fields are missing or do not match the schema (for example, missing `batchNumber`). |
+| `5xx` | Internal error or service unavailability. The batch itself is not modified; the integrator may retry later or reconcile through other means. |
-**Example Request**
+**Code Example**
**Requests**
-
+
```shell
curl -X POST \
+ -H "Content-Type: application/json" \
-H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
+ -d '{
+ "deviceType": "PAXA920MAX",
+ "serialNumber": "2740013262",
+ "batchNumber": "1"
+ }' \
+ "https://cloud.handpoint.io/batch/summary"
+```
+
+
+
+
+```shell
+curl -X POST \
-H "Content-Type: application/json" \
+ -H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
-d '{
- "minimumBrightnessLevel": 20,
- "maximumBrightnessLevel": 100
+ "deviceType": "PAXA920MAX",
+ "serialNumber": "2740013262"
}' \
- "https://cloud.handpoint.io/devices/PAXIM30/0000000000/set-screen-brightness"
+ "https://cloud.handpoint.io/batch/summary"
```
@@ -2485,74 +2405,133 @@ curl -X POST \
**Responses**
-
+
-No response body is returned.
+```json
+{
+ "batchNumber": "1",
+ "batchStatus": "CLOSED",
+ "batchSummaryGuid": "61573ba0-08ac-11f1-b002-eb225f134f40",
+ "customFields": {
+ "entry": [
+ {
+ "key": "salesCount",
+ "value": "155"
+ },
+ {
+ "key": "refundsCount",
+ "value": "3"
+ },
+ {
+ "key": "issuerBatchCloseLocalTimestamp",
+ "value": "2025-12-05T11:00:00"
+ }
+ ]
+ },
+ "httpStatus": "200",
+ "issuerResponseCode": "00",
+ "issuerResponseText": "DATA RETRIEVED",
+ "netAmount": "245.00",
+ "transactionCount": "158"
+}
+```
+
+Key fields:
+
+* `batchStatus` – Current status of the batch (for example, `"CLOSED"`).
+* `transactionCount` – Total number of transactions in the batch.
+* `netAmount` – Net amount for the batch in major units as a string (for example, `"245.00"`).
+* `customFields.entry` – Optional list of key/value pairs with acquirer-specific metrics (for example, `salesCount`, `refundsCount`, `issuerBatchCloseLocalTimestamp`).
-
+
```json
{
- "error": {
- "statusCode": 400,
- "name": "BadRequestError",
- "message": {
- "error": 1002,
- "message": "No device listening at the other end of the secure channel"
- }
- }
+ "error": {
+ "code": "VALIDATION_FAILED",
+ "details": [
+ {
+ "code": "required",
+ "info": {
+ "missingProperty": "batchNumber"
+ },
+ "message": "must have required property 'batchNumber'",
+ "path": ""
+ }
+ ],
+ "message": "The request body is invalid. See error object `details` property for more info.",
+ "name": "UnprocessableEntityError",
+ "statusCode": 422
+ }
}
```
+
----
-
-### Set Reboot Time
+### Batch Detail
-:::note
-This feature is only enabled for production devices.
-:::
+`BatchDetail`
+A Batch Detail allows the user to retrieve information about a specific batch (including a list of transacctions) included in the batch for a specific payment terminal.
-`POST /devices/{deviceType}/{serialNumber}/set-reboot-time`
+`POST /batch/detail` is used to retrieve information about a specific batch (including a list of transacctions) included in the batch for a specific payment terminal, identified by its
+`deviceType`, `serialNumber`, `batchNumber` and `RRN`.
-Sets the daily reboot time for the device. The actual reboot will occur at a random minute within the specified hour.
+#### Parameters
-**Request Body Parameters**
+| Parameter | Notes |
+| --------- | ----- |
+| `Header: ApiKeyCloud` Required | Cloud API key used to authenticate the merchant. |
+| `Request Body: BatchDetailRequest` Required | [BatchDetailRequest](restobjects#batchDetailRequest) object containing `deviceType`, `serialNumber`, `batchNumber` and `rrn`. |
-| Parameter | Type | Description |
-|-----------|---------|-----------------------------------------------------|
-| `hour` | integer | Hour of the day (0-23) when device should reboot |
+Typical fields in the request body (see [BatchDetailRequest](restobjects#batchDetailRequest) for full details):
-:::tip
-If hour is set to 22, the device will reboot at a random time between 22:01 and 22:59.
-:::
+- `deviceType` Required – Terminal model identifier (for example, `"PAXA920MAX"`).
+- `serialNumber` Required – Serial number of the payment terminal (for example, `"2740013262"`).
+- `batchNumber` Required – Identifier of the batch whose summary is being requested (for example, `"1"`).
+- `rrn` Optional – Retrieval Reference Number, unique number assigned by the acquirer (for example, `"123"`).
-**Response Codes**
+#### Returns
-| Code | Description |
-|------|---------------------------------------------|
-| 202 | The request is accepted and will be executed|
-| 403 | Authentication failed |
-| 422 | Invalid request |
-| 400 | Value is outside the valid range |
+| Result | Notes |
+| ------ | ----- |
+| `200` | Batch detail successfully retrieved. The response body is a [BatchDetailResponse](restobjects#batchDetailResponse) with batch status and optional details fields. |
+| `400` | Business / lookup error (for example, the batch cannot be summarised for the given terminal). Returned as `BadRequestError`, with `error.code`, `error.message` and optional `error.details`. |
+| `422` | Payload validation error (`VALIDATION_FAILED`) when required fields are missing or do not match the schema (for example, missing `batchNumber`). |
+| `5xx` | Internal error or service unavailability. The batch itself is not modified; the integrator may retry later or reconcile through other means. |
-**Example Request**
+**Code Example**
**Requests**
-
+
```shell
curl -X POST \
+ -H "Content-Type: application/json" \
-H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
+ -d '{
+ "deviceType": "PAXA920MAX",
+ "serialNumber": "2740013262",
+ "batchNumber": "1"
+ }' \
+ "https://cloud.handpoint.io/batch/detail"
+```
+
+
+
+
+```shell
+curl -X POST \
-H "Content-Type: application/json" \
+ -H "ApiKeyCloud: XXXXXXX-XXXXXXX-XXXXXXX-XXXXXXX" \
-d '{
- "hour": 22
+ "deviceType": "PAXA920MAX",
+ "serialNumber": "2740013262"
}' \
- "https://cloud.handpoint.io/devices/PAXIM30/0000000000/set-reboot-time"
+ "https://cloud.handpoint.io/batch/detail"
```
@@ -2561,24 +2540,67 @@ curl -X POST \
**Responses**
-
+
-No response body is returned.
+```json
+{
+ "httpStatus": "200",
+ "batchNumber": "1",
+ "closedAt": "20260213135114884",
+ "issuerResponseCode": "00",
+ "issuerResponseText": "Batch detail retrieved",
+ "details": [
+ {
+ "transactionType": "SALE",
+ "amount": "100.00",
+ "batchDetailElementGuid": "2fac8676-396a-4cf1-a5ab-650f3f79e923"
+ },
+ {
+ "transactionType": "SALE",
+ "retrievalReferenceNumber": "RRN08236",
+ "amount": "50.00",
+ "batchDetailElementGuid": "dcb718ef-59f0-4de8-b414-41048782aff9"
+ },
+ {
+ "transactionType": "REFUND",
+ "retrievalReferenceNumber": "RRN08237",
+ "amount": "25.00",
+ "batchDetailElementGuid": "d1a7ef06-c429-4a57-a07b-b461482bcafa"
+ }
+ ],
+ "batchDetailGuid": "10360390-08e4-11f1-8bbe-a982e87fcbf2",
+ "batchStatus": "CLOSED"
+}
+```
+
+Key fields:
+
+* `batchStatus` – Current status of the batch (for example, `"CLOSED"`).
+* `details.entry` – Optional list with transaction info (for example, `transactionType`, `amount`, `retrievalReferenceNumber`, `batchDetailElementGuid`).
-
+
```json
{
- "error": {
- "statusCode": 400,
- "name": "BadRequestError",
- "message": {
- "error": 1002,
- "message": "No device listening at the other end of the secure channel"
- }
- }
+ "error": {
+ "code": "VALIDATION_FAILED",
+ "details": [
+ {
+ "code": "required",
+ "info": {
+ "missingProperty": "batchNumber"
+ },
+ "message": "must have required property 'batchNumber'",
+ "path": ""
+ }
+ ],
+ "message": "The request body is invalid. See error object `details` property for more info.",
+ "name": "UnprocessableEntityError",
+ "statusCode": 422
+ }
}
```
+
-
+
\ No newline at end of file