using Hutopy.Infrastructure.Payments.Stripe.Configuration; using Hutopy.Modules.Creators.Contracts; using Hutopy.Modules.Tipping.Contracts; using Microsoft.Extensions.Options; using Stripe; using Stripe.Checkout; namespace Hutopy.Infrastructure.Payments.Stripe.Services; internal class StripeTipProcessor( IOptions stripeOptions) : ITipProcessor { public async Task CreateCheckoutSessionAsync( Guid tipId, CreatorReference creator, decimal amount, string currency, string message, Uri successUrl, Uri cancelUrl, CancellationToken ct = default) { StripeConfiguration.ApiKey = stripeOptions.Value.SecretKey; // Create Stripe customer for the user if not already created CustomerService customerService = new(); var customer = await customerService .CreateAsync( new CustomerCreateOptions(), cancellationToken: ct) .ConfigureAwait(false); // Create paymentIntent for the user SessionService sessionService = new(); var session = await sessionService.CreateAsync( new SessionCreateOptions { ClientReferenceId = tipId.ToString(), Customer = customer.Id, PaymentMethodTypes = ["card"], LineItems = [ new SessionLineItemOptions { PriceData = new SessionLineItemPriceDataOptions { Currency = currency, UnitAmountDecimal = amount, // Amount in cents ProductData = new SessionLineItemPriceDataProductDataOptions { Name = $"Tip for {creator.Name}", // or any descriptive name for the tip Metadata = new Dictionary { { "creatorId", creator.Id.ToString() } } } }, Quantity = 1 } ], Mode = "payment", PaymentIntentData = new SessionPaymentIntentDataOptions { ApplicationFeeAmount = Convert.ToInt64(amount * stripeOptions.Value.HutopyRate), // Platform fee TransferData = new SessionPaymentIntentDataTransferDataOptions { Destination = creator.StripeAccountId // Creator's Stripe account ID } }, SuccessUrl = successUrl.ToString(), // Redirect after successful payment CancelUrl = cancelUrl.ToString(), // Redirect after canceled payment Metadata = new Dictionary { { "creatorId", creator.Id.ToString() }, { "creatorName", creator.Name }, { "message", message } } }, cancellationToken: ct) .ConfigureAwait(false); return new TipCheckoutSession(session.Id, session.Url); } }