[!IMPORTANT] This mock application is currently in its alpha-release and is not supporting every terminal-api request and response. This application cannot reject all invalid requests.
Always test your request and responses on your own physical terminal device first.
The Adyen Mock Terminal-API Application is a mock server that handles incoming requests and returns hard-coded responses. The application matches the request by looking at the SaleToPOIRequest.MessageCategory
-field and returns the respective response, see /public/payloads/...
-folder.
This tool can be used by developers to quickly end-to-end test their application by sending having their application send requests to the Mock Terminal API Application (http://localhost:3000/sync
) instead of the Adyen servers. You can do this by overriding the CloudApiEndpoint
on the client (config) of your application.
Currently, we use the Mock Terminal-API Application to end-to-end test our in-person payments integration-examples in .NET, Java or Node.js.
We currently support the following Terminal API requests/responses below.
Request | Response | Description |
---|---|---|
PaymentRequest | PaymentResponse | A successful payment request. |
ReversalRequest | ReversalResponse | A successful reversal request. |
TransactionStatusRequest | TransactionStatusResponse | A successful transaction-status request. |
PaymentBusyResponse | Returned when the payment terminal is waiting for pin. | |
AbortRequest | Cancel an in-progress payment. Note: Only cancels the payment request. Parameters may slightly differ depending on the terminal. |
In general, test payments generate the result Approved. To simulate declined payments, you can change the last three digits of the RequestedAmount
that you specify in the payment request.
- We constructed the mock payloads using a
V400M-
terminal device. - We used the
Blue-green Adyen point-of-sale test card
(card inserted & pin entered, no tap) to retrieve the responses.
We currently support the following Payment Refusal Codes, see below.
Amount ending in | Result | Error Condition | Refusal Reason | Message |
---|---|---|---|---|
124 | Failure | Refusal | 210 Not enough balance | NOT_ENOUGH_BALANCE |
125 | Failure | Refusal | 199 Card blocked | BLOCK_CARD |
126 | Failure | Refusal | 228 Card expired | CARD_EXPIRED |
127 | Failure | Refusal | 214 Declined online | INVALID_AMOUNT |
128 | Failure | InvalidCard | 214 Declined online | INVALID_CARD |
134 | Failure | WrongPIN | 129 Invalid online PIN | INVALID_PIN - Remark: The terminal shows "Incorrect PIN" and then "Enter PIN". Cancel the payment on the terminal to get the failure response. |
When an invalid JSON is provided, an invalidJsonObjectNotificationResponse
is returned.
- Node.js 18+
We recommend to use an application that can send Terminal-API requests or one of our .NET, Java, Node.js example-integrations.
git clone https://github.com/adyen-examples/adyen-mock-terminal-api.git
npm install
npm start
Visit http://localhost:3000/ to see the mock Terminal API.
There are two ways in which you can use the application.
Once you've cloned the example, you can point the application to use http://localhost:3000
, this configurable by overriding the CloudApiEndpoint
URI. Now your application is ready to communicate to the terminal
- Alternatively, you can use this stand-alone application and send terminal API requests from within the application.
You can also run the adyen-mock-terminal-api
in a Docker container which exposes the application on port 3000 (default).
# Run on Mac (i.e. --platform linux/arm64/v8)
docker run --rm -d --name adyen-mock-terminal-api -p 3000:3000 -e PORT=3000 ghcr.io/adyen-examples/adyen-mock-terminal-api:main
We commit all our new features directly into our GitHub repository. Feel free to request or suggest new features or code changes yourself as well! Find out more in our contributing guidelines.
- Fork this repository and create a new branch.
- The example below adds
paymentRequest.json
andpaymentResponse.json
. Thesrc/routes/services/payloadService
will automatically load these files, if it's suffixed with*Request
/*Response
and if the JSON is valid.- Create a new folder, in this example we use the existing {payment}-folder.
- Add your
Request
to `/public/payloads/{payment}/paymentRequest - Add your
Response
to `/public/payloads/{payment}/paymentResponse - Note: Every
*Request
should have a*Response
, except for those that require some kind of state or logic (f.e: "paymentBusyResponse" triggers when a payment request is in-progress). - Note 2: Keep naming-conventions camelCased and prefixed with its root-folder. Example: if the root-folder is located in
/payloads/example
, we name the jsons accordingly:exampleRequest.json
/exampleResponse.json
.
- In
/src/routes/defaultRoutes.js
, find the/sync
-endpoint and add the logic needed to map your requests-and-responses.
if (req.body.SaleToPOIRequest.Request) {
sendOKResponse(res, "payment");
return;
}
if (req.body.SaleToPOIRequest.ExampleRequest) {
sendOKResponse(res, "example");
return;
}
- Open a Pull Request with your changes.
MIT license. For more information, see the LICENSE file.