BluePosGoSDK Android API Reference

1. Request and response data models

This reference describes the data exchanged between an external Android application
and BluePOS Go. It covers every request and response data class in this SDK,
including the nested objects exposed through transaction details.

The definitions below match the SDK source and its bundled
bluepos-poi-models-4.0.23.jar. Operation names identify where each model is used;
service binding, method contracts, callbacks, and a complete integration example will be covered in later sections of this reference guide.

Requirements

  • The BluePOS Go application must be installed on the device
  • The BluePOS Go application must have the AIDL service implemented

Contents

Conventions

  • Types and field names match the Kotlin SDK, including capitalization:
    customID and customId are different property names, and the clear-read
    timeout is named timeOut.
  • ? means the field can be null. Check nullable objects before accessing
    their fields. An empty string also commonly means that no value was supplied
    or returned.
  • No default means an argument must be supplied when constructing the Kotlin
    object. A constructor default does not mean the value is valid for an operation:
    for example, a sale requires a positive amount despite the 0.0 default.
  • SDK request and response classes implement Android Parcelable. Pass the SDK
    objects through AIDL; callers do not need to serialize them to JSON.
  • Monetary values use major currency units: 12.50 means twelve dollars and fifty
    cents in the current USD implementation. Request amounts use Double; nested
    processor amounts use decimal String values, such as "12.50". The current
    SDK has no request currency field, and BluePOS Go submits these transactions in
    USD. Use decimal arithmetic, such as BigDecimal, when calculating with returned
    amount strings.
  • A response object or a populated transaction ID is not itself proof of approval.
    Interpret the operation's status and, for payments, the authorization result and
    approved amount.

Model overview

ModelPackagePurpose
InitRequestcom.bluefin.blueposgo.sdk.requestInitialization request and optional credential configuration.
PaymentRequestcom.bluefin.blueposgo.sdk.requestSale, authorization, card-present credit/refund, or save-card request.
FullRefundRequestcom.bluefin.blueposgo.sdk.requestRefund the remaining refundable amount of an existing transaction.
PostProcessRequestcom.bluefin.blueposgo.sdk.requestRefund a specified amount or capture an earlier authorization.
ClearDataRequestcom.bluefin.blueposgo.sdk.requestRead clear card data from the reader.
InitResponsecom.bluefin.blueposgo.sdk.responseInitialization or reboot result.
DeviceCommandResponsecom.bluefin.blueposgo.sdk.responseConnect, disconnect, or forget result.
PaymentResponsecom.bluefin.blueposgo.sdk.responsePayment, refund, or capture result; also each transaction-list item.
ClearDataResponsecom.bluefin.blueposgo.sdk.responseClear card-data read result.
PaymentTransactionResponsecom.bluefin.blueposgo.sdk.responseAdditional transaction model included in the SDK; not returned by the current AIDL callbacks.
TransactionDetailscom.bluefin.blueposgo.sdk.responseDetailed transaction result nested in payment response models.
RefundObjectcom.bluefin.blueposgo.sdk.responseRefund balance and refund IDs nested in transaction details.

Request models

InitRequest

Package: com.bluefin.blueposgo.sdk.request.

Used for initialization. Credentials may be supplied by the caller or already
configured in BluePOS Go.

FieldKotlin typeDefaultDescription
requestIdString""Caller-provided identifier for this initialization request. Useful for identifying the request, but it is not returned in InitResponse. No idempotency behavior is defined for this field.
basicTokenString""Basic authentication credential for the Bluefin API. Accepts the credential with the Basic prefix or the encoded credential alone. A non-empty, valid value is applied and stored by BluePOS Go. See Credential fields.
accountIdString""Bluefin account identifier under which transactions are processed. A non-empty value updates the account when credentials are applied; an empty value preserves the current account.
environmentString""API environment selector. Recognized selectors are CERT and PROD; other values fall back to staging when no API path is already configured. See Credential fields for precedence.

Credential fields

InitRequest and PaymentRequest use the same basicToken, accountId, and
environment fields. Supply credentials issued for the intended Bluefin account.

The current application applies account and environment changes only when the
request supplies a non-empty token accepted by its Basic-token normalization.
Leaving basicToken empty preserves the existing credentials and also skips the
request's account/environment changes. The normalization accepts Basic <credential>
or <credential>; it does not construct an encoded credential from a username and
password.

For requests handled by this SDK, an already configured API base path takes
precedence over environment. If no path is configured, the selector is trimmed
and compared without regard to case:

SelectorDestination
CERTCertification environment.
PRODProduction environment.
Any other value, including ""Staging environment.

Consequently, setting environment alone is not a guaranteed way to switch an
already configured application to a different API endpoint.

PaymentRequest

Package: com.bluefin.blueposgo.sdk.request.

Describes a new card operation. For sale, authorization, and card-present
credit/refund, the transaction total is amount + tip.

FieldKotlin typeDefaultDescription
amountDouble0.0Base amount, excluding tip, in major currency units. Must be greater than zero for sale, auth, and refund. For save, BluePOS Go uses 0.0 regardless of the supplied value.
tipDouble0.0Gratuity added to amount. Must be non-negative for monetary operations. For save, BluePOS Go uses 0.0 regardless of the supplied value.
typeString"sale"Requested operation: "sale", "auth", "refund", or "save". The current parser converts the value to lowercase. See the operation table below.
customIDString""Caller-defined reference, such as an order or invoice ID. Stored with the transaction and echoed in the normal payment result. It is separate from the processor-assigned transactionId; do not use it as the transaction ID for refund or capture.
notesString""Caller-provided notes stored with the transaction and echoed in the normal payment result.
basicTokenString""Optional Basic authentication credential to apply before processing. An empty value keeps the current credentials. See Credential fields.
accountIdString""Optional account identifier to apply with a supplied token. An empty value preserves the current account.
environmentString""Environment selector applied with a supplied token, subject to the configured API-path precedence described above.
type valueMeaning
"sale"Charge the presented card for the requested total.
"auth"Authorize the requested total for a subsequent capture.
"refund"Start a card-present credit/refund. This request has no original transaction ID; use a refund request model below to refund an identified transaction.
"save"Read and tokenize/save the card without charging an amount. Returned token information, when available, is in TransactionDetails.

For example, amount = 10.00 and tip = 2.00 requests a total of 12.00.
Do not include the tip in amount a second time.

FullRefundRequest

Package: com.bluefin.blueposgo.sdk.request.

Identifies an existing transaction to refund. There is no amount field: BluePOS Go
uses the remaining refund balance when available, otherwise the original approved
amount or stored transaction total.

FieldKotlin typeDefaultDescription
transactionIdString?nullProcessor transaction ID from PaymentResponse.transactionDetails.transactionId. Supply a non-empty ID of a transaction stored by BluePOS Go. Although the model permits null, a missing or unknown ID cannot identify a transaction and results in failure.

PostProcessRequest

Package: com.bluefin.blueposgo.sdk.request.

Used for a refund of a specified amount or a capture of an earlier authorization.
These operations use the configured account and credentials; this model has no
credential fields.

FieldKotlin typeDefaultDescription
transactionIdStringNo defaultProcessor ID of the original transaction. For a refund, identify the transaction to refund; for a capture, identify the earlier authorization. Supply a non-empty ID, not a customID. The current refund flow looks up the original transaction in BluePOS Go's local history.
amountDouble0.0Amount to refund or capture, in major currency units. Must be greater than zero; 0.0 does not request an automatic full refund/capture. There is no separate tip field. Refund/capture eligibility and amount limits are determined when the operation is processed.
typePostProcessTypeNo defaultOperation discriminator. Use PostProcessType.REFUND with a refund request and PostProcessType.CAPTURE with a capture request. Keep the value consistent with the operation being called.

PostProcessType is declared in the same package:

Enum member.valueMeaning
REFUND"REFUND"Refund the specified amount against the original transaction.
CAPTURE"CAPTURE"Capture the specified amount against an earlier authorization.

