How to stop Stripe checkout fraud
Learn how to stop Stripe Checkout fraud before payment by scoring IP, email, domain, device, and behavior risk with RequestGuard.
Stripe Checkout makes it easy to accept payments, but it does not remove every fraud decision from your application. A fraudster can still use your checkout to test cards, abuse trials, create disposable accounts, route traffic through hosting networks, or place orders that look clean until fulfillment costs are already committed.
The strongest Stripe Checkout fraud strategy is to score the request before you create the Checkout Session, then use the result to decide whether to allow, challenge, review, or block the customer. RequestGuard gives you that risk layer with IP reputation, email risk, domain intelligence, device signals, and behavior scoring in one API call.
Why Stripe Checkout Fraud Happens
Checkout fraud usually starts before the payment page. The suspicious signals often appear in the account, browser, email address, IP network, and event context:
- Disposable or synthetic email addresses
- Hosting, proxy, VPN, or Tor network traffic
- Country or timezone mismatch between user, payment, and fulfillment signals
- New domains or suspicious TLDs
- Repeated checkout attempts from the same session or subnet
- High-risk events such as trial abuse, coupon abuse, card testing, or reshipping orders
Payment authorization can tell you whether a card transaction was accepted. It does not always tell you whether the user, account, or session should be trusted. That is where a pre-checkout risk assessment helps.
Where RequestGuard Fits in a Stripe Checkout Flow
Place RequestGuard before the call that creates the Stripe Checkout Session:
- Collect the checkout context from your server request.
- Send the IP, email, domain, user agent, event name, and metadata to RequestGuard.
- Read the
decisionandrisk_score. - Create the Stripe Checkout Session only when the decision is acceptable.
- Add the RequestGuard request ID to your internal order record for review and support.
This keeps fraud logic in your own backend, so you can change thresholds without changing the payment form.
Example: Score Checkout Risk Before Creating a Session
import RequestGuard from "@requestguard/js";
const requestGuard = RequestGuard({
apiKey: process.env.REQUESTGUARD_API_KEY!,
});
export async function createCheckout(request: Request) {
const body = await request.json();
const ip =
request.headers.get("cf-connecting-ip") ||
request.headers.get("x-forwarded-for")?.split(",")[0]?.trim();
const userAgent = request.headers.get("user-agent") || undefined;
const assessment = await requestGuard.assess({
ip,
email: body.email,
domain: body.email?.split("@")[1],
userAgent,
event: "checkout",
userId: body.userId,
sessionId: body.sessionId,
billingCountry: body.billingCountry,
shippingCountry: body.shippingCountry,
metadata: {
cart_total: body.cartTotal,
currency: body.currency,
coupon: body.coupon,
product_count: body.items?.length,
},
});
if (assessment.decision === "block") {
return Response.json(
{
error: "Checkout cannot be completed.",
request_id: assessment.request_id,
},
{ status: 403 },
);
}
if (assessment.decision === "review" || assessment.decision === "challenge") {
return Response.json(
{
error: "Additional verification required.",
request_id: assessment.request_id,
},
{ status: 409 },
);
}
// Create your Stripe Checkout Session here after the risk decision is allowed.
// Store assessment.request_id with your order or customer record.
}
This pattern blocks obvious abuse before it reaches Stripe Checkout, while preserving a review path for suspicious but potentially legitimate customers.
Recommended Decision Policy
A practical checkout policy should avoid treating every signal as final. Use layered decisions:
| RequestGuard decision | Checkout action |
|---|---|
allow | Create the Stripe Checkout Session. |
challenge | Require email verification, CAPTCHA, or step-up confirmation first. |
review | Hold the order or route the customer to manual review. |
block | Do not create the Checkout Session. |
For digital goods, trial plans, gift cards, high-value orders, or instant fulfillment, use stricter thresholds. For low-risk physical goods, you may allow more transactions and review fulfillment later.
Signals to Send for Better Checkout Fraud Detection
RequestGuard works best when you send enough context to connect the checkout attempt to the account and session:
ip: The real client IP from your trusted edge or load balancer.email: The checkout or account email.domain: The email domain or company domain.userAgent: The browser user agent.event: Usecheckout,trial_checkout,subscription_signup, or another stable event name.userId: Your internal customer or account ID.sessionId: Your server-side session ID.billingCountryandshippingCountry: Useful for mismatch checks.metadata: Cart total, currency, coupon code, SKU category, account age, or retry count.
Do not send full card numbers, CVC codes, passwords, or other secrets. RequestGuard only needs fraud context.
Common Stripe Checkout Fraud Patterns
Card Testing
Card testers often run many low-value payment attempts through clean-looking checkout pages. RequestGuard can help identify repeated attempts from suspicious networks, disposable email domains, and automated user agents before they reach payment.
Trial and Coupon Abuse
Fraudsters use disposable inboxes and repeated account creation to reuse free trials or promotional coupons. Score the signup or checkout event, and require verification when the email, domain, IP, or session looks synthetic.
High-Risk Digital Fulfillment
Digital goods, API credits, software keys, and account upgrades are hard to recover after delivery. For these checkouts, block or review high-risk decisions before fulfillment and store the RequestGuard request ID with the order.
Reshipping and Proxy Purchases
Reshipping abuse often combines mismatch signals: unusual IP country, disposable email, new account, high cart value, and shipping/billing inconsistency. A checkout risk score lets you pause fulfillment even when the payment is authorized.
Add a Webhook Review Step
Pre-checkout scoring stops many bad sessions early, but you should also keep a post-payment review step for orders that are expensive, irreversible, or operationally risky.
Use your payment webhook to look up the stored RequestGuard result and decide whether to fulfill immediately, hold for review, or request additional verification. The important part is consistency: store the risk decision and request ID alongside the Stripe customer, checkout session, or order record in your own database.
Operational Checklist
- Score checkout requests before creating a Stripe Checkout Session.
- Block high-risk decisions before payment when fulfillment is instant or expensive.
- Challenge medium-risk sessions with email verification or CAPTCHA.
- Store the RequestGuard
request_idwith the order. - Review high-risk orders before fulfillment.
- Tune thresholds separately for trials, subscriptions, digital goods, and physical goods.
- Monitor false positives and add allow rules for trusted customers or partners.
Final Takeaway
Stripe Checkout handles the payment experience. RequestGuard handles the pre-checkout risk decision. Combining both gives you a cleaner fraud boundary: suspicious sessions can be challenged, reviewed, or blocked before they become payment disputes, support tickets, or fulfillment losses.
If your checkout flow already runs through your backend, adding RequestGuard is a small change: score the request, read the decision, and only create the Stripe Checkout Session when the risk is acceptable.