> ## Documentation Index
> Fetch the complete documentation index at: https://vivawallet-sdk-docs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Cloud Terminal and Standard POS Helpers

> Use Cloud Terminal tokens and the standard Vivawallet POS helper modules to search devices, initiate POS transactions, retrieve sessions, and abort sessions.

The VivaWallet Cloud Terminal / ECR API lets a backend send card-present payment requests to physical POS terminals. The SDK exposes two layers for standard merchant integrations:

* `getCloudTerminalAccessToken()` returns Viva's raw Cloud Terminal token response so you can manage caching yourself.
* `vivawallet.pos` wraps common Cloud Terminal operations and requests a Cloud Terminal token internally for each SDK call.

<Note>
  Cloud Terminal credentials are separate from SmartCheckout credentials in many Viva setups. Use the Client ID and Client Secret intended for POS / Cloud Terminal access when calling these helpers.
</Note>

## Get a Cloud Terminal Access Token

Call `getCloudTerminalAccessToken()` when you need to call a Cloud Terminal endpoint not yet wrapped by the SDK.

```typescript theme={null}
const tokenResult = await vivawallet.getCloudTerminalAccessToken();

if (tokenResult.success && tokenResult.data) {
  const { access_token, expires_in } = tokenResult.data;
  console.log(access_token, expires_in);
}
```

Internally, this calls `POST /connect/token` with `grant_type=client_credentials`. The SDK does **not** cache this token; reuse it until `expires_in` seconds have elapsed, then request a new one.

A simple token-caching wrapper:

```typescript theme={null}
let cachedToken: string | null = null;
let tokenExpiry = 0;

async function getActiveCloudTerminalToken(): Promise<string> {
  const now = Math.floor(Date.now() / 1000);

  if (cachedToken && now < tokenExpiry - 30) {
    return cachedToken;
  }

  const result = await vivawallet.getCloudTerminalAccessToken();

  if (!result.success || !result.data) {
    throw new Error(result.message);
  }

  cachedToken = result.data.access_token;
  tokenExpiry = now + result.data.expires_in;

  return cachedToken;
}
```

## Standard POS Module

`vivawallet.pos` groups standard merchant Cloud Terminal helpers into three submodules:

| Module                        | Methods                                                                                                                                                               |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `vivawallet.pos.devices`      | `searchDevices(options?)`                                                                                                                                             |
| `vivawallet.pos.transactions` | `initiateSaleRequest()`, `capturePreAuthRequest()`, `refundTransaction()`, `unreferencedRefund()`, `fastRefund()`, `rebate()`, `createAction()`, `getActionDetails()` |
| `vivawallet.pos.session`      | `retrieveSessionById()`, `retrieveSessionInfoByDate()`, `abortSession()`                                                                                              |

Each wrapped method internally calls `getCloudTerminalAccessToken()` and returns the SDK's normal `MethodReturn` result. These calls do not share a token cache; add your own wrapper if your application needs token reuse across many POS requests.

## Search POS Devices

Use `searchDevices(options?)` to list terminals available to the merchant credentials. You can filter by `statusId` or `sourceCode`.

```typescript theme={null}
const devices = await vivawallet.pos.devices.searchDevices({
  statusId: 1,
  sourceCode: 'STORE-ATHENS',
});

if (devices.success && devices.data) {
  for (const device of devices.data) {
    console.log(device.terminalId, device.sourceCode, device.statusId);
  }
}
```

Use `terminalId` from this response when creating sale, refund, action, or session-related requests.

## Initiate a Sale Request

Use `initiateSaleRequest(options)` to send a payment request to a terminal. The SDK returns `data: null` when Viva accepts the asynchronous request; use session retrieval or webhooks to observe the final result.

```typescript theme={null}
const result = await vivawallet.pos.transactions.initiateSaleRequest({
  sessionId: 'session-1234',
  terminalId: 'terminal-1234',
  cashRegisterId: 'register-1',
  amount: 1000,
  currencyCode: '978',
  merchantReference: 'order-1234',
  customerTrns: 'Order #1234',
  showTransactionResult: true,
  showReceipt: true,
  tipAmount: 0,
});

if (!result.success) {
  throw new Error(result.message);
}
```

## POS Transaction Operations

The transaction helpers share the same base POS request shape: `sessionId`, `terminalId`, `cashRegisterId`, `amount`, `currencyCode`, and `merchantReference`, plus operation-specific fields.

| Method                           | Use                                                           |
| -------------------------------- | ------------------------------------------------------------- |
| `capturePreAuthRequest(options)` | Capture a previous pre-authorization; pass `parentSessionId`. |
| `refundTransaction(options)`     | Refund a referenced transaction; pass `parentSessionId`.      |
| `unreferencedRefund(options)`    | Send a refund request not tied to a previous session.         |
| `fastRefund(options)`            | Send a fast refund request through Cloud Terminal.            |
| `rebate(options)`                | Send a rebate request through Cloud Terminal.                 |

```typescript theme={null}
await vivawallet.pos.transactions.refundTransaction({
  sessionId: 'refund-session-1234',
  parentSessionId: 'sale-session-1234',
  terminalId: 'terminal-1234',
  cashRegisterId: 'register-1',
  amount: 1000,
  currencyCode: '978',
  merchantReference: 'refund-order-1234',
});
```

## Terminal Actions

Use `createAction(options)` for terminal actions such as `aade-fim-control`, then retrieve the action status with `getActionDetails(options)`.

```typescript theme={null}
const action = await vivawallet.pos.transactions.createAction({
  terminalId: 'terminal-1234',
  cashRegisterId: 'register-1',
  actionType: 'aade-fim-control',
  request: {
    command: 'status',
  },
});

if (action.success && action.data) {
  const details = await vivawallet.pos.transactions.getActionDetails({
    actionId: action.data.actionId,
  });

  console.log(details.data?.successfullyProcessed);
}
```

## Retrieve and Abort Sessions

Retrieve one POS session by ID:

```typescript theme={null}
const session = await vivawallet.pos.session.retrieveSessionById({
  sessionId: 'session-1234',
});

if (session.success && session.data) {
  console.log(session.data.transactionId, session.data.success);
}
```

List sessions for a date:

```typescript theme={null}
const sessions = await vivawallet.pos.session.retrieveSessionInfoByDate({
  date: '2026-07-03',
  AadeAutonomouslyOnly: false,
});
```

Abort an active session:

```typescript theme={null}
await vivawallet.pos.session.abortSession({
  sessionId: 'session-1234',
  cashRegisterId: 'register-1',
});
```

## ISV POS

For ISV integrations, use the `VivaISV` POS module instead. See [ISV POS](/guides/isv-pos) for `vivaIsv.pos.devices`, `vivaIsv.pos.transactions`, and `vivaIsv.pos.session` examples.

## Webhook Follow-up

Cloud Terminal sessions can be followed through POS session webhooks. Use `validateVivaPosSessionWebhook()` from the [Webhook Helpers](/guides/webhook-helpers#pos-and-operational-validators) guide when processing POS ECR session created or failed notifications.
