PayGuardian Android SDK
SDK Download:
Introduction
Mobile Point‐of‐Sales (mPOS) systems that process sensitive payment information are required to certify their payment applications to the Payment Application Data Security Standard (PA‐DSS). The addition of EMV certification and continued need for both encryption and tokenization has become a concern for both merchants and integrators.
Adherence to the Payments Card Industry Data Security Standards (PCI DSS) compliance requirements requires significant financial and employee resources. Subsequently, any changes made in the mPOS system may require a partial or full recertification, which increases the cost and time to market. BridgePay has engaged these issues through our product line, the PayGuardian suite, to better serve the needs of our integrators and merchants. PayGuardian Android is a light weight, highly secure Android application that integrates seamlessly into mPOS applications.
PayGuardian Android facilitates the transaction process by handling the collection and transmission of sensitive payment information as an out-of-scope PA-DSS solution, thereby offloading the certification responsibility from merchants and integrators. PayGuardian Android is EMV enabled, handles point to point encryption, and tokenizes all transactions to ensure transaction processing is seamless and secure.
Having previously been paired with a supported Bluetooth Low Energy Card Reader,
The host mPOS application will collect and forward transaction data to the PayGuardian instance using a concrete PaymentRequest.
The PayGuardian instance validates the request, and notifies the card reader that there is a pending transaction.
The card reader notifies the mPos application that it is ready via the ReaderRequestDelegate.
The mPOS application prompts the customer to use their payment card/device
The card reader collects the card data and passes it to the PayGuardian instance.
PayGuardian handles all of the communication with the Payment Gateway, returning a PaymentResponse to the mPOS application
Integration Setup
We have created a demonstration project for integrators that can serve as a base for a payment application. Currently, integration is supported only by referencing the SDK libraries in your application.
We provide wrapped versions of the supported device libraries to shield integrators from handling sensitive payment data directly, thereby simplifying compliance requirements. The wrapper abstracts device-specific details, ensuring that sensitive information is managed securely within the SDK. This allows integrators to focus solely on developing their application without needing to directly interact with or secure sensitive payment data.
Prerequisites
Android device (min API 26, must support Bluetooth, live internet connection)
IDTech VP3300 BT
Project Dependencies
In order to simplify testing and distribution, we have created a Core SDK library (pgmobileandroid-n.n.n.aar) and a device wrapper library for each card reader family we support. This ensures that integrators will have a version of the manufacturer’s device library that is compatible with our software.
The example below contains guidance on specific libraries and their usage in the demonstration project and are current as of December 2024.
Android application permission handling is beyond the scope of this document and is the responsibility of the integrator. We have made every effort to ensure that the core SDK functionality does not trigger unwanted or unexpected permissions requests. Use of the nammu library is taken solely at the risk of the integrator.
build.gradle (app)
// Core SDK and device wrapper
implementation(files("libs/pgmobileandroid-3.0.0.aar"))
implementation(files("libs/pg_idt_wrapper-1.0.0.aar"))
// other necessary libraries
implementation("com.google.code.gson:gson:2.11.0")
implementation("com.google.code.ksoap2-android:ksoap2-android:3.6.2")
// provided, optional.
// This library is unsupported due to age, but is still hosted publicly at https://github.com/tajchert/Nammu
// It is intended for use to smooth out permissions prompts on older, pre Android 12 devices.
// Integrators should evaluate their specific needs regarding permissions handling.
implementation(files("libs/nammu-1.0.0.aar"))
// Repo for simplexml - maven(url = "https://oss.sonatype.org/content/repositories/ksoap2-android-releases/")
implementation("org.simpleframework:simple-xml:2.7.1")
// These libraries provide necessary functionality at the level they are compiled at.
// Do not upgrade past this point at the risk of losing Android compatibility.
implementation("org.simpleframework:simple-xml:2.7.1") {
exclude(module = "xpp3")
}
implementation("org.apache.commons:commons-lang3:3.15.0")build.gradle.kts (Project)
repositories {
google()
mavenCentral()
maven(url = "https://oss.sonatype.org/content/repositories/ksoap2-android-releases/")
}PayGuardian initialization
The PayGuardian class is implemented as a singleton and accepts an instance of the PayGuardianDelegate interface to bind events. After instantiation and connection to a CardReader, that delegate is passed into the singleton as well.
public interface PayGuardianDelegate {
void initiateTransaction(PaymentRequest request);
void onTransactionStateChanged(TransactionState transactionState, String message);
void onReaderStateChanged(ReaderState readerState, String message);
void onMessageReceived(String message);
void onResponseReceived(PaymentResponse paymentResponse);
void onError(ArrayList<String> errors);
}payGuardian = PayGuardian.getInstance();
payGuardian.setDelegate(payGuardianDelegate);Device Connection
The device wrapper library provides integrators with an implementation of the CardReader interface from the core SDK library. The class name can be expected to be in the format of (device name)Delegate.
public interface CardReader {
int searchForDeviceByName(String name, int timeout);
void requestCardRead(Double amount, boolean isRefund);
void requestCardRead(Double amount, boolean isRefund, boolean disableEmv, boolean disableCtls);
boolean isConnected();
void cancel();
DeviceDetails getDeviceDetails();
} private void attemptConnection(String deviceName) {
new Thread(() -> {
// Please note that this response pattern is IDTech specific
runOnUiThread(() -> {
VP3300Delegate vp3300Delegate = new VP3300Delegate(this, payGuardian.readerResponseDelegate, new Handler(Looper.getMainLooper()));
int rc = vp3300Delegate.searchForDeviceByName(deviceName, 10000);
if (rc != 0) {
String message = switch (rc) {
case 1 -> "Invalid DEVICE_TYPE";
case 2 -> "Bluetooth LE is not supported on this device";
case 3 -> "Bluetooth LE is not available";
case 4 -> "Bluetooth LE is not enabled";
case 5 -> "Device not paired. Please pair first";
default -> "Unknown error";
};
viewModel.appendLogMessage(message);
} else {
payGuardian.setCardReader(vp3300Delegate);
viewModel.appendLogMessage("Found device " + deviceName);
}
});
}).start();
}While testing with the ID Tech VP3300, we found it helpful to leave it plugged into USB power. The Bluetooth Low Energy scheme will frequently put the reader to sleep. Further, it should not be physically plugged into any computing device as that will supersede a Bluetooth request and return those requests to the wired device regardless of the source.
Transaction Handling
All transaction calls are made through a direct call to PayGuardian.getInstance().processTransaction or through PayGuardianDelegate.initiateTransaction. The transaction handler will only process a single transaction at a time, and there is no queuing of requests for later processing. Including the payment card information on a transaction will bypass a card read.
private PaymentRequest buildBasicPaymentRequest() {
PaymentRequest paymentRequest = new PaymentRequest();
paymentRequest.setTerminalID(terminalID);
paymentRequest.setUsername(userName);
paymentRequest.setPassword(password);
paymentRequest.setMerchantCode(merchantCode);
paymentRequest.setMerchantAccountCode(merchantAccountCode);
paymentRequest.setTenderType(TenderType.Credit.toString());
return paymentRequest;
}
// This will trigger a card read request
private void sendSale() {
PaymentRequest paymentRequest = buildBasicPaymentRequest();
paymentRequest.setMode(PayGuardianMode.Test.toString());
paymentRequest.setTransType(TransactionType.Sale.toString());
paymentRequest.setAmount("10.00");
payGuardianDelegate.initiateTransaction(paymentRequest);
}
// This will be sent directly to the gateway
private void sendManualSale() {
PaymentRequest paymentRequest = buildBasicPaymentRequest();
paymentRequest.setMode(PayGuardianMode.Test.toString());
paymentRequest.setTransType(TransactionType.Sale.toString());
paymentRequest.setAmount("10.00");
paymentRequest.setCardNumber("4111111111111111");
paymentRequest.setExpDate("1225");
paymentRequest.setCvvNumber("123");
payGuardianDelegate.initiateTransaction(paymentRequest);
}
Input
All fields are assumed to be of type String unless otherwise specified
All amount fields will be processed as implied decimals regardless of the input format
Allowable date formats are “yyyyMMdd” and “MM/dd/yyyy”
Allowable time formats are "HHmmss" and "HHmm"
PaymentRequest
Property | Description | Data Type / Min - Max Values |
|---|---|---|
TenderType | Required. Valid values are: | String; |
TransType | Required. Valid values are: | String; |
TransIndustryType | Optional, defaults to RETAIL if not provided
| String; |
Amount | Required. Total transaction amount (includes subtotal, cash back, tax, and tip (Format example: 0000.00) | String; |
Username | Required. Username of the Merchant | String; |
Password | Required. Password of the Merchant. | String; |
Street | Optional. Zip code of billing address. | String; |
OrigRefNum | Original reference number. Used for follow‐on transactions (e.g., Void, Reversal). | String; |
Country | Country of billing address | String; |
Phone | Phone number for the payer | String; |
Email address for the payer | N/A | |
MerchantCode | Required. BridgePay Merchant Code. | String; |
MerchantAccountCode | Required. BridgePay Merchant Account Code. | String; |
InvNum | Required. POS system invoice/tracking number. | String; |
ReferenceID | Optional. Can be populated to echo back a variable in the response message. | String; |
PartialAuthorization | Optional. Sets the partial authorization flag for a transaction. The default setting is ‘false’ (meaning not active). | String; |
HolderType | Optional. Single character, either P (Personal account) or O (Organization account). | String; |
CardholderName | Optional. Name as it appears on the credit card, debit card, or gift card. | String; |
CardNumber | Optional. Account number of a credit card, debit card, or gift card used when collecting card data outside of PayGuardian (not recommended). | String; |
ExpDate | Optional. Expiration date of a credit card, debit card, or gift card (required for Token transactions). | String; |
CvvNumber | Optional. Card verification code of a credit card, debit card, or gift card used when collecting card data outside of PayGuardian (not recommended). | String; |
Memo | Optional. User supplied data. Valid values are: alphanumeric, dashes, spaces, and periods. | String; |
SoftwareVendor | Optional. Name of vendor that developed the software used in transmitting the transaction. | String; |
HostingSoftware | Optional. | String; |
VoiceAuthCode | Optional. Authorization Code for Voice Authorizations only when authorization was achieved outside of the network (by phone or other means). | String; |
TaxRate | Optional. Processed as implied decimal. 5.5% would be represented as 550. Additional Tax Amount. REQUIRED FOR LEVEL II/III | String; |
TaxAmount | Optional. Processed as implied decimal. $1.25 would be represented as 125. REQUIRED FOR LEVEL II. | String; |
TaxIndicator | Optional. Valid values are: P (Provided), N (Not Provided), or E (Exempt). REQUIRED FOR LEVEL II/III. | String; |
ShipToName | Optional. Shipping address name. REQUIRED FOR LEVEL II/III. | String; |
ShipToStreet | Optional. Shipping address street. REQUIRED FOR LEVEL II/III. | String; |
ShipToCity | Optional. Shipping address city. REQUIRED FOR LEVEL II/III. | String; |
ShipToState | Optional. Shipping address state. REQUIRED FOR LEVEL II/III. | String; |
ShipToZip | Optional. Shipping address postal code. Accepted formats are Canadian, UK and US (5 and 9 digit variation) postal codes. REQUIRED FOR LEVEL II/III. | String; |
ShipToCountryCode | Optional. Shipping address country code. REQUIRED FOR LEVEL II/III. ISO 3166-1 alpha-2 codes. | String; |
ShippingOriginZip | Availability pending processor certification. Conditional. *** REQUIRED FOR LEVEL III*** Postal code of the origin of the shipment. Accepted formats are Canadian, UK and US (5 and 9 digit variation) postal codes. Alphanumeric characters ONLY (no hyphens or dashes). Alpha characters must be all upper-case. | String; |
DiscountAmount | Availability pending processor certification. Conditional. *** REQUIRED FOR LEVEL III*** Processed as implied decimal. $1.25 would be represented as 125. Additional discount amount. | Integer |
ShippingAmount | Availability pending processor certification. Conditional. *** REQUIRED FOR LEVEL III*** Processed as implied decimal. $1.25 would be represented as 125. Additional discount amount. | Integer |
DutyAmount | Availability pending processor certification. Conditional. *** REQUIRED FOR LEVEL III*** Processed as implied decimal. $1.25 would be represented as 125. Additional discount amount. | Integer |
TaxInvoiceCode | Availability pending processor certification. Conditional. *** REQUIRED FOR LEVEL III*** Must be at least 1 and up to 15 characters. When separate VAT invoice is produced within the context of the order, unique identifier of this invoice. | String |
LocalTaxAmount | Availability pending processor certification. Conditional. *** REQUIRED FOR LEVEL III*** Processed as implied decimal. $1.25 would be represented as 125. Additional discount amount. | Integer |
LocalTaxIndicator | Availability pending processor certification. Conditional. *** REQUIRED FOR LEVEL III*** P (Provided), N (Not Provided), or E (Exempt). | String |
NationalTaxAmount | Availability pending processor certification. Conditional. *** REQUIRED FOR LEVEL III*** Processed as implied decimal. $1.25 would be represented as 125. Additional discount amount. | Integer |
NationalTaxIndicator | Availability pending processor certification. Conditional. *** REQUIRED FOR LEVEL III*** P (Provided), N (Not Provided), or E (Exempt). | String |
OrderCode | Availability pending processor certification. Conditional. *** REQUIRED FOR LEVEL III*** Unique identifier assigned to the order associated with this transaction in submitter's/merchant's front-end/ inventory system. | String |
OrderDate | Availability pending processor certification. Conditional. *** REQUIRED FOR LEVEL III*** Date in format YYYYMMDD. Date when the order associated with the transaction was placed. | String |
CommodityCode | Availability pending processor certification. Conditional. *** REQUIRED FOR LEVEL III*** Acquirer designated standardized code that classifies the group of items associated with this order/transaction. | String |
CustomerAccountTaxID | Availability pending processor certification. Conditional. *** REQUIRED FOR LEVEL III*** VAT registration number of the customer responsible for this transaction. | String |
ItemCount | Availability pending processor certification. Conditional. *** REQUIRED FOR LEVEL III*** The number of items included in the “Item” collection. | Int |
Item | Availability pending processor certification. Conditional. *** REQUIRED FOR LEVEL III*** Used to group the line item details as a collection of individual item contents for an item. | Collection<Item> |
CashBackAmount | Optional. Processed as implied decimal. $20.00 would be represented as 2000. Amount of money returned to a payment card holder. Used for Sale with cash back transactions. | String; |
EnableCashBack | Optional. When set to true, prompts for cashback on the device. | Boolean |
TipRecipientCode | Optional. Server ID for the customer. | String; |
ConvenienceFee | Convenience Fee. (Format example: 0000.00) The convenience fee is a line Item reference included in a SALE or SALE_AUTH transaction request in which the customer credit or debit card is charged the total sum in the ‘amount’ field where a transaction request contains both the transaction amount + convenience fee in a single transaction. | String; |
ServiceFee | Optional. Separate fee that processes to a separate merchant account (the username and password are passed in with the request message) with a SALE or SALE_AUTH transaction in which the customer credit or debit card will be charged the transaction amount on the merchant account of record, and a service fee amount on a separate transaction to the merchant account designated in the request. | ServiceFee |
ResellerCode | Reseller ID assigned by the gateway for the Reseller of the Service Fee account. | String;Min Value = 0;Max Value = 25 |
Property of BridgePay Network Solution ©2025