Home > Uncategorized > Accepting Direct Debit #payments as an alternative to #Card payments online using .NET

Accepting Direct Debit #payments as an alternative to #Card payments online using .NET

direct-debit-website-992x561

Direct debit is an alternative way to recieve payments, and is the norm for long term subscriptions or utility payments.

GoCardless is a provider of Direct debits and it can accept payments from the following countries;

  • United Kingdom – Bacs Direct Debit
  • Eurozone – SEPA Direct Debit
  • Sweden – Bg Autogiro
  • Denmark – Betalingsservice
  • Australia – BECS Direct Debit
  • New Zealand – BECS Direct Debit
  • Canada – Pre-Authorized Debit

Also, with the incomming new SCA applying to EU credit cards from september 14th 2019, this can protect recurring income, since ‘paperless’ direct debit is outside the scope of SCA.

Without further ado, here is a simple demo on how to get this running in Sandbox mode;

tl;dr; here’s the github repo https://github.com/infiniteloopltd/GoCardlessDemo

Create a new .NET console app in VS 2017, then add the GoCardless NUNIT package using

Install-Package GoCardless

Create the client as follows;

var client = GoCardlessClient.Create(
ConfigurationManager.AppSettings[“GoCardlessAccessToken”],
GoCardlessClient.Environment.SANDBOX
);

Defining your access token in the app.config

<appSettings>
<add key=”GoCardlessAccessToken” value=”sandbox_AnONLOlT7Xe4qH_kRNGKBHnp_NWytUpRXAQY4-7j”/>
</appSettings>

Now, you’ll need to generate a URL via the GoCardless API, in order to capture your customer’s details;

var SessionToken = Guid.NewGuid().ToString();

var redirectFlowResponse = client.RedirectFlows.CreateAsync(new RedirectFlowCreateRequest()
{
Description = “Cider Barrels”,
SessionToken = SessionToken,
SuccessRedirectUrl = “https://developer.gocardless.com/example-redirect-uri/&#8221;,
// Optionally, prefill customer details on the payment page
PrefilledCustomer = new RedirectFlowCreateRequest.RedirectFlowPrefilledCustomer()
{
GivenName = “Tim”,
FamilyName = “Rogers”,
Email = “tim@gocardless.com”,
AddressLine1 = “338-346 Goswell Road”,
City = “London”,
PostalCode = “EC1V 7LQ”
}
}).Result;

var redirectFlow = redirectFlowResponse.RedirectFlow;

OpenUrl(redirectFlow.RedirectUrl);

If this were a website, then you’d Redirect to the RedirectUrl, but here I’m opening Chrome to display the website as follows;

private static void OpenUrl(string url)
{
var proc = new Process
{
StartInfo =
{
FileName = @”C:\Program Files (x86)\Google\Chrome\Application\chrome.exe”,
Arguments = url
}
};
proc.Start();
}

Which shows a page such as the following;

page1

Once confirmed. you are directed to a page such as the following;

https://developer.gocardless.com/example-redirect-uri/?redirect_flow_id=RE0001V1ESQMPFBAMMP9NS869BPJJKKC

Note the redirect_flow_id, this is important, since you need to complete the signup process with some code as follows;

Console.WriteLine(“Type the redirect_flow_id”);
var redirect_flow_id = Console.ReadLine();

var redirectFlowResponse2 = client.RedirectFlows
.CompleteAsync(redirect_flow_id,
new RedirectFlowCompleteRequest
{
SessionToken = SessionToken
}
).Result;

Console.WriteLine($”Mandate: {redirectFlowResponse2.RedirectFlow.Links.Mandate}”);
Console.WriteLine($”Customer: {redirectFlowResponse2.RedirectFlow.Links.Customer}”);

OpenUrl(redirectFlowResponse2.RedirectFlow.ConfirmationUrl);

var mandate = redirectFlowResponse2.RedirectFlow.Links.Mandate;

The ConfirmationUrl looks something like the following;

page2

Now, you have the direct debit mandate, but in order to get money, you need to collect payments against it.  – This example collects 10 GBP against the newly created direct debit mandate.

var createResponse = client.Payments.CreateAsync(new PaymentCreateRequest()
{
Amount = 1000,
Currency = PaymentCreateRequest.PaymentCurrency.GBP,
Links = new PaymentCreateRequest.PaymentLinks()
{
Mandate = mandate,
},
Metadata = new Dictionary<string, string>()
{
{“invoice_number”, “001”}
},
IdempotencyKey = SessionToken
}).Result;

Payment payment = createResponse.Payment;

Console.WriteLine(payment.Id);

Now, the one thing about direct debit payments, is that there is a big delay between submitting the direct debit, and getting your money. It’s not like credit cards, where the payment is confirmed as soon as you get confirmation.

So, in order to handle out-of-band events from GoCardless, you need to handle webhooks, which I’ve created as follows (default.aspx)

protected void Page_Load(object sender, EventArgs e)
{
// start ngrok like follows
// ngrok http –host-header=rewrite localhost:12193
var requestBody = Request.InputStream;
var requestJson = new StreamReader(requestBody).ReadToEnd();
var secret = ConfigurationManager.AppSettings[“GoCardlessWebhookSecret”];
var signature = Request.Headers[“Webhook-Signature”] ?? “”;

foreach (Event evt in WebhookParser.Parse(requestJson, secret, signature))
{
switch (evt.Action)
{
case “created”:
System.Diagnostics.Debug.WriteLine(“Mandate ” + evt.Links.Mandate + ” has been created, yay!”);
break;
case “cancelled”:
System.Diagnostics.Debug.WriteLine(“Mandate ” + evt.Links.Mandate + ” has been cancelled”);
break;
}
}
}

I’ve run it in Visual Studio embedded webserver, it obviously crashes, since there is no post data. But I then use ngrok to proxy the local webserver to the internet;

using the command

ngrok http –host-header=rewrite localhost:12193

Where 12193 is the port that the VS webserver chose.

When ngrok generates a custom domain, I add this into the webhook settings on GoCardless.

Here, for example, is the event when a mandate is cancelled;

{
“events”: [
{
“id”: “EVTESTFWPNEMJP”,
“created_at”: “2019-07-30T16:12:05.407Z”,
“resource_type”: “mandates”,
“action”: “cancelled”,
“links”: {
“mandate”: “index_ID_123”
},
“details”: {
“origin”: “bank”,
“cause”: “bank_account_closed”,
“scheme”: “ach”,
“reason_code”: “R14”,
“description”: “This bank account has been closed as the customer is deceased.”
},
“metadata”: {

}
}
]
}

and here is one when a payment has been confirmed.

{
“events”: [
{
“id”: “EVTESTECKZWPZW”,
“created_at”: “2019-07-30T16:15:03.995Z”,
“resource_type”: “payments”,
“action”: “confirmed”,
“links”: {
“payment”: “index_ID_123”
},
“details”: {
“origin”: “gocardless”,
“cause”: “payment_confirmed”,
“description”: “Enough time has passed since the payment was submitted for the banks to return an error, so this payment is now confirmed.”
},
“metadata”: {

}
}
]
}

 

Advertisements
Categories: Uncategorized
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: