Bonaventure OgetoBy Bonaventure Ogeto|

Penetration Testing Checklist for Payment Flows

Run these checks on your Paystack integration: (1) price tampering — can you modify the amount in the initializeTransaction request and have it accepted? (2) webhook spoofing — does your handler reject requests without a valid x-paystack-signature? (3) reference replay — does sending the same reference twice to your verify endpoint trigger double fulfillment? (4) IDOR on payment endpoints — can user A fetch user B's transaction details? (5) secret key in source — does your frontend bundle or public files contain the secret key? (6) missing rate limits — can you spam the checkout endpoint without triggering a 429?

Paystack Payment Flow Penetration Testing Checklist

1. Price Tampering (Critical)

Intercept the request from your checkout page to your backend that triggers POST /transaction/initialize. Modify the amount field to NGN 1. Does your backend use the client-supplied amount, or does it read the amount from your own database (order record)?

Pass: Backend ignores client-supplied amount, reads from DB. Fail: Backend passes client amount to Paystack.

2. Webhook Signature Bypass (Critical)

Send a POST request to your webhook endpoint with a valid-looking JSON body but no x-paystack-signature header (or a wrong signature). Does your handler process it?

Pass: Handler returns 401/400 immediately. Fail: Handler processes the event.

3. Reference Replay (High)

Call your payment verification endpoint twice with the same reference. Does the second call fulfill the order again?

Pass: Idempotency check prevents double fulfillment. Fail: Order is fulfilled twice.

4. IDOR on Transaction Endpoints (High)

Log in as User A. Find a transaction reference belonging to User B (e.g., from a shared link). Call your GET /api/orders/:reference endpoint authenticated as User A. Does it return User B's order?

Pass: Returns 403 or 404. Fail: Returns User B's payment data.

5. Secret Key Exposure (Critical)

Search your deployed frontend bundle: curl https://yoursite.com/assets/main.js | grep -i "sk_live_". Also check public environment files, GitHub repos, and Vercel/Netlify build logs.

Pass: No secret key in any public files. Fail: Secret key found — rotate immediately.

6. Rate Limiting on Checkout (Medium)

Send 20 rapid POST requests to your checkout initiation endpoint from the same IP. Are requests throttled after your threshold?

Pass: 429 responses after threshold. Fail: All 20 requests succeed.

7. Webhook Event Type Trust (Medium)

Send a webhook with a valid signature but with event: "charge.success" and an amount lower than the expected order amount. Does your handler check that the amount matches the expected order amount?

Pass: Handler verifies amount matches order. Fail: Handler fulfills on event type alone.

8. Transfer Authorization (High)

If you have a payout endpoint, test whether it requires proper authentication and authorization — can any authenticated user trigger a transfer, or only users with the correct role?

Learn More

Key Takeaways

  • Test price tampering: intercept the initializeTransaction call and change the amount — your backend must set the amount, not trust the client.
  • Test webhook spoofing: send a fake charge.success webhook without the x-paystack-signature header — your handler must reject it with 401.
  • Test reference replay: verify the same transaction reference twice — your system must fulfill the order only once.
  • Test IDOR on payment endpoints: attempt to fetch another user's payment details using a known reference — must return 403.
  • Check for secret key exposure: search your deployed frontend bundle and public files for "sk_live_" patterns.
  • Test rate limiting: send 20 rapid checkout requests from the same IP — you should receive 429 responses after your threshold.

Frequently Asked Questions

Do I need Paystack's permission to pen test my integration?
You need permission to test Paystack's own infrastructure — do not run automated scans against api.paystack.co without prior authorization from Paystack. However, pen testing your own application code (your backend, your checkout page, your webhook handler) does not require Paystack's permission. Focus tests on your code, not on Paystack's systems.
Which OWASP Top 10 items apply most to payment integrations?
The most relevant for Paystack integrations: A01 (Broken Access Control) — IDOR on payment endpoints; A02 (Cryptographic Failures) — secret key exposure; A03 (Injection) — in payment metadata fields; A05 (Security Misconfiguration) — missing webhook signature validation; A07 (Identification and Authentication Failures) — missing auth on payout endpoints.
How do I test webhook security without real Paystack events?
Use the Paystack test dashboard webhook simulator to send real test events. For security tests (missing signature, wrong signature), use curl: send a POST to your webhook URL with a JSON body and missing or incorrect x-paystack-signature header. Your handler should reject it without processing.
Should I use automated scanning tools on my payment endpoints?
Yes — tools like OWASP ZAP or Burp Suite Community Edition can find common vulnerabilities in your payment endpoints. Run them against your staging environment, not production. Configure them to avoid actually completing real payments — test mode Paystack keys help here.

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