Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
e5d7b81
Add Cloud device models
gcatanese Aug 20, 2025
f263182
Add new models
gcatanese Aug 21, 2025
f21c8bb
Add Cloud device config
gcatanese Aug 21, 2025
ecee364
Add Cloud device API endpoint setup
gcatanese Aug 21, 2025
c544349
Add Cloud device service
gcatanese Aug 21, 2025
83fd646
Cloud device tests, refactoring Terminal API tests
gcatanese Aug 21, 2025
3d497d2
Update src/config.ts
gcatanese Aug 21, 2025
a7153e6
Rename files for consistency
gcatanese Aug 21, 2025
c150388
Order exports
gcatanese Aug 21, 2025
c96f56a
Simplify setup of store param
gcatanese Aug 21, 2025
77da64c
Rename files
gcatanese Aug 27, 2025
0aa2879
Move and rename file
gcatanese Aug 27, 2025
9ab00f8
Rename files
gcatanese Aug 27, 2025
106d1fe
Create new security service
gcatanese Aug 27, 2025
adb9b27
Add asyncEncrypted
gcatanese Aug 27, 2025
43fdf26
Add encrypted sync and async
gcatanese Aug 29, 2025
e8859b5
Add tests
gcatanese Aug 29, 2025
575cc14
Add NexoSecurityManager
gcatanese Aug 29, 2025
eb07407
Extract methods to define endpoints
gcatanese Aug 29, 2025
2c9bc03
Correct live endpoints
gcatanese Sep 5, 2025
b71ef93
Add ScanBarcodeResult event
gcatanese Sep 5, 2025
59e0b1c
Add overload supporting CloudDeviceApiResponse
gcatanese Sep 5, 2025
c04689d
Add tests for testing with Terminal
gcatanese Sep 9, 2025
eb7b0ec
Don't add extra curly braces
gcatanese Sep 10, 2025
fdc17b2
Format payload to encrypt
gcatanese Sep 11, 2025
6e61c23
Rename files
gcatanese Sep 11, 2025
cc3b08d
Disable testing with Terminal
gcatanese Sep 11, 2025
17d20d8
Refactor test
gcatanese Sep 11, 2025
8759528
Clean up test
gcatanese Sep 11, 2025
556045b
Improve comments and code
gcatanese Sep 11, 2025
ec6d8d1
Add decryptNotification
gcatanese Sep 11, 2025
e2e25fa
Add README files for Cloud Device and Terminal APIs
gcatanese Sep 11, 2025
befd75d
Minor edit
gcatanese Sep 11, 2025
10f4c26
Minor edit
gcatanese Sep 11, 2025
9c20c2a
Minor corrections
gcatanese Sep 11, 2025
9571f5e
Support event notification and async response in decryptNotification
gcatanese Sep 11, 2025
4358c7c
Moved README files to doc folder
gcatanese Sep 11, 2025
7e82688
Remove logging
gcatanese Sep 11, 2025
49e4503
Merge branch 'main' into cloud-devices-api
gcatanese Sep 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
251 changes: 12 additions & 239 deletions README.md

Large diffs are not rendered by default.

194 changes: 194 additions & 0 deletions doc/CloudDeviceApi.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
# Cloud Device API

