public async Task FufillOrderFromCompletedSessionAsync(Session session, CancellationToken cancellationToken = default) { var stripeSession = await _dbContext.StripeSessions .FirstOrDefaultAsync(s => s.Id == session.Id, cancellationToken); if (stripeSession == null) { _logger.LogError($"session does not exist. Has data been lost? ({session.Id})"); return; } if (string.IsNullOrEmpty(session.PaymentIntentId)) { _logger.LogCritical($"No Payment Intent associated with Checkout Session ({session.Id})"); return; } if (session.PaymentIntent == null) { session.PaymentIntent = await _paymentIntentService.GetAsync(session.PaymentIntentId, cancellationToken : cancellationToken); } // Record the patyment intent for future refunds. stripeSession.PaymentIntent = session.PaymentIntentId; if ((stripeSession.State == StripeSessionState.None || stripeSession.State == StripeSessionState.Processing) && session.PaymentIntent.Status == "succeeded") { var amountReceived = (int)session.PaymentIntent.AmountReceived.Value; // Assume the fee was included in the price during checkout when IncludeFee is enabled. if (_options.Value.IncludeFee) { amountReceived = amountReceived - (amountReceived * 29 / 1000) - 30; } await _orderService.AddReceivedFundsForOrderAsync( stripeSession.OrderId, amountReceived, NAME, session.PaymentIntentId, session.PaymentIntent.Created.Value, allowDuplicates : false, cancellationToken : cancellationToken); stripeSession.State = StripeSessionState.Completed; // TODO: Record audit log of payment received. } await _dbContext.SaveChangesAsync(); }
public async Task <PaymentIntentDao> GetPaymentIntent(string paymentIntentId, CancellationToken cancellationToken) { Guard.Argument(paymentIntentId, nameof(paymentIntentId)).NotNull().NotEmpty().NotWhiteSpace(); var paymentIntent = await _paymentIntentService.GetAsync(paymentIntentId, cancellationToken : cancellationToken); return(paymentIntent.ToPaymentIntentDao()); }
public async Task <ActionResult> StripeWebHook() { using var sr = new StreamReader(HttpContext.Request.Body); var json = await sr.ReadToEndAsync(); Event stripeEvent; try { stripeEvent = EventUtility.ConstructEvent(json, Request.Headers["Stripe-Signature"], _options.Value.WebHook, 3000, false); } catch (StripeException e) { Console.WriteLine($"Something failed {e}"); return(BadRequest()); } if (stripeEvent.Type == Events.CheckoutSessionCompleted) { if (stripeEvent.Data.Object is Session session && session.PaymentStatus == "paid") { var paymentIntentService = new PaymentIntentService(); var payment = await paymentIntentService.GetAsync(session.PaymentIntentId); if (payment?.Metadata.FirstOrDefault(x => x.Key == "SessionId").Value != null) { await Mediator.Send(new CreateOrderCommand { ShipToAddress = new AddressDto { FirstName = payment.Shipping.Name.Split('/')[0], LastName = payment.Shipping.Name.Split('/')[1], CompanyName = payment.Shipping.Name.Split('/')[2], Email = payment.ReceiptEmail, PhoneNumber = payment.Shipping.Phone, Country = payment.Shipping.Address.Country, City = payment.Shipping.Address.City, State = payment.Shipping.Address.State, ZipCode = payment.Shipping.Address.PostalCode, Street = payment.Shipping.Address.Line1, HomeNumber = payment.Shipping.Address.Line2, }, ShippingId = int.Parse(payment.Metadata.First(x => x.Key == "ShippingId").Value), SessionId = payment.Metadata.First(x => x.Key == "SessionId").Value, PaymentId = 3 }); } else { Console.WriteLine("Unhandled event type: {0}", stripeEvent.Type); } } } return(Ok()); }
public override async Task <ApiResult> FetchPaymentStatusAsync(PaymentProviderContext <StripeCheckoutSettings> ctx) { try { var secretKey = ctx.Settings.TestMode ? ctx.Settings.TestSecretKey : ctx.Settings.LiveSecretKey; ConfigureStripe(secretKey); // See if we have a payment intent to work from var paymentIntentId = ctx.Order.Properties["stripePaymentIntentId"]; if (!string.IsNullOrWhiteSpace(paymentIntentId)) { var paymentIntentService = new PaymentIntentService(); var paymentIntent = await paymentIntentService.GetAsync(paymentIntentId, new PaymentIntentGetOptions { Expand = new List <string>(new[] { "review" }) }); return(new ApiResult() { TransactionInfo = new TransactionInfoUpdate() { TransactionId = GetTransactionId(paymentIntent), PaymentStatus = GetPaymentStatus(paymentIntent) } }); } // No payment intent, so look for a charge var chargeId = ctx.Order.Properties["stripeChargeId"]; if (!string.IsNullOrWhiteSpace(chargeId)) { var chargeService = new ChargeService(); var charge = await chargeService.GetAsync(chargeId); return(new ApiResult() { TransactionInfo = new TransactionInfoUpdate() { TransactionId = GetTransactionId(charge), PaymentStatus = GetPaymentStatus(charge) } }); } } catch (Exception ex) { _logger.Error(ex, "Stripe - FetchPaymentStatus"); } return(ApiResult.Empty); }
/// <summary> /// validate a payment id /// </summary> /// <param name="paymentIntentId"></param> /// <returns></returns> public async Task <bool> ValidatePaymentIntentAsync(string paymentIntentId) { var paymentService = new PaymentIntentService(); try { var res = await paymentService.GetAsync(paymentIntentId, requestOptions : GetRequestOptions()); return(res != null); } catch (Exception e) { return(false); } }
public async Task <IActionResult> OnPostAsync( string paymentId, [FromServices] CreateOrder createOrder, [FromServices] GetCart getCart, [FromServices] PaymentIntentService paymentIntentService) { var payment = await paymentIntentService.GetAsync(paymentId); if (payment == null) { //todo do some kinda notification that this went wrong. return(RedirectToPage()); } var order = new Domain.Models.Order { StripeReference = paymentId, CartId = await getCart.Id(User.GetUserId()), }; await createOrder.Do(order); return(RedirectToPage("/Checkout/Success", new { orderId = order.Id })); }
public async Task <PaymentIntent> GetPaymentIntentAsync(string paymentIntentId) { var service = new PaymentIntentService(); return(await service.GetAsync(paymentIntentId)); }
public override async Task <CallbackResult> ProcessCallbackAsync(PaymentProviderContext <StripeCheckoutSettings> ctx) { // The ProcessCallback method is only intendid to be called via a Stripe Webhook and so // it's job is to process the webhook event and finalize / update the ctx.Order accordingly try { var secretKey = ctx.Settings.TestMode ? ctx.Settings.TestSecretKey : ctx.Settings.LiveSecretKey; var webhookSigningSecret = ctx.Settings.TestMode ? ctx.Settings.TestWebhookSigningSecret : ctx.Settings.LiveWebhookSigningSecret; ConfigureStripe(secretKey); var stripeEvent = await GetWebhookStripeEventAsync(ctx, webhookSigningSecret); if (stripeEvent != null && stripeEvent.Type == Events.CheckoutSessionCompleted) { if (stripeEvent.Data?.Object?.Instance is Session stripeSession) { if (stripeSession.Mode == "payment") { var paymentIntentService = new PaymentIntentService(); var paymentIntent = await paymentIntentService.GetAsync(stripeSession.PaymentIntentId, new PaymentIntentGetOptions { Expand = new List <string>(new[] { "review" }) }); return(CallbackResult.Ok(new TransactionInfo { TransactionId = GetTransactionId(paymentIntent), AmountAuthorized = AmountFromMinorUnits(paymentIntent.Amount), PaymentStatus = GetPaymentStatus(paymentIntent) }, new Dictionary <string, string> { { "stripeSessionId", stripeSession.Id }, { "stripeCustomerId", stripeSession.CustomerId }, { "stripePaymentIntentId", stripeSession.PaymentIntentId }, { "stripeSubscriptionId", stripeSession.SubscriptionId }, { "stripeChargeId", GetTransactionId(paymentIntent) }, { "stripeCardCountry", paymentIntent.Charges?.Data?.FirstOrDefault()?.PaymentMethodDetails?.Card?.Country } })); } else if (stripeSession.Mode == "subscription") { var subscriptionService = new SubscriptionService(); var subscription = await subscriptionService.GetAsync(stripeSession.SubscriptionId, new SubscriptionGetOptions { Expand = new List <string>(new[] { "latest_invoice", "latest_invoice.charge", "latest_invoice.charge.review", "latest_invoice.payment_intent", "latest_invoice.payment_intent.review" }) }); var invoice = subscription.LatestInvoice; return(CallbackResult.Ok(new TransactionInfo { TransactionId = GetTransactionId(invoice), AmountAuthorized = AmountFromMinorUnits(invoice.PaymentIntent.Amount), PaymentStatus = GetPaymentStatus(invoice) }, new Dictionary <string, string> { { "stripeSessionId", stripeSession.Id }, { "stripeCustomerId", stripeSession.CustomerId }, { "stripePaymentIntentId", invoice.PaymentIntentId }, { "stripeSubscriptionId", stripeSession.SubscriptionId }, { "stripeChargeId", invoice.ChargeId }, { "stripeCardCountry", invoice.Charge?.PaymentMethodDetails?.Card?.Country } })); } } else if (stripeEvent != null && stripeEvent.Type == Events.ReviewClosed) { if (stripeEvent.Data?.Object?.Instance is Review stripeReview && !string.IsNullOrWhiteSpace(stripeReview.PaymentIntentId)) { var paymentIntentService = new PaymentIntentService(); var paymentIntent = paymentIntentService.Get(stripeReview.PaymentIntentId, new PaymentIntentGetOptions { Expand = new List <string>(new[] { "review" }) }); return(CallbackResult.Ok(new TransactionInfo { TransactionId = GetTransactionId(paymentIntent), AmountAuthorized = AmountFromMinorUnits(paymentIntent.Amount), PaymentStatus = GetPaymentStatus(paymentIntent) })); } } } } catch (Exception ex) { _logger.Error(ex, "Stripe - ProcessCallback"); } return(CallbackResult.BadRequest()); }