Loymax, 2026

Receipt history migration


During transition to Loymax Loyalty Program (LP), a Company purchase history can be imported into Loymax Loyalty. As a result, customers will see their purchase history from the previous loyalty program.

This article presents a simplified integration contract. The format is used when migrating historical receipts from external loyalty programs for display in personal accounts and CRM systems. The description focuses on the historical data migration scenario and does not cover all Loymax integration capabilities. Examples are provided in simplified form and reflect minimal valid structures.

Company data is transmitted to Loymax via a special utility and the messaging broker Apache Kafka. The utility converts the JSON file provided by the Company into a historical record model. The sender publishes the message to Kafka in the topic hist-items-records. The consumer HistoryItemsConsumer reads the message, converts it to protobuf format, and writes it to the History database. As a result, when accessing the Loymax history service via API in the Admin Panel, Personal Account, or Mobile App, the customer's receipt history is displayed.

Data processing speed

The size of the data batch processed by the utility is fixed and equals 100. The optimal batch size for the HistoryItemsConsumer consumer is 1000. The processing time per message reaches 0.36 ms. Increasing the batch size in consumer settings increases processing time: 0.52 ms per message at a batch size of 10,000. Parallel operation of the utility and consumer reduces processing time to 0.22 ms per message.

Types of purchases to import

Purchase without detailed discounts and bonus pointsReceipt with item composition and total amount without revealing discount, accrual, and deduction mechanics.
Purchase with line-item discountsReceipt where applied discounts are recorded for individual items.
Purchase with line-item bonus points (with multi-currency support)Receipt where bonus accruals are reflected for specific items.
Purchase with bonus points deductionReceipt where the customer used bonus points to pay part of the purchase.
Separate accrual or deduction operations without a purchaseBonus operations not linked to a specific receipt (e.g., manual corrections or expiration).

Structure of transmitted data

When transmitting purchase data, a single structure is used, including the following logical blocks:

  1. General information about the purchase event.
  2. Data about the purchase itself.
  3. Receipt composition (item positions).
  4. Discounts, accruals, and deductions (if applicable).
  5. Payment information (if necessary).
  6. Additional attributes and auxiliary data (optional).

Each of the above blocks is described below, specifying required and optional parameters.

  • Minimum required parameters are marked as required.
  • Optional fields are either left unfilled or filled with default values.
FieldRequiredData TypeDescription
externalIdRequiredGuidUnique identifier of this history record
DateTimeRequiredDateTimeDate and time of the event
TypeRequiredstringEvent type
UserIdOptionalintIdentifier of the customer associated with the event
CustomerUidRequiredGuidInternal customer identifier, unique within the System
IdentityRequiredstringAdditional data allowing identification of the event. Fill with customer card number
WithdrawOptionalWithdrawDataViewModelDeduction (manual)
RewardOptionalRewardDataViewModelAccrual (manual)
DescriptionOptionalstringDescription for display in history
LocationIdOptionalGuidPoint of sale location identifier where the purchase was made. Not recommended to fill
PartnerIdOptionalGuidCompany identifier, constant
BrandUidOptionalGuidUid of the brand where the purchase occurred, often a constant
HistoryPurchaseRequiredHistoryPurchaseDataViewModelHistorical purchase data. See HistoryPurchaseDataViewModel model below
EventDateTimeRequiredlongFile upload date and time. Fill current date in ticks
LoyalityUidRequiredGuidExternal Loyalty Program identifier, constant
historyVersionRequired

HistoryVersionType 

Information about the history record version (database table where data from the uploaded file is written). Should be filled with value: V2
sourceRequiredstringRecord source information. When saving data from Loymax, leave this field empty. When importing external data, fill with any value, then the history record is marked with Imported=true.

Below the nested models for required fields of the general structure are listed and described. These also include both required and optional fields.

General purchase information: HistoryPurchaseDataViewModel

FieldRequiredData TypeDescription
ExternalPurchaseIdRequiredstringExternal purchase identifier
AmountRequireddecimalPurchase amount after discounts
CurrencyUidRequiredstringExternal POS currency identifier (default POS currency: euros). One currency can be passed for all purchases
MerchantUidRequiredGuidExternal point of sale identifier. One point of sale can be passed for all purchases
DeviceUidRequiredGuidExternal POS identifier. One POS terminal can be passed for all purchases
ChequeItemsRequiredHistoryChequeItemViewModelInformation about items in the receipt. See HistoryChequeItemViewModel model below
WithdrawsRequiredWithdrawDataViewModelDeductions within the purchase. See WithdrawDataViewModel model below
RewardsRequiredRewardDataViewModelAccruals within the purchase. See RewardDataViewModel model below
IsRefundOptionalboolWhether the purchase is a refund. If no refunds, value: false
ChequeNumberRequiredstringReceipt number
ChequeAdditionalAttributesOptionalChequeAdditionalAttributeViewModelInformation about additional receipt attributes. Not recommended to transmit
StateRequiredOperationStatePurchase state. Always pass value: Confirmed
AdditionalParamsOptionalstringAdditional purchase parameters
PaysOptionalPayModelPayment methods. Fill if needed to specify what portion was paid with POS currency (euros)
ActivitiesOptionalActivityActivities. Not recommended to transmit
DeviceEmulationOptionalboolIndicator whether the purchase was made on a test POS terminal. If transmitted, value always: false
OperationsOptionalPurchaseOperationOperations
CouponsOptionalCouponCoupons
ExternalPurchaseUidOptionalstringPurchase identifier
  • Fields Withdraws and Rewards in the model are marked as required, despite potentially being empty arrays.
  • Field IsRefund is used to transmit refunds during migration (value true if transmitted).