PostProcessType.fromValue(...) matches .value exactly and returns null for
an unknown value or null input.

ClearDataRequest

Package: com.bluefin.blueposgo.sdk.request.

Starts a clear card-data read. Reading card data does not itself submit a payment.

FieldKotlin typeDefaultDescription
amountDouble0.0Amount carried in the reader request, in major currency units. The current clear-read implementation stores it as reader context and starts a magnetic-stripe read; it does not charge this amount. Use 0.0 for a data-only read.
timeOutIntNo defaultRead timeout in seconds, for example 60. Use a positive value to bound the wait. In the current Android implementation, values less than or equal to zero disable BluePOS Go's clear-read timeout timer; the AIDL model does not supply a default timeout.

Response models

InitResponse

Package: com.bluefin.blueposgo.sdk.response.

Used for both initialization and reboot results.

FieldKotlin typeDefaultDescription
statusStringNo defaultOperation result. Current initialization results use "initialized" or "error"; reboot results use "rebooted" or "error". These strings are lowercase and are distinct from the transaction Status enum.
errorMessageStringNo defaultHuman-readable explanation of a failed operation. Normally empty when no error message is returned.

This model does not contain requestId, reader serial number, or a numeric error
code. An empty or unrecognized status should not be treated as successful.

DeviceCommandResponse

Package: com.bluefin.blueposgo.sdk.response.

Returned by connect, disconnect, and forget operations.

FieldKotlin typeDefaultDescription
commandStringNo defaultExecuted command: "connect", "disconnect", or "forget".
statusStringNo defaultTerminal result: "connected", "disconnected", "forgotten", "cancelled", or "error". Match the success value to the command that was requested.
deviceNameStringNo defaultSaved or selected reader name when available; otherwise empty.
serialStringNo defaultReader serial number when available; otherwise empty.
errorCodeStringNo defaultMachine-readable failure code. Empty for a successful command. Cancellation uses "cancelled".
errorMessageStringNo defaultDiagnostic failure or cancellation message. Empty for a successful command.

Use status, not the presence of a name or serial number, to determine success.
The companion object exposes constants for all command and status strings.

PaymentResponse

Package: com.bluefin.blueposgo.sdk.response.

Contains the result of a payment, save-card operation, refund, or capture. The
transaction-list response also contains objects of this type.

FieldKotlin typeDefaultDescription
amountDouble0.0Amount associated with the result. For normal PaymentRequest results, this is the requested base amount excluding the separately returned tip. For successful linked refund/capture results, it is the processor's approved amount; those results return a zero tip. History items contain their stored amount. Use transactionDetails.amounts.approved for the processor-approved total when present.
transactionDetailsTransactionDetails?nullDetailed result containing status, processor transaction ID, authorization information, card details, and amounts. May be missing; see TransactionDetails.
tipDouble0.0Gratuity associated with the result. Normal payment results echo the request's tip; linked refund/capture results currently return 0.0.
typeString"sale"Transaction type label. Live results currently derive it from transactionDetails.transactionType, typically producing uppercase values such as "SALE" or "AUTHORIZATION". History items use their stored type string, which may be lowercase. Prefer the typed transactionDetails.transactionType when available; this field is not guaranteed to echo the request's type.
customIDString""Caller reference returned with a normal payment or stored history item. Current linked refund/capture results leave it empty.
notesString""Notes returned with a normal payment or stored history item. Current linked refund/capture results leave them empty.
processorMessageString""Processor or application message, when supplied. For a processor result, related information may also appear in transactionDetails.auth.processorMessage. Error details may instead be in transactionDetails.description.
errorCodeInt0Numeric error code when the result path provides one. 0 is also used when no numeric code is supplied, including some failures; it is not a success flag. History items currently retain the default 0.

Inspect transactionDetails.status to understand the outcome. For an approval,
also inspect transactionDetails.auth.message and transactionDetails.amounts
when present, since an authorization may be partially approved. If processor
details are unavailable, the current app creates a fallback TransactionDetails
with Status.FAILED and an explanatory description. Its fallback transaction
type is SALE, which does not necessarily describe the operation that failed.

ClearDataResponse

Package: com.bluefin.blueposgo.sdk.response.

Contains the result of reading clear card data. Check status before using the
returned card fields; a completed read can still report masked, encrypted, or
missing data.

FieldKotlin typeDefaultDescription
statusClearDataReadStatusNo defaultRead outcome. See the enum table below.
clearPanString?""Unmasked primary account number (PAN) extracted from the returned track data, when available. May be null or empty when no clear PAN is returned.
clearTrack2String?""Clear track data returned by the reader. The current app uses track 2 when present, but can fall back to track 1 and place that data in this field; callers must not assume the format is always track 2.
maskedPanString?""Field for a masked PAN, if supplied. The current clear-read result path does not populate it, including on DATA_MASKED; do not rely on it being present.
errorMessageString?""Explanation of why clear data could not be returned. May be empty or null when there is no message.

ClearDataReadStatus is declared in the same package:

Enum member.valueMeaning
CLEAR_DATA_RETURNED"returned"Clear track data and a parseable, unmasked PAN were obtained.
PAN_MISSING"pan_missing"A clear PAN could not be extracted from the returned track data.
TRACK2_MISSING"track2_missing"No usable clear track data was returned.
DATA_MASKED"data_masked"The reader returned masked data rather than a clear PAN.
DATA_ENCRYPTED"data_encrypted"Encrypted data was available, but usable clear card data was not.
WHITELIST_NOT_APPLIED"whitelist_not_applied"The reader's clear-data whitelist was not applied, so clear data is unavailable.
DEVICE_ERROR"device_error"The reader could not complete the clear-data operation.
TIMEOUT"timeout"The read timed out. The current Android response mapper also uses this value if the incoming status is missing or unrecognized.
CANCELLED"cancelled"The read was cancelled.

ClearDataReadStatus.fromValue(...) matches .value exactly and returns null
for an unknown value or null input.

PaymentTransactionResponse

Package: com.bluefin.blueposgo.sdk.response.

This additional transaction container is part of the SDK. The current AIDL
transaction-list callback returns List<PaymentResponse>, not this class.

FieldKotlin typeDefaultDescription
amountDouble0.0Base transaction amount in major currency units. No current AIDL result path populates this model; the constructing code supplies its value.
tipDouble0.0Gratuity associated with the transaction.
transactionDetailsTransactionDetailsNo defaultRequired detailed transaction object. Unlike the field on PaymentResponse, this property is non-nullable.
customIdString""Caller-defined transaction reference. Note the lowercase d, unlike PaymentRequest.customID and PaymentResponse.customID.
notesString""Notes associated with the transaction.

TransactionDetails

Package: com.bluefin.blueposgo.sdk.response.

Nested in PaymentResponse and PaymentTransactionResponse. Optional information
depends on the operation, card, and processor response; the presence of this
object does not guarantee that its nested fields are populated.

FieldKotlin typeDefaultDescription
statusStatus?No defaultTransaction outcome. This constructor argument is required but nullable. Status comes from com.bluefin.bluepos.poi.models; see the status table below.
transactionIdString?nullBluefin/processor transaction identifier. Retain it to identify the transaction in later refund or capture requests.
timestampjava.time.Instant?nullTime of the transaction, represented as an instant. It is distinct from the nested trace timestamp.
binDataBinDataResponse?nullCard program classification derived from BIN information.
transactionTypeTransactionType?nullTyped transaction category reported in the result. This response enum is distinct from PaymentRequest.type.
entryModeResponseEntryMode?nullHow the card information was entered, such as chip, contactless, or swipe.
responseTlvString?nullProcessor response in tag-length-value (TLV) form, when supplied, for example EMV response data.
cardCardResponse?nullCardholder name, card brand, BIN, last four digits, and expiry.
authAuthResponse?nullAuthorization code, authorization outcome, processor message, and verification results.
descriptionString?nullTransaction description or explanatory message. Also carries an error explanation in the app's fallback failure response.
customerCustomer?nullCustomer contact information and billing address, if returned.
shippingAddressShippingAddress?nullShipping address and recipient information, if returned.
traceTraceResponse?nullReferences and metadata used to trace the transaction, including history when available.
shieldConexTokenShieldConexCardToken?nullShieldConex card token information, if returned.
antiFraudRecommendationAntiFraudRecommendation?nullAnti-fraud recommendation, if available. This is separate from the transaction's processing status.
refundObjectRefundObject?nullRemaining refund balance and associated refund IDs.
bfTokenReferenceString?nullBluefin token reference intended for subsequent payments through APIs that accept it. The current PaymentRequest has no token-reference input field.
amountsAmountsResponse?nullRequested and approved totals, currency, gratuity, fees, and balance reported by the processor.
healthcareHealthcare?nullHealthcare and related benefit-category amounts, if returned.