The [Cloud Device API](https://docs.adyen.com/api-explorer/cloud-device-api/1/overview) is our solution to create best-in-class in-person payments integrations.

With the Cloud device API you can:

- send Terminal API requests to a cloud endpoint. You can use this communication method when it is not an option to send Terminal API requests over your local network directly to a payment terminal.
- check the cloud connection of a payment terminal or of a device used in a Mobile solution for in-person payments.

## Benefits of the Cloud Device API

The Cloud Device API offers the following benefits:
- access to API logs in the Customer Area for troubleshooting errors
- using a version strategy for the API endpoints for controlled and safer rollouts
- improved reliability and security (OAuth support)

New features and products will be released exclusively on the Cloud Device API

## Use the Cloud Device API

### Setup

First you must initialise the Client **setting the closest** [Region](https://docs.adyen.com/point-of-sale/design-your-integration/terminal-api/#cloud):
``` javascript
// Step 1: Require the parts of the module you want to use
const {Client, TerminalCloudAPI} from "@adyen/api-library";
const { Config, EnvironmentEnum, RegionEnum } = require("@adyen/api-library");

// Step 2: Initialize the client object
const config = new Config({
apiKey: "YOUR_API_KEY",
environment: EnvironmentEnum.LIVE,
region: RegionEnum.US
});
const client = new Client(config);

// Step 3: Initialize the Cloud Device API service
const cloudDeviceAPI = new CloudDeviceAPI(client);
```

### Send a payment SYNC request

```javascript

// define the messageHeader
const messageHeader: MessageHeader = {
MessageCategory: MessageCategoryType.Payment,
MessageClass: MessageClassType.Service,
MessageType: MessageType.Request,
POIID: "V400m-123456789",
ProtocolVersion: "3.0",
SaleID: "POS-123", // Your unique ID for the system where you send this request from
ServiceID: "abvc-efgh", // Your unique ID for this request
};

// define the paymentRequest
const paymentRequest: PaymentRequest = {
PaymentTransaction: {
AmountsReq: {
Currency: "EUR",
RequestedAmount: 1,
},
},
SaleData: {
SaleTransactionID: {
TimeStamp: "2025-09-11T08:51:30.698Z",
TransactionID: "abc1234567890",
},
SaleToAcquirerData: {
applicationInfo: {
merchantApplication: {
version: "1",
name: "test"
}
},
metadata: {
someMetaDataKey1: "YOUR_VALUE",
someMetaDataKey2: "YOUR_VALUE"
},
}
},
};

// define the request
const cloudDeviceApiRequest: CloudDeviceApiRequest = {
SaleToPOIRequest: {
MessageHeader: messageHeader,
PaymentRequest: paymentRequest,
},
};

// perform the sync call
const response = await cloudDeviceAPI.sendSync(
"YOUR_MERCHANT_ACCOUNT",
"V400m-123456789",
cloudDeviceApiRequest
);
```


### Send a payment ASYNC request

If you choose to receive the response asynchronously, you only need to use a different method (`sendAsync`).
Don't forget to set up [event notifications](https://docs.adyen.com/point-of-sale/design-your-integration/notifications/event-notifications/) in the CA to be able to receive the Cloud Device API responses.

```javascript

// define the request
const cloudDeviceApiRequest: CloudDeviceApiRequest = {
SaleToPOIRequest: {
MessageHeader: messageHeader,
PaymentRequest: paymentRequest,
},
};

// perform the async call
const response = await cloudDeviceAPI.sendAsync(
"YOUR_MERCHANT_ACCOUNT",
"V400m-123456789",
cloudDeviceApiRequest
);

// handle both `string` and `CloudDeviceApiResponse`
if (typeof response === "string") {
// request was successful
console.log("response:", response); // should be 'ok'
} else {
// request failed: see details in the EventNotification object
console.log("EventToNotify:", response.SaleToPOIRequest?.EventNotification?.EventToNotify);
console.log("EventDetails:", response.SaleToPOIRequest?.EventNotification?.EventDetails);
}
```

### Verity the status of the terminals

The Cloud Device API allows your integration to check the status of the terminals.

```javascript

// list of payment terminals or SDK mobile installation IDs
const connectedDevices: ConnectedDevicesResponse = await cloudDeviceAPI.getConnectedDevices("YOUR_MERCHANT_ACCOUNT");
console.log(connectedDevices.uniqueDeviceIds);

// check the payment terminal or SDK mobile installation ID
const deviceStatus: DeviceStatusResponse = await cloudDeviceAPI.getDeviceStatus("YOUR_MERCHANT_ACCOUNT", "V400m-123456789");
console.log(deviceStatus.status);

```

### Error handling

In case of error, you can try-catch the `CloudDeviceApiError` to understand what went wrong.

```javascript
try {
const response = await client.sendSync("YOUR_MERCHANT_ACCOUNT", "V400m-123456789", cloudDeviceApiRequest);
console.log("response:", response);
} catch (err) {
if (err instanceof CloudDeviceApiError) {
console.error("CloudDevice API failed:", err.message);
console.error("Cause:", err.cause);
}
}
```

### Protect cloud communication

The Adyen Node.js library supports encrypting request and response payloads, allowing you to secure communication between your integration and the cloud.

```javascript

// Encryption credentials from the Terminal configuration on CA
const encryptionCredentialDetails: EncryptionCredentialDetails = {
AdyenCryptoVersion: 1,
KeyIdentifier: "myKeyIdentifier",
KeyVersion: "myKeyVersion",
Passphrase: "myPassphrase"
};

const response: CloudDeviceApiResponse = await cloudDeviceAPI.sendEncryptedSync(
"YOUR_MERCHANT_ACCOUNT", "V400m-123456789", cloudDeviceApiRequest, encryptionCredentialDetails);
console.log("response:", response);
```

In case of asynchronous integration, you can decrypt the payload of the event notifications using `decryptNotification()` method.

```javascript
// JSON with encrypted SaleToPOIResponse (for async responses) or SaleToPOIRequest (for event notifications)
const payload = "...";

const response: string = await cloudDeviceAPI.decryptNotification(payload, encryptionCredentialDetails);
console.log("response:", response);

```
Loading