White Papers                  Home |  White Papers  |  Message Board |  Free Tools |  Products |  Purchase | News |  Web Log |
 
 

Integrating Electronic Payment Processing into
ASP.NET Web Applications


By Rick Strahl
www.west-wind.com
rstrahl@west-wind.com

 

Last Update:

March 26, 2008


 

What's covered:

Related Resources:

 

 

If you find this article useful, consider making a small donation to show your support  for this Web site and its content.

 

 

Electronic Payment processing continues to be a common theme for many Web based applications and while the process is getting easier with the market maturing, there's still a maze of choices and options in setting up your payment solutions and get them integrated into existing applications. In this article, I'll give a high level overview of the electronic payment processing by looking at the various players involved in the payment processing operation and some suggestions and options you have on getting hooked up with the right provider. I'll talk about how the process works, what it takes to get started and what it's going to cost. Finally I'll take you through an application that integrates payment processing and show a class you can use to integrate a few of the common Gateway services into existing applications.

 

The process of taking electronic payments from customers and getting the money deposited into your own accounts is a winding one, with several levels of providers being part of the transaction process. Figure 1 shows an overview of the process and the entities involved.

Figure 1: The 10,000 foot view of Credit Card Processing using one of the big Gateway providers.

 

Your Web Application

The process starts with your Web application. I'll be approaching this topic from the perspective of

a small business that integrates payment processing into an existing Shopping Cart solution, so the Web application is responsible for collecting the customer's contact and credit card information. In order to process a Credit Card you'll need to capture some basic information which includes:

 

  • Name
  • Address
  • Email Address
  • Phone Number
  • Order Amount
  • Credit Card Number
  • Expiration Date
  • Card Verification Code (optional)

 

Gateway Processor

Once you have collected this information, you'll need to send the information collected to a Gateway provider that can process the credit card on your behalf. Gateway providers provide, as the name suggests, the Internet Gateway API that your application can communicate with. The APIs are generally HTTP or TCP/IP based and provide a relatively simple interface that your application can communicate with.

 

A few common Gateway providers are Authorize.NET, Verisign (PayFlow Pro), LinkPoint. There are many other Gateway service providers but they all perform the same basic functionality for providing a standard interface for your application to process a credit card. The Gateway provider essentially provides an API that your application can talk to. The nature of the API can vary with some providers using pure HTTP POST based interfaces and others using their own proprietary TCP/IP interfaces that you can interfaces with through some published SDK. We'll talk more about how some of the provider interfaces work later in the article.

 

In theory Gateway providers are optional. You could in theory talk directly to the underlying processing networks, but in order to gain access to these networks you need to be certified and you need to be able to communicate with the various different processing networks that handle the actual payment processing. So unless you are a bank or large vendor that deals with a high volume of transaction this is not going to be an option. For most of us a Gateway provider is not optional.

 

Front End Network

The various gateway providers communicate with the front end Credit Card Processing networks that handle the actual payment processing by passing inbound transactions to the issuing bank. You can think of the front end network sort of as the gateway for the gateway providers. There a number of different providers that service this front end processing network with names such as PaymentTec, FirstData, Nova, Global Payment. The Gateway Providers interface with each of these networks that are supported. The front end network in turn interfaces with each of the issuing banks.

 

The issuing banks then are ultimately responsible for authorizing the credit card transaction by comparing the inbound data and reserving funds (doing an 'AUTH' only at this time). The bank actually doesn't do a whole lot of checking of the data – it merely checks to see if there are funds available and passes back an authorization code as well as the customer information available to the bank back to the front end network.

 

Back to the Gateway and the Web Application

The front end passes the result back to the Gateway processor which can now examine the data returned for the bank. If the result was not approved and there are not enough funds the transaction is declined immediately. If funds were approved additional checks are performed for fraud detection. The gateway performs things like AVS (Address Verification Services) validation against the contact information provided and checks the CVS code (the 3 or 4 digit code on the back or front of the card) if provided, which if it doesn't match  can cause the transaction to be Declined. Note that both AVS and CVS verification is user definable at the gateway level, typically by the store owner, so how AVS and CVS are handled may vary based on your options.

 

