Stripe is the most widely used payment gateway for international transactions. This guide uses Stripe Checkout Sessions, the cleanest way to generate a dynamic, one-time payment URL to send to a customer on WhatsApp.
Stripe uses standard Bearer token auth, the same pattern as OpenAI and Mistral, so if you have connected an AI provider the auth step will feel familiar. The key difference is that the request body uses form encoding by default, though JSON also works with the right Content-Type header.
For WhatsApp, Stripe Checkout Sessions are better than Stripe Payment Links. A Checkout Session takes the amount and product details inline, returns a one-time hosted checkout URL, and expires after the customer completes or abandons the payment. That matches how WhatsApp transactions work: one customer, one order, one link.
New to the External API Request step? Read the foundation guide first.
Stripe test keys (sk_test_) do not process real payments. Use them while building and testing your flow. Switch to sk_live_ only when you are ready to accept real payments. The API endpoint is the same for both; only the key changes.
Stripe's v1 API accepts form-encoded request bodies by default, with Content-Type: application/x-www-form-urlencoded. Set Body Type to Form in the External API Request step. JSON bodies also work if you set Content-Type to application/json, but form encoding is the documented default for Stripe v1.
https://api.stripe.com/v1/checkout/sessions| Field | Value | Notes |
|---|---|---|
| mode | payment | For one-time payments |
| line_items[0][price_data][currency] | inr | Currency code |
| line_items[0][price_data][product_data][name] | {{product_name}} | Name of what is being paid for |
| line_items[0][price_data][unit_amount] | {{amount_paise}} | Amount in smallest unit (paise for INR) |
| line_items[0][quantity] | 1 | Usually 1 per transaction |
| success_url | https://yoursite.com/success | Customer lands here after paying |
| cancel_url | https://yoursite.com/cancel | Customer lands here if they abandon |
amount is in paise for INR (multiply rupee amount by 100). Map {{product_name}} and {{amount_paise}} from your flow.
{
"id": "cs_test_...",
"object": "checkout.session",
"url": "https://checkout.stripe.com/pay/cs_test_...",
"status": "open",
"expires_at": 1718999999,
"amount_total": 50000,
"currency": "inr"
}Map the url field into the next WhatsApp message step. The message might read: 'Please complete your payment here: {{payment_url}}. This link expires in 24 hours.' The customer taps the link and pays on Stripe's hosted checkout page.
| Symptom | Likely cause | Fix |
|---|---|---|
| 401 Unauthorized | Wrong or missing secret key | Confirm the Authorization header starts with Bearer sk_ and the key is complete |
| 400 Bad Request | Missing required fields | Ensure mode, line_items, success_url, and cancel_url are all present |
| Amount confusion | amount not in paise | Multiply rupee amount by 100; Rs 500 becomes 50000 in the request |
| Session expired link | Checkout session URL expired | Sessions expire after 24 hours; generate a new session if the customer needs more time |
| Indian card declined | Stripe India requires additional fields for some cards | Check Stripe's India documentation for any RBI mandate requirements on domestic transactions |
Free trial, no credit card required. And if you ever get stuck, we are the only platform in India that answers you live on WhatsApp.