The SDK class does not expose threeDSecure, level2, level3, items, or
dynamicDescriptor; commented-out declarations are not part of this model.

Transaction Status

Package: com.bluefin.bluepos.poi.models.

Enum memberMeaning
APPROVEDThe transaction was approved. Inspect the approved amount and authorization message for details.
DECLINEDThe transaction was declined.
FAILEDTransaction processing failed.
PENDINGThe transaction is pending; this is not a final approval.
INITIALIZEDThe transaction has been initialized.
AUTHORIZEDAn authorization was obtained; this is distinct from capture.
SAVEDCard/payment information was saved.
REFUNDEDA refund was processed.
VOIDEDThe transaction was voided.
CAPTUREDAn authorization was captured.
FORCEProcessor status for a force transaction.
CREDITEDA credit was processed.

These are values supported by the bundled model library, not a promise that
every status can be produced by every BluePOS Go operation.

TransactionType

Package: com.bluefin.blueposgo.sdk.response.

For each member, .value is the same uppercase string as its name.

Enum memberMeaning
SALESale transaction.
AUTHORIZATIONAuthorization transaction.
REFUNDRefund transaction.
CREDITCredit transaction; the card-present PaymentRequest refund flow submits a device credit.
DEBITDebit transaction.
STOREStore/tokenize payment information.
FORCEForce transaction.
REVERSALReversal transaction.
BALANCEBalance inquiry.
VOIDVoid transaction.
INITTransaction initialization.

The enum describes response categories; it does not add supported values to
PaymentRequest.type. TransactionType.fromValue(...) requires an exact match
and returns null for an unknown value or null input.

AntiFraudRecommendation

Package: com.bluefin.blueposgo.sdk.response.

Enum member.valueMeaning
ACCEPT"ACCEPT"The anti-fraud assessment recommends acceptance.
REJECT"REJECT"The anti-fraud assessment recommends rejection.

AntiFraudRecommendation.fromValue(...) requires an exact match and returns
null for an unknown value or null input. A missing recommendation does not
imply either acceptance or rejection.

RefundObject

Package: com.bluefin.blueposgo.sdk.response.

FieldKotlin typeDefaultDescription
refundBalanceString?No defaultRemaining refundable amount as a decimal string in major currency units, when supplied. The current full-refund flow uses it to determine the remaining amount to refund. The constructor requires this argument but accepts null.
refundIdsList<String>Empty listTransaction IDs of refunds associated with the original transaction. An empty list means no IDs were supplied.

Nested POI response models

All classes below are supplied by bluepos-poi-models-4.0.23.jar in package
com.bluefin.bluepos.poi.models. They are Java models exposed through Kotlin
getter properties. Their fields are reference types initialized to null,
including list fields. The tables use Kotlin-style nullable types to make that
runtime behavior explicit; do not assume Java platform types are non-null.

These fields can be returned as transaction metadata even though the current
request models do not provide matching input fields. Their presence depends on
the processor response. Defaults in these tables describe newly created POI
objects, not guarantees about populated responses.

AmountsResponse

Access through transactionDetails.amounts.

FieldKotlin-style typeDefaultDescription
currencyCurrency?nullCurrency of the amounts. The bundled Currency enum currently contains USD.
approvedString?nullTotal approved by the processor, for example "27.50". This can differ from the requested total on a partial approval.
requestedString?nullTotal requested from the processor, for example "27.50".
gratuityString?nullGratuity amount reported by the processor.
cashbackString?nullCashback amount reported by the processor.
surchargeString?nullSurcharge amount reported by the processor.
additionalFeeString?nullAdditional fee amount reported by the processor.
balanceString?nullTransaction balance: approved amount minus the sum of associated partial refunds. This is a transaction balance, not the cardholder's bank-account balance.

All amount strings use major currency units. They are processor totals/components;
do not add gratuity to approved again to calculate the approved total.

AuthResponse

Access through transactionDetails.auth.

FieldKotlin-style typeDefaultDescription
codeString?nullAuthorization code returned by the processor, for example "OK7805". It is not the transaction ID.
messageAuthMessageEnum?nullStructured authorization result, such as APPROVED, PARTIALLY_APPROVED, or DECLINED.
processorMessageString?nullHuman-readable processor message, for example "APPROVED".
networkNameString?nullAuthorization network used to process the transaction, when supplied.
avsResponseCodeAVSResponseCode?nullAddress verification service result code. This is a processor verification result, not the overall transaction status.
cvv2ResponseCodeCVV2ResponseCode?nullCard security-code verification result code. This contains the verification outcome, not the card's security code.

The bundled AuthMessageEnum contains APPROVED, FORCE, PARTIALLY_APPROVED,
INVALID_CARD_NUMBER, UNKNOWN, DECLINED, CCV_DECLINED, AVS_DECLINED,
INVALID_TRANSACTION, PROCESSING_EXCEPTION, TIMEOUT, INVALID_PIN,
INVALID_EXPIRY, SUSPECTED_FRAUD, VELOCITY_CHECK_FAILED, CAPTURED, and
PENDING. CCV_DECLINED is the enum's actual spelling.

BinDataResponse

Access through transactionDetails.binData.

FieldKotlin-style typeDefaultDescription
programBinDataResponse.ProgramEnum?nullCard program classification: STANDARD, UNKNOWN, HEALTHCARE, or FLEET.
programCardBinDataResponse.ProgramCardEnum?nullHealthcare card program, when applicable: FSA, HSA, or HRA.

CardResponse

Access through transactionDetails.card.

FieldKotlin-style typeDefaultDescription
nameString?nullCardholder name returned with the card information.
brandCardBrand?nullCard brand. The bundled enum contains VISA, MASTERCARD, DISCOVER, AMERICAN_EXPRESS, JCB, and DINERS_CLUB.
binString?nullCard BIN; the bundled model describes this as the first six digits of the card number.
last4String?nullLast four digits of the card number. Keep it as a string to preserve leading zeroes.
expiryString?nullCard expiration in MMYY format; for example, "1230" means December 2030.

ResponseEntryMode

Used by TransactionDetails.entryMode.

Enum memberMeaning
CONTACTContact chip entry.
CONTACTLESSContactless entry as classified by the processor.
NFCNear-field communication entry as classified by the processor.
SWIPEMagnetic-stripe swipe.
KEYEDManually entered card information.
FALLBACK_SWIPEMagnetic-stripe entry after chip-entry fallback.

Customer

Access through transactionDetails.customer.

FieldKotlin-style typeDefaultDescription
nameString?nullCustomer name.
emailString?nullCustomer email address.
phoneString?nullCustomer phone number as supplied.
billingAddressAddress?nullCustomer billing address, described below.

Address

Access through transactionDetails.customer.billingAddress.

FieldKotlin-style typeDefaultDescription
address1String?nullPrimary street-address line.
address2String?nullAdditional address line, such as a suite or apartment.
cityString?nullCity or locality.
stateString?nullState, province, or region, for example "GA".
zipString?nullPostal/ZIP code. Keep it as a string to preserve formatting and leading zeroes.
countryString?nullCountry value supplied by the processor; the bundled model example is "USA".
companyString?nullCompany associated with the address.