If AVS and CVS validation succeeded the order is approved and the Gateway sends back an confirmation message to the client application. Most Gateways support 3 different main response codes which are APPROVED, DECLINED, ERROR (or FAILED) along with additional information. For example Authorize.NET returns a comma delimited string that includes the authorization code, the input data of address and order amounts. The exact information returned from the providers varies per Gateway.

 

The key pieces of information that all providers return are:

 

  • Response Code
  • Message (a semi descriptive message of failure)
  • Authorization Code (if successful)
  • Transaction ID (Gateway Transaction Id you can map to your orders)

 

Most gateways also echo back the information that you sent to the gateway to ensure that if data was sent from one application to another that you can verify the transaction amounts.

 

Settling transactions

At this point the transaction has either been approved or declined. If approved the transaction is only Authorized with the issuing bank, which means that funds are put on hold only for the moment. Funds are not actually transferred and taken out of the user's account until the transaction batch is settled.

 

Gateways collect approved transactions into batches which are processed at regular intervals that you can specify as part of the Gateway interface. When batches are settles the Gateway communicates with the back end networks to cause the funds to be put on hold, but removed from the customer's account. At this point the money is being moved into the merchant bank account and held in escrow for a period of time – IOW, it's not immediately transferred into your checking account.

 

Merchant Bank – the 'Escrow' Account

The Merchant bank acts as the intermediary between your bank account the processing networks that retrieve the funds. The funds retrieved are held – typically for 2 days and then deposited into your bank account. The merchant bank also substracts the merchant percentage from each transaction, assigning the per transaction charges for the credit card processing.

 

The merchant provider also acts as an intermediary between you and the issuing banks should there be a dispute for payments. So if there's a fraudulent transaction or a charge back you'll hear from the Merchant bank that provides you with the details and to whom you have to send any documentation. A good merchant bank can also deflect frivolous charge back claims before they ever reach you.

 

 

AMEX, Discover, Diners, JCB – special cases

These card providers actually act as both the Issuing bank as well as the merchant provider – they essentially bypass the Merchant Service Provider when it comes for handling the authorized funds. Rather than holding funds with the Merchant Service Provider, AMEX etc. deposit directly into your merchant account after holding funds for a short period. In essence these companies are the merchant provider for the transactions. Note though that transactions still run through your merchant bank which will charge you per transaction fees for the AMEX etc. transactions as well as the Visa and MasterCard transactions.

 

Lest you think that this is less complicated, realize that all of the independent providers tend to charge considerably higher merchant percentages. Also, even though the merchant service provider isn't used for escrow, billing or dispute resolution cases, these providers still need to use the processing networks and gain access to them through the Merchant Service provider. So AMEX, Discover, Diner etc. all have their per transaction charges billed through the Merchant statement. Even if you were only to take AMEX you still need a merchant provider.

 

Your Bank Account

Finally at the end of this long journey the money from your customer – minus the merchant percentage will end up in your bank account.

 

Paying the man

As you might expect, most of the players in Figure 1 want to get paid in some way, so fees are involved at various levels. If you're starting out from scratch your first mission is to find a merchant provider.

 

Merchant Service Provider

The key to getting started usually is a merchant account which you can get from a variety of sources. The merchant account is where most of the recurring fees occur and this is where you want to make sure you're getting a good deal. Typical small business merchant rates range from 2.0-2.5% for Visa/MasterCard and 3.5-4% for AMEX, Discover etc. In addition you'll typically pay some sort of monthly statement fee, plus a per transaction charge (from 0.15 - 0.40 per transaction) for every charge and credit that is made. The Transaction charge is usually done as a minimum fee with a set number of transactions included. On my account it's a $25 minimum with 80 or so free transactions for example.

 

Also keep in mind that although Merchant providers quote rates like 2.2 percent, the reality is, especially for business transactions, that you rarely get these rates processed. Business cards, International cards, or cards with rewards points bump the rate in most cases into the mid 3% range. Checking my most recent statement for example, I see that my average transaction for MasterCard and Visa was 3.40% even though my discount rate is 2.25%. The base rate is important though because these 'special card' percentages are piled ontop of it.

 

Gateway Service

Next you'll need to find a gateway service that your merchant provider supports. This is a lot easier today than it used be in the past where typically a merchant provider was married to one specific Gateway service. Nowadays most merchant providers give you a choice Gateways you can use.

 

