Integrate with the POS+ API to process payments directly from your Castles device.
Before performing a transaction, obtain the following credentials:
- HMAC key: Used for authentication and to create the HMAC signature for each API request.
- Merchant credentials: Your merchant ID, site ID, and point-of-sale ID, as assigned by PXP.
- POS server URL: The address of the payment server. This is a combination of the IP address of the device and port 8181.
To find your HMAC key:
- In the Unity Portal, go to Merchant setup > Sites.
- Select a site.
- In the Services tab, find the Pos service row.
- Click Edit.
- The HMAC key is displayed in the top left. Click the copy icon () to copy it to your clipboard.

To find your merchant ID:
- In the Unity Portal, go to Merchant setup > Merchants.
- Select a merchant.
- In the General information tab, look for Merchant ID.
To find your site ID:
- In the Unity Portal, go to Merchant setup > Sites.
- Select a site.
- In the General information tab, look for Site ID.
- In the Unity Portal, go to Merchant setup > Sites.
- Select a site.
- In the Services tab, find the Pos service row.
- Click Edit.
- Select a device.
- Click General settings.
- In the POS settings section, look for POS ID.
The POS server URL is constructed from your Castles device's IP address and port 8181.
You'll need to obtain your device's IP address first. You can do this manually or programmatically.
To get the device's IP address manually:
- Go to the Settings option on your device.
- Select Network and Internet.
- Choose the Internet option.
- Click on the settings of your connected Wi-Fi and scroll down to view the IP address.
Once you have the IP address, construct your POS server URL:
http://{IpAddress}:8181/api/v1/pos-transactionsWhere:
{IpAddress}is the IP address from your device.8181is the open port for the endpoint.api/v1/pos-transactionsis the transaction endpoint.
For example:
http://192.168.10.108:8181/api/v1/pos-transactionsWith your credentials ready, prepare your API request payload. The following example shows an in-store purchase transaction:
{
"merchant": "{merchantId}",
"site": "{siteId}",
"pointOfInteraction": {
"pointOfSaleId": "{posId}",
"language": "en",
"storeAndForwardType": "None"
},
"merchantTransactionId": "{merchantTransactionId}",
"merchantTransactionDate": "2025-11-04T12:00:00.000Z",
"amounts": {
"transaction": 100.00,
"currencyCode": "USD",
"gratuity": null
},
"transactionMethod": {
"entryType": "Instore",
"fundingType": "Card",
"intent": "Purchase"
},
"merchantDeeplink": "myapp://payment/result"
}The POS+ API uses HMAC (Hash-based Message Authentication Code) with SHA256 for authentication to ensure secure communication and data integrity.
For each API request, you need to:
- Create a unique request ID (UUID or GUID).
- Generate a timestamp (Unix timestamp in seconds).
- Combine the timestamp, request ID, request path, and request body.
- Use your HMAC key to create an HMAC-SHA256 signature.
The signature is calculated using the following data:
{timestamp}{requestId}{requestPath}{requestBody}Where:
{timestamp}is the current Unix timestamp in seconds.{requestId}is a unique UUID for the request.{requestPath}is the API path (e.g.,api/v1/pos-transactions).{requestBody}is the JSON request body as a string.
using System;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
namespace Pxp.Pos.Sdk.Utils
{
public static class HttpRequestMessageExtensions
{
public static HttpRequestMessage BuildHMACAuthentication(
this HttpRequestMessage request,
string requestBody,
string apiKey,
string endpoint)
{
var uri = new Uri(endpoint);
var requestPath = uri.AbsolutePath.Trim('/');
var requestId = Guid.NewGuid().ToString();
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
var hmacRequestData = $"{timestamp}{requestId}{requestPath}{requestBody}";
var hmacResult = ComputeHmacSha256(hmacRequestData, apiKey);
var authHeader = $"PXP-HMAC1 {timestamp}:{hmacResult}";
request.Headers.Add("Authorization", authHeader);
request.Headers.Add("X-Request-Id", requestId);
return request;
}
private static string ComputeHmacSha256(string data, string key)
{
using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key)))
{
var hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(data));
return BitConverter.ToString(hashBytes).Replace("-", "").ToUpper();
}
}
}
}Include the HMAC signature and request ID in your HTTP headers:
| Header | Description | Format |
|---|---|---|
Authorization | The HMAC signature, consisting of the authentication scheme (PXP-HMAC1), timestamp, and HMAC value. | PXP-HMAC1 {timestamp}:{hmac} |
X-Request-Id | The unique request ID (UUID) that you generated. | {requestId} |
For example:
Authorization: PXP-HMAC1 1699876543:A1B2C3D4E5F6G7H8I9J0K1L2M3N4O5P6
X-Request-Id: 123e4567-e89b-12d3-a456-426614174000Send your API request to the POS server URL with the prepared payload and headers.
On successful authorisation, you'll receive a 200 response similar to the following:
{
"state": "Authorised",
"stateData": {},
"approvalCode": "041458",
"merchantTransactionDate": "2025-11-05T15:41:50.000000+07:00",
"merchantTransactionId": "051125_elv1",
"systemTransactionId": "590e722b-7507-4099-92da-9d9610485d4c",
"providerTransactionId": "",
"fundingData": {
"maskedPrimaryAccountNumber": "476173******0027",
"expiryMonth": "12",
"expiryYear": "2025",
"cardScheme": "Visa",
"gatewayTokenId": "2ae96210-c8a3-459e-8ad8-7d481a90ff71",
"pointOfInteraction": {
"entryType": "Swiped"
},
"providerResponse": {
"provider": "Elavon",
"code": "A",
"message": "APPROVAL",
"merchantId": "2100112262",
"terminalId": "210011226201",
"paymentAccountReference": "V0010013019319455709071563112",
"schemeTransactionId": "D3053093132307743RCGA",
"issuerResponseCode": "00",
"schemeTransactionLinkId": "",
"merchantAdvice": {
"code": "",
"message": ""
},
"settlementDate": "2025-11-05T15:42:12.735373+07:00"
}
}
}| Property | Description |
|---|---|
statestring (enum) | The current state of the transaction. Possible values:
|
stateDataobject | Key value pair for various state data. |
stateData.codestring | The state details code. |
stateData.messagestring | The state details message. |
approvalCodestring | A unique identifier code provided by the authorising entity, indicating approval or reference for the transaction. This code typically consists of alphanumeric characters, starting with an uppercase letter, and serves as a key reference for authorisation verification. |
merchantTransactionDatestring (date-time) | The date and time when you initiated the transaction. This timestamp is crucial for tracking the transaction throughout its lifecycle and for chronological order analysis. The date and time format follows the ISO 8601 standard, ensuring consistency and ease of interpretation in global contexts. It facilitates the accurate and precise logging of transaction initiation times, aiding in transaction management and reconciliation processes between the merchant and PXP. |
merchantTransactionIdstring | A unique transaction reference assigned by you, the merchant, to identify individual transactions. This identifier serves as a primary means of communication regarding the transaction status between you and PXP. It is essential to maintain uniqueness for each transaction, ensuring accurate tracking and communication throughout the transaction lifecycle. |
systemTransactionIdstring | A unique identifier generated by PXP for each transaction. It serves as a reference for tracking and querying transactions within the PXP system. This ID is crucial for performing modifications or querying transaction details. |
providerTransactionIdstring | A unique identifier assigned by the financial service provider for the transaction. It facilitates tracking, reconciliation, and support processes. |
fundingData.maskedPrimaryAccountNumberstring | The masked primary account number. |
fundingData.expiryMonthstring | The expiry month of the card. |
fundingData.expiryYearstring | The expiry year of the card. |
fundingData.cardSchemestring | The payment card's scheme, indicating the network through which the card transactions are processed. The card scheme is represented by name of the card network. This information is crucial for identifying the card type and facilitating transaction processing in accordance with the network's regulations and standards. |
fundingData.gatewayTokenIdstring | A securely stored token that corresponds to a previously saved payment card. This token is generated and maintained by PXP to facilitate recurring transactions or transactions using stored card details, ensuring enhanced security and convenience. When a transaction is performed with a saved card, this token ID should be provided instead of the full card details. This approach enhances security by reducing the exposure of sensitive card information and simplifies the transaction process for returning customers. |
fundingData.pointOfInteraction.entryTypestring | The method by which the card was presented for the transaction. |
fundingData.providerResponse.providerstring | The name of the provider that processed the transaction. |
fundingData.providerResponse.codestring | The raw result code returned by the provider that processed the transaction. |
fundingData.providerResponse.messagestring | The raw message associated with the result code from the provider that processed the transaction. |
fundingData.providerResponse.merchantIdstring | The unique identifier assigned by the provider to represent the merchant involved in the transaction processing. |
fundingData.providerResponse.terminalIdstring | The unique identifier assigned to the terminal used for the transaction processing. |
fundingData.providerResponse.paymentAccountReferencestring | The Payment Account Reference (PAR) is a unique identifier assigned to a payment account, independent of the card number. It remains constant over the account's lifetime, even if the card number (PAN) changes. PAR enhances transaction security and privacy, serving as a secure reference point for cardholders, merchants, and issuers. It's used in digital transaction processing to reliably link transactions and accounts without exposing the actual card number. |
fundingData.providerResponse.schemeTransactionIdstring | A unique identifier assigned by the card scheme to each transaction. This identifier is crucial for tracking, reconciliation, and managing the lifecycle of the transaction, especially in contexts like chargebacks and fraud analysis. For card transactions, this could be the Visa Transaction Identifier or MasterCard Banknet Reference Number. |
fundingData.providerResponse.issuerResponseCodestring | The response code returned by the card issuer. |
fundingData.providerResponse.schemeTransactionLinkIdstring | The unique identifier of the original transaction, as assigned by the card scheme. This identifier is used to link the original transaction to subsequent transactions, such as a refund or void. |
fundingData.providerResponse.merchantAdviceobject | Provides additional guidance or recommendations from the card network regarding the transaction. This information is particularly useful for understanding the reasons behind a transaction's refusal and can offer suggestions for next steps. For instance, it might indicate that updated account information is available or suggest specific actions to resolve the refusal. The merchantAdvice object includes a code and message to detail this advisory information, making it easier for merchants to take corrective action or understand the refusal context. |
fundingData.providerResponse.merchantAdvice.codestring | An advisory code provided by the card network that categorizes the type of advice or recommendation. |
fundingData.providerResponse.merchantAdvice.messagestring | A human-readable message that provides further details or clarification about the advice code, potentially suggesting next steps or reasons for the transaction refusal. |
fundingData.providerResponse.settlementDatestring (date) | The date on which the transaction funds are settled between banks for MasterCard payments. This field is applicable and provided only for transactions processed using MasterCard. The settlement date is crucial for financial reconciliation and is formatted as YYYY-MM-DD. |
Store the systemTransactionId for future reference, reconciliation, and any follow-up operations like refunds or reversals.