Integration Security Fresh
Ensure PCI compliance and secure customer-server communications.
PCI compliance
The Payment Card Industry Data Security Standard (PCI DSS) is the global security standard for all entities that store, process, or transmit cardholder data. PCI compliance is a shared responsibility:
- Stripe is certified annually by an independent PCI QSA as a PCI Level 1 Service Provider
- Your business must accept payments in a PCI-compliant manner and attest annually
Minimize your PCI scope
Some business models require handling raw card numbers. Most don't. Use Stripe's low-risk integrations to collect and transmit payment information directly to Stripe without it passing through your servers:
- Stripe Checkout — customers enter card details on Stripe's hosted page
- Stripe Elements / Payment Element — Stripe.js tokenizes card data in the browser before it reaches your server
- Mobile SDKs — card data is handled in Stripe's SDK before transmission
With these integrations, you reduce your PCI obligations to the simplest SAQ-A or SAQ-A-EP level.
What you can safely store
Stripe returns non-sensitive card information you're allowed to store:
- Card type (Visa, Mastercard, etc.)
- Last 4 digits
- Expiration date
Never store: full card numbers, CVCs, magnetic stripe data, or PINs.
TLS and HTTPS
All payment pages must use TLS 1.2 or above. TLS:
- Encrypts traffic between client and server
- Verifies the server's identity to prevent man-in-the-middle attacks
Requirements
- All pages that display or collect payment information must use HTTPS
- All resources (JavaScript, CSS, images) must be served over HTTPS to avoid mixed-content warnings
- Your webhook endpoints must use HTTPS (in production)
Setting up TLS
- Obtain a certificate from a reputable provider (Let's Encrypt, DigiCert, Namecheap)
- Configure your web server to use the certificate
- Validate your setup with SSL Labs' SSL Server Test
Content Security Policy
If you use a Content Security Policy, add these directives for Stripe integrations:
Stripe Checkout
connect-src https://checkout.stripe.com
frame-src https://checkout.stripe.com
script-src https://checkout.stripe.com
img-src https://*.stripe.comStripe Elements (Stripe.js)
connect-src https://api.stripe.com
frame-src https://js.stripe.com https://hooks.stripe.com
script-src https://js.stripe.com
img-src https://*.stripe.comConnect embedded components
frame-src https://connect-js.stripe.com https://js.stripe.com
img-src https://*.stripe.comAPI key security
- Never commit API keys to version control
- Never include secret keys in client-side code
- Store keys in environment variables or a secrets manager
- Rotate keys regularly and immediately after any suspected exposure
- Use restricted keys when possible (limit to specific API operations)
bash
# Always use environment variables
STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...Webhook security
Always verify webhook signatures to confirm events come from Stripe:
javascript
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
app.post('/webhooks', express.raw({ type: 'application/json' }), (req, res) => {
const sig = req.headers['stripe-signature'];
let event;
try {
event = stripe.webhooks.constructEvent(
req.body,
sig,
process.env.STRIPE_WEBHOOK_SECRET
);
} catch (err) {
return res.status(400).send(`Webhook Error: ${err.message}`);
}
// Handle the event
res.json({ received: true });
});Never process a webhook event without verifying its signature.
Additional resources
- OWASP (Open Web Application Security Project) — web security best practices
- SANS Reading Room — security guides
- NIST Cybersecurity Framework — federal standards