Gateway Services provide the Internet facing interface that your application can talk to. Fees here vary significantly with some of the high end, super high volume providers being fairly expensive and the mainstream providers being relatively cheap or even free in a package.

 

Rates for Gateways are paid for monthly gateway fee, which can range from free to $15 (Authorize.NET official rate) to the more expensive Verisign PayFlow Pro which charges $60 for monthly fees. In addition to the gateway fee the gateways also charge small per transaction fees for each transaction run against the gateway fail or not. These are typically 5 cents or so, but they can add up. And remember you're paying for transactions whether they go through or not and for the closing batches at the end of the day for each network.

 

There are differences in providers and the services they offer. For example, Authorize.NET works great, but they don't support debit cards. PayFlow Pro does as does LinkPoint. All the providers also claim better performance than other, but the reality is that today performance of any of the services I've worked with recently is under 5 seconds with some as fast as 1 second response times, so this shouldn't be a big issue.

 

How do I get my Merchant Account and Gateway?

There are a number of different ways to find providers. The easiest way today is probably to find a merchant account reseller that sells packages of both Gateway Service and Merchant Service Provider, since this is a one stop solution.  In this scenario you end up signing up in one place, filling out one set of paperwork as opposed to separately signing up with a merchant banks and gateway service.

 

Resellers can be found on the Internet and a good way to start if you have no idea where to look is by going to the Gateway providers and check several of their preferred services.

 
I'm very happy with the service and rates I get with a reseller called MerchantPlus (using Synergy for Merchant Bank and Authorize.NET for Gateway) which is the current setup I'm running. But don't take my word for it – be sure to do your research and check and compare rates and fees carefully. I can't make any other recommendations at the moment since it's been a while since I've looked provider (and I have no need <s>), but if you search around on the Web you'll find a number of good discussion boards that talk about various providers and the quality and rates of their services and user experiences. It's worth doing a little research.

 

Other options include checking with your existing bank which may provide merchant services, although it's probably with rates that are higher than what you can find yourself. But it never hurts to ask as pricing can vary. You can also check out large resellers like CostCo which have merchant programs that include Internet packages that are reasonable.

 

The Merchant provider you choose to some degree will determine which processing network is used such as Nova, PaymentTech, FirstData etc. but other than the Gateway provider you use this shouldn't make much of a difference.

Picking a Gateway Provider

These days when you sign up with a Merchant provider you likely get a choice of gateways that you can use with it. If you're building your own application, you will have to interface with these gateways. Later on in this article I'll present a class that handles a number of common gateways using a common interface.

 

Let's review some of the common Gateway providers:

 

Authorize.NET

Authorize.NET Gateway is super easy to integrate into existing applications. It uses a plain HTTP POST interface to communicate with the server, so there's no setup and configuration – you merely need an HTTP client that can post the data. Authorize.NET returns data over HTTP in a simple comma delimited format that's easy to access within just about any application.

 

Authorize.NET is fast and stable – I've been using them for 4 years now without any problems during that entire time. Response time's somewhere between 2-5 seconds per transaction which is plenty fast. Authorize.NET doesn't support debit cards so if you need to process those you'll need to look elsewhere.

 

Price: $7.95 a month, 0.05 per transaction (first 250 free), $175 cancellation fee

(prices are through MerchantPlus reseller)

 

Verisign PayFlow Pro

Versign's PayFlowPro uses a COM or C++ based API that works with custom client side certificate. Installation is a little more involved in that you need to install the certificate on a specific location on the Web Server. Versign has a COM based API and has published a .NET front end for the COM API (basically a COM Interop assembly). I've not used Verisign other than in test modes, but I work with several customers who use it and are happy with performance and stability. Verisign claims high stability and guarantees uptime (not sure if I buy that though) and they support a number of non-credit card payment types like debit cards, direct deposit and electronic checks.


Signing up with PayFlowPro can be done entirely on the Verisign site – they can hook you up with the gateway and merchant account. Many merchants also allow you to use PayFlowPro with their accounts. It's one of the more popular low to midrange solutions.

 

Direct Price: $60 a month, 0.10 per transaction(1000 free), $249 setup

http://www.verisign.com/products-services/payment-processing/index.html

