What to do when a customer pastes card details into a WhatsApp thread
By Super Admin
It happens to almost every business handling sales or support over social messaging:
An eager customer wants to complete an order. Instead of clicking the checkout link, they type directly into the WhatsApp or Instagram chat:
"Here's my card: 4532 8912 3456 7890, exp 08/28, CVV 412. Please charge it for the blue jacket."
To the customer, WhatsApp feels like a private, direct line to a helpful store assistant.
To your business, that message is a compliance emergency.
The moment that message enters your system, your database, your message queues, your backup snapshots, and your support agents' browser screens are all holding unencrypted Primary Account Numbers (PAN) and Card Verification Values (CVV).
Here is why this is dangerous, what standards apply, and how an enterprise-grade shared inbox handles it automatically.
The Problem: PCI-DSS and WhatsApp
The Payment Card Industry Data Security Standard (PCI-DSS) applies to any organization that stores, processes, or transmits cardholder data.
Under PCI-DSS Requirement 3:
- Cardholder data must be protected anywhere it is stored.
- Sensitive Authentication Data (SAD), including the 3- or 4-digit CVV/CVC code printed on the card, must NEVER be stored after authorization — even if encrypted.
When a customer sends card details in WhatsApp:
- The data exists on Meta's infrastructure (temporarily transit-cached).
- The webhook delivers it to your application server.
- Your database writes the message text to disk in your
messagestable. - Your background job queues (Redis, Horizon, SQS) store the message payload.
- Every agent with access to that conversation can read the customer's full card number and CVV.
If your database or employee laptop is ever breached, having unencrypted payment card details sitting in your chat logs exposes you to massive card brand fines (often $5,000 to $100,000 per month) and catastrophic reputational damage.
Step 1: Immediate Ingress Redaction
You cannot control what customers type. But you can control what your database persists.
The golden rule of compliance is: redact before storage.
Do not write raw chat text to your database and plan to "clean it up with a nightly cron job." By the time the nightly cron runs, the plaintext data has already been replicated to database replicas, written to transaction logs, and backed up to cloud snapshots.
Detecting and masking Primary Account Numbers (PAN)
Credit card numbers have recognizable patterns and obey the Luhn algorithm (Mod 10).
At the webhook ingestion layer — before inserting the record into your database or broadcasting via WebSockets — pass the inbound text through a redaction filter:
namespace App\Services;
class DataMaskingService
{
// Regex matching Visa, Mastercard, Amex, Discover with optional spaces/dashes
private const CARD_REGEX = '/\b(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|6(?:011|5[0-9]{2})[0-9]{12}|(?:2131|1800|35\d{3})\d{11})[\s\-]?[0-9]{3,4}?\b/x';
public function maskMessageText(string $text): string
{
// 1. Mask Card Numbers (Keep first 6 and last 4, or mask completely)
$text = preg_replace_callback(self::CARD_REGEX, function ($matches) {
$raw = preg_replace('/\D/', '', $matches[0]);
if ($this->passesLuhnCheck($raw)) {
return '[CARD REDACTED **** ' . substr($raw, -4) . ']';
}
return $matches[0];
}, $text);
// 2. Mask 3 or 4 digit CVVs preceded by keywords
$text = preg_replace(
'/\b(?:cvv|cvc|security\s*code|cid)[\s:=]+([0-9]{3,4})\b/i',
'[CVV REDACTED]',
$text
);
return $text;
}
private function passesLuhnCheck(string $number): bool
{
$sum = 0;
$numDigits = strlen($number);
$parity = $numDigits % 2;
for ($i = 0; $i < $numDigits; $i++) {
$digit = (int) $number[$i];
if ($i % 2 === $parity) {
$digit *= 2;
if ($digit > 9) {
$digit -= 9;
}
}
$sum += $digit;
}
return ($sum % 10 === 0);
}
}
By applying this filter inside your webhook handler, the text stored in your database looks like:
"Here's my card: [CARD REDACTED **** 7890], exp 08/28, [CVV REDACTED]. Please charge it for the blue jacket."
The PAN is scrubbed, the CVV is destroyed, and your PCI-DSS scope is preserved.
Step 2: Educate the Customer (Automated Canned Response)
When your system detects that a customer has shared payment credentials, trigger an immediate automated notice in the thread:
"For your security, we have automatically masked the payment card details you sent. Please do not send credit card numbers or CVVs over chat. Our agents will never ask for your card details in WhatsApp."
This achieves three things:
- Reassures the customer that their privacy is actively protected.
- Instructs them to stop pasting cards in future conversations.
- Sets expectations that agents cannot manually key in their card.
Step 3: Take Payments Securely (The Right Way)
If agents shouldn't manually type card numbers, how do you close the sale inside WhatsApp or Instagram?
Never take credit cards over chat. Instead, use one of these two modern mechanisms:
1. Hosted Payment Links (Stripe / Shopify / Razorpay)
When an agent agrees on an order total with a customer, the agent clicks "Create Payment Link" in the shared inbox side panel.
The inbox generates a one-time, secure checkout URL (e.g. https://buy.stripe.com/...) pre-filled with the customer's items and total. The link is dropped directly into the chat. The customer taps the link, pays via Apple Pay, Google Pay, or 3D-Secure credit card on Stripe's PCI Level 1 compliant hosted page, and the inbox updates automatically when the webhook confirms payment.
2. WhatsApp Native In-Chat Payments
In supported regions (such as India, Brazil, and Singapore), Meta offers native in-app WhatsApp Pay. Customers can browse your WhatsApp Product Catalog, add items to an in-chat cart, and tap "Pay" using WhatsApp's integrated UPI, Pix, or credit card flow without ever leaving the conversation.
Takeaways for Team Inboxes
Handling customer messaging at scale requires more than just connecting an API.
- Never store raw card data or CVVs — redact at webhook ingress before database insertion.
- Warn customers automatically when sensitive data is detected.
- Use hosted checkout links or native catalog payments rather than manual agent card entry.
- Audit internal team visibility with role-based permissions and access logs.
Protecting your customer's data builds trust and ensures your messaging channels remain an asset rather than a compliance liability.