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); }
public override async Task OnPaymentStartedAsync(Payment payment, ExtraPropertyDictionary configurations) { if (payment.Currency != "CNY") { throw new CurrencyNotSupportedException(payment.PaymentMethod, payment.Currency); } if (payment.ActualPaymentAmount <= decimal.Zero) { throw new PaymentAmountInvalidException(payment.ActualPaymentAmount, PaymentMethod); } var payeeAccount = configurations.GetOrDefault("PayeeAccount") as string ?? await _settingProvider.GetOrNullAsync(WeChatPaySettings.MchId); Check.NotNullOrWhiteSpace(payeeAccount, "PayeeAccount"); payment.SetPayeeAccount(payeeAccount); var appId = configurations.GetOrDefault("appid") as string; var openId = await _paymentOpenIdProvider.FindUserOpenIdAsync(appId, payment.UserId); var outTradeNo = payment.Id.ToString("N"); var result = await _serviceProviderPayService.UnifiedOrderAsync( appId : appId, subAppId : null, mchId : payment.PayeeAccount, subMchId : null, deviceInfo : PaymentServiceWeChatPayConsts.DeviceInfo, body : configurations.GetOrDefault("body") as string ?? "EasyAbpPaymentService", detail : configurations.GetOrDefault("detail") as string, attach : configurations.GetOrDefault("attach") as string, outTradeNo : outTradeNo, feeType : payment.Currency, totalFee : _weChatPayFeeConverter.ConvertToWeChatPayFee(payment.ActualPaymentAmount), billCreateIp : "127.0.0.1", timeStart : null, timeExpire : null, goodsTag : configurations.GetOrDefault("goods_tag") as string, notifyUrl : configurations.GetOrDefault("notify_url") as string ?? await _settingProvider.GetOrNullAsync(WeChatPaySettings.NotifyUrl), tradeType : configurations.GetOrDefault("trade_type") as string, productId : null, limitPay : configurations.GetOrDefault("limit_pay") as string, openId : openId, subOpenId : null, receipt : configurations.GetOrDefault("receipt") as string ?? "N", sceneInfo : null); var dict = result.SelectSingleNode("xml").ToDictionary() ?? throw new NullReferenceException(); if (dict.GetOrDefault("return_code") != "SUCCESS") { throw new UnifiedOrderFailedException(dict.GetOrDefault("return_code"), dict.GetOrDefault("return_msg")); } if (dict.GetOrDefault("result_code") != "SUCCESS") { throw new UnifiedOrderFailedException( dict.GetOrDefault("return_code"), dict.GetOrDefault("return_msg"), dict.GetOrDefault("err_code_des"), dict.GetOrDefault("err_code") ); } payment.SetProperty("appid", configurations.GetOrDefault("appid") as string); payment.SetProperty("trade_type", dict.GetOrDefault("trade_type")); payment.SetProperty("prepay_id", dict.GetOrDefault("prepay_id")); payment.SetProperty("code_url", dict.GetOrDefault("code_url")); await _paymentRecordRepository.InsertAsync( new PaymentRecord(_guidGenerator.Create(), _currentTenant.Id, payment.Id), true); await _paymentRepository.UpdateAsync(payment, true); }