コード例 #1
0
        public async Task <Result> Refund(string referenceCode, ApiCaller apiCaller, DateTime operationDate, IPaymentCallbackService paymentCallbackService,
                                          string reason)
        {
            return(await GetChargingAccountId()
                   .Bind(GetRefundableAmount)
                   .Bind(RefundMoneyToAccount)
                   .Bind(ProcessPaymentResults));


            Task <Result <int> > GetChargingAccountId()
            => paymentCallbackService.GetChargingAccountId(referenceCode);


            async Task <Result <(int accountId, MoneyAmount)> > GetRefundableAmount(int accountId)
            {
                var(_, isFailure, refundableAmount, error) = await paymentCallbackService.GetRefundableAmount(referenceCode, operationDate);

                if (isFailure)
                {
                    return(Result.Failure <(int, MoneyAmount)>(error));
                }

                return(accountId, refundableAmount);
            }

            async Task <Result <Payment> > RefundMoneyToAccount((int, MoneyAmount) refundInfo)
            {
                var(accountId, refundableAmount) = refundInfo;
                return(await GetPayment(referenceCode)
                       .Check(Refund)
                       .Map(UpdatePaymentStatus));


                Task <Result> Refund(Payment _)
                => _accountPaymentProcessingService.RefundMoney(accountId,
                                                                new ChargedMoneyData(
                                                                    refundableAmount.Amount,
                                                                    refundableAmount.Currency,
                                                                    reason: reason,
                                                                    referenceCode: referenceCode),
                                                                apiCaller);


                async Task <Payment> UpdatePaymentStatus(Payment payment)
                {
                    payment.Status         = PaymentStatuses.Refunded;
                    payment.RefundedAmount = refundableAmount.Amount;
                    _context.Payments.Update(payment);
                    await _context.SaveChangesAsync();

                    return(payment);
                }
            }

            Task <Result> ProcessPaymentResults(Payment payment)
            => paymentCallbackService.ProcessPaymentChanges(payment);
        }
コード例 #2
0
        public async Task <Result <PaymentResponse> > Authorize(NewCreditCardPaymentRequest request,
                                                                string languageCode, string ipAddress, IPaymentCallbackService paymentCallbackService, AgentContext agent)
        {
            _logger.LogCreditCardAuthorizationStarted(request.ReferenceCode);

            var(_, isFailure, servicePrice, error) = await paymentCallbackService.GetChargingAmount(request.ReferenceCode);

            if (isFailure)
            {
                _logger.LogCreditCardAuthorizationFailure(request.ReferenceCode, error);
                return(Result.Failure <PaymentResponse>(error));
            }

            return(await Validate(request)
                   .Bind(Authorize)
                   .TapIf(IsSaveCardNeeded, SaveCard)
                   .Bind(StorePaymentResults)
                   .Finally(WriteLog));
コード例 #3
0
        public async Task <Result <PaymentResponse> > Charge(string referenceCode, ApiCaller apiCaller, IPaymentCallbackService paymentCallbackService)
        {
            return(await GetChargingAccountId()
                   .Bind(GetChargingAccount)
                   .Bind(GetChargingAmount)
                   .Check(ChargeMoney)
                   .Tap(SendNotificationIfRequired)
                   .Bind(StorePayment)
                   .Bind(ProcessPaymentResults)
                   .Map(CreateResult));


            Task <Result <int> > GetChargingAccountId()
            => paymentCallbackService.GetChargingAccountId(referenceCode);


            async Task <Result <AgencyAccount> > GetChargingAccount(int accountId)
            => await _context.AgencyAccounts.SingleOrDefaultAsync(a => a.Id == accountId)
            ?? Result.Failure <AgencyAccount>("Could not find agency account");


            async Task <Result <(AgencyAccount, MoneyAmount)> > GetChargingAmount(AgencyAccount account)
            {
                var(_, isFailure, amount, error) = await paymentCallbackService.GetChargingAmount(referenceCode);

                if (isFailure)
                {
                    return(Result.Failure <(AgencyAccount, MoneyAmount)>(error));
                }

                return(account, amount);
            }

            Task <Result> ChargeMoney((AgencyAccount account, MoneyAmount amount) chargeInfo)
            {
                var(account, amount) = chargeInfo;
                return(_accountPaymentProcessingService.ChargeMoney(account.Id, new ChargedMoneyData(
                                                                        currency: amount.Currency,
                                                                        amount: amount.Amount,
                                                                        reason: $"Charge money for service '{referenceCode}'",
                                                                        referenceCode: referenceCode),
                                                                    apiCaller));
            }

            async Task <Result <Payment> > StorePayment((AgencyAccount account, MoneyAmount amount) chargeInfo)
            {
                var(account, amount) = chargeInfo;
                var(paymentExistsForBooking, _, _, _) = await GetPayment(referenceCode);

                if (paymentExistsForBooking)
                {
                    return(Result.Failure <Payment>("Payment for current booking already exists"));
                }

                var now     = _dateTimeProvider.UtcNow();
                var info    = new AccountPaymentInfo(string.Empty);
                var payment = new Payment
                {
                    Amount        = amount.Amount,
                    AccountNumber = account.Id.ToString(),
                    Currency      = amount.Currency,
                    Created       = now,
                    Modified      = now,
                    Status        = PaymentStatuses.Captured,
                    Data          = JsonConvert.SerializeObject(info),
                    AccountId     = account.Id,
                    PaymentMethod = PaymentTypes.VirtualAccount,
                    ReferenceCode = referenceCode
                };

                _context.Payments.Add(payment);
                await _context.SaveChangesAsync();

                _context.Detach(payment);

                return(payment);
            }

            Task <Result> ProcessPaymentResults(Payment payment)
            => paymentCallbackService.ProcessPaymentChanges(payment);


            Task SendNotificationIfRequired((AgencyAccount account, MoneyAmount amount) chargeInfo)
            => _balanceManagementNotificationsService.SendNotificationIfRequired(chargeInfo.account, chargeInfo.amount);


            PaymentResponse CreateResult()
            => new(string.Empty, CreditCardPaymentStatuses.Success, string.Empty);
        }