/// <summary>
            /// Charge and unlock gift card.
            /// </summary>
            /// <param name="giftCardId">Gift card identifier.</param>
            /// <param name="amount">Amount to pay.</param>
            /// <param name="paymentCurrencyCode">Currency code to use for payment.</param>
            /// <param name="channelId">Channel identifier.</param>
            /// <param name="terminalId">Terminal identifier.</param>
            /// <param name="staffId">Staff identifier.</param>
            /// <param name="transactionId">Transaction identifier.</param>
            /// <param name="receiptId">Receipt identifier.</param>
            /// <param name="cardCurrencyCode">Currency code of the gift card.</param>
            /// <param name="balance">New gift card balance.</param>
            public void PayGiftCard(
                string giftCardId,
                decimal amount,
                string paymentCurrencyCode,
                long channelId,
                string terminalId,
                string staffId,
                string transactionId,
                string receiptId,
                out string cardCurrencyCode,
                out decimal balance)
            {
                ThrowIf.NullOrWhiteSpace(giftCardId, "giftCardId");
                ThrowIf.Null(paymentCurrencyCode, "paymentCurrencyCode");
                ThrowIf.Null(terminalId, "terminalId");
                ThrowIf.Null(staffId, "staffId");
                ThrowIf.Null(transactionId, "transactionId");
                ThrowIf.Null(receiptId, "receiptId");

                if (channelId <= 0)
                {
                    throw new ArgumentOutOfRangeException("channelId", "A valid channel identifier must be specified.");
                }

                DateTimeOffset timeStamp  = this.context.GetNowInChannelTimeZone();
                string         dateString = SerializationHelper.ConvertDateTimeToAXDateString(timeStamp, AxDateSequence);
                string         timeString = SerializationHelper.ConvertDateTimeToAXTimeString(timeStamp);

                object[] parameters =
                {
                    giftCardId,
                    string.Empty,       // Store is replaced by Channel id. Prameter is left for N-1 support.
                    terminalId,
                    staffId,
                    transactionId,
                    receiptId,
                    paymentCurrencyCode,
                    amount,
                    dateString,
                    timeString,
                    AxDateSequence,
                    channelId
                };

                var data = this.InvokeMethod(
                    GiftCardPaymentMethodName,
                    parameters);

                // Parse response data
                cardCurrencyCode = (string)data[0];
                balance          = (decimal)data[1];
            }
            /// <summary>
            /// Add funds to gift card.
            /// </summary>
            /// <param name="giftCardId">Gift card identifier.</param>
            /// <param name="amount">Amount to deposit.</param>
            /// <param name="depositCurrencyCode">Currency code to use for deposit.</param>
            /// <param name="channelId">Channel identifier.</param>
            /// <param name="terminalId">Terminal identifier.</param>
            /// <param name="staffId">Staff identifier.</param>
            /// <param name="transactionId">Transaction identifier.</param>
            /// <param name="receiptId">Receipt identifier.</param>
            /// <param name="cardCurrencyCode">Currency code of the gift card.</param>
            /// <param name="balance">New gift card balance.</param>
            public void AddToGiftCard(
                string giftCardId,
                decimal amount,
                string depositCurrencyCode,
                long channelId,
                string terminalId,
                string staffId,
                string transactionId,
                string receiptId,
                out string cardCurrencyCode,
                out decimal balance)
            {
                ThrowIf.NullOrWhiteSpace(giftCardId, "giftCardId");
                ThrowIf.Null(terminalId, "terminalId");
                ThrowIf.Null(staffId, "staffId");
                ThrowIf.Null(terminalId, "transactionId");
                ThrowIf.Null(terminalId, "receiptId");

                DateTime timeStamp  = this.context.GetNowInChannelTimeZone().DateTime;
                string   dateString = SerializationHelper.ConvertDateTimeToAXDateString(timeStamp, AxDateSequence);
                string   timeString = SerializationHelper.ConvertDateTimeToAXTimeString(timeStamp);

                object[] parameters =
                {
                    giftCardId,
                    string.Empty,       // Store is replaced by Channel id. Prameter is left for N-1 support.
                    terminalId,
                    staffId,
                    transactionId,
                    receiptId,
                    depositCurrencyCode,
                    amount,
                    dateString,
                    timeString,
                    AxDateSequence,
                    channelId
                };

                var serviceResponse = this.InvokeMethod(
                    AddToGiftCardMethodName,
                    parameters);

                // Parse response data
                cardCurrencyCode = (string)serviceResponse[0];
                balance          = (decimal)serviceResponse[1];
            }
            /// <summary>
            /// Issue new credit memo.
            /// </summary>
            /// <param name="storeId">Store identifier.</param>
            /// <param name="terminalId">Terminal identifier.</param>
            /// <param name="staffId">Staff identifier.</param>
            /// <param name="transactionId">Transaction identifier.</param>
            /// <param name="receiptId">Receipt identifier.</param>
            /// <param name="currencyCode">Currency code.</param>
            /// <param name="amount">Amount of the credit memo.</param>
            /// <returns>Identifier of issued credit memo.</returns>
            public string IssueCreditMemo(
                string storeId,
                string terminalId,
                string staffId,
                string transactionId,
                string receiptId,
                string currencyCode,
                decimal amount)
            {
                ThrowIf.Null(storeId, "storeId");
                ThrowIf.Null(terminalId, "terminalId");
                ThrowIf.Null(staffId, "staffId");
                ThrowIf.Null(receiptId, "receiptId");
                ThrowIf.Null(transactionId, "transactionId");
                ThrowIf.Null(currencyCode, "currencyCode");

                DateTime timeStamp  = this.context.GetNowInChannelTimeZone().DateTime;
                string   dateString = SerializationHelper.ConvertDateTimeToAXDateString(timeStamp, AxDateSequence);
                string   timeString = SerializationHelper.ConvertDateTimeToAXTimeString(timeStamp);

                object[] parameters =
                {
                    storeId,
                    terminalId,
                    staffId,
                    transactionId,
                    receiptId,
                    "1", // LineNum parameter, EPOS always passing hardcoded "1" value.
                    currencyCode,
                    amount,
                    dateString,
                    timeString,
                    AxDateSequence
                };

                var serviceResponse = this.InvokeMethod(
                    IssueCreditMemoMethodName,
                    parameters);

                // Parse response data
                string creditMemoId = (string)serviceResponse[0];

                return(creditMemoId);
            }
            /// <summary>
            /// Pay with credit memo.
            /// </summary>
            /// <param name="creditMemoId">Identifier of issued credit memo.</param>
            /// <param name="storeId">Store identifier.</param>
            /// <param name="terminalId">Terminal identifier.</param>
            /// <param name="staffId">Staff identifier.</param>
            /// <param name="transactionId">Transaction identifier.</param>
            /// <param name="receiptId">Receipt identifier.</param>
            /// <param name="currencyCode">Currency code.</param>
            /// <param name="amount">Amount of the credit memo.</param>
            public void PayCreditMemo(
                string creditMemoId,
                string storeId,
                string terminalId,
                string staffId,
                string transactionId,
                string receiptId,
                string currencyCode,
                decimal amount)
            {
                ThrowIf.NullOrWhiteSpace(creditMemoId, "creditMemoId");
                ThrowIf.Null(storeId, "storeId");
                ThrowIf.Null(terminalId, "terminalId");
                ThrowIf.Null(staffId, "staffId");
                ThrowIf.Null(transactionId, "transactionId");
                ThrowIf.Null(receiptId, "receiptId");
                ThrowIf.Null(currencyCode, "currencyCode");

                DateTime timeStamp  = this.context.GetNowInChannelTimeZone().DateTime;
                string   dateString = SerializationHelper.ConvertDateTimeToAXDateString(timeStamp, AxDateSequence);
                string   timeString = SerializationHelper.ConvertDateTimeToAXTimeString(timeStamp);

                object[] parameters =
                {
                    creditMemoId,
                    storeId,
                    terminalId,
                    staffId,
                    transactionId,
                    receiptId,
                    "1", // LineNum parameter, EPOS always passing hardcoded "1" value.
                    amount,
                    dateString,
                    timeString,
                    AxDateSequence
                };

                this.InvokeMethodNoDataReturn(
                    UpdateCreditMemoMethodName,
                    parameters);
            }
            /// <summary>
            /// Gets the status of the loyalty reward points by card number or directory party record identifier.
            /// </summary>
            /// <param name="channelLocalDate">The local date of the channel.</param>
            /// <param name="loyaltyCardNumber">The loyalty card number.</param>
            /// <param name="excludeBlocked">
            /// The flag indicating whether to exclude the card status if the card is blocked.
            /// </param>
            /// <param name="excludeNoTender">
            /// The flag indicating whether to exclude the card status if the card is no tender or blocked.
            /// </param>
            /// <param name="includeRelatedCardsForContactTender">
            /// The flag indicating whether to include the status of the related cards if the given card is contact tender.
            /// </param>
            /// <param name="includeNonRedeemablePoints">
            /// The flag indicating whether to include non-redeemable points status in the result.
            /// </param>
            /// <param name="includeActivePointsOnly">
            /// The flag indicating whether to return only the active points; otherwise, returns the status of issued, used and expired points as well.
            /// </param>
            /// <param name="locale">The locale of the translations.</param>
            /// <returns>The loyalty point status per loyalty card.</returns>
            public Collection <LoyaltyCard> GetLoyaltyCardRewardPointsStatus(
                DateTimeOffset channelLocalDate,
                string loyaltyCardNumber,
                bool excludeBlocked,
                bool excludeNoTender,
                bool includeRelatedCardsForContactTender,
                bool includeNonRedeemablePoints,
                bool includeActivePointsOnly,
                string locale)
            {
                string channelLocalDateStr = SerializationHelper.ConvertDateTimeToAXDateString(channelLocalDate.LocalDateTime, 213);
                var    parameters          = new object[]
                {
                    channelLocalDateStr,
                    loyaltyCardNumber,
                    excludeBlocked,
                    excludeNoTender,
                    includeRelatedCardsForContactTender,
                    includeNonRedeemablePoints,
                    includeActivePointsOnly,
                    locale
                };

                var data = this.InvokeMethod(GetLoyaltyCardRewardPointsStatusMethodName, parameters);

                // Translate the result data into a list of loyalty card with reward points status
                string statusXML = (string)data[0];

                XDocument doc  = XDocument.Parse(statusXML);
                XElement  root = doc.Elements("LoyaltyCardRewardPointsStatusList").SingleOrDefault();
                Collection <LoyaltyCard> cards = null;

                if (root != null)
                {
                    var cardStatusList = root.Elements("LoyaltyCardRewardPointsStatus");
                    cards = new Collection <LoyaltyCard>();
                    foreach (var cardStatus in cardStatusList)
                    {
                        var card = new LoyaltyCard();
                        card.CardNumber = TransactionServiceClient.GetAttributeValue(cardStatus, "LoyaltyCardNumber");
                        cards.Add(card);

                        var rewardPointStatusList = cardStatus.Elements("RewardPointStatus");
                        foreach (var rewardPointStatus in rewardPointStatusList)
                        {
                            var rewardPoint = new LoyaltyRewardPoint();
                            rewardPoint.RewardPointId       = TransactionServiceClient.GetAttributeValue(rewardPointStatus, "RewardPointId");
                            rewardPoint.Description         = TransactionServiceClient.GetAttributeValue(rewardPointStatus, "RewardPointDescription");
                            rewardPoint.RewardPointType     = (LoyaltyRewardPointType)Convert.ToInt32(TransactionServiceClient.GetAttributeValue(rewardPointStatus, "RewardPointType"));
                            rewardPoint.RewardPointCurrency = TransactionServiceClient.GetAttributeValue(rewardPointStatus, "Currency");
                            rewardPoint.IsRedeemable        = Convert.ToBoolean(TransactionServiceClient.GetAttributeValue(rewardPointStatus, "Redeemable"));
                            if (rewardPoint.IsRedeemable)
                            {
                                rewardPoint.RedeemRanking = Convert.ToInt32(TransactionServiceClient.GetAttributeValue(rewardPointStatus, "RedeemRanking"));
                            }

                            rewardPoint.IssuedPoints  = Convert.ToDecimal(TransactionServiceClient.GetAttributeValue(rewardPointStatus, "Issued"));
                            rewardPoint.UsedPoints    = Convert.ToDecimal(TransactionServiceClient.GetAttributeValue(rewardPointStatus, "Used"));
                            rewardPoint.ExpiredPoints = Convert.ToDecimal(TransactionServiceClient.GetAttributeValue(rewardPointStatus, "Expired"));
                            rewardPoint.ActivePoints  = Convert.ToDecimal(TransactionServiceClient.GetAttributeValue(rewardPointStatus, "Active"));

                            card.RewardPoints.Add(rewardPoint);
                        }
                    }
                }

                return(cards);
            }