(note: there are resellers that can get this pricing down a little)

 

LinkPoint API

LinkPoint tends to be a Gateway used for many high risk sites. The most common match is with CardServices account which also are frequently of the high risk type. Linkpoint is a frequent choice required if you get a merchant account through a local bank when you let slip that you are doing an Internet business. LinkPoint/CardServices will tend to take on just about any customer, but the rates tend to be higher and the amount of declined transaction due to fraud checks can be much higher on this network than any other.

 

LinkPoint provides both a COM and .NET APIs and I've used both of them. Both basically work on the same message part model where you set various objects (Order,Billing,Options etc.) and fill each with the order data.

 

The .NET API is using some proprietary SLL driver you have to download and install in a specific location. For both API's you also must install a certificate on your server. The API itself passes messages via proto-XML – the documents passed are not actually parsable XML, but an XML fragment. Everything about this API made me cringe and think – who designed this???

 

Once hooked up and installed though LinkPoint works well and fast, but as mentioned watch for higher numbers of declined orders.

 

I would avoid LinkPoint if you have a choice. As mentioned many traditional banks resell LinkPoint and CardServices and if you go that route you may not have a choice.

 

Many more providers

There are many more providers, but the above are common ones that I've worked with. A few others include AccessPoint, BluePay, PaymentNet, iTransact to name a few of the smaller ones. There are also providers that cater to the high end for the mega online stores with millions of dollars in revenue a month. Cybersource is one of the providers in that end of the market and these providers provide special merchant deals that cater to these higher end customers.

 

In the old days some of these high end providers were the only ones able to handle the high volume vendors were throwing at them, but times have changed and technology has improved. All the gateways I've worked with now return transaction results in under 5 seconds typically and generally don't balk at high volume. The main difference is that large vendors have enough dollar volume going through the gateways and merchant providers to work special deals for better rates.

 

For anything but the high end of e-Commerce applications the solutions mentioned here should work just fine.

 


 

Web Site Integration

OK, so you've picked your merchant provider and gateway – the next step is to integrate the payment processing into your Web Application. In order to do this the first step is to create the basic credit card processing routines that can interface your code with the Gateway of your choice. The focus of the following discussion is describe how to create a somewhat generic credit card processing class hierarchy that can work with various providers, and then describe how to use these classes in a custom Web Store application.

Implementing a generic set of Credit Card Classes

Assuming the rest of your site is in place the first thing you need to figure out is how to actually process the credit cards you receive. This means you'll need to write the code that interfaces with the Gateway you selected. You can go download the providers API reference and start figuring out how to use the particular gateway interface from scratch, which with most providers is not terribly difficult but even though the process is often fairly straight forward, integration tends to be time consuming due to the testing and the interaction with Gateway support to get all the information (account ids, passwords, sometimes certificates, switching accounts from test to live mode etc.) you need in order to start processing transactions.

 

I believe it's a good idea to use a more generic framework that is more flexible and allows to potentially switch to a different provider in the future. Over the years, I've gone through 6 different merchant providers and with each switch I ended up on a new kind of gateway. Rather than writing application level code to integrate with each of the gateways, I long ago created a generic Credit Card processing class that provides a base interface for credit card processing. The base class provides the core properties that every credit card gateway requires as well as few helper methods that validate field input, deal with formatting properties such as card numbers and card expiration dates, deal with MOD10 validation, switching into test mode, logging and so on. The provider specific implementation then handles the actual credit card processing with the Gateway.

 

The result is a hierarchy of credit card processing classes which are provided as part of this article. The classes include support for the following gateway services:

 

  • Authorize.NET
  • Verisign PayFlowPro
  • LinkPoint
  • AccessPoint
  • BluePay

 

Figure 2: The hierarchy of credit card processing classes presented here.


These are providers I have worked with over the years and while this list is not extensive, it contains some of the most popular Gateways and it's relatively straight forward to add other providers using the same processing logic.

 

This class hierarchy starts out with an abstract base class called ccProcessing. The ccProcessing class provides a core property interface that provides the common interface that application code writes to. So regardless of whether you're using Authorize.NET or BluePay, you're always setting the MerchantID and MerchantPassword properties even though the providers may call these different things (for example, BluePay calls it the AccountId and SecretKey).You always fill in customer billing information, order amounts and credit card number and expiration and this class provides a common baseline to assign the values before processing.

 

