In this article we will walk through moving from zero to a full transaction interaction using Connect API and a device on the local network.
Let’s start with making sure we can see the device on the network and making sure we can connect to it.
On a macOS system, open Terminal or iTerm and enter:
nc -ul 33310
This will listen on UDP port 33310 for any broadcasts from Kinetic devices that are powered on and available.
In iTerm, we see the following:
{"name":"AIBMS V3","id":"000118162200026","address":"https://ip-10-0-1-62.devices.kineticsmart.com:44443","battery":{"percentage":0,"charging":false}}
We can see a Vega3000 broadcasting that can be interacted with via the Connect API. The key piece of information is the URL, which for this device is:
https://ip-10-0-1-62.devices.kineticsmart.com:44443
We’re going to add on the api and version suffix, making the full URL prefix to use (more on this here):
https://ip-10-0-1-62.devices.kineticsmart.com:44443/api/v1/
Now let’s make sure we can send a command and receive a response to and from the device using a curl command. At the command prompt:
curl https://ip-10-0-1-62.devices.kineticsmart.com:44443/api/v1/ping.json
And we received the following JSON response from the device:
{"ping":true}
This is what we hoped to see and we have confirmed that we can interact with the device.
We will only ever send commands to the device and receive a response back. There is no way for the device to respond later once an action is complete, instead it is up to us to poll the device for progress status when, for example, a transaction is in progress and we want the result.
If the connection times out, the device is most likely off or the network is down. A device that is already busy with a transaction will response to let you know its busy.
The last big piece to know about is authentication. The ping.json command is very simple and it serves our purpose of validating that a connection to the device is possible, but for all other commands we need to authenticate our application with the device.
On startup, the device generates an API username and password that you need to use as part of your command to authenticate with the device. On the device, press the red key for Manager Menu and enter the passcode (the default is 1397139, but this should be changed regularly). Scroll down to API credentials for the username and password to use with basic http authentication.
To check the authenticated commands are working, we will attempt to query the battery level of the device. This will work with non-portable devices too, although the result will always be an empty battery that is not charging.
Let’s first try the command without authentication:
https://ip-10-0-1-62.devices.kineticsmart.com:44443/api/v1/battery.json
This predictably returns:
{"error":"basic authorization required"}
Now let’s add the basic authentication with the credentials the device has in API Credentials:
curl "https://ip-10-0-1-62.devices.kineticsmart.com:44443/api/v1/battery.json" -u kinetic_admin:8qhEaKoR
The result back from the device confirms the battery situation:
{"error":"Device has no battery","success":false}
Despite the error, this is a successfully authenticated command and response. Let’s try something that causes an action on the device so we can see the result of a command. The find.json command is authenticated and, if the device is on the idle screen, will change screen to let us know that a location request was received.
curl "https://ip-10-0-1-62.devices.kineticsmart.com:44443/api/v1/find.json" -u kinetic_admin:8qhEaKoR
For this, the response is a simple {“success”:true} and the screen on the device will alert us of the location request. This is especially useful for visually figuring out which mobile Vega3000 and MP200 devices you are connecting to when there are multiple devices on the same network.
Now let’s get to the more interesting part: running a transaction. While there is no “Hello World!” of transactions, we can run a simple sale transaction for 1.00 as an equivalent to make sure everything is working together as it should be.
The device you are using will most likely be connected to a test host at an acquirer. In all cases, you should only use test EMV cards to work with and never your own personal “live” cards. It is unlikely that the transactions will ever be settled on a test host, but if your device is connected to an acquirer’s live production system, they will definitely process the transaction and deduct funds from the account being used.
In addition, acquirer test systems often reject live cards and can cause EMV cards to be blocked. If you are using a live card with the test system and the card no longer works after a few transactions, please contact your card issuer for a new card.
For most of the testing we do, we use the Visa CDET application available for Android devices on Google Play. It is a full deck of Visa contactless cards available for free on Android devices that support NFC. You can also buy the formal card brand test or validation kits from Collis/UL or ICC Solutions, however the cost of these from a few hundred pounds/euro up to over £/€ 9000.
For this example we will use Visa contactless CDET v2.3 Card 01, the first card in the CDET Android application.
To begin, we need to POST a sale.json command. This is authenticated, so we must send the basic auth data, and we need to tell the device the amount of the sale that we want processed. The curl command for this is:
curl -X "POST" "https://ip-10-0-1-62.devices.kineticsmart.com:44443/api/v1/sale.json" -H "Content-Type: application/json; charset=utf-8" -u kinetic_admin:8qhEaKoR -d $'{ "amount": 100 }'
Notice the additional -d $'{amount:100}’ as well as the description of the content type of this data -H “Content-Type: application/json; charset=utf-8”. This is to tell the device that we are POSTing JSON data in the body of the request, and the JSON we are sending is the amount of 100.
Why not 1.00? To simplify amount handling and avoid rounding errors across the many systems that can interface with Connect API, the amounts are all specified as integers in pence or cents. £1.00 = 100, €2,00 = 200.
When we send this command, we receive back a uuid for this transaction. Specifically:
{"success":true,"uuid":"d9640f45-8785-4fe1-cf3b-388a08f26b52"}
If the device is busy, the amount is missing or the instruction is in any way not complete, you will instead see an error message with some useful information on why the command failed.
Here we have a successful transaction with the uuid d9640f45-8785-4fe1-cf3b-388a08f26b52. This is generated by the device, but we could have specified this in our request too by adding a uuid field to the JSON in the request.
The uuid is what we will use to reference this transaction in future calls to the device to check on status while the transaction is being handled and to retrieve the result when the transaction is complete. The transaction is available on the device up until the end of day/close process has been run on the device or via Connect API.
Now that the transaction is initiated, let’s poll the device to find out what’s happening. To do this, we send a GET request to transaction.json using the uuid we received in the original request.
curl "https://ip-10-0-1-62.devices.kineticsmart.com:44443/api/v1/transaction.json?uuid=d9640f45-8785-4fe1-cf3b-388a08f26b52" -H "Content-Type: application/json; charset=utf-8" -u kinetic_admin:8qhEaKoR
The device, which is currently waiting to accept a card or phone payment, sends us the response:
{"description":"Transaction in progress","status":"EMV: Starting transaction","success":false}
Why success:false? The transaction.json GET command is provided to retrieve the full transaction record, however the device is currently busy and cannot give us the transaction record. It does tell us what is happening on the device, which is useful to know if your own application wants to reflect this status to a user.
On the device, I’m going to use the first card in the Visa CDET Android application to run a quick contactless EMV transaction.
And now when I run the same GET transaction.json request:
curl "https://ip-10-0-1-62.devices.kineticsmart.com:44443/api/v1/transaction.json?uuid=d9640f45-8785-4fe1-cf3b-388a08f26b52" -H "Content-Type: application/json; charset=utf-8" -u kinetic_admin:8qhEaKoR
I receive a LOT more information to work with in JSON format, starting with the UUID of the transaction and all of the relevant data generated as a result of the transaction. You can download this specific transaction JSON result here.
Of particular interest are the fields “result” (approved, declined, error), merchant receipt and customer_receipt. Using these, your application can decide on the next appropriate action to take to conclude the transaction or carry out the next transaction.
Note that there is no cardholder data returned in the transaction record. Your application will only ever receive masked card data to work with, ensuring that everything outside of the device’s PCI-PTS environment is kept out of PCI scope.
The full receipt information used to generate the paper receipts on devices with printers is contained within merchant_receipt and customer_receipt, however for transporting over JSON and to support special characters, they are returned as URL encoded strings. Pass this data through a URL decode function to expose the JSON array with each line and styling characteristics to consume in your own application. More on receipt generation can be found here.
There are more examples of transaction requests and responses here.
Congratulations! You have successfully carried out a complete transaction using the Connect API. In the remaining articles we examine each individual transaction type, give examples of data returned and examine the receipt format. If you encounter any issues, please contact us at team@kineticsmart.com or submit a ticket.