/// <summary> /// Reserves the gift card for a given terminal so it cannot be used on other terminals. /// </summary> /// <param name="request">The <see cref="LockGiftCardRealtimeRequest"/> request.</param> /// <returns>The <see cref="SingleEntityDataServiceResponse{GiftCard}"/> response.</returns> private static SingleEntityDataServiceResponse <GiftCard> LockGiftCard(LockGiftCardRealtimeRequest request) { var transactionClient = new TransactionService.TransactionServiceClient(request.RequestContext); string cardCurrencyCode; decimal amount; transactionClient.LockGiftCard(request.GiftCardId, request.ChannelId, request.TerminalId, out cardCurrencyCode, out amount); var giftCard = new GiftCard { Id = request.GiftCardId, CardCurrencyCode = cardCurrencyCode, BalanceInCardCurrency = amount }; return(new SingleEntityDataServiceResponse <GiftCard>(giftCard)); }
/// <summary> /// Authorizes the payment. /// </summary> /// <param name="request">The request.</param> /// <returns>A response containing the authorized tender line.</returns> private static AuthorizePaymentServiceResponse AuthorizePayment(AuthorizePaymentServiceRequest request) { if (request == null) { throw new ArgumentNullException("request"); } ValidateNotAlreadyAdded(request.Transaction, request.TenderLine.GiftCardId); var lockGiftCardRealtimeRequest = new LockGiftCardRealtimeRequest( request.TenderLine.GiftCardId, request.RequestContext.GetPrincipal().ChannelId, request.RequestContext.GetTerminal() == null ? string.Empty : request.RequestContext.GetTerminal().TerminalId); GiftCard giftCard = request.RequestContext.Execute <SingleEntityDataServiceResponse <GiftCard> >(lockGiftCardRealtimeRequest).Entity; GetCurrencyValueServiceResponse convertAmountToGiftCardCurrencyResponse; try { if (!request.TenderLine.Currency.Equals(request.RequestContext.GetChannelConfiguration().Currency, StringComparison.OrdinalIgnoreCase)) { throw new PaymentException( PaymentErrors.Microsoft_Dynamics_Commerce_Runtime_GiftCardCurrencyMismatch, string.Format("Gift card payments are only supported in channel currency. Currency requested: {0}", request.TenderLine.Currency)); } convertAmountToGiftCardCurrencyResponse = ToGiftCardCurrency(request.RequestContext, request.TenderLine.Amount, giftCard.CardCurrencyCode); // Check if gift card has enough balance. if (giftCard.BalanceInCardCurrency < convertAmountToGiftCardCurrencyResponse.RoundedConvertedAmount) { throw new PaymentException(PaymentErrors.Microsoft_Dynamics_Commerce_Runtime_PaymentAmountExceedsGiftBalance); } } catch { try { // At this point payment failed but gift card is already locked. // Need to unlock gift card (better as void payment) so it can be used in future. var voidGiftCardPaymentRequest = new VoidGiftCardPaymentRealtimeRequest( request.TenderLine.GiftCardId, request.RequestContext.GetPrincipal().ChannelId, request.RequestContext.GetTerminal() == null ? string.Empty : request.RequestContext.GetTerminal().TerminalId); request.RequestContext.Execute <NullResponse>(voidGiftCardPaymentRequest); } catch (Exception ex) { RetailLogger.Log.CrtServicesGiftCardServiceUnlockGiftCardFailure(ex); } throw; } request.TenderLine.Currency = giftCard.CardCurrencyCode; request.TenderLine.AmountInTenderedCurrency = convertAmountToGiftCardCurrencyResponse.RoundedConvertedAmount; request.TenderLine.ExchangeRate = convertAmountToGiftCardCurrencyResponse.ExchangeRate; request.TenderLine.Status = TenderLineStatus.PendingCommit; request.TenderLine.IsVoidable = true; return(new AuthorizePaymentServiceResponse(request.TenderLine)); }