Here's the interface for the abstract ccProcessing class:

 

Member

Description

AvsCodeToString

Returns a string for a single AVS code value Supported codes: ANSUWXYZER_
public string AvsCodeToString( string AvsCode );

Mod10Check

Determines whether given string passes standard Mod10 check.
public static bool Mod10Check( string StringToValidate );

ValidateCard

Base ValidateCard method that provides the core CreditCard checking. Should always be called at the beginning of the subclassed overridden method.
public virtual bool ValidateCard();

Address

Billing Street Address.

AuthorizationCode

Authorization Code returned for Approved transactions from the gateway

AvsResultCode

The AVS Result code from the gateway if available

CertificatePath

Used for Linkpoint only. Specifies the path to the certificate file

City

Billing City

Comment

Order Comment. Usually this comment shows up on the CC bill.

Company

Billing Company

Country

Two letter Country Id - US, DE, CH etc.

CreditCardExpiration

Full expiration date in the format 01/2003

CreditCardExpirationMonth

Credit Card Expiration Month as a string (2 digits ie. 08)

CreditCardExpirationYear

Credit Card Expiration Year as a 4 or 2 digit string

CreditCardNumber

The credit card number. Number can contain spaces and other markup characters which are stripped for processing later.

Email

Email address

Error

Error flag set after a call to ValidateCard if an error occurs.

ErrorMessage

Error message if error flag is set or negative result is returned. Generally this value will contain the value of this.ValidatedResult for processor failures or more general API/HTTP failure messages.

Firstname

First Name of customer's name on the card. Can be used in lieu of Name property. If Firstname and Lastname are used they get combined into a name IF Name is blank.

Http

Reference to an wwHttp object. You can preseed this object after instantiation to allow setting custom HTTP settings prior to calling ValidateCard().

HttpLink

The link to hit on the server. Depending on the interface this can be a URL or domainname or domainname:Port combination.

Lastname

Last Name of customer's name on the card. Can be used in lieu of Name property. If Firstname and Lastname are used they get combined into a name IF Name is blank.

LogFile

Optional path to the log file used to write out request results. If this filename is blank no logging occurs. The filename specified here needs to be a fully qualified operating system path and the application has to be able to write to this path.

MerchantId

The merchant Id or store name or other mechanism used to identify your account.

MerchantPassword

The merchant password for your merchant account. Not used in most cases.

Name

First name and last name on the card

OrderAmount

The amount of the order.

OrderId

The Order Id as a string. This is mainly for reference but should be unique.

Phone

Billing Phone Number

ProcessType

Determines what type of transaction is being processed (Sale, Credit, PreAuth)

RawProcessorRequest

This is a string that contains the format that's sent to the processor. Not used with all providers, but this property can be used for debugging and seeing what exactly gets sent to the server.

RawProcessorResult

The raw response from the Credit Card Processor Server.

ReferingUrl

Referring Url used with certain providers

SecurityCode

The 3 or 4 letter digit that is on the back of the card

State

Billing State (2 letter code or empty for foreign)

TaxAmount

The amount of Tax for this transaction

Timeout

Timeout in seconds for the connection against the remote processor

TransactionId

The Transaction ID returned from the server. Use to match transactions against the gateway for reporting.

UseMod10Check

Determines whether a Mod10Check is performed before sending the credit card to the processor. Turn this off for testing so you can at least get to the provider.

UseTestTransaction

Optional flag that determines whether to send a test transaction Not supported for AccessPoint

ValidatedMessage

The parsed error message from the server if result is not APPROVED This message generally is a string regarding the failure like 'Invalid Card' 'AVS Error' etc. This info may or may not be appropriate for your customers to see - that's up to you.

ValidatedResult

The parsed short form response. APPROVED, DECLINED, FAILED, FRAUD

Zip

Postal or Zip code

 

As you can see the main portion of this class provides properties for most of the possible values that you need to describe a credit card transaction. There's billing information for the customer, the Credit Card information including the Card Number, Card Expiration and CVS SecurityCode as well as the order amount.

 

There are processing specific properties such as the HttpLink (used with HTTP based providers like Authorize.NET, BluePay and AccessPoint). There's MerchantId and MerchantPassword that identifies the merchange.


