public async Task <string> PayReservation(int reservationId, decimal amount, Dictionary <string, string> metadata) { var(reservation, company, user) = await GetReservation(reservationId); if (reservation == null) { throw new RecordNotFoundException(); } var accountId = await GetStripeAccountFromCompany(company.Id); metadata[MetadataReservationIdKey] = reservationId.ToString(); metadata[MetadataUserIdKey] = user.Id.ToString(); var paymentIntent = await _stripeService.CreatePaymentIntent(accountId, amount, user.Email, metadata); var payment = new Payment { Amount = amount, Created = DateTime.UtcNow, ReservationId = reservation.Id, Status = PaymentStatus.IntentGenerated, PaymentIntentId = paymentIntent.Id, UserId = user.Id }; _meredithDbContext.Payments.Add(payment); await _meredithDbContext.SaveChangesAsync(); return(paymentIntent.ClientSecret); }
public async Task <CustomerCartModel> Handle(GetCustomerCartQuery request, CancellationToken cancellationToken) { var data = await Task.FromResult(from o in _context.Orders.AsEnumerable() join m in _context.Merchants.AsEnumerable() on o.MerchantID equals m.ID join ost in _context.OrderStatusTypes.AsEnumerable() on o.OrderStatusTypeID equals ost.ID join li in _context.LineItems.AsEnumerable() on o.ID equals li.OrderID into tmp_li from li in tmp_li.DefaultIfEmpty() join i in _context.Items.AsEnumerable() on li?.ItemID equals i.ID into tmp_i from i in tmp_i.DefaultIfEmpty() where o.CustomerID == request.CustomerID && o.MerchantID == request.MerchantID && o.IsOpenOrder() select new { o, li }); var rows = data?.ToList(); if (rows == null || rows.Count == 0) { return(new CustomerCartModel()); } var dict_ci = new Dictionary <int, CustomerCartItemModel>(); var total = 0M; foreach (var row in rows) { if (row.li != null) { if (!dict_ci.ContainsKey(row.li.ItemID)) { dict_ci.Add(row.li.ItemID, _mapper.Map <CustomerCartItemModel>(row.li)); } dict_ci[row.li.ItemID].CurrentQuantity++; total += row.li.ItemAmount; } } var order = rows[0].o; var paymentIntent = request.AllowCheckout && total > 0 ? _stripe.CreatePaymentIntent(orderId: order.ID, centAmount: Convert.ToInt64(total * 100)) : null; return(new CustomerCartModel( cartItems: dict_ci.Values.ToList(), displayPrice: total.ToString("C"), clientSecret: paymentIntent?.ClientSecret, orderId: order.ID, merchantId: order.MerchantID, merchantName: order.Merchant.Name, total: total)); }
public async Task <ActionResult <int> > TryPayWithPaymentMethod(CreateServiceRequestModel model) { PaymentIntent paymentIntent; try { //TODO: optimize/consolidate TryPayWithPaymentMethod var customer = await _mediator.Send(new GetCustomerQuery(_user.ClaimID)); var cart = await _mediator.Send(new GetCustomerCartQuery(customer.ID, model.MerchantID)); var amount = cart.Total; paymentIntent = _stripe.CreatePaymentIntent(new PaymentIntentCreateOptions { Amount = Convert.ToInt64(amount) * 100, Currency = "usd", PaymentMethod = model.Payment.StripePaymentMethodID, Customer = customer.StripeCustomerID, // A PaymentIntent can be confirmed some time after creation, // but here we want to confirm (collect payment) immediately. Confirm = true, // If the payment requires any follow-up actions from the // customer, like two-factor authentication, Stripe will error // and you will need to prompt them for a new payment method. ErrorOnRequiresAction = true, }); } catch (StripeException e) { return(StatusCode(501, e.StripeError.Message)); } if (paymentIntent?.Status == "succeeded") { // Handle post-payment fulfillment return(await CreateServiceRequest(model)); } else { // Any other status would be unexpected, so error return(StatusCode(500, new { error = "Invalid PaymentIntent status" })); } }