public async Task <Account> GetOrCreateAccount(AccountIdentification id) { using (var con = new ConScope(_dataService)) using (var trans = await con.BeginTransaction()) { var account = await GetAccount(id); if (account == null) { if (!id.GlobalUserId.HasValue) { throw new Exception("Can only auto create account when using global user id."); } account = new Account { GlobalUserId = id.GlobalUserId.Value }; await con.Connection.SaveAsync(account); trans.Commit(); _logger.LogInformation("Created account {AccountId} for global user {GlobalUserId", account.Id, id.GlobalUserId); } return(account); } }
private async Task <(Flow flow, Domain.Account)> GetFlow(string flowId) { flowId.NotNullOrEmpty(); Flow flow = null; { var data = await _distributedCache.GetAsync($"flow-{flowId}"); if (data == null || data.Length == 0) { throw new Exception($"Invalid flow {flowId}"); } flow = JsonSerializer.Deserialize <Flow>(data); } flow.NotNull(); var account = await _accountsService.GetOrCreateAccount(AccountIdentification.ByGlobalUserId(User.GetUserId())); if (flow.AccountId != account.Id) { throw new Exception("Flow for wrong account."); } return(flow, account); }
public async Task <IViewComponentResult> InvokeAsync(string selectedTab) { var account = await _accountsService.GetAccount(AccountIdentification.ByGlobalUserId(((ClaimsPrincipal)User).GetUserId())); return(View(new SideBarViewModel { SelectedTab = selectedTab, Amount = account?.CurrentBalance ?? 0 })); }
public async Task <CreateOrderResponse> CreateOrder([FromBody] CreateOrderRequest request) { var account = await _accountsService.GetOrCreateAccount(AccountIdentification.ByGlobalUserId(User.GetUserId())); var pendingOrder = await _payPalService.CreatePendingOrder(account.Id, request.Amount); return(new CreateOrderResponse { OrderId = pendingOrder.PayPalOrderId }); }
public async Task <ActionResult> PayPalOrderCreate([FromBody] CreatePayPalOrderRequest request) { var(flow, _) = await GetFlow(request.FlowId); var account = await _accountsService.GetOrCreateAccount(AccountIdentification.ByGlobalUserId(User.GetUserId())); var pendingOrder = await _payPalService.CreatePendingOrder(account.Id, flow.Amount); return(Json(new CreatePayPalOrderResponse { OrderId = pendingOrder.PayPalOrderId })); }
public async Task <Account> GetAccount(AccountIdentification id) { using (var con = new ConScope(_dataService)) { if (id.Id.HasValue) { return(await con.Connection.SingleAsync <Account>(id.Id)); } if (id.GlobalUserId.HasValue) { return(await con.Connection.SingleAsync <Account>(x => x.GlobalUserId == id.GlobalUserId)); } throw new Exception("Invalid id"); } }
public async Task <ActionResult> Index(SpecifyAmountInputModel model) { model.Amount = model.Amount.TrimMoney(); if (!ModelState.IsValid) { return(View(new SpecifyAmountViewModel { Amount = model.Amount })); } var flowId = Guid.NewGuid().ToString(); await _distributedCache.SetAsync($"flow-{flowId}", JsonSerializer.SerializeToUtf8Bytes(new Flow { Amount = model.Amount, AccountId = (await _accountsService.GetOrCreateAccount(AccountIdentification.ByGlobalUserId(User.GetUserId()))).Id }), new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5) }); return(RedirectToAction("Fund", new { flowId = flowId })); }
public async Task <PayPalOrder> CreatePendingOrder(Guid accountId, decimal amount) { // TODO: Make this range configurable. if (amount <= 0 || amount > 500) { throw new Exception("Invalid amount."); } _logger.LogInformation("Creating pending paypal order for {AccountId} for {Amount}", accountId, amount); var account = await _accountsService.GetAccount(AccountIdentification.ById(accountId)); account.NotNull(); var potentialOrderId = Guid.NewGuid(); string paypalOrderId; { var client = _payPalClientProvider.BuildHttpClient(); var request = new OrdersCreateRequest(); request.Prefer("return=representation"); request.RequestBody(new OrderRequest { CheckoutPaymentIntent = "CAPTURE", PurchaseUnits = new List <PurchaseUnitRequest> { new PurchaseUnitRequest { ReferenceId = potentialOrderId.ToString(), AmountWithBreakdown = new AmountWithBreakdown { Value = amount.ToString(CultureInfo.InvariantCulture), CurrencyCode = "USD" } } } }); var response = await client.Execute(request); if (response.StatusCode != HttpStatusCode.Created) { _logger.LogError("Invalid status code from PayPal order create: status: {Status} response: {Response}", response.StatusCode, SerializePayPalType(response.Result <object>())); throw new Exception("Invalid PayPal response"); } paypalOrderId = response.Result <Order>().Id; } // Great, we created a PayPal order, let's add the record into the database. using (var con = new ConScope(_dataService)) { var pendingOrder = new PayPalOrder { Id = potentialOrderId, OrderStatus = PayPalOrderStatus.Pending, PayPalOrderId = paypalOrderId, AccountId = account.Id, Amount = amount }; await con.Connection.InsertAsync(pendingOrder); return(pendingOrder); } }