ShippingAddress

Access through transactionDetails.shippingAddress.

FieldKotlin-style typeDefaultDescription
address1String?nullPrimary shipping street-address line.
address2String?nullAdditional shipping address line.
cityString?nullShipping city or locality.
stateString?nullShipping state, province, or region.
zipString?nullShipping postal/ZIP code.
countryString?nullShipping country value; the bundled model example is "USA".
companyString?nullCompany at the shipping address.
recipientString?nullRecipient's name.
recipientPhoneString?nullRecipient's phone number.
recipientEmailString?nullRecipient's email address.

TraceResponse

Access through transactionDetails.trace.

FieldKotlin-style typeDefaultDescription
cashierString?nullCashier/operator or terminal reference associated with the transaction.
clientIpString?nullClient IP address recorded in the trace.
sourceIpString?nullSource IP address recorded in the trace.
sourceString?nullSource application/system label, such as "BluePos".
gpsLocationGpsLocation?nullLocation metadata, if supplied.
customIdString?nullCustom transaction reference recorded in the processor trace. It is separate from the top-level response field customID and may be absent.
timestampjava.util.Date?nullTrace timestamp. This uses Date, whereas TransactionDetails.timestamp uses Instant.
extTransactionIdString?nullExternal transaction identifier recorded in the trace.
networkTransactionIdString?nullIdentifier of the transaction created at the processor/network.
tagsList<String>?nullLabels attached to the transaction trace. May be null rather than an empty list.
historyList<TransactionHistoryRecord>?nullRecorded actions performed on the transaction. May be null rather than an empty list.
clickToPayTraceDataClickToPayTraceData?nullClick to Pay identifiers, when present in the processor response.

GpsLocation

Access through transactionDetails.trace.gpsLocation.

FieldKotlin-style typeDefaultDescription
latitudeString?nullLatitude represented as a string, for example "39.477446".
longitudeString?nullLongitude represented as a string, for example "-98.059873".
accuracyString?nullLocation accuracy reported by the source. The bundled model does not specify a unit.

TransactionHistoryRecord

Each element of transactionDetails.trace.history.

FieldKotlin-style typeDefaultDescription
actionTransactionHistoryRecord.ActionEnum?nullRecorded action. Members are INIT, UPDATE, AUTHORIZATION, CAPTURE, TRANSACTION, and REFUND; their serialized values are lowercase ("init", "update", and so on).
requestIdString?nullRequest ID associated with this historical action; not guaranteed to be the caller's InitRequest.requestId.
correlationIdString?nullCorrelation ID used to associate processing activity across systems.
timestampjava.util.Date?nullTime the action occurred.

ClickToPayTraceData

Access through transactionDetails.trace.clickToPayTraceData. This is optional
response metadata; the current AIDL request models do not expose a Click to Pay
operation.

FieldKotlin-style typeDefaultDescription
merchantTransactionIdString?nullUnique identifier for the merchant transaction.
correlationIdString?nullIdentifier for tracing the transaction across systems.
srcFlowIdString?nullSource flow identifier associated with the transaction.

ShieldConexCardToken

Access through transactionDetails.shieldConexToken.

FieldKotlin-style typeDefaultDescription
bfidString?nullBluefin identifier associated with the ShieldConex token data.
cardNumberString?nullCard-number value in the ShieldConex token object. Treat it as token data, not as the clear PAN returned by a clear-data read.
cardExpirationString?nullCard-expiration value in the token object. The bundled model does not define a readable date format for this field; do not assume the MMYY format of CardResponse.expiry.

Healthcare

Access through transactionDetails.healthcare. Values are decimal amount strings
in major currency units, for example "10.00", when returned by the processor.

FieldKotlin-style typeDefaultDescription
totalAmountString?nullTotal amount reported in the healthcare breakdown.
prescriptionString?nullPrescription-category amount.
visionString?nullVision-care amount.
dentalString?nullDental-care amount.
clinicalString?nullClinical/medical-care amount.
copayString?nullCopayment amount.
transitString?nullTransit-benefit amount included in this model.

Reference sources

Field names, Kotlin types, and defaults are defined in the SDK's
request models and
response models. Nested Java
models come from the bundled POI library.

Behavior notes reflect the current BluePOS Go application, including its
Android request/response mapper,
external request parsing,
payment result mapping,
refund/capture processing,
credential application, and
API path selection.

2. Constants

All constants in this section are top-level String constants declared in
com.bluefin.blueposgo.sdk. Import them directly, for example
import com.bluefin.blueposgo.sdk.EXTRA_PAYMENT_REQUEST.

They identify the BluePOS Go application, select the service or activity entry
point, and describe an operation in the activity's Intent. Use the SDK constants
when constructing Intents so the names match the installed application's protocol.

Application identifiers and Intent actions

These constants are shared by all operations.

ConstantString valuePurpose
BLUEPOS_GO_PACKAGEcom.bluefin.blueposgoAndroid package name of the BluePOS Go application. Use it with Intent.setPackage(...) when binding to the service and as the package argument of Intent.setClassName(...) when opening the activity.
BLUEPOS_GO_ACTIVITYcom.bluefin.blueposgo.MainActivityFully qualified activity class that receives external operation Intents. Use it as the class argument of setClassName(BLUEPOS_GO_PACKAGE, BLUEPOS_GO_ACTIVITY).
PAYMENT_SERVICE_ACTIONcom.bluefin.blueposgo.sdk.PaymentServiceIntent action for binding to the AIDL service. The binding Intent uses this action and targets BLUEPOS_GO_PACKAGE. The resulting connection provides access to PaymentServiceAIDL.
ACTION_EXTERNALcom.bluefin.blueposgo.sdk.action.ACTION_EXTERNALIntent action for delivering an external operation to the BluePOS Go activity. The activity's external-command handler processes Intents with this action. Set the explicit activity component using the package and activity constants above.

For example, the service-binding Intent is constructed as follows:

val serviceIntent = Intent(PAYMENT_SERVICE_ACTION)
    .setPackage(BLUEPOS_GO_PACKAGE)

PAYMENT_SERVICE_ACTION selects the service connection; ACTION_EXTERNAL
selects the activity's external-command handler. The particular operation is
selected separately through EXTRA_COMMAND.

Intent extra keys

ConstantString valueValue stored under this key
EXTRA_COMMANDcom.bluefin.blueposgo.sdk.extra.COMMANDA String command constant from the operation table below. It tells BluePOS Go which operation to execute.
EXTRA_PAYLOADcom.bluefin.blueposgo.sdk.extra.PAYLOADThe operation's SDK request object as an Android Parcelable. The class must match the selected command. Omit this extra for transaction-list, reboot, and device-command requests.

The operation constants below are values stored under EXTRA_COMMAND.
For example, a payment Intent contains
putExtra(EXTRA_COMMAND, EXTRA_PAYMENT_REQUEST) and
putExtra(EXTRA_PAYLOAD, paymentRequest). The payment request object is always
stored under EXTRA_PAYLOAD.

Operation command constants

The String suffix column gives the part after
com.bluefin.blueposgo.sdk.extra.. For example, the complete value of
EXTRA_INIT is com.bluefin.blueposgo.sdk.extra.INIT.

