コード例 #1
0
        public void Handle(OrderStatusChanged @event)
        {
            if (@event.IsCompleted)
            {
                var order       = _orderDao.FindById(@event.SourceId);
                var orderStatus = _orderDao.FindOrderStatusById(@event.SourceId);
                var pairingInfo = _orderDao.FindOrderPairingById(@event.SourceId);
                var account     = _accountDao.FindById(order.AccountId);

                if (_serverSettings.GetPaymentSettings(order.CompanyKey).PaymentMode == PaymentMethod.RideLinqCmt)
                {
                    // Check if card declined
                    InitializeCmtServiceClient();

                    if (CmtErrorCodes.IsTerminalError(orderStatus.PairingError))
                    {
                        // Terminal error, no need to react to paymentFailure.
                        return;
                    }
                    var trip = _cmtTripInfoServiceHelper.CheckForTripEndErrors(pairingInfo.PairingToken);

                    if (trip != null && trip.ErrorCode == CmtErrorCodes.CardDeclined)
                    {
                        _commandBus.Send(new ReactToPaymentFailure
                        {
                            AccountId       = order.AccountId,
                            OrderId         = order.Id,
                            IBSOrderId      = order.IBSOrderId,
                            CreditCardId    = account.DefaultCreditCard.GetValueOrDefault(),
                            TransactionId   = orderStatus.OrderId.ToString().Split('-').FirstOrDefault(), // Use first part of GUID to display to user
                            OverdueAmount   = Convert.ToDecimal(@event.Fare + @event.Tax + @event.Tip + @event.Toll),
                            TransactionDate = @event.EventDate
                        });

                        return;
                    }

                    // Since RideLinqCmt payment is processed automatically by CMT, we have to charge booking fees separately
                    _feeService.ChargeBookingFeesIfNecessary(orderStatus);
                }

                // If the user has decided not to pair (paying the ride in car instead),
                // we have to void the amount that was preauthorized
                if (_serverSettings.GetPaymentSettings(order.CompanyKey).PaymentMode != PaymentMethod.RideLinqCmt &&
                    (order.Settings.ChargeTypeId == ChargeTypes.CardOnFile.Id || order.Settings.ChargeTypeId == ChargeTypes.PayPal.Id) &&
                    (pairingInfo == null || pairingInfo.WasUnpaired) &&
                    !orderStatus.IsPrepaid)    //prepaid order will never have a pairing info
                {
                    // void the preauthorization to prevent misuse fees
                    _paymentService.VoidPreAuthorization(order.CompanyKey, @event.SourceId);
                }
            }
        }
コード例 #2
0
        public PairingResponse Pair(string companyKey, Guid orderId, string cardToken, int autoTipPercentage)
        {
            try
            {
                if (_serverPaymentSettings.PaymentMode == PaymentMethod.RideLinqCmt)
                {
                    // CMT RideLinq flow

                    var orderStatusDetail = _orderDao.FindOrderStatusById(orderId);
                    if (orderStatusDetail == null)
                    {
                        throw new Exception("Order not found");
                    }

                    var pairingMethod = _serverPaymentSettings.CmtPaymentSettings.PairingMethod;
                    if (pairingMethod == RideLinqPairingMethod.NotSet && companyKey.HasValueTrimmed())
                    {
                        // we are on a company that wasn't migrated to the new pairing method setting, use the old one
                        pairingMethod = _serverPaymentSettings.CmtPaymentSettings.UsePairingCode
                            ? RideLinqPairingMethod.PairingCode
                            : RideLinqPairingMethod.VehicleMedallion;
                    }

                    if (pairingMethod == RideLinqPairingMethod.PairingCode &&
                        !orderStatusDetail.RideLinqPairingCode.HasValue())
                    {
                        // We haven't received the pairing code from IBS yet, set the ignore response false
                        // so that the caller can exit without interpreting the response as a failure
                        return(new PairingResponse {
                            IgnoreResponse = true
                        });
                    }

                    _logger.LogMessage("Starting pairing with RideLinq for Order {0}", orderId);

                    if (orderStatusDetail.IBSOrderId == null)
                    {
                        throw new Exception("Order has no IBSOrderId");
                    }

                    // We need to extract the errorCode and resend it as a pairing response failed if necessary to prevent redoing a pairing after terminal error.
                    var savedPairingErrorCode = CmtErrorCodes.ExtractTerminalError(orderStatusDetail.PairingError);

                    if (savedPairingErrorCode.HasValue)
                    {
                        _logger.LogMessage("An attempt to pair order {0} after previous pairing ended in terminal error has been detected. Returning original pairing error {1}.", orderStatusDetail.OrderId, savedPairingErrorCode);
                        return(new PairingResponse
                        {
                            IsSuccessful = false,
                            ErrorCode = savedPairingErrorCode
                        });
                    }

                    var response = PairWithVehicleUsingRideLinq(pairingMethod, orderStatusDetail, cardToken, autoTipPercentage);

                    if (response.ErrorCode.HasValue)
                    {
                        return(new PairingResponse
                        {
                            IsSuccessful = false,
                            ErrorCode = response.ErrorCode
                        });
                    }

                    // send a command to save the pairing state for this order
                    _commandBus.Send(new PairForPayment
                    {
                        OrderId      = orderId,
                        Medallion    = response.Medallion,
                        DriverId     = response.DriverId.ToString(),
                        PairingToken = response.PairingToken,
                        PairingCode  = response.PairingCode,
                        TokenOfCardToBeUsedForPayment = cardToken,
                        AutoTipPercentage             = autoTipPercentage
                    });

                    return(new PairingResponse
                    {
                        IsSuccessful = true,
                        Message = "Success",
                        PairingToken = response.PairingToken,
                        PairingCode = response.PairingCode,
                        Medallion = response.Medallion,
                        TripId = response.TripId,
                        DriverId = response.DriverId
                    });
                }
                else
                {
                    // Normal CMT flow
                    _pairingService.Pair(orderId, cardToken, autoTipPercentage);

                    return(new PairingResponse
                    {
                        IsSuccessful = true,
                        Message = "Success"
                    });
                }
            }
            catch (Exception e)
            {
                _logger.LogError(e);

                return(new PairingResponse
                {
                    IsSuccessful = false,
                    Message = e.Message,
                    ErrorCode = CmtErrorCodes.UnableToPair
                });
            }
        }
