updated as of: August 20, 2012
last author: Andy Theuninck
This is a guide to writing a paycard class that can be used with IS4C. This is not a guide to PCI compliance. Asking whether is a given module is PCI compliant is probably the wrong approach. Modules shouldn't retain any credit card numbers, but I highly encourage you to trace through and verify that to your own satisfaction. Even that, however, is a small facet of PCI compliance.

OK, no more soapbox. Most payment gateways are actually pretty simple. You take some data - card info, amount, transaction type, etc - format it to the gateway's liking - as HTTP, XML, SOAP, etc - and send it to an HTTPS URL. The gateway sends a response, again formatted somehow, telling you what happened. Generally this response is approved, declined, or an error message.

In a lot of cases, all that really varies from one gateway to another is the formatting of what you send and the formatting of how it replies. That leaves a lot of potential for code re-use and interchangeable payment modules.

Primer: Credit Cards

Some collective knowledge on cards isn't a bad idea, although doubtless I don't know everything.

Your basic credit card transaction consists of two parts: an auth transaction requests funds from the customer's bank, and a settle transaction that actually transfers funds to your account. A settle must correspond to an existing auth. Most gateways provide another type of transaction that combines the two - an auth that will automatically settle - but terminology varies from one to another.

The other common credit card operations are void and credit. A void transaction cancels an existing auth - sort of. If you void an auth, it will never settle, but it may hang on the cardholder's account as a pending charge. How long this pending charge sticks around is up to the issuing bank; as the merchant, it's out of your control. A credit transaction is a refund.

Most gateways will accept either a card number, commonly called PAN, and expiration date or track data. Track data is what's on the magnetic stripe. Sending track data will generally result in significantly lower processing charges. Most cards have two tracks, actually called Track 1 and Track 2. You may or may not get both depending on the card and how readable the stripe is. You can generally send either or both. The exact format required may vary from processor to processor. Note the parsing functions in lib/paycardLib.php remove start and end sentinel characters; if your gateway wants them, the start and end for track 1 are (normally) "%" and "?". The start and end for track 2 are ";" and "?".

Primer: Gift Cards

These probably vary more from provider to provider. When a customer uses their gift card as tender, IS4C calls this an auth transaction. Gift cards also usually include transaction types to check current balance, activate a new card, and add value to an activated card. Refunds to a gift card map nicely to add value. If there isn't a specific void transaction, you can fake one with auths and add values to reverse earlier transactions.

BasicCCModule Class

This class has a few methods that are required by every implementation and a few utility functions that may be helpful. First, required methods: I normally put a switch statement in doSend and have a separate send function for each sub-type of transaction (auth, void, etc). Each send function builds an appropriate data "block" and sends it using curlSend(). In turn, curlSend() gives the result to handlesResponse(). From there I use another switch on type with handleResponse functions for each type. There's no particular reason doSend needs to be implemented this way, but if you're trying to trace along that's the general plan.

What's Going to Go Wrong?

Implementation isn't so bad, but there are potential problems (if anyone knows solutions, clue me in and I'll happily trim this list).