Then there are Response values such as the ValidatedResult (APPROVED, DECLINED, FAILED, FRAUD), ValidatedMessage which returns a descriptive message returned from the provider, RawProcessorResult, which returns the raw data returned if available. There's also AuthorizationCode and TransactionId which return these values from transactions.

 

The base class also supports logging of every request to a log file and you can easily Test mode on and off (for those providers that support it through the gateway API) for a transaction.

 

There are also a couple of helper methods that can do Mod10 checking and convert a single AVS code to a string value. AVS codes are returned for failed transactions and you can use the conversion to potentially provide more information to your customers.

 

The worker method that does all the work is ValidateCard(). Since this class is abstract the default ValidateCard() method doesn't do anything useful (it does have logic though so make sure to call the base method in your implementation) – this method needs to be overridden by the specific processor implementation classes.

Customizations do the real work

Logic says there should be a common Gateway API for all providers, but the reality is that most of the APIs work very differently. Even those that are operationally similar – those that use pure HTTP POST interfaces like Authorize.NET, AccessPoint and BluePay – use completely different POST variables and formats. So, each of these classes essentially features a complete custom implementation to talk to the specific Gateway provider.

 

While the base class interface of the various processing classes is identical, most of the classes require slightly different start up configuration. This means if you plan on supporting multiple credit card providers in a single application (such as a more generic shopping cart) there's a little bit of conditional code required for each of the providers.

 

The following C# code is an example of how all of the supported credit card providers are integrated into my Invoice business object, which gives you a pretty good idea how the class can be used at the Application level:

 

/// <summary>

/// Processes credit cards for the provider set in App.Configuration.CCMerchant

/// Works with the WebStoreConfig settings for setting to configure the provider

/// settings.

/// </summary>

/// <remarks>The Invoice is not saved at this point.

/// Make sure to call Save() after this operation.</remarks>

/// <returns></returns>

public bool ProcessCreditCard()

{

    bool Result = false;

 

    wws_invoiceRow Inv = this.Entity;

    wws_customersRow Cust = this.Customer.Entity;

 

    ccProcessing CC = null;

    ccProcessors CCType = App.Configuration.CCProcessor;

 

    try

    {

        if (CCType == ccProcessors.AccessPoint)

        {

            CC = new ccAccessPoint();

        }

        else if (CCType == ccProcessors.AuthorizeNet)

        {

            CC = new ccAuthorizeNet();

            CC.MerchantPassword = App.Configuration.CCMerchantPassword;

        }

        else if (CCType == ccProcessors.PayFlowPro)

        {

            CC = new ccPayFlowPro();

            CC.MerchantPassword = App.Configuration.CCMerchantPassword;

        }

        else if (CCType == ccProcessors.LinkPoint)

        {

            CC = new ccLinkPoint();

            CC.MerchantPassword = App.Configuration.CCMerchantPassword;

            CC.CertificatePath = App.Configuration.CCCertificatePath;  

            // ie. "d:\app\MyCert.pem"

        }

        else if (CCType == ccProcessors.PayPalWebPaymentsPro)

        {

            CC = new ccPayPalWebPaymentsPro();

            CC.MerchantPassword = App.Configuration.CCMerchantPassword;

            ((ccPayPalWebPaymentsPro)CC).PrivateKeyPassword = "";

        }

        else if (CCType == ccProcessors.BluePay)

        {

            CC = new ccBluePay();

            CC.MerchantId = App.Configuration.CCMerchantId;

            CC.MerchantPassword = App.Configuration.CCMerchantPassword;

        }

 

        CC.MerchantId = App.Configuration.CCMerchantId;

 

        //CC.UseTestTransaction = true;

 

        // *** Tell whether we do SALE or Pre-Auth

        CC.ProcessType = App.Configuration.CCProcessType;

 

        // *** Disable this for testing to get provider response

        CC.UseMod10Check = true;

 

        CC.Timeout = App.Configuration.CCConnectionTimeout;  // In Seconds

        CC.HttpLink = App.Configuration.CCHostUrl;         

 

        CC.LogFile = App.Configuration.CCLogFile;

        CC.ReferingUrl = App.Configuration.CCReferingOrderUrl;

 

        // *** Name can be provided as a single string or as firstname and lastname

        //CC.Name = Cust.Firstname.TrimEnd() + " " + Cust.Lastname.TrimEnd();

        CC.Firstname = Cust.Firstname.TrimEnd();

        CC.Lastname = Cust.Lastname.TrimEnd();

 

        CC.Company = Cust.Company.TrimEnd();

        CC.Address = Cust.Address.TrimEnd();

        CC.State = Cust.State.TrimEnd();

        CC.City = Cust.City.TrimEnd();

        CC.Zip = Cust.Zip.TrimEnd();

        CC.Country = Cust.Countryid.TrimEnd();  // 2 Character Country ID

        CC.Phone = Cust.Phone.TrimEnd();

        CC.Email = Cust.Email.TrimEnd();

 

        CC.OrderAmount = Inv.Invtotal;

        CC.TaxAmount = Inv.Tax;                             // Optional

        CC.CreditCardNumber = Inv.Cc.TrimEnd();

        CC.CreditCardExpiration = Inv.Ccexp.TrimEnd();

 

        CC.SecurityCode = Inv.Ccsecurity.TrimEnd();

 

        // *** Make this Unique

        CC.OrderId = Inv.Invno.TrimEnd() + "_" + DateTime.Now.ToString();

        CC.Comment = App.Configuration.CompanyName + " Order # " +

                                                     Inv.Invno.TrimEnd();

        // *** Result returned as true or false

        Result = CC.ValidateCard();

 

        // *** Pick up the Validated result values from the class

        Inv.Ccresult = CC.ValidatedResult;

        if (!Result)

        {

            this.ErrorMessage = CC.ValidatedMessage;

            Inv.Ccerror = this.ErrorMessage;

        }

 

        // *** Always write out the raw response

        if (string.NullOrEmpty(CC.RawProcessorResult))

            Inv.Ccresultx = CC.ValidatedMessage;

        else

            Inv.Ccresultx = CC.RawProcessorResult;

    }

    catch (Exception ex)

    {

        this.SetError(ex.Message);

        Inv.Ccresult = "FAILED";

        Inv.Ccresultx = "Processing Error: " + ex.Message;

        Inv.Ccerror = "Processing Error: " + ex.Message;

        return false;

    }

 

    return Result;

}

 

This class method is designed to work with multiple credit card providers that are supported by the store. Using this routine as a front end I can use basically any of the credit card providers that are supported by the ccProcessing subclasses simply by setting a switch in the web.config file (or via an admin interface).

 

The code starts out instantiating each of the individual classes and setting a few provider specific properties on it. You notice that some require a certificate, others require only a merchant id, others require password and so on. Aside from that though all the various providers use identical code.

 

The code that follows assigns the application specific data to the processing object – in this case the data comes from Invoice and Customer objects and – for the system configuration settings – from an App.Configuration object which provides application configuration settings of various kinds with the ultimate source being in the web.config file.

 

The call to ValidateCard() is made which goes out and uses the provider specific code to process the credit card. The method returns true or false. If true the order was approved otherwise it was declined or failed.

 

The code here captures the ValidatedResult (APPROVED, DECLINED, FAILED or FRAUD) as well as the ValidatedMessage and the RawProcessorResult which in turn are stored in the invoice object. Storing the RawProcessorResult may seem like overkill but it provides a good record in case there are problem in the future such as a chargeback or fraudulent transaction. I highly recommend storing the raw response data if available by the provider.

 

The response value from the ValidateCard() method and the parsed result values make it easy to quickly figure out what happened during processing and take appropriate action in your application. All the parsing of the card processor response is taken care of for you in the various processor specific classes, so it's short work to pick up the result values.

 

In this case the results are simply stored in the business object and saved. If a failure occurs the ValidatedResult error message is displayed back to the user in the Web interface.

 

Notice that this code is completely provider agnostic and keeps all the messy domain knowledge about the credit card processing out of the business object code. The code is relatively short and clean and easy to read and modify and generic enough to work with various gateways at the flick of a switch. Sweet.

Gateway Provider Implementations

So now let's take a look at the individual provider implementations. As you might have guessed each one of the provider classes essentially implements the ValidateCard() method and maybe a few of the stock property