Search code examples
c#asp.net-mvcstripe-payments3d-secure

How to integrate stripe payment with custom form in ASP.NET MVC?


How do I use custom stripe form and then integration with 3D Security options using ASP.NET MVC?


Solution

  • enter image description here Custom Form Design using Razor/ Html

     <div class="campagin_start content" style="max-width:100%">
               <div class="cell example example2" id="">
                    <form>
                       <div class="row">
                           <div class="field">
                                 <div id="example2-card-number" class="input empty"></div>
                                    <label for="example2-card-number" data-tid="elements_examples.form.card_number_label">Card number</label>
                                        <div class="baseline"></div>
                                    </div>
                                </div>
                                <div class="row">
                                    <div class="field half-width">
                                        <div id="example2-card-expiry" class="input empty"></div>
                                        <label for="example2-card-expiry" data-tid="elements_examples.form.card_expiry_label">Expiration</label>
                                        <div class="baseline"></div>
                                    </div>
                                    <div class="field half-width">
                                        <div id="example2-card-cvc" class="input empty"></div>
                                        <label for="example2-card-cvc" data-tid="elements_examples.form.card_cvc_label">CVC</label>
                                        <div class="baseline"></div>
                                    </div>
                                </div>
                             
                                <button id="card-button">@WebResources.Donate [email protected]</button>
                                <a href="#" class="btn btn-border mt-10" style="display: none;margin-top: 10px;margin-left: 15px;" id="canceltran"> Cancel</a>
                            </form>
                           
                            <p id="payment-result"><!-- we'll pass the response from the server here --></p>
                        </div>
    
                    </div>
    

    Script

    var stripe = Stripe('@ViewBag.StripePublishKey');
        var elementStyles = {
            base: {
                color: '#32325D',
                fontWeight: 500,
                fontFamily: 'Source Code Pro, Consolas, Menlo, monospace',
                fontSize: '16px',
                fontSmoothing: 'antialiased',
    
                '::placeholder': {
                    color: '#CFD7DF',
                },
                ':-webkit-autofill': {
                    color: '#e39f48',
                },
            },
            invalid: {
                color: '#E25950',
    
                '::placeholder': {
                    color: '#FFCCA5',
                },
            },
        };
    
        var elementClasses = {
            focus: 'focused',
            empty: 'empty',
            invalid: 'invalid',
        };
        var elements = stripe.elements({
            fonts: [
                {
                    cssSrc: 'https://fonts.googleapis.com/css?family=Source+Code+Pro',
                },
            ],
            // Stripe's examples are localized to specific languages, but if
            // you wish to have Elements automatically detect your user's locale,
            // use `locale: 'auto'` instead.
            locale: window.__exampleLocale
        });
        var Id = @Html.Raw(Json.Encode(Model.Id)); // Get Id From Model
        var cardNumber = elements.create('cardNumber', {
                showIcon: true,
                style: elementStyles,
                classes: elementClasses,
            });
            cardNumber.mount('#example2-card-number');
        
            var cardExpiry = elements.create('cardExpiry', {
                style: elementStyles,
                classes: elementClasses,
            });
            cardExpiry.mount('#example2-card-expiry');
        
            var cardCvc = elements.create('cardCvc', {
                style: elementStyles,
                classes: elementClasses,
            });
            cardCvc.mount('#example2-card-cvc');
        var formClass = '.example2';
        var example = document.querySelector(formClass);
        var form = example.querySelector('form');
        var resultContainer = document.getElementById('payment-result');
    
        // Payment Button Handle
    
         form.addEventListener('submit', function (event) {
            $('#AjaxLoader').show();
            event.preventDefault();
            resultContainer.textContent = "";
            stripe.createPaymentMethod({
                type: 'card',
                card: cardNumber,
            }).then(handlePaymentMethodResult);
        });
    
        function handlePaymentMethodResult(result) {
            if (result.error) {
                $('#AjaxLoader').hide();
                $("#canceltran").show(); 
                // An error happened when collecting card details, show it in the payment form
                resultContainer.textContent = result.error.message;
            } else {
                // Otherwise send paymentMethod.id to your server 
                fetch('/cart/pay', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ PaymentMethodId: result.paymentMethod.id, Id: Id}) 
                }).then(function (result) {
                    return result.json();
                }).then(handleServerResponse);
    
            }
        }
    
        function handleServerResponse(responseJson) {
            if (responseJson.error) {
                // An error happened when charging the card, show it in the payment form
                resultContainer.textContent = responseJson.error;
                $('#AjaxLoader').hide();
                $("#canceltran").show();
            } else if (responseJson.requiresAction) {
    
                // Use Stripe.js to handle required card action
                stripe.handleCardAction(
                    responseJson.clientSecret
                ).then(function (result) {
    
                    if (result.error) {
                       
                        $('#AjaxLoader').hide();
                        resultContainer.textContent = result.error.message;
                        $("#canceltran").show();
                        // Show `result.error.message` in payment form
                    } else {
                        // The card action has been handled
                        // The PaymentIntent can be confirmed again on the server
                        fetch('/cart/pay', {
                            method: 'POST',
                            headers: { 'Content-Type': 'application/json' },
                            body: JSON.stringify({ PaymentIntentId: result.paymentIntent.id, Id:Id })
                        }).then(function (confirmResult) {
                            return confirmResult.json();
                        }).then(handleServerResponse);
                        $('#AjaxLoader').hide();
                    }
                });
            }
            else {
                // Show a success message or Required action
                
              }
        }
    

    Controller -In Constructor, you have to use your Stripe Credentials

        public class CartController : ControllerBase
        {
            public CartController()
            {
                StripeConfiguration.ApiKey = YOUR API KEY; // Replace your API KEY here
            }
            string stripePublishKey = YOUR PUBLISHER KEY; // Replace your PUBLISHER KEY here
        
            private class StripeDataReq
            {
                public string PaymentMethodId { get; set; }
                public string PaymentIntentId { get; set; }
                public string Id { get; set; }
            }
        
            public async Task<ActionResult> Pay(StripeDataReq stripeDataReq)
            {
                // From Id you can get the value 
                var cart = await Cart.Table.LookupAsync(stripeDataReq.Id);
                // We set amount (amout*100) because here amount consider in cent (100 cent charge $1) so 
                var amount = cart.Budget * 100;
                var email = ""; // Set Email Id for payment Receiver
        
                var service = new PaymentIntentService();
                PaymentIntent paymentIntent = null;
                try
                {
                    if (stripeDataReq.PaymentMethodId != null)
                    {
                        // Create the PaymentIntent
                        var options = new PaymentIntentCreateOptions
                        {
                            Description = cart.Desc,
                            PaymentMethod = stripeDataReq.PaymentMethodId,
                            //Shipping is not nessasery for every region this is useful for an Indian Standard 
                            //Shipping = new ChargeShippingOptions
                            //{
                            //    Name = giver.Name,
                            //    Address = new AddressOptions
                            //    {
                            //        Line1 = "510 Townsend St",
                            //        PostalCode = "98140",
                            //        City = "San Francisco",
                            //        State = "CA",
                            //        Country = "US",
                            //    },
                            //},
        
                            ReceiptEmail = email,
                            Amount = amount,
                            Currency = "usd",
                            Confirm = true,
                            //ErrorOnRequiresAction = true,
                            ConfirmationMethod = "manual",
                        };
        
                        paymentIntent = service.Create(options);
                    }
                    if (stripeDataReq.PaymentIntentId != null)
                    {
                        var confirmOptions = new PaymentIntentConfirmOptions { };
                        paymentIntent = service.Confirm(
                            stripeDataReq.PaymentIntentId,
                            confirmOptions
                        );
                    }
                }
        
                // StripeException handle all types of failure error and then return the message into FE 
                catch (StripeException e)
                {
        
                    return Json(new { error = e.StripeError.Message });
                }
                TempData["Id"] = stripeDataReq.Id;
                return await generatePaymentResponse(paymentIntent);
            }
        
        
        
            //For 3D secure card 
            private async Task<ActionResult> generatePaymentResponse(PaymentIntent intent)
            {
                var CartId = TempData["Id"];
        
                if (intent.Status.ToString().ToLower() == "succeeded")
                {
                    // Handle post-payment fulfillment
                    return Json(new { success = true });
        
                }
                // requires_action means 3d secure card required more authentications for payment
                else if (intent.Status == "requires_action")
                {
                    // Tell the client to handle the action
                    return Json(new
                    {
                        requiresAction = true,
                        clientSecret = intent.ClientSecret
                    });
                }
                else
                {
        
                    // Any other status would be unexpected, so error
                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Invalid PaymentIntent status");
                }
            }
        
        }
    

    Here is my working code with custom form integration using stripe payment, hope this post will help many developers