Accept CC info and associate with order

Hi all, looking for some advice on how to approach this.

We want to be able to take orders, and then have the customer pay for the order without ever letting the customer service rep hear the credit card information.

I have thought of a few ways to do this but not sure the best approach:

  1. CSR takes the order, then transfers the customer to an IVR along with inputting the order number so the IVR knows the order number, and then the IVR asks customer for CC info/expiration date. After IVR completes CC info + order number are sent to an API to input the order into the system.

  2. CSR takes the order, then transfers the customer to an IVR and then the IVR asks customer for CC info/expiration date and order number. After IVR completes CC info + order number are sent to an API to input the order into the system. This is probably a bad idea because the customer would enter the wrong order number.

  3. Pay for some 3rd party service that takes CC info over the phone and use a dynamic route to send the customer to that portal. Not preferred but if you have any suggestions for companies that do this please let me know.

  4. CSR takes order, tells customer they have to enter CC info, then CSR presses special code, asterisk mutes DTMF codes, (PauseMonitor?) and asterisk then sends that CC info to an API where the CC info and order number are processed.

  5. Something I have not thought of yet. I am open to all suggestions.

Given the liabilities of me F’ingU, I wouldn’t touch 1,2,4 or 5

This is the way. The money spent is offset by liability relief and the added infrastructure you would need to perform the transaction internally.

As of right now, the only savings are in the liability - the infrastructure and code to take orders in a PCI compliant manner already exist. The only new addition would be the phone orders. Currently the website services thousands of orders daily. Do you know of any services that do this? I am open to exploring 3rd party options but I haven’t found any yet for this specific purpose.

What if you had to and the company didn’t want to go with option 3?

I would have to indemnify myself with an insurance policy that would be ‘huge’ and that said company would have to pay for it :wink: , but that has never happened and never will, it’s never wrong to drop a perceived risky client.

Before even thinking of anything but option 3, familiarise yourself with the PCI DSS (Payment Card Industry Data Security Standard) starting at https://listings.pcisecuritystandards.org/documents/PCI_DSS-QRG-v3_2_1.pdf

Even option 3 requires you to make sure the call is not recorded, and if DTMF is used, for sensitive data, that it is not logged. Recording and deleting is not, I believe, acceptable.

The rest of the business is already PCI compliant. CC #s are never written to disk, only stored in memory for use and then discarded. For this particular purpose the IVR would not be recording calls, the DTMF keypresses would be saved to variable along with an order number, then passed to an AGI script (the current payment gateway), and then the order recorded into the database if payment successful. The CC information would never be written to disk or stored anywhere.

This is going to need a lot of editing but this is what I came up with as a skeleton so far. There is no error handling or anything yet.

[default]
exten => 1000,1,Answer()
same => n,Playback(welcome)
same => n,WaitExten(5)

exten => 1,1,Goto(order_input,s,1)

[order_input]
exten => s,1,Answer()
same => n,Playback(enter_order_number)
same => n,Read(order_number,beep,10)
same => n,GotoIf($[“${order_number}” = “”]?s,3)
same => n,Goto(ivrs,1,1)

exten => s,3,Playback(silence/1&invalid_extension)
same => n,Goto(order_input,s,1)

[ivrs]
exten => 1,1,Answer()
same => n,Playback(enter_credit_card)
same => n,Read(credit_card_number,beep,16)
same => n,Playback(enter_expiration_date)
same => n,Read(expiration_date,beep,4)
same => n,Playback(enter_zip_code)
same => n,Read(zip_code,beep,5)
same => n,GotoIf($[“${credit_card_number}” = “” | “${expiration_date}” = “” | “${zip_code}” = “”]?1:2)

exten => 1,1,Playback(silence/1&invalid_input)
same => n,Goto(ivrs,1,1)

exten => 2,1,AGI(api_request.php,${credit_card_number},${expiration_date},${zip_code},${order_number})
same => n,Playback(thank_you)
same => n,Goto(default,1000,1)