views:

884

answers:

7

I have had a number of requests from clients wanting to take a customer's credit card number online and then process the payment in store at a POS of terminal. I'm wondering what the best method of doing this is.

I don't want to store the credit card number on the server in plain text and I don't want to send an email with the number in plain text.

The clients don't want to sign up for an online payment accounts because of the higher and additional cost of an online payment processor. Also both customers can't charge online because the total will likely change because of out of stock products or problems with customers request.

What other options do I have?

I'll be using PHP. I am also in Canada if the rules have any effect on which method I should use.

+2  A: 

You could store the credit card data in a MySql Database (other may work but I am unfamiliar) using the MySql AES_ENCRYPT function to encrypt the card number and then AES_DECRYPT when retrieving. Use a strong key and delete the entry in the database once they are processed.

There may be a way to do the AES en/decryption with PHP but I am not aware of a native way.

MitMaro
+1  A: 

I solved this problem by building a frontend to GPG and allowing the website owner to generate their own GPG keys. Then, all credit card data is GPG encrypted and can only be decrypted with the website owner's private key, which for additional security could be kept off the server if desired.

Josh
+2  A: 

I recommend using Authorize.net (only because that's what I have used). You can post the credit card information to Authorize.net to capture (AUTH_CAPTURE I believe) the credit card information to be charged. Then your client can log in to the Authorize.net virtual terminal and charge or void each payment depending on available inventory.

DO NOT store credit card information, even if it's encrypted, in a database that is accessible via the internet. I do not know where PCI compliance begins and ends, but I do know that if your client is storing credit card information, then they are required to be PCI compliant by the credit providers they accept. PCI compliance is a pain, and the approach I recommend is the easiest way around it that I have found. And with minimal headaches for the client.

Jesse Kochis
I wish this was an option.
Darryl Hein
I know it doesn't directly address the question, but it pertains directly to this answer:If you do an authorization, it puts a hold on the funds, even if you don't end up charging the card. With everybody wired-into their online bank statements these days, this is a customer service nightmare because they think you've charged them when you haven't.The best way is to use a service (like Authorize.net's Customer Information Manager) that is designed for storing the info for later use.
grossvogel
+3  A: 

There are a large number of payment processors available that I would recommend over using a POS machine. Most comment are PayPal, Authorize.net, CyberSource... all have programming APIs to let you interface with your site.

Secondly, I use Rijndael encryption, as I believe it is the most secure way to store card data. I go to great lengths to hide the encryption key outside of the web config (seperate file, reg key, etc).

Last, but probably most important, is that you should strongly look at PCI (Payment Card Industry) compliance certification (https://www.pcisecuritystandards.org/). I believe this is quickly becoming a requirement (if it isn't already) to accepting card data online. In the future, there may be a fine for those who do not comply with the regulations.

Kyle B.
A: 

Your best bet is to use asymmetric encryption. Generate a RSA public and private key pair. Place the private key in a SECURE location. Put the public key on your webserver. When clients want to submit their credit card details, push the public key to them. Encrypt the data using the public key, on this client side. In OpenSSL, look at the Envelope routines (EVP_**).

This way, the only way to recover the plaintext credit card data will be to Decrypt using the very secure, never placed online, never seen an internet connected computer private key.

You could create a pretty simple standalone app that does this, again with OpenSSL.

Considering the small amount of data you want to encrypt, I think this is a fairly practical solution.

A more efficient, but more complicated solution is to AES encrypt the data with a key generated client side. Then encrypt this AES key as above (replace credit card with AES key in my above solution.)

James
A: 

I know you asked for a solution that doesn't involve a payment processor, but there's a credit card processor called CurePay in Canada that from what I have heard is relatively cheap (I don't use it myself). www.curepay.com. Might be worth giving them a shout, at least to find out about pricing.

Also, I seem to remember something about some sort of compliance around taking credit card numbers. Storing credit cards or processing them "incorrectly" might leave you open to legal troubles. Not trying to scare you, just making sure you are definitely considering things like this with whatever solution you go ahead with.

shufler
+1  A: 

Storing the credit card at all will come under PCI compliance. The rules and regs of PCI are ornorous and detailed. This is not a simple problem. If I had to do it over again, I would look at buying a cart that is PCI compliant and installing that and be done with it.

Dave