Generating Paystack Integration Code with Claude Code
Claude Code generates accurate Paystack boilerplate when you specify: 1) Your stack (Next.js App Router, Express, Django). 2) What you need (one-time checkout, subscription, split payment, transfer). 3) Explicit security requirements: "verify HMAC signature on webhooks using raw body", "fetch price server-side from database, not from request", "use idempotency key on transfers". Always verify: HMAC validation uses x-paystack-signature and raw body; amounts are in kobo (NGN amount × 100); secret key loads from environment variable, not hardcoded; webhook returns 200 before processing.
Prompts That Generate Correct Paystack Code
The more context you give, the better the output. Compare these prompts:
| Weak Prompt | Better Prompt |
|---|---|
| "Add Paystack to my Next.js app" | "Add Paystack checkout to my Next.js 14 App Router app. Needs: 1) Server action to initialize transaction (fetch product price from Prisma — do not trust client amount). 2) Webhook handler at /api/webhooks/paystack that validates HMAC signature using raw request body and x-paystack-signature header, verifies payment via GET /transaction/verify/:ref, updates order status in Prisma, returns 200 immediately. 3) Use PAYSTACK_SECRET_KEY from env. Include idempotency check to handle duplicate webhooks." |
| "Write a Paystack webhook" | "Write an Express webhook handler for Paystack charge.success events. Must: validate x-paystack-signature HMAC-SHA512 using raw body (not req.body), check for duplicate references in DB before processing, update order to 'paid', return 200 before database writes. Load secret from process.env.PAYSTACK_SECRET_KEY." |
| "Add subscriptions" | "Add Paystack subscription creation to my Express API. Customer provides email and plan_code. Server calls POST /subscription with customer email and plan_code. Return subscription_code and email_token to client. Handle the charge.success webhook to mark subscription as active. Include the subscription disable flow (POST /subscription/disable) for cancellation." |
After generation, run this review checklist:
// Generated code review checklist — verify each item
var checklist = [
'HMAC uses crypto.createHmac("sha512", secret).update(rawBody).digest("hex")',
'rawBody collected as Buffer before JSON parsing',
'Compares against req.headers["x-paystack-signature"]',
'Amount in kobo: ngn_amount * 100',
'Price fetched from DB, not from req.body.amount',
'Duplicate reference check before processing',
'Returns res.sendStatus(200) before async processing',
'Secret key: process.env.PAYSTACK_SECRET_KEY (not hardcoded)',
'HTTPS webhook URL (not HTTP)',
];
Common Mistakes in AI-Generated Paystack Code
- Parsing body before HMAC — Claude Code sometimes writes
const sig = req.headers['x-paystack-signature']; const body = JSON.stringify(req.body). This is wrong — HMAC must be computed on the raw byte buffer, before JSON parsing. Verify:app.use('/api/webhook', express.raw({ type: 'application/json' }))and usereq.bodydirectly (as Buffer). - Amount in NGN not kobo — Claude sometimes generates
amount: product.pricewhere price is in NGN. Paystack expects kobo:amount: product.price_ngn * 100. - Missing idempotency check — Paystack can deliver the same webhook twice. Generated code often processes the event without checking if the reference was already processed.
- Using deprecated endpoints — Claude's training data may reference older Paystack API endpoints. Verify endpoint paths against current Paystack documentation, especially for newer features like bulk transfers (POST /transfer/bulk).
Learn More
See reviewing AI-generated payment code for the full checklist after generation.
Key Takeaways
- ✓Specify your stack, your use case, and explicit security requirements in the prompt — do not leave these to inference.
- ✓Always verify HMAC webhook validation uses raw body (not parsed JSON) and the x-paystack-signature header.
- ✓Verify amounts are in kobo — Claude Code sometimes uses NGN amounts directly without ×100 conversion.
- ✓Never use generated code with a hardcoded secret key — always load from environment variable.
- ✓Test the generated webhook handler against a real Paystack test event before deploying.
Frequently Asked Questions
- Is it safe to paste my Paystack test key into Claude Code for testing generated code?
- No — do not paste any Paystack key (test or live) into Claude Code. Instead, add your keys to a .env file in your project and reference process.env.PAYSTACK_SECRET_KEY in the generated code. Claude Code can read your environment setup from CLAUDE.md or project context without needing to see the actual key values. If you have already pasted a key, rotate it immediately from the Paystack dashboard.
- Can I ask Claude Code to update code after a Paystack API change?
- Yes — describe the specific change: "Paystack has deprecated /charge/tokenize in favor of /charge. Update the tokenization flow in src/payments/charge.ts to use the new endpoint and payload format." Provide the new API spec or documentation link as context. Generated updates should go through the same review checklist as initial generation.
- How do I verify the generated HMAC validation is correct?
- Use Paystack's webhook simulator in the dashboard (Settings → API Keys → Test Webhooks) to send a real charge.success event to your local server via ngrok. If the HMAC validation rejects a real Paystack event, the generated validation code is wrong. Specifically test with both a valid signature (should pass) and a manually modified body (should fail) to verify both paths.
Ready to build real-world apps?
Join the McTaba Labs full-stack marathon (4 months full-time · 6 months part-time). Learn M-Pesa, USSD, and WhatsApp engineering while shipping 8 production apps.
Apply to the McTaba Marathon