Command constantString suffixOperation and matching AIDL methodRequest in EXTRA_PAYLOAD
EXTRA_INITINITInitialize BluePOS Go and its reader, applying supplied credentials as described in section 1. Matches init(...). Perform initialization before the other commands.InitRequest
EXTRA_PAYMENT_REQUESTPAYMENT_REQUESTStart a new card operation. Matches payment(...); PaymentRequest.type selects sale ("sale"), authorization ("auth"), card-present credit/refund ("refund"), or save-card/tokenization ("save").PaymentRequest
EXTRA_FULL_REFUND_REQUESTFULL_REFUND_REQUESTRefund the remaining refundable amount of an identified transaction. Matches fullRefund(...); BluePOS Go determines the amount from the original transaction.FullRefundRequest
EXTRA_REFUND_REQUESTREFUND_REQUESTRefund a specified amount against an identified transaction. Matches refund(...).PostProcessRequest with type = PostProcessType.REFUND
EXTRA_CAPTURE_REQUESTCAPTURE_REQUESTCapture a specified amount against an earlier authorization. Matches capture(...).PostProcessRequest with type = PostProcessType.CAPTURE
EXTRA_CLEAR_DATA_REQUESTCLEAR_DATA_REQUESTStart a clear card-data read using the supplied reader context and timeout. Matches clearDataRead(...). This operation does not submit a payment.ClearDataRequest
EXTRA_TR_LIST_REQUESTTR_LIST_REQUESTRetrieve transactions stored by BluePOS Go. Matches getTransactionsListResponse(...).None; omit EXTRA_PAYLOAD.
EXTRA_REBOOTREBOOTRequest a reboot of the connected card reader. Matches reboot(...). This command targets the reader, not the Android device.None; omit EXTRA_PAYLOAD.
EXTRA_CONNECTCONNECTConnect the saved reader or show BluePOS Go's reader-selection flow. Matches connectDevice(...).None; omit EXTRA_PAYLOAD.
EXTRA_DISCONNECTDISCONNECTDisconnect the current reader while retaining the saved reader association. Matches disconnectDevice(...).None; omit EXTRA_PAYLOAD.
EXTRA_FORGETFORGETDisconnect the current reader and remove its saved association. Matches forgetDevice(...).None; omit EXTRA_PAYLOAD.

An authorization or save-card request uses EXTRA_PAYMENT_REQUEST with the
appropriate PaymentRequest.type; there are no separate authorization or
save-card command constants. A card-present PaymentRequest(type = "refund")
also uses EXTRA_PAYMENT_REQUEST. To refund an existing transaction by its ID,
use EXTRA_FULL_REFUND_REQUEST or EXTRA_REFUND_REQUEST as described above.

Combining the constants

The following fragment shows the Intent structure for a payment. It assumes
request is a PaymentRequest and uses android.content.Intent:

val operationIntent = Intent(ACTION_EXTERNAL)
    .setClassName(BLUEPOS_GO_PACKAGE, BLUEPOS_GO_ACTIVITY)
    .putExtra(EXTRA_COMMAND, EXTRA_PAYMENT_REQUEST)
    .putExtra(EXTRA_PAYLOAD, request)

In the current integration, first call the matching AIDL method with the request
and callback. Launch the operation Intent only if that method accepts the
operation by returning true. For operations with a payload, use the same
request in the AIDL call and the activity Intent: the activity handler reads the
request from EXTRA_PAYLOAD. Full service binding and launch code will be covered
in the integration example.

The current activity handler requires initialization for every command except
EXTRA_INIT. After a reader reboot, initialize again before sending further
commands. A required payload that is missing produces a request-not-received
error. Once the initialization check passes, an unrecognized command produces
an unknown-command error. Use the exact SDK command values and corresponding
request types from the table.

setDebugMode(...), getDebugMode(), hasOngoingOperations(), and
isInitialized() are direct AIDL calls. They have no corresponding operation
command constant or activity payload.

Constant reference sources

Names and values are defined in
Constants.kt.
The application manifest declares the
activity and service entry points. The
external-command handler
defines command routing and payload types, and the
AIDL interface
defines the matching service methods.

3. PaymentCallback interface

PaymentCallback receives asynchronous results from operations accepted by
PaymentServiceAIDL. Implement it by extending PaymentCallback.Stub and pass
the implementation to each asynchronous service method.

An accepted operation normally invokes one operation-specific callback method.
If BluePOS Go cannot complete or route the operation, it invokes onError(...)
instead. Callback methods run on a Binder thread; switch to the application's
main thread before changing views or other UI state.

Callback methods

CallbackCalled forParameterDescription
onPaymentResult(response)payment(...), fullRefund(...), refund(...), capture(...)PaymentResponseReports the transaction result. Inspect response.transactionDetails?.status, authorization data, and approved amounts to determine the outcome. Receiving this callback does not by itself mean the transaction was approved.
onClearDataResult(response)clearDataRead(...)ClearDataResponseReports the clear card-data read result. Check response.status before using clearPan or clearTrack2; the callback can report timeout, cancellation, masked/encrypted data, or another non-success status.
onTransactionsListResponse(response)getTransactionsListResponse(...)List<PaymentResponse>Returns the transactions stored by BluePOS Go. An empty list is a valid successful response meaning that no stored transactions are available. Each item uses the PaymentResponse model.
onInitResult(response)init(...)InitResponseReports initialization. Check for the expected success status "initialized"; otherwise inspect errorMessage.
onRebootResult(response)reboot(...)InitResponseReports the connected reader reboot request. The expected success status is "rebooted". After this callback, initialize BluePOS Go again before starting another operation.
onDeviceCommandResult(response)connectDevice(...), disconnectDevice(...), forgetDevice(...)DeviceCommandResponseReports the device command and its terminal status. Successful statuses are "connected", "disconnected", and "forgotten"; connect can also return "cancelled". For "error", inspect errorCode and errorMessage.
onError(message)Any asynchronous operationString? in generated KotlinReports that the requested operation could not be completed, for example because BluePOS Go is not initialized, a payload is missing, or a command cannot be routed. The message is intended for diagnostics and may change; do not use it as a stable machine-readable error code.

The AIDL source declares non-null response parameters, but generated Kotlin
overrides can expose AIDL reference parameters as platform or nullable types.
Handle a defensive null response if the generated signature permits it.

Threading and callback lifetime

  • Callback methods execute on a Binder thread. Use runOnUiThread, a main-thread
    Handler, or a coroutine dispatcher such as Dispatchers.Main for UI updates.
  • Keep a strong reference to the callback for as long as an operation can run.
    BluePOS Go retains the Binder callback for the accepted operation and releases
    it after delivering a result or onError.
  • Callback code should return promptly. Move database, network, or other lengthy
    work off the Binder thread.
  • Catch RemoteException around service calls. A Binder/service disconnect can
    prevent delivery of the expected callback; handle onServiceDisconnected and
    bind again when appropriate.
  • Each accepted operation produces at most one terminal callback through the
    current service implementation. Use the method's Boolean return value to know
    whether BluePOS Go accepted responsibility for that operation.

Kotlin callback skeleton

private val paymentCallback = object : PaymentCallback.Stub() {
    override fun onPaymentResult(response: PaymentResponse) {
        runOnUiThread {
            // Inspect response.transactionDetails?.status.
        }
    }

    override fun onClearDataResult(response: ClearDataResponse?) {
        runOnUiThread {
            // Check response?.status before reading card data.
        }
    }

    override fun onTransactionsListResponse(response: List<PaymentResponse?>?) {
        val transactions = response.orEmpty().filterNotNull()
        runOnUiThread {
            // Display or store transactions.
        }
    }

    override fun onInitResult(response: InitResponse?) {
        runOnUiThread {
            // Treat status == "initialized" as successful initialization.
        }
    }

    override fun onRebootResult(response: InitResponse?) {
        runOnUiThread {
            // Treat status == "rebooted" as success, then initialize again.
        }
    }

    override fun onDeviceCommandResult(response: DeviceCommandResponse?) {
        runOnUiThread {
            // Check response?.command and response?.status.
        }
    }

    override fun onError(message: String?) {
        runOnUiThread {
            // Report message.orEmpty() and restore the calling UI state.
        }
    }
}

The exact platform nullability exposed to Kotlin can vary with the Android build
tools. If an override differs, use the method signature generated from the AAR in
the consuming project.

Callback reference sources

The callback contract is defined in
PaymentCallback.aidl.
Result dispatch and operation-state cleanup are implemented by
PaymentService.kt.

4. PaymentServiceAIDL methods

