public virtual async Task HandleAsync(WeChatPayHandlerContext context)
        {
            var dict = context.WeChatRequestXmlData.SelectSingleNode("xml").ToDictionary() ??
                       throw new NullReferenceException();

            if (dict.GetOrDefault("return_code") != "SUCCESS" || dict.GetOrDefault("device_info") != PaymentServiceWeChatPayConsts.DeviceInfo)
            {
                return;
            }

            using var disabledDataFilter = _dataFilter.Disable <IMultiTenant>();

            var paymentId = Guid.Parse(dict.GetOrDefault("out_trade_no") ??
                                       throw new XmlDocumentMissingRequiredElementException("out_trade_no"));

            var payment = await _paymentRepository.GetAsync(paymentId);

            payment.SetExternalTradingCode(dict.GetOrDefault("transaction_id") ??
                                           throw new XmlDocumentMissingRequiredElementException("transaction_id"));

            await _paymentRepository.UpdateAsync(payment, true);

            await RecordPaymentResultAsync(dict, payment.Id);

            if (dict.GetOrDefault("result_code") == "SUCCESS")
            {
                await _paymentManager.CompletePaymentAsync(payment);
            }
            else
            {
                await _paymentManager.StartCancelAsync(payment);
            }
        }
        public override async Task OnPaymentStartedAsync(Payment payment, ExtraPropertyDictionary configurations)
        {
            if (payment.ActualPaymentAmount <= decimal.Zero)
            {
                throw new PaymentAmountInvalidException(payment.ActualPaymentAmount, PaymentMethod);
            }

            if (!Guid.TryParse(configurations.GetOrDefault("AccountId") as string, out var accountId))
            {
                throw new ArgumentNullException("AccountId");
            }

            var account = await _accountRepository.GetAsync(accountId);

            if (account.UserId != _currentUser.GetId())
            {
                throw new UserIsNotAccountOwnerException(_currentUser.GetId(), accountId);
            }

            payment.SetProperty("AccountId", accountId);

            var accountGroupConfiguration = _accountGroupConfigurationProvider.Get(account.AccountGroupName);

            if (!accountGroupConfiguration.AllowedUsingToTopUpOtherAccounts &&
                payment.PaymentItems.Any(x => x.ItemType == PrepaymentConsts.TopUpPaymentItemType))
            {
                throw new AccountTopingUpOtherAccountsIsNotAllowedException(account.AccountGroupName);
            }

            if (payment.PaymentItems.Any(x =>
                                         x.ItemType == PrepaymentConsts.TopUpPaymentItemType && x.ItemKey == accountId.ToString()))
            {
                throw new SelfTopUpException();
            }

            if (payment.Currency != accountGroupConfiguration.Currency)
            {
                throw new CurrencyNotSupportedException(payment.Currency);
            }

            var accountChangedBalance = -1 * payment.ActualPaymentAmount;

            var transaction = new Transaction(_guidGenerator.Create(), _currentTenant.Id, account.Id, account.UserId,
                                              payment.Id, TransactionType.Credit, PrepaymentConsts.PaymentActionName, payment.PaymentMethod,
                                              payment.ExternalTradingCode, accountGroupConfiguration.Currency, accountChangedBalance,
                                              account.Balance);

            await _transactionRepository.InsertAsync(transaction, true);

            account.ChangeBalance(accountChangedBalance);

            await _accountRepository.UpdateAsync(account, true);

            await _paymentManager.CompletePaymentAsync(payment);

            await _paymentRepository.UpdateAsync(payment, true);
        }
예제 #3
0
        public override async Task OnPaymentStartedAsync(Payment payment, Dictionary <string, object> configurations)
        {
            if (payment.ActualPaymentAmount != decimal.Zero)
            {
                throw new PaymentAmountInvalidException(payment.ActualPaymentAmount, PaymentMethod);
            }

            // payment.SetPayeeAccount("None");

            // payment.SetExternalTradingCode(payment.Id.ToString());

            await _paymentManager.CompletePaymentAsync(payment);

            await _paymentRepository.UpdateAsync(payment, true);
        }