public async Task <WalletRecord> IncomeOfOrderRebate(UserIdentifier userIdentifier, decimal money, string remark, Order order) { WalletRecord walletRecord = BuildWalletRecord(WalletRecordType.Recharge, userIdentifier.UserId, money, remark); WalletRecordRepository.Insert(walletRecord); Wallet wallet = GetWalletOfUser(userIdentifier); wallet.Money += money; WalletRepository.Update(wallet); CurrentUnitOfWork.SaveChanges(); string openid = WechatUserManager.GetOpenid(userIdentifier); if (!string.IsNullOrEmpty(openid)) { OrderRebateTemplateMessageData data = new OrderRebateTemplateMessageData( new TemplateDataItem(remark), new TemplateDataItem(order.Number), new TemplateDataItem(order.PayMoney.ToString()), new TemplateDataItem(order.PaymentDatetime.ToString()), new TemplateDataItem(money.ToString()), new TemplateDataItem(L("ThankYouForYourPatronage")) ); await TemplateMessageManager.SendTemplateMessageOfOrderRebateAsync(order.TenantId, openid, null, data); } return(walletRecord); }
[InlineData(MoneyManipulationOperation.Withdraw, 101, -1)] //should be failed public async Task MoneyOperation_MakeWithdrawAndCharge_CheckResult(MoneyManipulationOperation mmo, float fakeAmount, float expectedResult) { //arrange var fakeAccountId = 1; var fakeCurrency = new CurrencyRecord { Id = 1, Name = "FAKE" }; var fakeWallet = new WalletRecord { CashValue = 100 }; var userServiceMock = new Mock <IUserService>(); userServiceMock .Setup(x => x.FindCurrencyAsync(It.IsAny <string>())) .ReturnsAsync(fakeCurrency); userServiceMock .Setup(x => x.FindUserWalletAsync(It.IsAny <int>(), It.IsAny <int>())) .ReturnsAsync(fakeWallet); var adminController = new AdminController(userServiceMock.Object, _adminServiceMock.Object, _dbMock.Object); //act var result = await adminController.MoneyOperation(mmo, fakeCurrency.Name, fakeAccountId, fakeAmount); //assert if (expectedResult == -1) { Assert.IsType <BadRequestObjectResult>(result); } else { Assert.Equal(expectedResult, fakeWallet.CashValue); } }
private WalletRecord BuildWalletRecord(WalletRecordType type, long userId, decimal money, string remark) { WalletRecord walletRecord = new WalletRecord(type, userId, money, remark); walletRecord.SerialNumber = NumberProvider.BuildNumber(); return(walletRecord); }
protected override async void Run(Session session, C2G_QueryWalletRecord message, Action <G2C_QueryWalletRecord> reply) { G2C_QueryWalletRecord response = new G2C_QueryWalletRecord(); response.IsSuccess = false; try { DBProxyComponent dBProxyComponent = Game.Scene.GetComponent <DBProxyComponent>(); var acounts = await dBProxyComponent.Query <WalletRecord>("{ '_WalletID': " + message.WalletID + "}"); if (acounts.Count > 0) { WalletRecord user = acounts[0] as WalletRecord; response.Amount = user._Amount; response.CreateDate = user._CreateDate; response.Info = user._Info; response.DealDate = user._DealDate; response.SpeiaclInfo = user._SpeiaclInfo; response.Type = user._Type; response.State = user._State; response.IsSuccess = true; response.Message = MethodBase.GetCurrentMethod().DeclaringType.FullName + "." + MethodBase.GetCurrentMethod().Name + "钱包交易记录获取成功"; } reply(response); } catch (Exception e) { response.Message = MethodBase.GetCurrentMethod().DeclaringType.FullName + "." + MethodBase.GetCurrentMethod().Name + "钱包交易记录获取失败,服务器维护中。"; ReplyError(response, e, reply); } }
protected override async void Run(Session session, C2G_AddWalletRecord message, Action <G2C_AddWalletRecord> reply) { G2C_AddWalletRecord response = new G2C_AddWalletRecord(); try { DBProxyComponent dBProxyComponent = Game.Scene.GetComponent <DBProxyComponent>(); WalletRecord WalletRecord = ComponentFactory.Create <WalletRecord>(); WalletRecord._WalletID = message.WalletID; WalletRecord._Amount = message.Amount; WalletRecord._Info = message.Info; WalletRecord._CreateDate = message.CreateDate; WalletRecord._DealDate = message.DealDate; WalletRecord._SpeiaclInfo = message.SpeiaclInfo; WalletRecord._Type = message.Type; WalletRecord._State = message.State; await dBProxyComponent.Save(WalletRecord); await dBProxyComponent.SaveLog(WalletRecord); reply(response); } catch (Exception e) { //response.IsOk = false; response.Message = "数据库异常"; ReplyError(response, e, reply); } }
public async Task ChangeAccountValueAsync(string userName, string accountName, string currencyName, double value) { var accountId = (await _walletContext.Accounts.FirstOrDefaultAsync(a => a.Name == accountName && a.User.UserName == userName)).Id; var currencyId = (await _walletContext.Currencies.FirstOrDefaultAsync(c => c.Name == currencyName)).Id; var wallet = await _walletContext.Wallets.FirstOrDefaultAsync(w => w.CurrencyId == currencyId && w.AccountId == accountId); if (wallet == null) { wallet = new WalletRecord { CurrencyId = currencyId, Value = value, AccountId = accountId }; await _walletContext.Wallets.AddAsync(wallet); } else { wallet.Value = value; } await _walletContext.SaveChangesAsync(); }
public WalletRecord SetPayStatusOfFail(WalletRecord walletRecord, string failReason = null) { walletRecord.PayStatus = PayStatus.Fail; walletRecord.FailReason = failReason; WalletRecordRepository.Update(walletRecord); CurrentUnitOfWork.SaveChanges(); return(walletRecord); }
public WalletRecord Transaction(UserIdentifier userIdentifier, decimal money, string remark) { WalletRecord walletRecord = BuildWalletRecord(WalletRecordType.Transaction, userIdentifier.UserId, -money, remark); WalletRecordRepository.Insert(walletRecord); CurrentUnitOfWork.SaveChanges(); return(walletRecord); }
public override ErrorCode Set(string key, string value) { var record = new WalletRecord() { Value = value, TimeCreated = DateTime.Now }; _records[key] = record; return(ErrorCode.Success); }
private static void CreateWallet(this ModelBuilder builder, CurrencyRecord currency, AccountRecord account, double value, int id) { var wallet = new WalletRecord { Id = id, CurrencyId = currency.Id, AccountId = account.Id, Value = value }; builder.Entity <WalletRecord>().HasData(wallet); }
protected override async void Run(Session session, C2G_QueryWalletRecord message, Action <G2C_QueryWalletRecord> reply) { G2C_QueryWalletRecord response = new G2C_QueryWalletRecord(); WalletRecord WalletRecord = null; try { DBProxyComponent dBProxyComponent = Game.Scene.GetComponent <DBProxyComponent>(); var acounts = await dBProxyComponent.Query <WalletRecord>("{ '_AccountID': " + message.WalletID + "}"); if (acounts.Count <= 0) { WalletRecord Info = ComponentFactory.Create <WalletRecord>(); Info._WalletID = message.WalletID; Info._Amount = 0; Info._Info = ""; Info._CreateDate = ""; Info._DealDate = ""; Info._SpeiaclInfo = ""; Info._Type = 0; Info._State = 0; await dBProxyComponent.Save(Info); await dBProxyComponent.SaveLog(Info); } else { WalletRecord = acounts[0] as WalletRecord; response.Amount = WalletRecord._Amount; response.Info = WalletRecord._Info; response.CreateDate = WalletRecord._CreateDate; response.DealDate = WalletRecord._DealDate; response.SpeiaclInfo = WalletRecord._SpeiaclInfo; response.Type = WalletRecord._Type; response.State = WalletRecord._State; } await dBProxyComponent.Save(WalletRecord); await dBProxyComponent.SaveLog(WalletRecord); reply(response); } catch (Exception e) { response.Message = "数据库异常"; ReplyError(response, e, reply); } }
public async Task <WalletRecord> ProcessWithdrawAsync(WalletRecord walletRecord) { IWithdrawProvider WithdrawProvider = IocManager.Instance.Resolve <IWithdrawProvider>(); try { await WithdrawProvider.Withdraw(walletRecord); } catch (Exception exception) { WithdrawNotify(walletRecord, false, exception.Message); } return(walletRecord); }
public async Task Operation_ConfirmLimitCondition_ReturnsOkWithNewRequests() { //arrange var fakeUser = TestUser(); var fakeAmount = 1000.0f; var fakeCurrency = new CurrencyRecord { Id = 1, Name = "FAKE", ConfirmLimit = 999.9f }; var fakeAccount = TestUserAccount(); var fakeWallet = new WalletRecord { CashValue = 1000 }; var userServiceMock = new Mock <IUserService>(); userServiceMock .Setup(x => x.FindCurrencyAsync(It.IsAny <string>())) .ReturnsAsync(fakeCurrency); userServiceMock .Setup(x => x.FindUserWalletAsync(It.IsAny <int>(), It.IsAny <int>())) .ReturnsAsync(fakeWallet); userServiceMock .Setup(x => x.FindUserAccountAsync(It.IsAny <int>(), It.IsAny <int>())) .ReturnsAsync(fakeAccount); userServiceMock .Setup(x => x.FindUserByNameAsync(It.IsAny <string>())) .ReturnsAsync(fakeUser); userServiceMock .Setup(x => x.FindCurrencyCommissionAsync(It.IsAny <int>())) .ReturnsAsync(null as CommissionRecord); userServiceMock .Setup(x => x.FindUserCommissionAsync(It.IsAny <int>())) .ReturnsAsync(null as CommissionRecord); var accountController = new AccountController(userServiceMock.Object, _dbMock.Object) { ControllerContext = _controllerContext }; //act var result = await accountController.Operation(fakeAccount.Id, OperationType.Deposit, fakeAmount, fakeCurrency.Name, null); //assert Assert.IsType <OkObjectResult>(result); userServiceMock.Verify(x => x.AddRequestToConfirmAsync(It.IsAny <OperationType>(), It.IsAny <AccountRecord>(), It.IsAny <AccountRecord>(), It.IsAny <float>(), It.IsAny <float>(), It.IsAny <string>())); }
public WalletRecord Recharge(UserIdentifier userIdentifier, decimal money, string remark) { using (CurrentUnitOfWork.SetTenantId(userIdentifier.TenantId)) { WalletRecord walletRecord = BuildWalletRecord(WalletRecordType.Recharge, userIdentifier.UserId, money, remark); WalletRecordRepository.Insert(walletRecord); Wallet wallet = GetWalletOfUser(userIdentifier); wallet.Money += money; WalletRepository.Update(wallet); CurrentUnitOfWork.SaveChanges(); return(walletRecord); } }
public WalletRecord SetPayStatusOfSuccess(WalletRecord walletRecord) { walletRecord.PayStatus = PayStatus.Success; walletRecord.PayDateTime = DateTime.Now; Wallet wallet = GetWalletOfUser(walletRecord.GetUserIdentifier()); if (walletRecord.Type == WalletRecordType.Recharge) { wallet.Money += walletRecord.Money; } WalletRepository.Update(wallet); WalletRecordRepository.Update(walletRecord); CurrentUnitOfWork.SaveChanges(); return(walletRecord); }
public async Task Operation_WithdrawMoneyWithCommission_VerifyResult() { //arrange var fakeUser = TestUser(); var fakeAmount = 1000.0f; var fakeCurrency = new CurrencyRecord { Id = 1, Name = "FAKE" }; var fakeAccount = TestUserAccount(); var fakeWallet = new WalletRecord { CashValue = 1010 }; var fakeCommission = new CommissionRecord { CurrencyId = 1, WithdrawCommission = 10, IsAbsoluteType = true }; var userServiceMock = new Mock <IUserService>(); userServiceMock .Setup(x => x.FindCurrencyAsync(It.IsAny <string>())) .ReturnsAsync(fakeCurrency); userServiceMock .Setup(x => x.FindUserWalletAsync(It.IsAny <int>(), It.IsAny <int>())) .ReturnsAsync(fakeWallet); userServiceMock .Setup(x => x.FindUserAccountAsync(It.IsAny <int>(), It.IsAny <int>())) .ReturnsAsync(fakeAccount); userServiceMock .Setup(x => x.FindUserByNameAsync(It.IsAny <string>())) .ReturnsAsync(fakeUser); userServiceMock .Setup(x => x.FindCurrencyCommissionAsync(It.IsAny <int>())) .ReturnsAsync(fakeCommission); userServiceMock .Setup(x => x.FindUserCommissionAsync(It.IsAny <int>())) .ReturnsAsync(null as CommissionRecord); var accountController = new AccountController(userServiceMock.Object, _dbMock.Object) { ControllerContext = _controllerContext }; //act await accountController.Operation(fakeAccount.Id, OperationType.Withdraw, fakeAmount, fakeCurrency.Name, null); //assert Assert.Equal(0, fakeWallet.CashValue); }
public async Task Confirm_VerifyConfirmationAndAddingToOperationsHistory_ReturnOk() { var fakeCurrency = new CurrencyRecord { Id = 1, Name = "FAKE" }; var fakeWallet = new WalletRecord { CashValue = 50 }; var fakeUser = new UserRecord { Id = 1 }; var fakeConfirmRequest = new ConfirmRequestRecord { Currency = "FAKE", OperationType = OperationType.Deposit, SenderId = 1, Amount = 45, Commission = 0.0f }; var adminServiceMock = new Mock <IAdminService>(); adminServiceMock .Setup(x => x.FindRequestToConfirm(It.IsAny <int>())) .ReturnsAsync(fakeConfirmRequest); var userServiceMock = new Mock <IUserService>(); userServiceMock .Setup(x => x.FindCurrencyAsync(fakeConfirmRequest.Currency)) .ReturnsAsync(fakeCurrency); userServiceMock .Setup(x => x.FindUserByAccountIdAsync(fakeConfirmRequest.SenderId)) .ReturnsAsync(fakeUser); userServiceMock .Setup(x => x.FindUserWalletAsync(fakeConfirmRequest.SenderId, fakeCurrency.Id)) .ReturnsAsync(fakeWallet); var adminController = new AdminController(userServiceMock.Object, adminServiceMock.Object, _dbMock.Object); //act var result = await adminController.Confirm(It.IsAny <int>()); //assert Assert.IsType <OkObjectResult>(result); Assert.Equal(RequestStatus.Completed, fakeConfirmRequest.Status); userServiceMock.Verify(x => x.AddOperationHistoryAsync(fakeConfirmRequest.OperationType, fakeUser.Id, fakeConfirmRequest.SenderId, fakeConfirmRequest.Amount, fakeConfirmRequest.Commission, fakeCurrency.Name)); }
public async Task <WalletRecord> WithdrawAsync(UserIdentifier userIdentifier, decimal money, string remark) { using (CurrentUnitOfWork.DisableFilter(DataFilters.MustHaveTenant)) { WalletRecord walletRecord = BuildWalletRecord(WalletRecordType.Withdraw, userIdentifier.UserId, -money, remark); WalletRecordRepository.Insert(walletRecord); Wallet wallet = GetWalletOfUser(userIdentifier); wallet.Money -= money; WalletRepository.Update(wallet); CurrentUnitOfWork.SaveChanges(); await ProcessWithdrawAsync(walletRecord); return(walletRecord); } }
protected async Task <WalletRecord> GetOrCreateWalletAsync(int currencyId, int accountId) { var wallet = await Context.Wallets .FirstOrDefaultAsync(w => w.CurrencyId == currencyId && w.AccountId == accountId); if (wallet != null) { return(wallet); } wallet = new WalletRecord { AccountId = accountId, CurrencyId = currencyId }; await Context.Wallets.AddAsync(wallet); await Context.SaveChangesAsync(); return(wallet); }
public async Task Withdraw(WalletRecord walletRecord) { using (CurrentUnitOfWork.SetTenantId(walletRecord.TenantId)) { string appId = await SettingManager.GetSettingValueForTenantAsync(WechatSettings.General.AppId, walletRecord.TenantId); string mchId = await SettingManager.GetSettingValueForTenantAsync(WechatSettings.Pay.MchId, walletRecord.TenantId); string key = await SettingManager.GetSettingValueForTenantAsync(WechatSettings.Pay.Key, walletRecord.TenantId); UserLogin userLogin = userLoginRepository.GetAll().Where(model => model.UserId == walletRecord.UserId && model.LoginProvider == "Weixin").FirstOrDefault(); if (userLogin == null) { throw new Exception(L("TheUserHasNoWeixinLogin")); } string openId = userLogin.ProviderKey; string nonce = TenPayV3Util.GetNoncestr(); TenPayV3TransfersRequestData TenPayV3TransfersRequestData = new TenPayV3TransfersRequestData( appId, mchId, null, nonce, walletRecord.SerialNumber, openId, key, "NO_CHECK", null, (int)(-walletRecord.Money), L("Withdraw"), IPHelper.GetAddressIP()); TransfersResult transfersResult = await TransfersAsync(walletRecord.TenantId, TenPayV3TransfersRequestData); if (transfersResult.return_code == "FAIL") { WalletManager.WithdrawNotify(walletRecord, false, transfersResult.return_msg); } bool success = transfersResult.result_code == "FAIL" ? false : true; WalletManager.WithdrawNotify(walletRecord, success, transfersResult.err_code_des); } }
protected override async void Run(Session session, C2G_AddWalletRecord message, Action <G2C_AddWalletRecord> reply) { G2C_AddWalletRecord response = new G2C_AddWalletRecord(); response.IsSuccess = false; try { DBProxyComponent dBProxyComponent = Game.Scene.GetComponent <DBProxyComponent>(); WalletRecord WalletData = ComponentFactory.Create <WalletRecord>(); WalletData._Amount = message.Amount; WalletData._CreateDate = message.CreateDate; WalletData._DealDate = message.DealDate; WalletData._Info = message.Info; WalletData._SpeiaclInfo = message.SpeiaclInfo; WalletData._State = message.State; WalletData._Type = message.Type; WalletData._WalletID = message.WalletID; await dBProxyComponent.Save(WalletData); await dBProxyComponent.SaveLog(WalletData); response.IsSuccess = true; reply(response); } catch (Exception e) { response.Message = MethodBase.GetCurrentMethod().DeclaringType.FullName + "." + MethodBase.GetCurrentMethod().Name + "创建钱包交易记录失败,服务器维护中。"; ReplyError(response, e, reply); } }
protected override bool CheckWalletValue(WalletRecord wallet, OperationRecord operation) => true;
protected override bool CheckWalletValue(WalletRecord wallet, OperationRecord operation) => wallet.Value > operation.Value + operation.Commission;
protected override async Task <OperationRecord> CreateOperationAsync(TransferOperationDto dto, int currencyId, double commission, int accountId, WalletRecord wallet) { var userId = (await Context.Users.FirstOrDefaultAsync(u => u.UserName == dto.UserName)).Id; var toAccountId = (await Context.Accounts.FirstOrDefaultAsync(a => a.Name == dto.ToAccountName && a.UserId == userId)) .Id; var toWallet = await GetOrCreateWalletAsync(currencyId, toAccountId); return(new OperationRecord { WalletId = wallet.Id, Type = Type, Value = dto.Value, Commission = commission, TransferWalletId = toWallet.Id }); }
protected override async Task <OperationRecord> CreateOperationAsync(OperationDto dto, int currencyId, double commission, int accountId, WalletRecord wallet) { var time = DateTime.Now; return(new OperationRecord { WalletId = wallet.Id, Type = Type, Value = dto.Value, Commission = commission }); }
public static Models.Wallet ToWallet(this WalletRecord record) => new Models.Wallet(record.Id, record.Value, record.Currency.Name);
protected abstract bool CheckWalletValue(WalletRecord wallet, OperationRecord operation);
protected abstract Task <OperationRecord> CreateOperationAsync(TRequest request, int currencyId, double commission, int accountId, WalletRecord wallet);
/// <summary> /// Updates the specified record. Properties that are null won't be changed. /// </summary> /// <param name="authUser">The e-mail address of the user to whom the record should be added</param> /// <param name="authToken">A valid API token (linked to the e-mail of the specified user)</param> /// <param name="recordToUpdate">Record object that specifie the properties of the record to be updated</param> /// <returns>Returns the unique Id of the newly created record</returns> public static async Task <string> UpdateAsync(string authUser, string authToken, WalletRecord recordToUpdate) { if (recordToUpdate.Id == null) { throw new ArgumentException("Id of updated record object can't be null"); } var putConformObject = new { currencyId = recordToUpdate.CurrencyId, accountId = recordToUpdate.AccountId, categoryId = recordToUpdate.CategoryId, amount = recordToUpdate.Amount, paymentType = recordToUpdate.PaymentType.ToValidApiString(), note = recordToUpdate.Note, date = recordToUpdate.Date.ToString(), recordState = recordToUpdate.RecordState.ToValidApiString() }; var urlSpecifier = $"record/{recordToUpdate.Id}"; var contentType = "application/json"; var contentJson = JsonConvert.SerializeObject(putConformObject); var content = new StringContent(contentJson, Encoding.Default, contentType); using (var client = new HttpClient { BaseAddress = new Uri(Constants.BaseUrl) }) { client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Add(Constants.TokenHeaderKey, authToken); client.DefaultRequestHeaders.Add(Constants.UserHeaderKey, authUser); var response = await client.PutAsync(urlSpecifier, content); var responseJson = await response.Content.ReadAsStringAsync(); return(JsonConvert.DeserializeObject <dynamic>(responseJson).id.ToString()); } }
public WalletRecord WithdrawNotify(WalletRecord walletRecord, bool success, string failReason = null) { using (CurrentUnitOfWork.SetTenantId(walletRecord.TenantId)) { string openid = WechatUserManager.GetOpenid(walletRecord.GetUserIdentifier()); User user = walletRecord.User; if (user == null) { user = UserRepository.Get(walletRecord.UserId); } if (success) { walletRecord.FetchStatus = FetchStatus.Success; walletRecord.FailReason = ""; WalletRecordRepository.Update(walletRecord); CurrentUnitOfWork.SaveChanges(); if (!string.IsNullOrEmpty(openid)) { Task.Run(async() => { WalletWithdrawTemplateMessageData data = new WalletWithdrawTemplateMessageData( new TemplateDataItem(L("WithdrawSuccessfully")), new TemplateDataItem(user.NickName), new TemplateDataItem((-walletRecord.Money).ToString()), new TemplateDataItem(L("ThankYouForYourPatronage")) ); await TemplateMessageManager.SendTemplateMessageOfWalletWithdrawAsync(walletRecord.TenantId, openid, null, data); }); } } else { if (string.IsNullOrEmpty(failReason)) { failReason = L("UnKnowFail"); } walletRecord.FetchStatus = FetchStatus.Fail; walletRecord.FailReason = failReason; WalletRecordRepository.Update(walletRecord); CurrentUnitOfWork.SaveChanges(); if (!string.IsNullOrEmpty(openid)) { Task.Run(async() => { WalletWithdrawTemplateMessageData data = new WalletWithdrawTemplateMessageData( new TemplateDataItem(L("WithdrawFailed") + ":" + failReason), new TemplateDataItem(user.NickName), new TemplateDataItem((-walletRecord.Money).ToString()), new TemplateDataItem(L("ThankYouForYourPatronage")) ); await TemplateMessageManager.SendTemplateMessageOfWalletWithdrawAsync(walletRecord.TenantId, openid, null, data); }); } } return(walletRecord); } }