Bonaventure OgetoBy Bonaventure Ogeto|

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 PromptBetter 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 use req.body directly (as Buffer).
  • Amount in NGN not kobo — Claude sometimes generates amount: product.price where 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.

Sign up for the McTaba newsletter

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