PaymentServiceAIDL is the Binder interface obtained after binding to BluePOS
Go with PAYMENT_SERVICE_ACTION. It contains eleven asynchronous operation
methods and four direct service-state methods.

Asynchronous operation lifecycle

Calling an asynchronous service method reserves BluePOS Go for the operation and
registers its callback. It does not by itself open the BluePOS Go UI or start the
card-reader workflow. After the method returns true, launch the matching
ACTION_EXTERNAL activity Intent described in section 2. For methods with a
request, put the same request object in EXTRA_PAYLOAD.

Call AIDL method -> Boolean accepted? -> Launch matching activity Intent
                                      -> Receive one result callback or onError

Only one asynchronous operation can be active across the service at a time:

  • true means the service accepted the operation and stored its callback. It
    does not mean that payment, initialization, or another operation succeeded.
  • false means another operation is already active. BluePOS Go does not register
    the new request or callback, and no callback is expected for that rejected call.
    Do not launch its activity Intent.
  • A terminal result or onError releases the active-operation slot.
  • If the caller receives true but does not launch the matching activity Intent,
    the reserved operation cannot progress and remains active. Avoid abandoning an
    accepted operation between the service call and activity launch.
  • With the exception of init(...), operation Intents require the service to be
    initialized. Call init(...) successfully before other operations and again
    after a reader reboot.

The service method and activity Intent must describe the same operation. For
example, pair service.refund(request, callback) with
EXTRA_REFUND_REQUEST, not another command value.

Transaction and device operations

payment(request, callback): Boolean

Accepts a PaymentRequest for a sale, authorization, card-present credit/refund,
or save-card/tokenization operation. request.type selects the operation as
documented in section 1.

  • Intent command: EXTRA_PAYMENT_REQUEST
  • Intent payload: the same PaymentRequest
  • Success/result callback: onPaymentResult(PaymentResponse)
  • Error callback: onError(String)

The Boolean return reports whether the service accepted the operation, not
whether the transaction was approved.

fullRefund(request, callback): Boolean

Requests a refund of the remaining refundable amount for the transaction
identified by FullRefundRequest.transactionId.

  • Intent command: EXTRA_FULL_REFUND_REQUEST
  • Intent payload: the same FullRefundRequest
  • Success/result callback: onPaymentResult(PaymentResponse)
  • Error callback: onError(String)

The original transaction must be available to BluePOS Go. A missing or unknown
transaction ID cannot be processed.

clearDataRead(request, callback): Boolean

Starts a clear card-data read using a ClearDataRequest. This reads card data
from the connected reader and does not submit a payment.

  • Intent command: EXTRA_CLEAR_DATA_REQUEST
  • Intent payload: the same ClearDataRequest
  • Result callback: onClearDataResult(ClearDataResponse)
  • Error callback: onError(String)

The returned ClearDataResponse.status determines whether usable clear data is
available.

refund(request, callback): Boolean

Requests a refund of PostProcessRequest.amount against an existing transaction.
Set request.type to PostProcessType.REFUND.

  • Intent command: EXTRA_REFUND_REQUEST
  • Intent payload: the same PostProcessRequest
  • Success/result callback: onPaymentResult(PaymentResponse)
  • Error callback: onError(String)

The original transaction is looked up by transactionId; the amount must be
positive and must be eligible for refund.

capture(request, callback): Boolean

Captures PostProcessRequest.amount against an earlier authorization. Set
request.type to PostProcessType.CAPTURE.

  • Intent command: EXTRA_CAPTURE_REQUEST
  • Intent payload: the same PostProcessRequest
  • Success/result callback: onPaymentResult(PaymentResponse)
  • Error callback: onError(String)

The request must identify an authorization that can be captured.

init(request, callback): Boolean

Initializes BluePOS Go and its reader using InitRequest. It can also apply the
request's API credentials as documented in section 1.

  • Intent command: EXTRA_INIT
  • Intent payload: the same InitRequest
  • Result callback: onInitResult(InitResponse)
  • Error callback: onError(String)

Check InitResponse.status; the expected success value is "initialized".
Do not interpret the method's true return as successful initialization.

reboot(callback): Boolean

Requests a reboot of the connected card reader. It does not reboot the Android
device.

  • Intent command: EXTRA_REBOOT
  • Intent payload: none
  • Result callback: onRebootResult(InitResponse)
  • Error callback: onError(String)

Check for the expected success status "rebooted". The current service clears
its initialized state when it dispatches the reboot result, including an error
result, so call init(...) before the next operation.

connectDevice(callback): Boolean

Connects the saved reader. If no reader is saved, BluePOS Go opens its reader
selection and pairing flow.

  • Intent command: EXTRA_CONNECT
  • Intent payload: none
  • Result callback: onDeviceCommandResult(DeviceCommandResponse)
  • Error callback: onError(String)

The success status is "connected". If the selection flow is closed without a
connection, the status is "cancelled". A status of "error" includes stable
errorCode and diagnostic errorMessage values. The returned deviceName or
serial can be empty when the reader does not provide that value.

disconnectDevice(callback): Boolean

Disconnects and releases the current reader without removing the saved reader
association, allowing a later connection to reuse it.

  • Intent command: EXTRA_DISCONNECT
  • Intent payload: none
  • Result callback: onDeviceCommandResult(DeviceCommandResponse)
  • Error callback: onError(String)

The success status is "disconnected". Disconnecting when no reader is active
is treated as successful. A status of "error" includes errorCode and
errorMessage.

forgetDevice(callback): Boolean

Disconnects and releases the current reader and removes BluePOS Go's saved
reader association.

  • Intent command: EXTRA_FORGET
  • Intent payload: none
  • Result callback: onDeviceCommandResult(DeviceCommandResponse)
  • Error callback: onError(String)

The success status is "forgotten". Forgetting when no reader is active is
valid. A later connectDevice(...) call opens reader selection again.

getTransactionsListResponse(callback): Boolean

Requests transactions stored by BluePOS Go.

  • Intent command: EXTRA_TR_LIST_REQUEST
  • Intent payload: none
  • Result callback: onTransactionsListResponse(List<PaymentResponse>)
  • Error callback: onError(String)

An empty returned list is a successful result with no stored transactions.

Direct service-state methods

These methods communicate directly with the bound service. They do not reserve
an asynchronous operation, use PaymentCallback, or require an activity Intent.
As Binder calls, they can throw RemoteException.

MethodDescription
setDebugMode(debugMode: Boolean)Enables or disables additional logging for external-command handling. This setting affects diagnostics only; it does not change transaction behavior. The current value is kept in the BluePOS Go process and is not documented as persistent across process restarts. Avoid enabling it in production unless needed for troubleshooting.
getDebugMode(): BooleanReturns the current debug-mode setting controlled by setDebugMode(...).
hasOngoingOperations(): BooleanReturns true after an asynchronous operation has been accepted and until its terminal result or error is dispatched. Use it as a snapshot for UI or diagnostics; a later operation can change the value immediately.
isInitialized(): BooleanReturns the service's internal initialization flag. The flag becomes true only when an InitResponse with status "initialized" is dispatched and becomes false after a reboot result. The value is process-local and is not a substitute for handling service disconnection or reader state changes.

Exceptions, disconnection, and process lifetime

  • Wrap AIDL calls in try/catch (e: RemoteException). A call can fail if the
    remote process or Binder connection is unavailable.
  • Set the local PaymentServiceAIDL reference to null in
    onServiceDisconnected. Bind again before starting another operation.
  • Service flags and debug mode belong to the running BluePOS Go process. Do not
    treat them as durable state across application restarts.
  • Validate request values before calling the service. A true acceptance return
    reserves the service, while request validation and actual processing occur
    after the activity command is delivered.

Method reference sources

The public interface is defined in
PaymentServiceAIDL.aidl.
Acceptance, busy-state, initialization-state, and debug-mode behavior are
implemented in
PaymentService.kt.
Activity command validation and routing are implemented in
ExternalPaymentProcessor.kt.

5. Integration example

