protocol-retailer

The protocol-retailer module provides the definitive implementation of the Retailer (POI-PIS) protocol. It is the primary high-level communication language between Sale Systems (ECR) and Payment Terminals (POI) within the App2AppSDK, featuring robust support for both XML and JSON data encapsulations.

Overview

pl.novelpay.retailer

The initialization and orchestration root for the protocol.

  • src/main/java/pl/novelpay/retailer/RetailerProtocol.kt: The concrete implementation of pl.novelpay.protocol.Protocol.

  • src/main/java/pl/novelpay/retailer/RetailerProtocolFactory.kt: The singleton factory that assembles the complex dependency graph of the Retailer module.

pl.novelpay.retailer.configuration

Static environment and identity definitions.

  • src/main/java/pl/novelpay/retailer/configuration/RetailerConfiguration.kt: Defines crucial terminal identification attributes such as poiID, saleID, and SoftwareComponent metadata.

pl.novelpay.retailer.client

The primary developer surface for interacting with the Retailer protocol.

  • src/main/java/pl/novelpay/retailer/RetailerProtocol.kt: An exhaustive API contract defining business capabilities (sendPaymentRequest, sendReversalRequest, etc.).

  • src/main/java/pl/novelpay/retailer/client/RetailerCommunicationInterfaceImpl.kt: The concrete router that binds high-level SDK method calls to underlying domain message generation.

pl.novelpay.retailer.message

The domain model declarations, strictly categorized by intent.

  • request.*: Initiators of operations (e.g., src/main/java/pl/novelpay/retailer/message/request/RetailerPaymentRequest.kt, src/main/java/pl/novelpay/retailer/message/request/RetailerLoginRequest.kt).

  • response.*: Results of operations (e.g., src/main/java/pl/novelpay/retailer/message/response/RetailerPaymentResponse.kt).

  • src/main/java/pl/novelpay/retailer/message/RetailerRawMessageType.kt: The low-level envelope representing the raw XML/JSON string before domain parsing.

pl.novelpay.retailer.conversion

The transformation engine powering the protocol.

  • src/main/java/pl/novelpay/retailer/conversion/RetailerRawDomainConverterImpl.kt: Uses strategy patterns (src/main/java/pl/novelpay/retailer/converter/set/RetailerConvertersSet.kt) to map parsed XML/JSON into concrete Kotlin data classes.

  • src/main/java/pl/novelpay/retailer/conversion/RetailerRawTypeConverterImpl.kt: The RawReader implementation that performs the initial text analysis to determine message type.

pl.novelpay.retailer.runtime

Session and state persistence.

  • src/main/java/pl/novelpay/retailer/runtime/RetailerProtocolRuntimeStorage.kt: Maintains dynamic configuration like the active MessageFormat (XML vs JSON) and session IDs.

Standard Usage Example

// Obtain the communication interface interface
val retailerApi = sdk.provideCommunicationInterface(RetailerCommunicationInterface::class)

// Configure protocol optimizations dynamically
retailerApi.switchMessageFormat(MessageFormat.JSON)

// Dispatch a domain operation
retailerApi.sendPaymentRequest(
PaymentRequestMessageArguments.RegularPaymentRequestMessageArguments(
amount = 125.50,
currency = "PLN"
)
)

Protocol Versioning and Message Migration

To ensure backward compatibility between the SDK and the payment application, the SDK implements a message migration mechanism. This system allows the SDK to modify outgoing domain messages on-the-fly to conform to the specific protocol version supported by the connected payment application.

The Migration Process

  1. Version Detection: When the SDK establishes a connection, it queries the payment application to get the specific version of the Retailer protocol it is using. This is handled by ProtocolVersionMigrationEnvironmentImpl, which makes an IPC call to the server.

  2. Migration Execution: Before a DomainMessage is sent, it passes through the MigrateSendingDomainMessage processor. This processor applies a list of registered migrations to the message. Each migration is a class that extends MessageMigration.

  3. Conditional Logic: Inside each migration class, the ServerClientMigrationEnvironment provides helper functions like forVersions(...) and notForVersions(...) to execute logic conditionally based on the detected protocol version.

Example: DonationsMigration

A practical example is the DonationsMigration. If a new donations field was added in version 1.3 of the protocol, older versions of the payment application would not understand it. This migration ensures that for any protocol version that is not 1.3, the donations field is removed from the RetailerPaymentRequest before it is sent.

// DonationsMigration.kt
class DonationsMigration : MessageMigration() {
override fun migrate(message: DomainMessage): DomainMessage =
// Only run this logic for versions that are NOT "1.3"
serverClientMigrationEnvironment.notForVersions("1.3") { version ->
when (message) {
is RetailerPaymentRequest -> message.copy(
// Remove the unsupported field
marketpayPaymentExtensions = extensions.copy(additionalAmount = null)
)
else -> message
}
} ?: message // If the version is 1.3, return the original message
}

Important: Maintaining Migrations

It is crucial to maintain migration classes as new protocol versions are released. For example, the DonationsMigration uses notForVersions("1.3"). If a new version 1.4 is released (which presumably supports donations), this logic would incorrectly remove the donations field when communicating with a 1.4 server.

To prevent this, migrations must be updated to be explicit about the versions they target. The logic should be changed to either:

  • Specify incompatible versions: forVersions("1.0", "1.1", "1.2") { ... }

  • Explicitly exclude all newer versions: notForVersions("1.3", "1.4") { ... }

Forgetting to update these classes will lead to incorrect message formatting and potential communication failures with new server versions.

Packages

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard