Archive

Archive for April, 2015

Stripe Webhook in C# (Asp.net)

Stripe is a payment platform that allows some finer-grained control over payments than paypal does. However, it’s a good bit more complex, but the extra work should pay off..

So, lets see what’s involved with a payment; first you do a bit of JavaScript as follows

<a class=”btn btn-primary btn-lg” role=”button” id=”customButton”>Purchase</a>

<script>
var handler = StripeCheckout.configure({
key: ‘pk_test_uhSAMkhrXb9GP6MqtCzL09hd’,
image: ‘/img/documentation/checkout/marketplace.png’,
token: function (token) {
// Use the token to create the charge with a server-side script.
// You can access the token ID with `token.id`
alert(token.id);
$.get(“/pages/ProcessStripePayment.aspx?token=” + token.id, function (data) {
alert(data);
});
}
});

$(‘#customButton’).on(‘click’, function (e) {
// Open Checkout with further options
handler.open({
name: ‘Demo Site’,
description: ‘2 widgets’,
currency: “gbp”,
amount: 2000
});
e.preventDefault();
});

// Close Checkout on page navigation
$(window).on(‘popstate’, function () {
handler.close();
});
</script>

Note the Ajax call with the token? this means we have to add some server side code to process the charge, once the credit card details have been captured.

You need to then do a NuGet “Install-Package Stripe”, then use this code to convert the token to a charge;

protected void Page_Load(object sender, EventArgs e)
{
string token = Request.QueryString[“token”];
var apiKey = “sk_test_NYqtadezpWaohbRKmY9y2R8a”; // can be found here https://manage.stripe.com/#account/apikeys
var api = new StripeClient(apiKey); // you can learn more about the api here https://stripe.com/docs/api

StripeObject charge = api.CreateChargeWithToken(20.00m, token);

// need to query paid
if (Convert.ToBoolean(charge[“paid”]) == true)
{
Response.Write(“OK”);
}
else
{
Response.Write(“Fail”);
}
}

And that’t the charge made.

I did add another bit of code, purely for diagnostics at this stage, but a webhook that gets called when a charge is made, and this is implemented on the server as follows –

<%@ WebHandler Language=”C#” Class=”StripeMerchant.StripeHook” %>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Text;

using System.Web.Script.Serialization;

namespace StripeMerchant {

[Serializable]
public class StripeHookResponse {
public long Created { get; set; }
public string Type { get; set; }
public bool LiveMode { get; set; }
public string Id { get; set; }
public StripeDataObj Data { get; set; }
}

[Serializable]
public class StripeDataObj {
public StripeData Object { get; set; }
}

[Serializable]
public class StripeData {
public double Amount { get; set; }
public StripeCard Card { get; set; }
}

[Serializable]
public class StripeCard {
public string Country { get; set; }
public int Exp_Month { get; set; }
public int Exp_Year { get; set; }
public string Id { get; set; }
public int Last4 { get; set; }
public string Object { get; set; }
public string Type { get; set; }
}

/// <summary>
/// Summary description for StripeHook
/// </summary>
public class StripeHook : IHttpHandler {

public void ProcessRequest(HttpContext context) {

string sPathName = context.Server.MapPath(“log.txt”);
StreamWriter sw = new StreamWriter(sPathName,true);
sw.WriteLine(“—————————————————“);
sw.WriteLine(DateTime.Now);
sw.WriteLine(“—————————————————“);

try {
JavaScriptSerializer js = new JavaScriptSerializer();

StringBuilder sb = new StringBuilder();
int streamLength;
int streamRead;
Stream s = context.Request.InputStream;
streamLength = Convert.ToInt32(s.Length);
sw.WriteLine(“Length:” + streamLength);
Byte[] streamArray = new Byte[streamLength];

streamRead = s.Read(streamArray, 0, streamLength);

for (int i = 0; i < streamLength; i++) {
sb.Append(Convert.ToChar(streamArray[i]));
}

string raw = sb.ToString();
sw.WriteLine(raw);

StripeHookResponse stripeResponse = (StripeHookResponse)js.Deserialize(raw, typeof(StripeHookResponse));

//handle the data received from Stripe

context.Response.ContentType = “text/plain”;
context.Response.StatusCode = 200;

} catch (Exception e) {
//handle error and tell Stripe that a fault occurred
context.Response.ContentType = “text/plain”;
context.Response.StatusCode = 301; //Let Stripe know that this failed
}
sw.Flush();
sw.Close();

}

public bool IsReusable {
get {
return false;
}
}
}
}

Categories: Uncategorized

Scripted setup of website in IIS

Here’s how to use AppCmd to create a website in IIS with a dedicated apppool

cd %systemroot%\system32\inetsrv\

appcmd add apppool /name:”<SITENAME>” /managedRuntimeVersion:”v4.0″ /managedPipelineMode:”Integrated”

appcmd add site /name:”<SITENAME>” /bindings:http://<SITENAME&gt;:80 /physicalPath:”C:\inetpub\wwwroot\<SITENAME>”

APPCMD set app “<SITENAME>/” /applicationPool:”<SITENAME>”

Categories: Uncategorized

Extending WebClient in Visual Basic .NET

The WebCient class encapsulates away most of the stuff that you would normally do with a HttpWebRequest and HttpWebResponse, but sometimes this ‘simplification’ does tend to hide functionality that would be useful. Luckily you can create a derived class, and access this functionality again, to expose it to your app.

The two key functions that WebClient misses is cookie awareness, i.e. cookes set by the server in one request are persisted to the next request. This is done by overriding the GetWebRequest method and setting a CookieContainer.

The next function was that if a Http request encounters a 301 or 302 redirect, then you don’t know where the server has sent you to. I fixed this by overriding GetWebResponse and setting currentPage as the ResponseUri

And… it’s all in VB.NET

Imports System.Web
Imports System.Net

Public Class CookieAwareWebClient
Inherits WebClient

Private cc As New CookieContainer()
Private lastPage As String
Public currentPage As Uri
Protected Overrides Function GetWebRequest(ByVal address As System.Uri) As System.Net.WebRequest
Dim R = MyBase.GetWebRequest(address)
If TypeOf R Is HttpWebRequest Then
With DirectCast(R, HttpWebRequest)
.CookieContainer = cc
If Not lastPage Is Nothing Then
.Referer = lastPage
End If
End With
End If
lastPage = address.ToString()
Return R
End Function

Protected Overrides Function GetWebResponse(request As WebRequest) As WebResponse
Dim R = MyBase.GetWebResponse(request)
If TypeOf R Is HttpWebResponse Then
With DirectCast(R, HttpWebResponse)
currentPage = .ResponseUri
End With
End If
Return R
End Function

End Class

Categories: Uncategorized