Processing Payments and with Stripe, JavaScript and C# - PCI compliant

The source code and post have been updated to use the latest Stripe.NET API => v4.2

Online payments! We've all used them and some of us may have had the "fortune" implementing them on one website or another. Stripe is the not-so-new kid on the block, since it recently expanded in many countries, that makes this development task a breeze.

If you are using .NET, then Stripe.NET is an excellent library that hides away most of the complexity and provides a very nice API. You can get it as a NuGet package or you can check the source code on GitHub. Although Stripe.NET is excllent, it comes with a big caveat: if you process the payment details on your server, then you need to be PCI compliant and you are bound to some really strict regulations. Yes, this applies even when you don't store Credit/Debit card information on your servers. The simple transmission of the data makes you liable to PCI legislation.

If you are PCI-compliant and still want to use the Stripe.NET exclusively to process payments, please check my post here.

But fret not my friend, as there is a fairly simple solution : Stripe.js. This is the library provided by the lovely folks over at Stripe that allows you to process payment information and charge credit cards to your heart's content and still be PCI-compliant. By using the Stripe.js library, you can send the payment details (card number, cvc and expiry date) to Stripe directly from the javascript client and in return you get a token which you can use later to make a one off charge. The good news is that the payment details never make it to your server so you don't have to worry about the legal implications.

So, let's create an example to see all this in action.

1. The ASP.NET MVC View

We will create a basic MVC View which will be used to retrieve and process the payment details from the user.

The View, we will name it Charge.cshtml for now, is a boiler plate input form. The interesting part is that the view is logically split into two sections with some input elements inside the form and some elements outside the form. The reason for this is that the input elements outside the form will not be posted back to the server when we submit the form, hence making the process PCI-compliant.

The View has a strongly typed model StripeChargeModel, to pass the data to and from the controller. It is highly recommended that you add validation using your preferred way to ensure that the data entered has the right format and it's valid - e.g. ExpiryDate set in the past or not a valid date etc.

Now, at the bottom of the page, add the JavaScript code to get the Stripe token and submit the form. I am using a view with a layout so my Javascript is inside a section. In addition to the imported .js libraries on this page, the layout page also includes a reference to jQuery, so make sure you add it to your page as well if not already available.

Let's break down the code, shall we?

First we add a reference to the the Stripe.js file and then inside the document.ready() we set our Publisheable key. You can get your public key from the Stripe dashboard. Then we create an event handler for the button click and a callback method stripeResponseHandler(). The 'click' event handler is responsible for retrieve the Credit/Debit card details and posting them directly to Stripe in order to get a Token. Notice that we use the minimum information necessary in order to retrieve the Token. Once that call is successful, Stripe sends a response which we process in the stripeResponseHandler() callback method. If the response has an error, e.g. due to invalid credit card number etc, then we alert the user with the error message. If the response is successful, we save the Token value to a hidden field and then submit the form to the server with the rest of the details in order to charge the user's card.

NOTE: the current code contains no validation. You should definitely implement validation to ensure that users enter valid data and provide a great user experience by giving feedback accordingly.

2. The DataModel

The DataModel is used to pass data between the view and the controller. The model attached below is a very crude one and doesn't contain any validation other than setting the Amount and the Token properties to mandatory. I would argue that the CardHolderName should also be made mandatory/required as it will show up on the Stripe Dashboard when running reports etc.

3. The controller

The controller contains two methods, the first is the GET and the second is the POST. The first one doesn't do anything other than serve the View with the corresponding model. The second, on the other hand, validates the model and makes the Credit/Debit card charge.

Pay close attention to the ProcessPayment() helper method that performs the actual charge with Stripe. We create a StripeChargeCreateOptions object with the amount and currency and StripeSourceOptions which contains the token. Then we create an instance of a StripeChargeService where we pass our private stripe key. The service is used to make the charge by calling the chargeService.Create(myCharge); method. This method returns a StripeCharge object which you can again persist or discard as you please.

This implementation ensures that any payment processed through your site is PCI-compliant. Stripe's simple and awesome!

You can check the full working source code on this GitHub repo.

I hope this post made your life a little bit easier.


  • Share this post on
comments powered by Disqus