PayFast is the payment gateway most South African online businesses land on eventually. Xero is where most of those same businesses run their books. The problem: there is no native integration between the two. PayFast payments don't appear in Xero automatically, which means every payment either gets entered manually or sits unrecorded until someone catches it at month-end.
This guide explains how PayFast webhooks work, what you can build on top of them, and what a working PayFast-to-Xero automation looks like in practice.
Why there's no built-in connection
PayFast doesn't have a Xero integration in its dashboard. Xero doesn't list PayFast as a supported payment service in its app marketplace. Both platforms have APIs, but neither has built the connection to the other — which is common for SA-specific platforms that haven't reached the scale where Xero's integration partners prioritise them. (Yoco has the same gap — if you use both payment gateways, see the Yoco-to-Xero integration guide.)
The way to connect them is through PayFast's webhook system — specifically the Instant Transaction Notification (ITN) — which fires every time a payment event occurs on your PayFast account.
How PayFast ITN webhooks work
When a customer completes a payment through PayFast, PayFast sends an HTTP POST request to a URL you specify. This is the ITN. It fires in the background, regardless of whether the customer lands on your thank-you page.
The ITN payload contains everything you need to create a Xero record:
pf_payment_id— PayFast's unique reference for the transactionpayment_status— COMPLETE, FAILED, PENDING etc.amount_gross— the amount the customer paiditem_name— the product or descriptionemail_address— the buyer's emailcustom_str1throughcustom_str5— fields you can use to pass your own references (invoice numbers, order IDs, customer codes)merchant_payment_id— your own payment reference if you set one
The most important of these is payment_status. You only want to create Xero records for COMPLETE transactions — not pending or failed ones.
What "automatically recorded in Xero" can mean
There are a few different things this can mean, depending on your business model:
Option 1: Create a Xero invoice and mark it paid
If your workflow is: raise Xero invoice → send to customer → customer pays via PayFast — then the automation should match the PayFast payment to the existing Xero invoice and apply the payment. This keeps your invoice workflow intact and handles the reconciliation automatically.
Option 2: Create a Xero payment directly (no pre-raised invoice)
If you're selling via a website and raising invoices in Xero after the fact, the automation can create a bank transaction in Xero directly — recording the payment amount, date, and description without needing a pre-existing invoice to match against.
Option 3: Create the invoice and apply the payment in a single step
If you're running a simple online store and Xero isn't involved until after payment, the automation can create the invoice and apply the payment in a single workflow triggered by the ITN.
Which option is right depends on your accounting process. Most businesses are better served by Option 1 or 3.
How to build the integration
The ITN URL in your PayFast account settings needs to point to something that can receive the POST, validate it, and then call the Xero API. The most practical tool for this is n8n.
The workflow structure
Step 1 — Receive the webhook
n8n has a Webhook node that creates a URL you can set as your PayFast ITN URL. When PayFast fires the ITN, n8n receives the payload.
Step 2 — Validate the payment status
Add an IF node: if payment_status equals COMPLETE, continue. If not, stop or log the event without creating a Xero record.
Step 3 — Validate the PayFast signature
PayFast includes an m_payment_id and a signature hash in the ITN that you should verify before taking any action. This prevents fraudulent requests from outside PayFast hitting your webhook URL and triggering false Xero records. The validation logic is straightforward — PayFast's documentation covers it — and can be handled in an n8n Code node.
Step 4 — Look up or create the Xero contact
Use the Xero API node in n8n to look up whether a contact already exists for the email_address in the ITN. If they exist, use that contact. If not, create them. This keeps your Xero contacts clean.
Step 5 — Create the Xero record
Depending on which option above fits your workflow, either:
- Create a new invoice and apply a payment to it
- Create a bank transaction against your PayFast bank account in Xero
- Search for an existing invoice by your
merchant_payment_idorcustom_str1reference and apply the payment
Step 6 — Handle errors
Add error handling so failed API calls don't silently drop records. n8n can send a Slack or email notification if any step in the workflow fails, so you can investigate and re-run rather than discovering missing records at month-end.
Setting up the PayFast webhook URL
In your PayFast merchant dashboard:
- Go to Settings → Merchant Profile
- Find the Notify URL field
- Enter your n8n webhook URL
If you're using PayFast's payment button or a hosted checkout, you can also pass the notify URL per-transaction. For integration with platforms like WooCommerce or a custom checkout, the notify URL is typically set in the plugin or payment configuration.
The PayFast bank account in Xero
PayFast holds funds before paying them out to your bank account. This means you'll likely have two accounts to track in Xero: a PayFast clearing account (where incoming payments land) and your actual bank account (where PayFast payouts arrive).
The cleanest approach is to set up a PayFast bank account in Xero and record all incoming customer payments against it. When PayFast pays out to your FNB, Nedbank, or Standard Bank account, you record that as a transfer from the PayFast account to your bank account. This keeps your reconciliation clean and lets you see exactly what's sitting in PayFast at any point.
What you'll need before building this
- A PayFast merchant account with ITN access (available on standard accounts)
- A Xero account with API access (available on all paid Xero plans)
- n8n — either self-hosted or a cloud instance
- A Xero OAuth 2.0 app configured in the Xero developer portal to generate API credentials
The Xero API setup takes 20–30 minutes if you haven't done it before. n8n's Xero integration handles OAuth token refresh automatically once configured.
What this looks like in practice
Once built, the workflow runs in the background without any manual steps. A customer pays via PayFast → within seconds, n8n receives the ITN → validates the payment → creates or updates the Xero record. By the time you check Xero at the end of the day, every PayFast payment is already there.
The main ongoing maintenance point is the Xero OAuth token, which expires periodically. n8n handles token refresh automatically, but if the n8n-to-Xero connection is ever revoked (usually because Xero credentials are rotated), you'll need to re-authorise it.
Some links in this guide are affiliate links. If you sign up through them, Gainly may earn a commission — at no cost to you. We only recommend tools we'd recommend regardless.
Need this built for your business?
Describe what you're working with and I'll come back with something specific — not a sales call.
Tell me what you're dealing with →