What is the best way to handle a JavaScript POST request in an ASP.NET WebForm?

Although it may seem like a basic question, I am a bit rusty when it comes to webforms. This is my first time using Stripe.js and I would like to utilize it alongside stripe.net for client-side processing. Below is the client code:

<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true"
CodeBehind="StripePage.aspx.cs" Inherits="StripePage.StripePage" %>

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
<script type="text/javascript">
    // This identifies your website in the createToken call below
    // You need to put your real publish key here.
    Stripe.setPublishableKey('pk_test_1nDJ3hA1Mv2Sy9bUoYcBMXmm');
    // ...
    // I am using jquery to process the payment. It knows what form to 
    // process it on based on the name 'payment-form'
    jQuery(function ($) {
        //payment submission
        $('#payment-form').submit(function (event) {
            var $form = $(this);

            // Disable the submit button to prevent repeated clicks
            $form.find('button').prop('disabled', true);

            Stripe.createToken($form, stripeResponseHandler);

            // Prevent the form from submitting with the default action
            return false;
        });

        //if there is a error, it is displayed on the page if there was
        //no error this is where it gets sent to the server.
        var stripeResponseHandler = function (status, response) {
            var $form = $('#payment-form');

            if (response.error) {
                // Show the errors on the form
                $form.find('.payment-errors').text(response.error.message);
                $form.find('button').prop('disabled', false);
            } else {
                // token contains id, last4, and card type
                var token = response.id;
                // Insert the token into the form so it gets submitted to the server
                $form.append($('<input type="hidden" name="stripeToken" />').val(token));
                // and submit
                $form.get(0).submit();
            }
        };
    });
</script>

<form method="POST" id="paymentForm" runat="server">
    <span class="payment-errors" runat="server"></span>

    <div class="form-row">
        <label>
            <span>Card Number</span>
            <br />
            <input id="number" type="text" data-stripe="number" clientidmode="Static" />
            <input type="text" size="20" data-stripe="number" runat="server" />
        </label>
    </div>

    <div class="form-row">
        <label>
            <span>CVC</span>
            <br />
            <input type="text" size="4" data-stripe="cvc" runat="server" />
        </label>
    </div>

    <div class="form-row">
        <label>
            <span>Expiration (MM/YYYY)</span>
            <br />
            <input type="text" size="2" data-stripe="exp-month" runat="server" />
        </label>
        <br />
        <input type="text" size="4" data-stripe="exp-year" runat="server" />
    </div>
    <asp:Button ID="submit" ClientIDMode="Static" runat="server" Text="SubmitPayment" OnClick="submit_Click" />
</form>
</asp:Content>

The final JS call creates a JSON object that I need to access on the C# page when the button is clicked:

protected void submit_Click(object sender, EventArgs e)
{
....
}

I'm opting for the Javascript implementation to avoid dealing with PCI compliance. Is this approach correct? Should I solely rely on Stripe.net for all processes and skip using JS altogether? If the current approach is valid, how can I retrieve the form post data in the button click event?

Answer №1

Thank you to everyone who provided helpful tips in the comments. Despite countless hours of searching online and frustration, I decided to take a break and return with a new solution.

  1. I changed the button to a standard HTML input instead of using asp:Button
  2. I retrieved the information sent back through JavaScript in the Page_Load event

Code Behind:

protected void Page_Load(object sender, EventArgs e)
{
    if (IsPostBack)
    {
        StripeConfiguration.SetApiKey("[API Secret Key");
        NameValueCollection nvc = Request.Form;
        string amount = nvc["amount"];
        var centsArray = amount.Split('.');
        int dollarsInCents = Convert.ToInt32(centsArray[0]) * 100;
        int remainingCents = Convert.ToInt32(centsArray[1]);
        string tokenId = nvc["stripeToken"];

        var tokenService = new StripeTokenService();
        StripeToken stripeToken = tokenService.Get(tokenId);


        var myCharge = new StripeChargeCreateOptions
        {
            TokenId = tokenId, 
            AmountInCents = dollarsInCents + remainingCents,
            Currency = "usd"
        };
        var chargeService = new StripeChargeService();
        StripeCharge stripeCharge = chargeService.Create(myCharge);
    }
}

By utilizing the NameValueCollection from the System.Collections.Specialized namespace, I was able to easily extract the necessary data from Request.Form by referencing it with variable names. This allowed me to efficiently retrieve the needed information and then utilize the documentation from the Stripe .NET library to process the payment.

Answer №2

Unfortunately, I am unable to directly comment on the answer at this time. However, I feel compelled to share my thoughts regarding the OP's discoveries.

In my current project, I am utilizing Stripe.js in a similar manner. I have managed to retrieve the stripeToken through Request.Form and access other non-card-related fields using standard code-behind methods (such as extracting an integer value from PaymentTotal.Value). What stands out to me is not the process of retrieving data, but rather the necessity of handling it during Page_Load or another point in the page life cycle due to the fact that the onclick event of the Submit button is bypassed when the form is submitted via JavaScript instead of the button itself.

To address the initial query more directly, it seems impossible to obtain the data within the button click event without triggering said event manually on postback (at least, this is my interpretation).

I hope this insight aids others who may encounter similar challenges when integrating Stripe with .NET technology.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Firefoxx unable to communicate with server through ajax requests