コード例 #3
0
        public void Handle(OrderStatusChanged @event)
        {
            if (@event.IsCompleted)
            {
                if (@event.Status.IsPrepaid)
                {
                    // Send receipt for PrePaid
                    // No tolls and surcharge for prepaid orders
                    SendTripReceipt(@event.SourceId,
                                    Convert.ToDecimal(@event.Fare ?? 0),
                                    Convert.ToDecimal(@event.Tip ?? 0),
                                    Convert.ToDecimal(@event.Tax ?? 0));
                }
                else
                {
                    var order       = _orderDao.FindById(@event.SourceId);
                    var pairingInfo = _orderDao.FindOrderPairingById(@event.SourceId);

                    var orderStatus = _orderDao.FindOrderStatusById(@event.SourceId);
                    if (CmtErrorCodes.IsTerminalError(orderStatus.PairingError))
                    {
                        return;
                    }

                    if (order.Settings.ChargeTypeId == ChargeTypes.PaymentInCar.Id)
                    {
                        // Send receipt for Pay in Car
                        SendTripReceipt(@event.SourceId,
                                        Convert.ToDecimal(@event.Fare ?? 0),
                                        Convert.ToDecimal(@event.Tip ?? 0),
                                        Convert.ToDecimal(@event.Tax ?? 0),
                                        toll: Convert.ToDecimal(@event.Toll ?? 0),
                                        surcharge: Convert.ToDecimal(@event.Surcharge ?? 0));
                    }
                    else if (pairingInfo != null && pairingInfo.DriverId.HasValue() && pairingInfo.Medallion.HasValue() && pairingInfo.PairingToken.HasValue())
                    {
                        // Send receipt for CMTRideLinq
                        InitializeCmtServiceClient(order.CompanyKey);

                        var tripInfo = _cmtTripInfoServiceHelper.GetTripInfo(pairingInfo.PairingToken);
                        if (tripInfo != null && !tripInfo.ErrorCode.HasValue && tripInfo.EndTime.HasValue)
                        {
                            var tollHistory = tripInfo.TollHistory != null
                                                                ? tripInfo.TollHistory.Sum(p => p.TollAmount)
                                                                : 0;

                            var meterAmount         = Math.Round(((double)tripInfo.Fare / 100), 2);
                            var tollAmount          = Math.Round(((double)tollHistory / 100), 2);
                            var tipAmount           = Math.Round(((double)tripInfo.Tip / 100), 2);
                            var taxAmount           = Math.Round(((double)tripInfo.Tax / 100), 2);
                            var surchargeAmount     = Math.Round(((double)tripInfo.Surcharge / 100), 2);
                            var extraAmount         = Math.Round(((double)tripInfo.Extra / 100), 2);
                            var accessFee           = Math.Round(((double)tripInfo.AccessFee / 100), 2);
                            var fareAtAlternateRate = Math.Round(((double)tripInfo.FareAtAlternateRate / 100), 2);

                            var tolls = new List <TollDetail>();

                            if (tripInfo.TollHistory != null)
                            {
                                tolls.AddRange(tripInfo.TollHistory.Select(toll =>
                                                                           new TollDetail
                                {
                                    TollName   = toll.TollName,
                                    TollAmount = toll.TollAmount
                                }));
                            }

                            SendTripReceipt(@event.SourceId,
                                            Convert.ToDecimal(meterAmount),
                                            Convert.ToDecimal(tipAmount),
                                            Convert.ToDecimal(taxAmount),
                                            extra: Convert.ToDecimal(extraAmount),
                                            toll: Convert.ToDecimal(tollAmount),
                                            surcharge: Convert.ToDecimal(surchargeAmount),
                                            cmtRideLinqFields: new SendReceipt.CmtRideLinqReceiptFields
                            {
                                DriverId            = tripInfo.DriverId.ToString(),
                                PickUpDateTime      = tripInfo.StartTime,
                                DropOffDateTime     = tripInfo.EndTime,
                                TripId              = tripInfo.TripId,
                                Distance            = tripInfo.Distance,
                                LastFour            = tripInfo.LastFour,
                                AccessFee           = accessFee,
                                FareAtAlternateRate = fareAtAlternateRate,
                                RateAtTripEnd       = tripInfo.RateAtTripEnd,
                                RateAtTripStart     = tripInfo.RateAtTripStart,
                                Tolls        = tolls.ToArray(),
                                TipIncentive = order.TipIncentive ?? 0
                            });
                        }
                    }
                }
            }
        }