This example is adapted from the TestAIDL_GO sample application. It shows the
complete Android flow:

  1. Add the BluePOS Go SDK AAR.
  2. Declare package visibility for BluePOS Go.
  3. Bind to PaymentServiceAIDL.
  4. Implement PaymentCallback.
  5. Initialize BluePOS Go and wait for onInitResult.
  6. For each operation, call the matching AIDL method and then launch the matching
    BluePOS Go activity Intent if the method returns true.
  7. Receive the result through the callback and unbind when the activity stops.

Add the SDK dependency

Copy the complete versioned AAR into the consuming application's app/libs
directory. Do not extract only classes.jar, because the AAR also supplies
consumer ProGuard/R8 rules required for parcelable class names.

In app/build.gradle.kts:

dependencies {
    implementation(files("libs/blueposgo-sdk-1.0.0.aar"))
}

For a Groovy build script, use:

dependencies {
    implementation files("libs/blueposgo-sdk-1.0.0.aar")
}

The consuming application must use Android API 26 or later, matching the SDK's
minimum API level.

Declare BluePOS Go package visibility

Add the following <queries> block as a direct child of <manifest> in the
consuming application's AndroidManifest.xml. This lets the application discover
the BluePOS Go package and payment service on Android versions that enforce
package visibility.

<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <queries>
        <package android:name="com.bluefin.blueposgo" />
        <intent>
            <action android:name="com.bluefin.blueposgo.sdk.PaymentService" />
        </intent>
    </queries>

    <application>
        <!-- Your application components. -->
    </application>
</manifest>

BluePOS Go must be installed on the device. Its exported AIDL service and activity
are implemented by the BluePOS Go application; the SDK AAR only supplies the
client interface, constants, and parcelable models.

Provide credentials securely

Initialization can use credentials already configured in BluePOS Go or credentials
supplied in InitRequest. The example below accepts accountId, basicToken, and
environment as parameters so no secrets are embedded in the documentation.

basicToken accepts either Basic <Base64(apiKey:apiSecret)> or the encoded
credential without the prefix. If the consuming application constructs it, the
equivalent of the sample application's helper is:

fun buildBasicToken(apiKey: String, apiSecret: String): String {
    val credentials = "$apiKey:$apiSecret"
    val encoded = android.util.Base64.encodeToString(
        credentials.toByteArray(Charsets.UTF_8),
        android.util.Base64.NO_WRAP
    )
    return "Basic $encoded"
}

Do not commit API keys, secrets, or generated tokens to source control. Load them
from the consuming application's approved secure configuration or provisioning
flow. Supported environment selectors are described under InitRequest in
section 1.

Bind, initialize, and run operations

The following activity contains the core integration code. Replace showStatus
with the consuming application's UI or state-management logic. The example uses
the callback signatures generated by the current SDK AAR.

package com.example.blueposclient

import android.content.ActivityNotFoundException
import android.content.ComponentName
import android.content.Intent
import android.content.ServiceConnection
import android.os.Bundle
import android.os.IBinder
import android.os.Parcelable
import android.os.RemoteException
import androidx.activity.ComponentActivity
import com.bluefin.blueposgo.sdk.ACTION_EXTERNAL
import com.bluefin.blueposgo.sdk.BLUEPOS_GO_ACTIVITY
import com.bluefin.blueposgo.sdk.BLUEPOS_GO_PACKAGE
import com.bluefin.blueposgo.sdk.EXTRA_CAPTURE_REQUEST
import com.bluefin.blueposgo.sdk.EXTRA_CLEAR_DATA_REQUEST
import com.bluefin.blueposgo.sdk.EXTRA_COMMAND
import com.bluefin.blueposgo.sdk.EXTRA_CONNECT
import com.bluefin.blueposgo.sdk.EXTRA_DISCONNECT
import com.bluefin.blueposgo.sdk.EXTRA_FORGET
import com.bluefin.blueposgo.sdk.EXTRA_FULL_REFUND_REQUEST
import com.bluefin.blueposgo.sdk.EXTRA_INIT
import com.bluefin.blueposgo.sdk.EXTRA_PAYLOAD
import com.bluefin.blueposgo.sdk.EXTRA_PAYMENT_REQUEST
import com.bluefin.blueposgo.sdk.EXTRA_REBOOT
import com.bluefin.blueposgo.sdk.EXTRA_REFUND_REQUEST
import com.bluefin.blueposgo.sdk.EXTRA_TR_LIST_REQUEST
import com.bluefin.blueposgo.sdk.PAYMENT_SERVICE_ACTION
import com.bluefin.blueposgo.sdk.PaymentCallback
import com.bluefin.blueposgo.sdk.PaymentServiceAIDL
import com.bluefin.blueposgo.sdk.request.ClearDataRequest
import com.bluefin.blueposgo.sdk.request.FullRefundRequest
import com.bluefin.blueposgo.sdk.request.InitRequest
import com.bluefin.blueposgo.sdk.request.PaymentRequest
import com.bluefin.blueposgo.sdk.request.PostProcessRequest
import com.bluefin.blueposgo.sdk.request.PostProcessType
import com.bluefin.blueposgo.sdk.response.ClearDataResponse
import com.bluefin.blueposgo.sdk.response.DeviceCommandResponse
import com.bluefin.blueposgo.sdk.response.InitResponse
import com.bluefin.blueposgo.sdk.response.PaymentResponse

class MainActivity : ComponentActivity() {

    private var service: PaymentServiceAIDL? = null
    private var isBound = false
    @Volatile
    private var initialized = false

    private val callback = object : PaymentCallback.Stub() {
        override fun onPaymentResult(response: PaymentResponse) {
            runOnUiThread {
                val details = response.transactionDetails
                showStatus(
                    "Transaction status: ${details?.status}\n" +
                        "Transaction ID: ${details?.transactionId.orEmpty()}\n" +
                        "Processor message: ${response.processorMessage}"
                )
            }
        }

        override fun onClearDataResult(response: ClearDataResponse?) {
            runOnUiThread {
                showStatus(
                    "Clear-data status: ${response?.status}\n" +
                        "Error: ${response?.errorMessage.orEmpty()}"
                )
            }
        }

        override fun onTransactionsListResponse(
            response: List<PaymentResponse?>?
        ) {
            val transactions = response.orEmpty().filterNotNull()
            runOnUiThread {
                showStatus("Received ${transactions.size} transaction(s)")
            }
        }

        override fun onInitResult(response: InitResponse?) {
            initialized = response?.status == "initialized"
            runOnUiThread {
                showStatus(
                    if (initialized) {
                        "BluePOS Go initialized"
                    } else {
                        "Initialization failed: ${response?.errorMessage.orEmpty()}"
                    }
                )
            }
        }

        override fun onRebootResult(response: InitResponse?) {
            initialized = false
            runOnUiThread {
                showStatus(
                    "Reader reboot status: ${response?.status}\n" +
                        "Initialize BluePOS Go again before the next operation."
                )
            }
        }

        override fun onDeviceCommandResult(response: DeviceCommandResponse?) {
            runOnUiThread {
                showStatus(
                    "Device command: ${response?.command}\n" +
                        "Status: ${response?.status}\n" +
                        "Reader: ${response?.deviceName.orEmpty()}\n" +
                        "Serial: ${response?.serial.orEmpty()}\n" +
                        "Error: ${response?.errorMessage.orEmpty()}"
                )
            }
        }

        override fun onError(message: String?) {
            runOnUiThread {
                showStatus("BluePOS Go error: ${message.orEmpty()}")
            }
        }
    }