My dilemma involves transmitting data to my server using the json data type with ajax. Oddly enough, in Firefox the server fails to receive any data at all, while in Chrome and IE the data is successfully transmitted and displayed on the server console. H ...

Maximizing CPU power with Parallel.For loops

Currently, I am developing a WPF application that is responsible for processing an image data stream from an infrared camera. To facilitate the various processing steps such as rescaling and colorizing, I have created a custom class library. An example of ...

Attempting to iterate through and retrieve the names listed in the table

I have a code that I need help with in extracting names from td elements using jQuery. In certain instances, if the td is empty, I want to merge the left-side td with the 5 right-side tds because the first td on the right side is empty and the second td c ...

Update the contents of a neighbor div within the same parent element using jQuery

Attempting to set the range slider value within the slider parent sibling var updateRangeSlider = function() { var slider = $('.range-slider'), range = $('.range- value = $('.range-slider__value'); sli ...

What could be causing the issue of Vuejs 3.3 defineModel consistently returning undefined?

I am currently working with Nuxt version 3.5.1 and Vuejs version 3.3, however, I am encountering an issue where the defineModel macro always returns undefined. I am unsure why this is happening? <template> <input v-model="count"& ...

Step-by-step guide on how to load an Ext JS tab after clicking on it

I have an Ext JS code block that creates 4 tabs with Javascript: var tabs; $(document).ready( function() { fullscreen: true, renderTo: 'tabs1', width:900, activeTab: 0, frame:true, ...

What is the best way to retrieve a list of unchecked checkboxes in a Razor Page model?

Currently, I am working on a razor page using .NET Core 7. I have encountered an issue where I am unable to pass values of 1, 2, and 3 for unchecked checkboxes from the HTML page to the page model in the post method. When the user clicks the submit button ...

Image encoded in base64 not appearing on the screen

Hey there, I'm currently working on implementing a jQuery image uploader that generates a base64 code when an image is selected. function readImage(input) { if (input.files && input.files[0]) { var FR= new FileReader(); FR.onload ...

Perform an Ajax request to a C# Controller Function

In my javascript file named "data handling.js" within a folder labeled "JS", you'll find the following piece of code: document.getElementById('submit-new-project').addEventListener("click", function () { var ProjectName = document.getEl ...

What are some ways to monitor the movement of elements and activate functions at precise locations?

I am working on a project that involves a #ball element which, when clicked, utilizes jQuery animate to move downwards by 210px. The code I currently have is as follows: $('#ball').click(function() { $(this).animate({ top: '+=2 ...

What is the optimal method for organizing MongoClient and express: Should the Client be within the routes or should the routes be within the client?

Which is the optimal way to utilize MongoClient in Express: placing the client inside routes or embedding routes within the client? There are tutorials showcasing both methods, leaving me uncertain about which one to adopt. app.get('/',(req,res) ...

multer - the file uploaded by the request is not defined

I've been working on an app with Node, Express, and multer for image uploads. However, after submitting the form, req.file is coming up as undefined. I've spent hours trying to troubleshoot this issue but haven't been able to pinpoint the pr ...

Is it possible to retrieve the text usually posted in the "Messages" section by using SqlCommand to execute a non-query?

Is there a way to retrieve the message text that would typically appear on the "Messages" tab in Management Studio when using SqlCommand to execute a non-query, such as a database restore, programmatically? If so, how can this be achieved? ...

Combining strings and variables in Vue.js with the use of bootstrap-vue syntax

Hey, I'm facing a little syntax hiccup with '="collapse-{{ product.id }}"' in both the b-button and b-collapse. Any ideas on how to properly structure this? Just looking to set up a unique ID that connects the button to the collaps ...

What could be causing my dangerouslySetInnerHTML to show altered content?

I am working on a project using React and have encountered an issue with the code: const externalMarkup = ` <a data-refpt='DN_0OKF_177480_ID0EMPAC' /> <ol> <li value='1'> <p> <strong&g ...

Linking query branches without encountering the "Exceeded the number of hooks rendered during the previous render" error

This apollo client utilizes a rest link to interact with 2 APIs. The first API returns the value and ID of a record, while the second API provides additional information about the same record. I combine this information to render the content without using ...

Generate several different elements

Is it possible to use Vue.js to render a component multiple times based on a variable? For instance, I have a size variable set to 5 and I want to display the Widget component 5 times. Here is my current code snippet: Template : <template> &l ...

Is it possible to trigger a bootstrap modal-dialog without specifying an ID or class using JQuery or JavaScript?

Is there a way to work with Bootstrap modal-dialog without setting an id or class, perhaps using JQuery or JavaScript instead? <html> <head> <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstr ...

Received the error message "Material-UI: capitalize(string) expects a string argument" while implementing the snackbar feature in a React Material-UI project

While working with Material-UI, I came across an issue with the snackbar where I received an error message saying: Error: Material-UI: capitalize(string) expects a string argument. Here's a snippet of my code: this.state = { snackBarOpenVer ...

Pressing a shortcut key will direct the focus to the select tag with the help of Angular

I was trying to set up a key shortcut (shift + c) that would focus on the select tag in my form when pressed, similar to how tab works. Here is the HTML code for my form's select tag: <select id="myOptions"> <option selected> Opti ...