PayFast ITN (Webhook) not updating Bubble database – always getting 400/401 errors

Hi everyone :waving_hand:
I’m integrating PayFast (South Africa) with my Bubble app, and I’m struggling to get the Instant Transaction Notification (ITN) working correctly.

My setup is as follows:

  • I’m using PayFast Sandbox

  • My app’s notify_url points to
    https://myappname.bubbleapps.io/version-test/api/1.1/wf/payfast_ipn

  • The payment page redirects correctly to PayFast, but when the sandbox sends the ITN back to Bubble, I get HTTP 400 or 401 errors and my database is not updating.


My Backend Workflow Configuration

  • Endpoint name: payfast_ipn

  • Expose as public API workflow :white_check_mark:

  • Run without authentication :white_check_mark:

  • Ignore privacy rules :white_check_mark:

  • Trigger with: POST

  • Parameter definition: Manual definition

Parameters:

payment_status (text)
amount_gross (text)
pf_payment_id (text)
custom_str1 (text)
item_name (text)
merchant_id (text)
signature (text)

Workflow Steps:

  1. Make changes to Order

    • Search for order where order_id = custom_str1

    • Update fields:

      • Payment_Status = payment_status

      • amount_gross = amount_gross

      • pf_payment_id = pf_payment_id

      • Payment_date = Current date/time

  2. Return data from API

    • status = success

What I See in PayFast Sandbox

  • ITN Payload shows the correct data (e.g. payment_status=COMPLETE, custom_str1=20251009081006, etc.)

  • ITN Response:

    HTTP/1.1 400 Bad Request
    or
    HTTP/1.1 401 Unauthorized
    
    
  • My Bubble database table (Orders) remains unchanged.


What I’ve Tried

  • Confirmed that the notify_url starts with https

  • Changed all parameter types to text

  • Confirmed backend workflow is deployed and public

  • Added a “Return data from API” step with status=success


What I Need Help With

  1. Is my Bubble backend workflow configuration correct for PayFast ITN (form-urlencoded POST)?

  2. Do I need to configure something special to handle PayFast’s POST format?

  3. Why does PayFast return 400/401 even though the endpoint is accessible?

Goal

When PayFast sends the ITN, Bubble should update the corresponding “Order” record (based on custom_str1) and store the payment_status, pf_payment_id, and amount_gross.

400 is a bad encoding or missing parameters

401 is wrong authorization header (or missing)

You can remove the checbox for authorization

After, check your parameters set (and maybe check optionnal if some values could be missing)

You should share screenshot of your endpoint setting

Dear , thank you for your help finally got it to work. The issue was the missing parameters has you previous mentioned.

1 Like