public void when_order_on_external_company_has_booking_fees_configured_with_cmt_and_card_is_declined() { // Prepare var creditCardId = Guid.NewGuid(); var accountId = Guid.NewGuid(); var orderId = Guid.NewGuid(); string companyKey = "ext"; var orderAmount = 100.85m; var bookingFees = 40.85m; using (var context = new BookingDbContext(DbName)) { context.RemoveAll <FeesDetail>(); context.SaveChanges(); context.Save(new AccountDetail { Id = accountId, CreationDate = DateTime.Now, IBSAccountId = 123, DefaultCreditCard = creditCardId }); context.Save(new AccountIbsDetail { CompanyKey = companyKey, AccountId = accountId, IBSAccountId = 123 }); context.Save(new CreditCardDetails { AccountId = accountId, CreditCardId = creditCardId, Token = "token" }); context.Save(new OrderDetail { Id = orderId, AccountId = accountId, PickupDate = DateTime.Now, CreatedDate = DateTime.Now, IBSOrderId = 12345, CompanyKey = companyKey, BookingFees = bookingFees }); context.Save(new OrderPairingDetail { OrderId = orderId }); context.Save(new FeesDetail { Market = null, Booking = bookingFees, Id = Guid.NewGuid() }); } var tip = FareHelper.CalculateTipAmount(orderAmount, ConfigurationManager.ServerData.DefaultTipPercentage); var ibsOrder = new IBSOrderInformation { Fare = Convert.ToDouble(orderAmount) }; var status = new OrderStatusDetail { OrderId = orderId, CompanyKey = companyKey, AccountId = accountId, IBSOrderId = 12345 }; ConfigurationManager.SetPaymentSettings(null, new ServerPaymentSettings { PaymentMode = PaymentMethod.Cmt }); ConfigurationManager.SetPaymentSettings(companyKey, new ServerPaymentSettings { PaymentMode = PaymentMethod.Cmt }); EnsurePreAuthForFeeWasCalled(status, bookingFees); EnsurePreAuthPaymentForTripWasCalled(status, orderAmount + tip); // Act Sut.Update(ibsOrder, status); // Wait for commands to be sent properly Thread.Sleep(5000); // Assert PaymentServiceMock.Verify(); Assert.AreEqual(3, Commands.Count); Assert.AreEqual(typeof(ReactToPaymentFailure), Commands.First().GetType()); Assert.AreEqual(typeof(ReactToPaymentFailure), Commands.Skip(1).First().GetType()); Assert.AreEqual(typeof(ChangeOrderStatus), Commands.Skip(2).First().GetType()); }
public void when_order_is_paired_and_received_fare_with_preauth_disabled_and_preauth_fails() { // Prepare var accountId = Guid.NewGuid(); var orderId = Guid.NewGuid(); string companyKey = null; var orderAmount = 100.55m; var creditCardId = Guid.NewGuid(); using (var context = new BookingDbContext(DbName)) { context.Save(new AccountDetail { Id = accountId, CreationDate = DateTime.Now, IBSAccountId = 123, DefaultCreditCard = creditCardId }); context.Save(new CreditCardDetails { AccountId = accountId, CreditCardId = creditCardId, Token = "token" }); context.Save(new OrderDetail { Id = orderId, AccountId = accountId, PickupDate = DateTime.Now, CreatedDate = DateTime.Now, IBSOrderId = 12345, CompanyKey = companyKey }); context.Save(new OrderPairingDetail { OrderId = orderId }); } var tip = FareHelper.CalculateTipAmount(orderAmount, ConfigurationManager.ServerData.DefaultTipPercentage); var ibsOrder = new IBSOrderInformation { Fare = Convert.ToDouble(orderAmount) }; var status = new OrderStatusDetail { OrderId = orderId, CompanyKey = companyKey, AccountId = accountId, IBSOrderId = 12345 }; ConfigurationManager.SetPaymentSettings(null, new ServerPaymentSettings { PaymentMode = PaymentMethod.Braintree }); EnsurePreAuthPaymentForTripWasCalled(status, orderAmount + tip); // Act Sut.Update(ibsOrder, status); // Assert PaymentServiceMock.Verify(); Assert.AreEqual(1, Commands.Count); Assert.AreEqual(typeof(ChangeOrderStatus), Commands.First().GetType()); }
public void when_order_is_paired_and_received_fare_with_preauth_enabled_and_commit_fails_with_card_declined() { // Prepare var accountId = Guid.NewGuid(); var orderId = Guid.NewGuid(); var creditCardId = Guid.NewGuid(); string companyKey = null; var orderAmount = 100.85m; var preAuthAmount = 50m; using (var context = new BookingDbContext(DbName)) { context.Save(new AccountDetail { Id = accountId, CreationDate = DateTime.Now, IBSAccountId = 123, DefaultCreditCard = creditCardId }); context.Save(new CreditCardDetails { AccountId = accountId, CreditCardId = creditCardId, Token = "token" }); context.Save(new OrderDetail { Id = orderId, AccountId = accountId, PickupDate = DateTime.Now, CreatedDate = DateTime.Now, IBSOrderId = 12345, CompanyKey = companyKey }); context.Save(new OrderPaymentDetail { PaymentId = Guid.NewGuid(), OrderId = orderId, CompanyKey = companyKey, PreAuthorizedAmount = preAuthAmount, FirstPreAuthTransactionId = "asdasdnasd", TransactionId = "asdasdnasd" }); context.Save(new OrderPairingDetail { OrderId = orderId }); } var tip = FareHelper.CalculateTipAmount(orderAmount, ConfigurationManager.ServerData.DefaultTipPercentage); var ibsOrder = new IBSOrderInformation { Fare = Convert.ToDouble(orderAmount) }; var status = new OrderStatusDetail { OrderId = orderId, CompanyKey = companyKey, AccountId = accountId, IBSOrderId = 12345 }; ConfigurationManager.SetPaymentSettings(null, new ServerPaymentSettings { PaymentMode = PaymentMethod.Braintree }); EnsureCommitWasCalled(status, preAuthAmount, orderAmount + tip, orderAmount, tip); EnsureVoidPreAuthWasCalled(status); // Act Sut.Update(ibsOrder, status); // Assert PaymentServiceMock.Verify(); Assert.AreEqual(3, Commands.Count); Assert.AreEqual(typeof(LogCreditCardError), Commands.First().GetType()); Assert.AreEqual(typeof(ReactToPaymentFailure), Commands.Skip(1).First().GetType()); Assert.AreEqual(typeof(ChangeOrderStatus), Commands.Skip(2).First().GetType()); }
private void ValidatePayment(string companyKey, CreateOrderRequest request, Guid orderId, AccountDetail account, bool isFutureBooking, double?appEstimate, decimal bookingFees, bool isPrepaid, CreateReportOrder createReportOrder) { var tipPercent = account.DefaultTipPercent ?? _serverSettings.ServerData.DefaultTipPercentage; // If there's an estimate, add tip to that estimate if (appEstimate.HasValue) { appEstimate = appEstimate.Value + FareHelper.CalculateTipAmount(appEstimate.Value, tipPercent); } var appEstimateWithTip = appEstimate.HasValue ? Convert.ToDecimal(appEstimate.Value) : (decimal?)null; if (isPrepaid) { // Verify that prepaid is enabled on the server if (!_serverSettings.GetPaymentSettings(companyKey).IsPrepaidEnabled) { ThrowAndLogException(createReportOrder, ErrorCode.CreateOrder_RuleDisable, _resources.Get("CannotCreateOrder_PrepaidButPrepaidNotEnabled", request.ClientLanguageCode)); } // Payment mode is CardOnFile if (request.Settings.ChargeTypeId.HasValue && request.Settings.ChargeTypeId.Value == ChargeTypes.CardOnFile.Id) { if (!appEstimateWithTip.HasValue) { ThrowAndLogException(createReportOrder, ErrorCode.CreateOrder_RuleDisable, _resources.Get("CannotCreateOrder_PrepaidNoEstimate", request.ClientLanguageCode)); } ValidateCreditCard(account, request.ClientLanguageCode, request.Cvv, createReportOrder); var result = PaymentHelper.CapturePaymentForPrepaidOrder(companyKey, orderId, account, Convert.ToDecimal(appEstimateWithTip), tipPercent, bookingFees, request.Cvv); if (!result.IsSuccessful) { ThrowAndLogException(createReportOrder, ErrorCode.CreateOrder_RuleDisable, result.Message); } } } else { // Payment mode is CardOnFile if (request.Settings.ChargeTypeId.HasValue && request.Settings.ChargeTypeId.Value == ChargeTypes.CardOnFile.Id) { ValidateCreditCard(account, request.ClientLanguageCode, request.Cvv, createReportOrder); var isSuccessful = PaymentHelper.PreAuthorizePaymentMethod(companyKey, orderId, account, isFutureBooking, appEstimateWithTip, bookingFees, request.Cvv); if (!isSuccessful) { ThrowAndLogException(createReportOrder, ErrorCode.CreateOrder_RuleDisable, _resources.Get("CannotCreateOrder_CreditCardWasDeclined", request.ClientLanguageCode)); } } // Payment mode is PayPal if (request.Settings.ChargeTypeId.HasValue && request.Settings.ChargeTypeId.Value == ChargeTypes.PayPal.Id) { ValidatePayPal(companyKey, orderId, account, request.ClientLanguageCode, isFutureBooking, appEstimateWithTip, bookingFees, createReportOrder); } } }
public InitializePayPalCheckoutResponse InitializeWebPayment(Guid accountId, Guid orderId, string baseUri, double?estimatedFare, decimal bookingFees, string clientLanguageCode) { if (!estimatedFare.HasValue) { return(new InitializePayPalCheckoutResponse { IsSuccessful = false, Message = _resources.Get("CannotCreateOrder_PrepaidNoEstimate", clientLanguageCode) }); } var regionName = _serverSettings.ServerData.PayPalRegionInfoOverride; var conversionRate = _serverSettings.ServerData.PayPalConversionRate; _logger.LogMessage("PayPal Conversion Rate: {0}", conversionRate); // Fare amount var fareAmount = Math.Round(Convert.ToDecimal(estimatedFare.Value) * conversionRate, 2); var currency = conversionRate != 1 ? CurrencyCodes.Main.UnitedStatesDollar : _resources.GetCurrencyCode(); // Need the fare object because tip amount should be calculated on the fare excluding taxes var fareObject = FareHelper.GetFareFromAmountInclTax(Convert.ToDouble(fareAmount), _serverSettings.ServerData.VATIsEnabled ? _serverSettings.ServerData.VATPercentage : 0); // Tip amount (on fare amount excl. taxes) var defaultTipPercentage = _accountDao.FindById(accountId).DefaultTipPercent; var tipPercentage = defaultTipPercentage ?? _serverSettings.ServerData.DefaultTipPercentage; var tipAmount = FareHelper.CalculateTipAmount(fareObject.AmountInclTax, tipPercentage); // Booking Fees with conversion rate if necessary var bookingFeesAmount = Math.Round(bookingFees * conversionRate, 2); // Fare amount with tip and booking fee var totalAmount = fareAmount + tipAmount + bookingFeesAmount; var redirectUrl = baseUri + string.Format("/{0}/proceed", orderId); _logger.LogMessage("PayPal Web redirect URL: {0}", redirectUrl); var redirUrls = new RedirectUrls { cancel_url = redirectUrl + "?cancel=true", return_url = redirectUrl }; // Create transaction var transactionList = new List <Transaction> { new Transaction { amount = new Amount { currency = currency, total = totalAmount.ToString("N", CultureInfo.InvariantCulture) }, description = string.Format( _resources.Get("PayPalWebPaymentDescription", regionName.HasValue() ? SupportedLanguages.en.ToString() : clientLanguageCode), totalAmount), item_list = new ItemList { items = new List <Item> { new Item { name = _resources.Get("PayPalWebFareItemDescription", regionName.HasValue() ? SupportedLanguages.en.ToString() : clientLanguageCode), currency = currency, price = fareAmount.ToString("N", CultureInfo.InvariantCulture), quantity = "1" }, new Item { name = string.Format(_resources.Get("PayPalWebTipItemDescription", regionName.HasValue() ? SupportedLanguages.en.ToString() : clientLanguageCode), tipPercentage), currency = currency, price = tipAmount.ToString("N", CultureInfo.InvariantCulture), quantity = "1" } } } } }; if (bookingFeesAmount > 0) { transactionList.First().item_list.items.Add(new Item { name = _resources.Get("PayPalWebBookingFeeItemDescription", regionName.HasValue() ? SupportedLanguages.en.ToString() : clientLanguageCode), currency = currency, price = bookingFeesAmount.ToString("N", CultureInfo.InvariantCulture), quantity = "1" }); } // Create web experience profile var profile = new WebProfile { name = Guid.NewGuid().ToString(), flow_config = new FlowConfig { landing_page_type = _serverPaymentSettings.PayPalServerSettings.LandingPageType.ToString() } }; try { var webExperienceProfile = profile.Create(GetAPIContext(GetAccessToken())); // Create payment var payment = new Payment { intent = Intents.Sale, payer = new Payer { payment_method = "paypal" }, transactions = transactionList, redirect_urls = redirUrls, experience_profile_id = webExperienceProfile.id }; var createdPayment = payment.Create(GetAPIContext(GetAccessToken())); var links = createdPayment.links.GetEnumerator(); while (links.MoveNext()) { var link = links.Current; if (link.rel.ToLower().Trim().Equals("approval_url")) { return(new InitializePayPalCheckoutResponse { IsSuccessful = true, PaymentId = createdPayment.id, PayPalCheckoutUrl = link.href // Links that give the user the option to redirect to PayPal to approve the payment }); } } _logger.LogMessage("Error when creating PayPal Web payment: no approval_urls found"); // No approval_url found return(new InitializePayPalCheckoutResponse { IsSuccessful = false, Message = "No approval_url found" }); } catch (Exception ex) { var exceptionMessage = ex.Message; var paymentException = ex as PaymentsException; if (paymentException != null && paymentException.Details != null) { exceptionMessage = paymentException.Details.message; } _logger.LogMessage("Initialization of PayPal Web Store failed: {0}", exceptionMessage); return(new InitializePayPalCheckoutResponse { IsSuccessful = false, Message = exceptionMessage }); } }
public object Post(SendReceiptAdmin request) { var order = _orderDao.FindById(request.OrderId); if (order == null || !(order.IsManualRideLinq || order.IBSOrderId.HasValue)) { throw new HttpError(HttpStatusCode.BadRequest, ErrorCode.OrderNotInIbs.ToString()); } AccountDetail account; // if the admin is requesting the receipt then it won't be for the logged in user if (!request.RecipientEmail.IsNullOrEmpty()) { account = _accountDao.FindById(order.AccountId); } else { account = _accountDao.FindById(new Guid(this.GetSession().UserAuthId)); if (account.Id != order.AccountId) { throw new HttpError(HttpStatusCode.Unauthorized, "Not your order"); } } // If the order was created in another company, need to fetch the correct IBS account var ibsAccountId = _accountDao.GetIbsAccountId(account.Id, order.CompanyKey); if (!(ibsAccountId.HasValue || order.IsManualRideLinq)) { throw new HttpError(HttpStatusCode.BadRequest, ErrorCode.IBSAccountNotFound.ToString()); } var ibsOrder = !order.IsManualRideLinq ? _ibsServiceProvider.Booking(order.CompanyKey).GetOrderDetails(order.IBSOrderId.Value, ibsAccountId.Value, order.Settings.Phone) : null; var orderPayment = _orderPaymentDao.FindByOrderId(order.Id, order.CompanyKey); var pairingInfo = _orderDao.FindOrderPairingById(order.Id); var orderStatus = _orderDao.FindOrderStatusById(request.OrderId); double?fareAmount; double?tollAmount = null; double?tipAmount; double?taxAmount; double?surcharge; double?bookingFees = null; double?extraAmount = null; PromotionUsageDetail promotionUsed = null; ReadModel.CreditCardDetails creditCard = null; var ibsOrderId = orderStatus.IBSOrderId; Commands.SendReceipt.CmtRideLinqReceiptFields cmtRideLinqFields = null; if (orderPayment != null && orderPayment.IsCompleted) { fareAmount = Convert.ToDouble(orderPayment.Meter); tipAmount = Convert.ToDouble(orderPayment.Tip); taxAmount = Convert.ToDouble(orderPayment.Tax); surcharge = Convert.ToDouble(orderPayment.Surcharge); bookingFees = Convert.ToDouble(orderPayment.BookingFees); // promotion can only be used with in app payment promotionUsed = _promotionDao.FindByOrderId(request.OrderId); creditCard = orderPayment.CardToken.HasValue() ? _creditCardDao.FindByToken(orderPayment.CardToken) : null; } else if (order.IsManualRideLinq) { var manualRideLinqDetail = _orderDao.GetManualRideLinqById(order.Id); fareAmount = manualRideLinqDetail.Fare; ibsOrderId = manualRideLinqDetail.TripId; tollAmount = manualRideLinqDetail.Toll; extraAmount = manualRideLinqDetail.Extra; tipAmount = manualRideLinqDetail.Tip; taxAmount = manualRideLinqDetail.Tax; surcharge = manualRideLinqDetail.Surcharge; orderStatus.DriverInfos.DriverId = manualRideLinqDetail.DriverId.ToString(); order.DropOffAddress = _geocoding.TryToGetExactDropOffAddress(orderStatus, manualRideLinqDetail.LastLatitudeOfVehicle, manualRideLinqDetail.LastLongitudeOfVehicle, order.DropOffAddress, order.ClientLanguageCode); cmtRideLinqFields = new Commands.SendReceipt.CmtRideLinqReceiptFields { TripId = manualRideLinqDetail.TripId, DriverId = manualRideLinqDetail.DriverId.ToString(), Distance = manualRideLinqDetail.Distance, AccessFee = manualRideLinqDetail.AccessFee, PickUpDateTime = manualRideLinqDetail.StartTime, DropOffDateTime = manualRideLinqDetail.EndTime, LastFour = manualRideLinqDetail.LastFour, FareAtAlternateRate = manualRideLinqDetail.FareAtAlternateRate, RateAtTripEnd = (int)(manualRideLinqDetail.RateAtTripEnd.GetValueOrDefault()), RateAtTripStart = (int)(manualRideLinqDetail.RateAtTripStart.GetValueOrDefault()), LastLatitudeOfVehicle = order.DropOffAddress.Latitude, LastLongitudeOfVehicle = order.DropOffAddress.Longitude, TipIncentive = order.TipIncentive ?? 0 }; } else if (pairingInfo != null && pairingInfo.AutoTipPercentage.HasValue) { var tripInfo = GetTripInfo(pairingInfo.PairingToken); if (tripInfo != null && !tripInfo.ErrorCode.HasValue && tripInfo.EndTime.HasValue) { // this is for CMT RideLinq only, no VAT fareAmount = Math.Round(((double)tripInfo.Fare / 100), 2); var tollHistory = tripInfo.TollHistory != null ? tripInfo.TollHistory.Sum(p => p.TollAmount) : 0; tollAmount = Math.Round(((double)tollHistory / 100), 2); extraAmount = Math.Round(((double)tripInfo.Extra / 100), 2); tipAmount = Math.Round(((double)tripInfo.Tip / 100), 2); taxAmount = Math.Round(((double)tripInfo.Tax / 100), 2); surcharge = Math.Round(((double)tripInfo.Surcharge / 100), 2); orderStatus.DriverInfos.DriverId = tripInfo.DriverId.ToString(); cmtRideLinqFields = new Commands.SendReceipt.CmtRideLinqReceiptFields { TripId = tripInfo.TripId, DriverId = tripInfo.DriverId.ToString(), Distance = tripInfo.Distance, AccessFee = Math.Round(((double)tripInfo.AccessFee / 100), 2), PickUpDateTime = tripInfo.StartTime, DropOffDateTime = tripInfo.EndTime, LastFour = tripInfo.LastFour, FareAtAlternateRate = Math.Round(((double)tripInfo.FareAtAlternateRate / 100), 2), RateAtTripEnd = tripInfo.RateAtTripEnd, RateAtTripStart = tripInfo.RateAtTripStart, Tolls = tripInfo.TollHistory, TipIncentive = (order.TipIncentive.HasValue) ? order.TipIncentive.Value : 0 }; } else { fareAmount = ibsOrder.Fare; tollAmount = ibsOrder.Toll; tipAmount = FareHelper.CalculateTipAmount(ibsOrder.Fare.GetValueOrDefault(0), pairingInfo.AutoTipPercentage.Value); taxAmount = ibsOrder.VAT; surcharge = order.Surcharge; } orderPayment = null; creditCard = pairingInfo.TokenOfCardToBeUsedForPayment.HasValue() ? _creditCardDao.FindByToken(pairingInfo.TokenOfCardToBeUsedForPayment) : null; } else { fareAmount = ibsOrder.Fare; tollAmount = ibsOrder.Toll; tipAmount = ibsOrder.Tip; taxAmount = ibsOrder.VAT; surcharge = order.Surcharge; orderPayment = null; } var orderReport = _reportDao.GetOrderReportWithOrderId(order.Id); var sendReceiptCommand = SendReceiptCommandBuilder.GetSendReceiptCommand( order, account, ibsOrderId, (orderReport != null ? orderReport.VehicleInfos.Number : ibsOrder.VehicleNumber), orderStatus.DriverInfos, fareAmount, tollAmount, extraAmount, surcharge, bookingFees, tipAmount, taxAmount, orderPayment, promotionUsed != null ? Convert.ToDouble(promotionUsed.AmountSaved) : (double?)null, promotionUsed, creditCard, cmtRideLinqFields); // Since the user or an admin requested the receipt, we should bypass the normal notification settings. sendReceiptCommand.BypassNotificationSettings = true; if (!request.RecipientEmail.IsNullOrEmpty()) { sendReceiptCommand.EmailAddress = request.RecipientEmail; } _commandBus.Send(sendReceiptCommand); return(new HttpResult(HttpStatusCode.OK, "OK")); }
public object Get(ExecuteWebPaymentAndProceedWithOrder request) { _logger.LogMessage("ExecuteWebPaymentAndProceedWithOrder request : " + request.ToJson()); var temporaryInfo = _orderDao.GetTemporaryInfo(request.OrderId); var orderInfo = JsonSerializer.DeserializeFromString <TemporaryOrderCreationInfo>(temporaryInfo.SerializedOrderCreationInfo); if (request.Cancel || orderInfo == null) { var clientLanguageCode = orderInfo == null ? SupportedLanguages.en.ToString() : orderInfo.Request.ClientLanguageCode; _commandBus.Send(new CancelOrderBecauseOfError { OrderId = request.OrderId, ErrorDescription = _resources.Get("CannotCreateOrder_PrepaidPayPalPaymentCancelled", clientLanguageCode) }); } else { // Execute PayPal payment var response = _payPalServiceFactory.GetInstance(orderInfo.BestAvailableCompany.CompanyKey).ExecuteWebPayment(request.PayerId, request.PaymentId); if (response.IsSuccessful) { var account = _accountDao.FindById(orderInfo.AccountId); var tipPercentage = account.DefaultTipPercent ?? _serverSettings.ServerData.DefaultTipPercentage; var tipAmount = FareHelper.CalculateTipAmount(orderInfo.Request.Fare.AmountInclTax, tipPercentage); _commandBus.Send(new MarkPrepaidOrderAsSuccessful { OrderId = request.OrderId, TotalAmount = orderInfo.Request.Fare.AmountInclTax + tipAmount, MeterAmount = orderInfo.Request.Fare.AmountExclTax, TaxAmount = orderInfo.Request.Fare.TaxAmount, TipAmount = tipAmount, TransactionId = response.TransactionId, Provider = PaymentProvider.PayPal, Type = PaymentType.PayPal }); } else { _commandBus.Send(new CancelOrderBecauseOfError { OrderId = request.OrderId, ErrorDescription = response.Message }); } } // Build url used to redirect the web client to the booking status view string baseUrl; if (_serverSettings.ServerData.BaseUrl.HasValue()) { baseUrl = _serverSettings.ServerData.BaseUrl; } else { baseUrl = Request.AbsoluteUri .Replace(Request.PathInfo, string.Empty) .Replace(GetAppHost().Config.ServiceStackHandlerFactoryPath, string.Empty) .Replace(Request.QueryString.ToString(), string.Empty) .Replace("?", string.Empty); } var redirectUrl = string.Format("{0}#status/{1}", baseUrl, request.OrderId); return(new HttpResult { StatusCode = HttpStatusCode.Redirect, Headers = { { HttpHeaders.Location, redirectUrl } } }); }