1. If at all possible, don't store credit card numbers in your database. A payment gateway will take care of this for you - you have an iframe the user uses to submit their credit card details straight to the payment gateway, and the payment gateway gives you back a token you can use to charge and refund at your convenience (locked to your merchant account so not useful to attackers). DataCash and Chase Paymentech are two companies that provide this service, and I'm sure there are others too.
2. If the user forgets their password and resets it, ask them to re-enter their credit card details in case their e-mail has been hacked. (Also ask them to re-enter their details for deliveries to new postal addresses, if applicable)
So if you can't access CC data after a customer resets their password, that's no problem.
3. Use database-level security; set up roles and accounts in your database so tables containing sensitive data only have select grants to apps and users that really need them. When a table has some columns that are sensitive and others that aren't, set up a view with the sensitive columns replaced with placeholder data and give them access to that instead.
YOu have a dedicated box that stores details and is remotely contacted through an XML-RPC/JSON-HTTP API of some sort.
The API should have two methods:
* Add a new card to account.
* Make payment of £xx from card NN.
The machine is locked down, runs no other services, and so cards cannot be exported/stolen from this system. You'd encrypt the filesystem and prompt for a key/passphrase at boot. Ideally you'd only login via the serial console so the only service exposed is your "add/charge" methods.
(Even allowing the remote-deletion of cards could be a security issue; obviously.)
Payment gateways have it somewhat easy - the system making the "make a payment" request doesn't ever need the actual sensitive data returned. That data can be stored on a heavily secured server that only can call out to the banks.
It's not really a risk you can really protect against in any meaningful way with insurance. It's the banks that ultimately eat the loss, and they just write this off as a cost of doing business. Banks really do lose a lot of money to fraud, card losses, and other miscellaneous security issues and bad actors -- a lot more than people think.
Storing CC data can be done sufficiently securely, of course, although PCI DSS guidelines are insufficient and silly in places, and you really have to go above and beyond to make it secure enough because data breaches can threaten the status of your merchant account. If you become too costly or too risky to do business with, the bank will simply cut you off by terminating your merchant account. You may also end up on the TMF which will make it very hard to get another merchant facility in the future.
2. If the user forgets their password and resets it, ask them to re-enter their credit card details in case their e-mail has been hacked. (Also ask them to re-enter their details for deliveries to new postal addresses, if applicable)
So if you can't access CC data after a customer resets their password, that's no problem.
3. Use database-level security; set up roles and accounts in your database so tables containing sensitive data only have select grants to apps and users that really need them. When a table has some columns that are sensitive and others that aren't, set up a view with the sensitive columns replaced with placeholder data and give them access to that instead.