The Money Shot
Rather than drag you through pre-amble, here's all you need to do to charge your customers:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using AuthorizeNET; namespace SampleAuthorization { class Program { static void Main(string[] args) { //step 1 - create the request var request = new AuthorizationRequest("4111111111111111", "1216", 10.00M, "Test Transaction"); //step 2 - create the gateway, sending in your credentials var gate = new Gateway("YOUR_API_LOGIN_ID", "YOUR_TRANSACTION_KEY"); //step 3 - make some money var response = gate.Send(request); Console.WriteLine("{0}: {1}",response.ResponseCode, response.Message); Console.Read(); } } }
This is a console application - and it's showing you how Authorize.Net's Advanced Integration Method (or AIM) works. I managed to get the meat of the transaction complete in 3 lines of code - pretty slick if you ask me!
Design Principle One: Testability
Payment system SDKs and sample code usually don't take testing into account and Authorize.Net has changed that. No one likes how invasive gateway code can be - the good news is that this has been changed.
There are 3 core interfaces that you work against - only one that you need to know about (the gateway itself). The first is IGateway:
using System; using System.Collections.Specialized; namespace AuthorizeNET { public interface IGateway { string ApiLogin { get; set; } string TransactionKey { get; set; } IResponse Send (IGatewayRequest request); IResponse Send(IGatewayRequest request, string description); } }
This interface logs you into Authorize.Net and sends off an IGatewayRequest, returning an IResponse. There are 4 IGatewayRequests:
The essential flow is:
Design Principle Two: Smaller Method Calls
It's easy to get into a situation where you have a neat idea and you crack out a simple API - but as you start adding changes and permutations to it, the API turns into overload oatmeal (see HtmlHelpers for ASP.NET MVC). The good news is that with the new SDK - you can get around this with fluent interfaces - when you create a Request object you only pass in the core of what's needed. In the first code example (which is the largest signature) you pass in the card number, expiration, card code, and an optional description.
The Authorize.Net API can handle a lot more than that, however. If you have fraud protection or address verification you also have to pass in additional information about the user (name, address, etc). That doesn't belong in an overload - that belongs in a fluent interface that you can tack on as needed:
var req = new AuthorizationRequest("4111111111111111", "0115", 10.00M, "Sample", false) .AddCustomer("123", "Mick", "Jones", "The Casbah", "WA", "201010");
Design Principle Three: Love the Dev With Helpers
Payment systems are moving more and more into "helping" the developer deal with the core of the transaction as well as make life simple for them when it comes to markup and other things. This is one great thing about the Helpers that come with Authorize.Net's SDK (currently they only work for ASP.NET MVC as extensions to HtmlHelper).
Html Credit Card Inputs
Tired of writing up the same checkout stuff? Me too. Here are some helpers for you that are specifically designed to work with some love on the backend:
Here's what they look like (from the sample app that ships with the SDK - which is an ASP.NET MVC 1.0 app)
Form Readers
There's also a set of helpers for the controller so you can receive and load a request based on a form post. Here's a sample post receiver that sends the request off to Authorize.Net:
[AcceptVerbs(HttpVerbs.Post)] [ValidateAntiForgeryToken] public ActionResult Create() { //send an order id to the merchant var orderId = new Guid(Request.Form["order_id"]); //pull from the store var order = MyDatabase.Find(orderId) //this is an IGateway and should be injected via IoC var gate = new Gateway(login, transactionKey, true); //build the request from the Form post var apiRequest = CheckoutFormReaders.BuildAuthAndCaptureFromPost(); //send to Auth.NET var response = gate.Send (apiRequest); if (response.Approved) { //validate the amounts match and so on //... order.AuthCode = response.AuthorizationCode; order.TransactionID = response.TransactionID; order.OrderMessage = string.Format("Thank you! Order approved: {0}", response.AuthorizationCode); //record the order, send to the receipt page return Redirect(Url.Action("details", "orders", new { id = orderId.ToString() })); } else { //error... oops. Handle it //... return Redirect(Url.Action("error", "orders", new { id = orderId.ToString() })); } }
One thing with the above is the "naked" reading of variables from a form POST. Usually not a good idea due to spoofing and POST overloading. In this case, however, the read is going against the API - and no other values can be passed in as the reader is checking against another handy helper: ApiFields
ApiFields: An On-The-Fly Reference API
The core of the Authorize.Net API is a Key/Value POST with a set of well-defined keys for the API. When I've worked with Authorize.Net in the past, I used to have the PDF open on one monitor with all the key definitions, and my code on the other. This handy helper allows you to work with readable properties on an object - you can use them in naming your inputs and other things.
All of the fields, and the documentation, are popped into a reference class:
If you don't like using Helpers, or if you're using ASP.NET WebForms, you can use ApiFields to set the name of your inputs. The FormReaders above look for these names (I tried to keep it all consistent and non-surprising). So you can do something like this:
input type = 'text' name = '<%=ApiFields.Amount%>'
ASP.NET MVC Reference Application
You can see all of this lovely stuff in action in the sample application included with the SDK download (CoffeeShop). It's ASP.NET MVC 1.0 so it works on Mono - the entire SDK works with Mono!
Hope you enjoy.
----
robconery is a guest contributor for Authorize.Net