When statement_descriptor or statement_descriptor_suffix is omitted, charges fall back to the Stripe account's legal name — often a holding company or DBA that the customer does not recognize on their bank statement. Unrecognized line items drive chargebacks filed as 'fraudulent transaction' even when the purchase was legitimate, and excess chargeback ratios escalate Stripe Radar risk scoring, raise processing fees, and can trigger account review. This hits the user-experience and content-integrity taxons directly: the customer sees a string they cannot tie back to your store, and the dispute is decided against you regardless of delivery proof.
Low because the issue surfaces as chargeback friction and post-purchase confusion rather than data loss or takeover.
Set a recognizable descriptor on every paymentIntents.create or charges.create call so the value rendered on the bank statement matches the brand the customer transacted with. Keep it between 5 and 22 characters, use only the allowed character set (letters, numbers, space, -, ., ', &), and prefer statement_descriptor_suffix when the Stripe account prefix is already the storefront name. Apply this in src/lib/stripe/createPaymentIntent.ts:
await stripe.paymentIntents.create({
amount,
currency: 'usd',
statement_descriptor_suffix: 'GARDEN SHOP',
})
ID: ecommerce-payment-security.payment-errors.statement-descriptors
Severity: low
What to look for: Count all payment intent or charge creation calls. For each, check for the statement_descriptor or statement_descriptor_suffix parameter. Quote the descriptor value if present. If omitted, the descriptor defaults to the Stripe account name, which may be an internal business name that customers do not recognize. Descriptors must be between 5 and 22 characters.
Pass criteria: Payment charges include a statement_descriptor or statement_descriptor_suffix that clearly identifies the business and is between 5 and 22 characters. The descriptor is recognizable to a customer scanning their bank statement (matches the store name or product type).
Fail criteria: No statement_descriptor is set on charge calls, and the Stripe account name is not a clearly recognizable customer-facing business name. Or the descriptor is set to a cryptic internal identifier.
Skip (N/A) when: The project uses a hosted checkout page where the statement descriptor is configured at the Stripe account level, and the account name is confirmed to be the correct customer-facing name.
Detail on fail: Describe the missing or unclear descriptor. Example: "stripe.paymentIntents.create() calls do not include statement_descriptor — customers will see the Stripe account name 'ACME LLC HOLDING CO' which is not recognizable as the store name 'GardenSupplyShop'"
Remediation: Set a clear statement descriptor on every charge:
const paymentIntent = await stripe.paymentIntents.create({
amount,
currency: 'usd',
statement_descriptor_suffix: 'GARDEN SHOP', // Up to 22 chars, no special chars
// or at the account level: statement_descriptor: 'GARDENSUPPLYSHOP'
})
Rules for Stripe statement descriptors:
-, ., ', &<, >, ", \