Receipt item information: HistoryChequeItemViewModel

FieldRequiredData TypeDescription
PositionIdRequiredint?Receipt position. Filled as sequential number within each receipt
DescriptionOptionalstringDescription
QuantityOptionaldecimalQuantity. If not passed, 0 will be displayed
UnitOptionalstringUnit of measure
AmountRequireddecimalAmount after discount deduction
ItemIdOptionalstringExternal product identifier (article)
Discounts

Required

(conditional)

Discount

Discounts provided on receipt positions. Required if line-item detail is needed.

See Discount model below

commonCodeOptionalstringCommon code of the item
attributesOptionalstringItem attributes. Not recommended to transmit
internalGoodIdOptionalintInternal product identifier

Preference model: Discount

This model is used only when line-item discount detail is required (discount detail/payment detail/bonus points detail) and is included in the HistoryChequeItemViewModel model.

FieldRequiredData TypeDescription
DiscountTypeRequiredPositionDiscountTypeType of preference provided. See PositionDiscountType model below
OfferIdRequiredintInternal offer identifier. Value must not equal 0. Pass identifier of a offer specifically created in the System; one can be created and passed as a constant
OfferVersionIdRequiredintInternal version identifier of the offer. Value must not equal 0. Pass identifier of a offer version specifically created in the System; one can be created and passed as a constant
AmountRequireddecimal

Amount of preference provided in virtual currency (if preference type: CalculatedCashback/PartnerCashback or CalculatedPayment) or in POS currency (if preference type: CalculatedDiscount/PartnerDiscount)

CurrencyIdRequiredint?Preference discount currency identifier. Must pass a currency that actually exists in the System: monetary or any virtual currency
CashAmountRequireddecimal?Discount amount in POS currency (if preference type: CalculatedPayment). Do not fill if preference type: CalculatedCashback
Type of preference provided: PositionDiscountType

One of the specified values below must be passed if the Discount model is transmitted (see above).

ValueNameDescription 
CalculatedCashbackDeferred bonus pointsbonus points
CalculatedDiscountDiscountDirect discount
PartnerDiscountPartner discountExternal/POS discount (passed from the point of sale POS terminal)
PartnerCashbackPartner bonus pointsExternal/POS bonus points (passed from the point of sale POS terminal)
PositionChargeBonus points accrualBonus points accrual. This value is not used
CalculatedPaymentPaymentDeduction of bonus points for purchase

Deduction information: WithdrawDataViewModel

This model is used to transmit line-item deductions within a purchase in HistoryPurchaseDataViewModel, required to fill, and also for manual deductions in the root object (field Withdraw), filling optional.

FieldRequiredData TypeDescription
MoneyAmountRequireddecimal?Amount in POS currency (euros)
DescriptionRequiredstringOperation description
PositionInfoOptionalint, decimalDistribution of deduction across positions
AmountRequireddecimalAmount in bonus points
WithdrawTypeRequiredWithdrawTypeDeduction type. See WithdrawType model below
CurrencyUidRequiredstringExternal virtual currency identifier

Deduction types: WithdrawType

One of the specified values below must be passed if the WithdrawDataViewModel model is transmitted (see above).

ValueNameDescription
BonusBonusesBonus points deduction
WithdrawDeductionDeduction as a separate operation type

Expiration

Expiration

Bonus points expiration

Accrual information: RewardDataViewModel

This model is used to transmit accruals within a purchase in HistoryPurchaseDataViewModel, required to fill, and also for manual accruals in the root object (field Reward), filling optional.

FieldRequiredTypeDescription
OfferExternalIdRequiredstringExternal offer identifier
DescriptionRequiredstringDetailed description specifying this accrual operation
PositionInfoOptionalint, decimalDistribution of accrual across positions (position number, amount)
AmountRequireddouble?Preference amount
RewardTypeRequiredRewardType?Accrual type. See RewardType model below
CurrencyUidRequiredstringExternal virtual currency identifier (if accrual type: Bonus or Charging) or POS currency (if accrual type: Discount)

Accrual type: RewardType

One of the specified values below must be passed if the RewardDataViewModel model is transmitted (see above).

ValueNameDescription
Bonusbonus pointsBonus points
DiscountDiscountDiscount
ChargingAccrualAdditional bonus points accrual (within receipt, but not linked to positions)