    private val connection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName?, binder: IBinder?) {
            service = PaymentServiceAIDL.Stub.asInterface(binder)
            showStatus("Connected to BluePOS Go")
        }

        override fun onServiceDisconnected(name: ComponentName?) {
            service = null
            initialized = false
            showStatus("BluePOS Go service disconnected")
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // Set up the consuming application's UI here.
    }

    override fun onStart() {
        super.onStart()

        val serviceIntent = Intent(PAYMENT_SERVICE_ACTION)
            .setPackage(BLUEPOS_GO_PACKAGE)

        isBound = bindService(serviceIntent, connection, BIND_AUTO_CREATE)
        if (!isBound) {
            showStatus("BluePOS Go service was not found")
        }
    }

    override fun onStop() {
        if (isBound) {
            unbindService(connection)
            isBound = false
        }
        service = null
        super.onStop()
    }

    fun initializeBluePosGo(
        accountId: String,
        basicToken: String,
        environment: String
    ) {
        val request = InitRequest(
            requestId = java.util.UUID.randomUUID().toString(),
            accountId = accountId,
            basicToken = basicToken,
            environment = environment
        )
        startOperation(EXTRA_INIT, request)
    }

    fun makeSale(amount: Double, tip: Double = 0.0, orderId: String = "") {
        require(amount > 0) { "Sale amount must be greater than zero" }
        require(tip >= 0) { "Tip must not be negative" }

        val request = PaymentRequest(
            amount = amount,
            tip = tip,
            type = "sale",
            customID = orderId,
            notes = "External Android application"
        )
        startOperation(EXTRA_PAYMENT_REQUEST, request)
    }

    fun authorize(amount: Double, tip: Double = 0.0) {
        require(amount > 0) { "Authorization amount must be greater than zero" }
        require(tip >= 0) { "Tip must not be negative" }

        val request = PaymentRequest(
            amount = amount,
            tip = tip,
            type = "auth"
        )
        startOperation(EXTRA_PAYMENT_REQUEST, request)
    }

    fun saveCard() {
        val request = PaymentRequest(type = "save")
        startOperation(EXTRA_PAYMENT_REQUEST, request)
    }

    fun refund(transactionId: String, amount: Double) {
        require(transactionId.isNotBlank()) { "Transaction ID is required" }
        require(amount > 0) { "Refund amount must be greater than zero" }

        val request = PostProcessRequest(
            transactionId = transactionId,
            amount = amount,
            type = PostProcessType.REFUND
        )
        startOperation(EXTRA_REFUND_REQUEST, request)
    }

    fun fullRefund(transactionId: String) {
        require(transactionId.isNotBlank()) { "Transaction ID is required" }

        val request = FullRefundRequest(transactionId = transactionId)
        startOperation(EXTRA_FULL_REFUND_REQUEST, request)
    }

    fun capture(transactionId: String, amount: Double) {
        require(transactionId.isNotBlank()) { "Transaction ID is required" }
        require(amount > 0) { "Capture amount must be greater than zero" }

        val request = PostProcessRequest(
            transactionId = transactionId,
            amount = amount,
            type = PostProcessType.CAPTURE
        )
        startOperation(EXTRA_CAPTURE_REQUEST, request)
    }

    fun readClearCardData(timeoutSeconds: Int = 60) {
        require(timeoutSeconds > 0) { "Timeout must be greater than zero" }

        val request = ClearDataRequest(amount = 0.0, timeOut = timeoutSeconds)
        startOperation(EXTRA_CLEAR_DATA_REQUEST, request)
    }

    fun loadTransactions() {
        startOperation(EXTRA_TR_LIST_REQUEST)
    }

    fun rebootReader() {
        startOperation(EXTRA_REBOOT)
    }

    fun connectReader() {
        startOperation(EXTRA_CONNECT)
    }

    fun disconnectReader() {
        startOperation(EXTRA_DISCONNECT)
    }

    fun forgetReader() {
        startOperation(EXTRA_FORGET)
    }

    private fun startOperation(command: String, request: Parcelable? = null) {
        val remoteService = service
        if (remoteService == null) {
            showStatus("BluePOS Go service is not connected")
            return
        }

        if (command != EXTRA_INIT && !initialized) {
            showStatus("Initialize BluePOS Go before starting this operation")
            return
        }

        val operationIntent = Intent(ACTION_EXTERNAL)
            .setClassName(BLUEPOS_GO_PACKAGE, BLUEPOS_GO_ACTIVITY)
            .putExtra(EXTRA_COMMAND, command)
            .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP)
            .also { intent ->
                request?.let { intent.putExtra(EXTRA_PAYLOAD, it) }
            }

        if (operationIntent.resolveActivity(packageManager) == null) {
            showStatus("BluePOS Go activity was not found")
            return
        }

        try {
            val accepted = when (command) {
                EXTRA_INIT ->
                    remoteService.init(request as InitRequest, callback)

                EXTRA_PAYMENT_REQUEST ->
                    remoteService.payment(request as PaymentRequest, callback)

                EXTRA_FULL_REFUND_REQUEST ->
                    remoteService.fullRefund(request as FullRefundRequest, callback)

                EXTRA_REFUND_REQUEST ->
                    remoteService.refund(request as PostProcessRequest, callback)

                EXTRA_CAPTURE_REQUEST ->
                    remoteService.capture(request as PostProcessRequest, callback)

                EXTRA_CLEAR_DATA_REQUEST ->
                    remoteService.clearDataRead(request as ClearDataRequest, callback)

                EXTRA_TR_LIST_REQUEST ->
                    remoteService.getTransactionsListResponse(callback)

                EXTRA_REBOOT ->
                    remoteService.reboot(callback)

                EXTRA_CONNECT ->
                    remoteService.connectDevice(callback)

                EXTRA_DISCONNECT ->
                    remoteService.disconnectDevice(callback)

                EXTRA_FORGET ->
                    remoteService.forgetDevice(callback)

                else -> error("Unsupported BluePOS Go command: $command")
            }

            if (!accepted) {
                showStatus("BluePOS Go is busy with another operation")
                return
            }

            startActivity(operationIntent)
            showStatus("Operation started; waiting for callback")
        } catch (e: RemoteException) {
            showStatus("BluePOS Go service error: ${e.message.orEmpty()}")
        } catch (e: ActivityNotFoundException) {
            showStatus("BluePOS Go activity was not found")
        } catch (e: ClassCastException) {
            showStatus("Request type does not match the selected command")
        }
    }

    private fun showStatus(message: String) {
        // Replace with a TextView, Compose state, ViewModel event, or logging.
        android.util.Log.d("BluePosClient", message)
    }
}

Call initializeBluePosGo(...) only after onServiceConnected has run. Wait for
onInitResult with status "initialized" before calling makeSale(...) or any
other operation. A typical sequence is:

initializeBluePosGo(
    accountId = securelyLoadedAccountId,
    basicToken = securelyLoadedBasicToken,
    environment = "CERT"
)

// Later, after onInitResult reports "initialized":
makeSale(amount = 12.50, tip = 2.00, orderId = "order-123")

amount and tip use major currency units. If the UI collects integer minor
units, convert them once before creating the request; for example, 1250 cents
becomes 12.50. Avoid converting an already decimal amount a second time.

Important integration behavior

  • BluePOS Go must be installed before binding or launching its activity.
  • Do not launch the operation Intent when the AIDL method returns false; no
    callback is registered for that rejected call.
  • The activity Intent is required even after the service accepts an operation.
    Android 14 restrictions prevent the background service from opening the
    activity on the caller's behalf.
  • Pass the same request object to the service and in EXTRA_PAYLOAD so the AIDL
    reservation and activity command stay consistent.
  • Keep only one operation in flight. Enable the next action after a result callback
    or onError arrives.
  • After onRebootResult, run initialization again before another operation.
  • Connect, disconnect, and forget require successful initialization and return
    through onDeviceCommandResult.
  • Treat callback statuses as authoritative. The Boolean service return only means
    the operation was accepted for processing.
  • Clear PAN and track data are sensitive payment data. Do not log, persist, or
    display clearPan or clearTrack2 unless the integration's security and PCI
    requirements explicitly permit it.

The full TestAIDL_GO sample also demonstrates a Compose UI, debug-mode control,
transaction-list display, and request helper functions. The example above keeps
only the code needed to integrate the SDK from an external Android application.


Did this page help you?