To type a Stripe API payload, paste the JSON object (a PaymentIntent, Charge, or a webhook event's data.object) into PayloadIQ and it generates TypeScript interfaces, a Zod schema, and a typed client — all in your browser, with nothing uploaded. Stripe objects are deeply nested and full of optional and nullable fields, which is exactly where generated types save you from guesswork.
Example Stripe PaymentIntent
A trimmed PaymentIntent — the shape you get back from stripe.paymentIntents.create or a payment_intent.succeeded webhook:
{
"id": "pi_3MtwBwLkdIwHu7ix28a3tqPa",
"object": "payment_intent",
"amount": 2000,
"amount_received": 2000,
"currency": "usd",
"status": "succeeded",
"customer": "cus_NhD8HD2bY8dP3V",
"payment_method": "pm_1MtwBwLkdIwHu7ixABCDEF",
"payment_method_types": ["card"],
"created": 1680800504,
"livemode": false,
"metadata": { "order_id": "6735" },
"latest_charge": "ch_3MtwBwLkdIwHu7ix1Fas4uVZ"
}What you get back
PayloadIQ infers a PaymentIntent interface (with the right string, number, and nested metadata types), a matching Zod schema you can use to validate webhook bodies at the edge, and a typed fetch client. Paste two payloads — say a v1 and a v2 of the object — and it reports the breaking changes between them, which is handy when Stripe evolves an API version.
Why browser-local matters here
Payment payloads are sensitive. Because every transform runs in your browser and nothing is uploaded, you can safely paste real (test-mode) Stripe objects without sending customer or charge data to a third-party server.