stripe aws lambda
Covers the common failure modes when a coding agent runs Stripe calls inside AWS Lambda: webhook signature mismatches from API Gateway body encoding, timeouts on synchronous payment confirmation, and duplicate webhook deliveries. Use when your Lambda-based payment flow misbehaves or you are hardening it before launch. Not for Stripe.js browser issues, raw server SDK debugging, or non-AWS serverless runtimes.
Stripe on AWS Lambda: webhooks, timeouts, and duplicate deliveries ("stripe aws lambda")
TL;DR
Almost every Stripe-on-Lambda failure falls into three buckets: API Gateway mangles the webhook body so signature verification fails, the default 3-second timeout kills in-flight Stripe API calls, and Lambda retries deliver the same webhook event twice. Raise the timeout to 30s, verify signatures against the raw unparsed body, and dedupe events by event id. Those three fixes solve the vast majority of agent-built Lambda payment flows.
stripe aws lambdaSteps
- Raise the function timeout to 30 seconds. Lambda's default is 3 seconds, and a single Stripe API call plus a cold start blows past it. Success check: no more
Task timed out after 3.00 secondsin CloudWatch during payment calls.
- Verify webhook signatures against the RAW body, not parsed JSON. API Gateway can re-serialize the payload, which breaks the signature. Configure the integration to pass the body through untouched and read the exact bytes received. Success check: signature verification passes both locally (via the Stripe CLI) and in production.
- Dedupe webhook events by event id. Stripe retries undelivered webhooks, and Lambda retries failed invocations, so double delivery is normal. Store processed event ids in your datastore and return 200 for repeats without re-running business logic. Success check: a replayed event returns 200 and creates no duplicate charge or fulfillment.
- Create the Stripe client once at module scope so warm invocations reuse it. Success check: warm-invocation latency drops and no new client setup appears in logs.
- Send an idempotency key derived from YOUR order id on every create call (payment intent, charge, refund). Success check: a retried Lambda invocation does not create a second payment intent.
When this applies
- A coding agent generated a Lambda-based Stripe integration that times out, rejects webhooks, or double-charges.
- You are hardening an existing serverless Stripe flow before launch.
- Webhook signature checks pass in local dev but fail after deploy.
When it doesn't
- Browser-side Stripe.js or Elements issues; those are a different layer.
- Debugging raw Stripe server SDK calls outside serverless.
- Non-AWS serverless runtimes, though the patterns (timeouts, raw body, dedupe) are similar.
Tool + version compatibility
Stripe API 2024-06 and later, stripe-node v14+ or stripe-python v7+, AWS Lambda Node.js 20 / Python 3.12 runtimes, API Gateway REST and HTTP APIs, Stripe CLI for local webhook testing.
"stripe webhook signature invalid lambda"
This is the raw-body problem from step 2. Check whether API Gateway or your framework parsed the body before the verification ran.
"stripe lambda task timed out"
Timeout fix from step 1. If it still times out after 30s, the Stripe call is hanging on network config (VPC with no NAT), not on Stripe.
"stripe duplicate charge lambda retry"
Dedupe plus idempotency keys (steps 3 and 5). Never rely on "it probably ran once."
Why it happens
Lambda's execution model (short-lived, automatically retried, payloads proxy-encoded by API Gateway) clashes with what Stripe expects: signatures computed over raw bytes, synchronous API calls that take a second or two, and at-least-once webhook delivery. Agent-generated code usually treats Lambda like an always-on server, so it misses all three.
Edge cases / pitfalls
- API Gateway HTTP APIs and REST APIs use different payload formats (1.0 vs 2.0). Body decoding must match your API type or signatures still fail.
- Returning a non-200 from a webhook handler triggers Stripe retries AND Lambda retries; always acknowledge before doing slow work, and do the slow work asynchronously.
- Provisioned concurrency fixes cold starts but changes nothing about signatures or dedupe.
- Test webhooks with the Stripe CLI forwarding to a local tunnel rather than hand-crafting payloads.
Provenance
Resolved from the public thread: https://vectle.com/posts/pstghWr8iakBD9RxXkCpS6XQ
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.