Key Takeaways
POPIA applies to virtually every WordPress site run by a South African business or charity, regardless of how small the site is
Most SA WordPress sites are not compliant. Common gaps: no cookie consent, no privacy policy linked at the consent point, no documented data retention, contact form data emailed to personal Gmail accounts
The Information Regulator can issue fines up to R10 million and the law gives data subjects the right to sue for damages directly
WordPress out-of-the-box collects personal information through comments, forms, analytics, and any plugin that tracks visitors. Each of those needs a lawful basis
POPIA compliance is mostly a documentation and consent problem, not a technical one. Getting the documentation right is the harder part
What POPIA is, in the shortest possible form
POPIA is the Protection of Personal Information Act, 2013. It came into full force in mid-2021. It applies to any business or organisation in South Africa that processes personal information, and to organisations outside South Africa that process personal information about South African data subjects.
Personal information under POPIA is broad. It covers names, contact details, identity numbers, financial information, biometric data, opinions about a person, and anything else that identifies a living natural person or an existing juristic person (a registered business). If your WordPress site collects any of that, POPIA applies.
This post is the practical version of what we tell SA WordPress site owners when they ask what they need to do. It covers the technical and configuration layer. It does not cover everything a privacy lawyer would (we are not lawyers), and for anything significant you want a lawyer involved.
The compliance gap most SA WordPress sites have
When we audit South African WordPress sites for performance and security, we usually find the same POPIA gaps. None of them are exotic. All of them are fixable in a day or two of focused work.
The most common gaps, in roughly the order we find them:
- No cookie consent layer. The site loads Google Analytics, Facebook Pixel, and a chat widget before any consent is gathered.
- A "privacy policy" page that is a generic template copied from a US-focused source, never reviewed for POPIA, last updated three years ago.
- Contact form submissions emailed to a personal Gmail account with no record of retention, no documented purpose, no way for a data subject to request deletion.
- WooCommerce account data retained indefinitely, including customers who haven't ordered in five years, with no policy on retention or deletion.
- No documented lawful basis for any of the processing. The site collects names and emails because the form has those fields. No-one ever wrote down why or under what condition.
- No breach response plan. If the site is hacked and customer data leaks, no-one knows who to notify, in what timeframe, or how.
None of these is hard to fix. The blocker is usually that nobody has owned the problem internally. Below is the workable order of operations.
Step 1: register an Information Officer
Under POPIA, every responsible party (which is what the Act calls the organisation processing personal information) must designate an Information Officer. By default this is the head of the business: the CEO for a company, the head of a public body, the senior partner of a firm.
The Information Regulator maintains a register and you are required to register your Information Officer with them. This is a free, online process. It takes about 20 minutes.
https://www.justice.gov.za/inforeg/
The single most common compliance gap we see is sites that have done none of this. Registering is free, mandatory, and quick. It also serves as a forcing function: once you have registered, you are formally on the hook.
Step 2: get the cookie consent layer right
WordPress, by default, sets a small number of strictly-necessary cookies (session cookies for logged-in users, comment cookies, WooCommerce cart and session cookies). Those do not require consent.
The cookies that do require consent:
- Google Analytics (or any analytics tool)
- Google Tag Manager
- Facebook Pixel
- LinkedIn Insight Tag
- Hotjar, Microsoft Clarity, or any heatmap tool
- Live chat widgets that track visitor behaviour
- Marketing automation cookies (Mailchimp, HubSpot, ActiveCampaign)
- Affiliate tracking pixels
- Any third-party embed that sets cookies (YouTube, Vimeo with cookie tracking, X/Twitter, Instagram)
The plugin landscape for cookie consent in WordPress is wide. We have used and recommend:
- CookieYes, a paid plugin with reasonable free tier, properly handles consent categories and respects POPIA-style consent requirements.
- Complianz, a privacy compliance plugin that does both POPIA and GDPR, with country-aware behaviour.
- Cookie Notice & Compliance, lighter weight, fine for simple sites.
The technical requirement, regardless of plugin, is that no non-essential cookies fire before consent is given. This is the part most plugins handle correctly in their paid tiers and incorrectly in their free tiers.
Implementing consent mode for Google Analytics
If you use Google Analytics 4, the correct technical implementation is Google's Consent Mode v2. This tells GA4 to wait for consent before firing the tracking pixels, and to use cookieless modelling for users who decline.
<!-- Before the GA4 script loads -->
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
// Default to denied, before any consent decision
gtag('consent', 'default', {
'ad_storage': 'denied',
'analytics_storage': 'denied',
'ad_user_data': 'denied',
'ad_personalization': 'denied',
'wait_for_update': 500,
});
</script>
<!-- After the user consents, fire: -->
<script>
gtag('consent', 'update', {
'analytics_storage': 'granted',
});
</script>Most consent plugins emit those gtag calls for you when configured. The thing to verify is that they emit them in the right order: the default call must execute before the GA4 snippet, otherwise GA4 fires before the consent gate kicks in.
This is one of the most common implementation errors we find in audits. The plugin is installed. The settings look correct. But the script order is wrong, GA4 fires before consent, and the consent layer is theatre.
Step 3: privacy policy that is actually yours
POPIA requires that you tell data subjects what you collect, why, who you share it with, how long you keep it, and how they can exercise their rights. A copy-pasted generic privacy policy from a US template does not meet that requirement.
The privacy policy needs to specifically describe:
- What information your site collects (contact forms, WooCommerce checkout, account registration, comments, newsletter signup, analytics)
- The lawful basis for each (consent for marketing, legitimate interest for analytics, contract performance for order fulfilment)
- Who you share it with (your email provider, your CRM, your payment gateway, Google for analytics)
- How long you keep it (with specific retention periods, not "as long as necessary")
- The rights of the data subject (access, correction, deletion, objection, complaint to the Regulator)
- Your contact details and your Information Officer's contact details
The privacy policy needs to be linked from every consent gate. The cookie banner should link to it. The contact form should link to it. The newsletter signup should link to it. The WooCommerce checkout should link to it.
We typically write the privacy policy as a working document the site owner can maintain themselves, rather than as a once-off legal artifact that goes stale within a year.
Step 4: contact forms done properly
Most SA WordPress sites collect personal information through contact forms and do nothing about the consent or retention side.
The technical requirements for a POPIA-compliant contact form:
- A consent checkbox the user must actively tick (not pre-ticked). The consent text should reference the privacy policy and the specific purpose of the data collection.
- A documented retention period for form submissions. If you are storing them in the WordPress database via a plugin like WPForms or Gravity Forms, you need a policy on how long they stay and a process to delete them.
- A documented destination for the data. If form submissions go to a personal Gmail account, that is a problem (Gmail is a Google product hosted internationally, which raises cross-border transfer questions). Forwarding to a corporate email account hosted on a properly contracted service is the cleaner pattern.
- A way for the data subject to request access, correction, or deletion. This usually means an email address dedicated to privacy requests, with an actual person who handles them.
// Example: a small mu-plugin to enforce POPIA-compliant
// retention on Contact Form 7 submissions stored by
// Flamingo (CF7's logging companion plugin).
// Runs daily via cron, deletes records older than 12 months.
add_action( 'init', function() {
if ( ! wp_next_scheduled( 'popia_purge_old_form_submissions' ) ) {
wp_schedule_event( time(), 'daily', 'popia_purge_old_form_submissions' );
}
});
add_action( 'popia_purge_old_form_submissions', function() {
$cutoff = strtotime( '-12 months' );
$old_submissions = get_posts( array(
'post_type' => 'flamingo_inbound',
'date_query' => array(
array( 'before' => date( 'Y-m-d', $cutoff ) ),
),
'posts_per_page' => 500,
'fields' => 'ids',
));
foreach ( $old_submissions as $id ) {
wp_delete_post( $id, true );
}
});The exact retention period (12 months in the example above) should match what your privacy policy says. If your policy says "we retain enquiries for 12 months", the cleanup needs to enforce that. If you say "indefinitely", you need to defend why indefinitely is necessary, and POPIA's minimality principle says you usually cannot.
Step 5: WooCommerce customer data retention
WooCommerce keeps customer accounts and order data forever by default. POPIA says you may only keep personal information for as long as is necessary to fulfil the purpose for which it was collected, plus any period required by other laws.
For SA WooCommerce stores this typically means:
- Order and customer data: retain for the period required by SARS for tax records (currently 5 years from the end of the tax year in which the transaction occurred).
- Customer accounts with no orders for X years: delete or anonymise.
- Abandoned cart data: short retention, typically 30-90 days.
- Marketing contact lists: only as long as consent is current.
WooCommerce ships with privacy tools under WooCommerce > Settings > Accounts & Privacy that automate some of this. The retention thresholds default to blank, which means nothing gets deleted. We typically configure them to:
- Inactive accounts: trash after 24 months of inactivity, delete after 30 months.
- Failed orders: trash after 30 days, delete after 60 days.
- Cancelled orders: trash after 90 days, delete after 180 days.
- Completed orders: never trashed automatically (SARS requires 5-year retention).
Then, separately, a yearly cron job archives or anonymises completed orders older than 5 years.
Step 6: cross-border data transfers
Section 72 of POPIA restricts cross-border transfers of personal information. You can transfer SA data subjects' personal information to another country only if certain conditions are met (data subject consent, contractual safeguards, comparable privacy law in the destination country, etc.).
In WordPress practice, this affects almost every site, because almost every WordPress site uses some combination of:
- Google Analytics (US servers)
- Mailchimp or similar email platform (US servers)
- Cloudflare CDN (global edge)
- A backup service like UpdraftPlus to Amazon S3 (US servers)
- A CRM like HubSpot or Salesforce (US servers)
- A hosting provider with international data centres
Each of these is a cross-border transfer. The compliant path is to:
- Document which third parties receive personal information and where they process it.
- Have appropriate contractual safeguards in place (most major providers offer Data Processing Addendums that you can sign electronically).
- Disclose these transfers in your privacy policy.
Most SA sites have done none of these and are technically non-compliant. The Information Regulator has so far not pursued enforcement on this point against small businesses, but the legal exposure is real.
Step 7: breach response
POPIA requires that you notify the Information Regulator and the affected data subjects of any "compromise" of personal information, as soon as reasonably possible. There is no formal 72-hour deadline like GDPR has, but the standard is "as soon as reasonably possible after the discovery of the compromise".
You need a written breach response plan that covers:
- Who is notified internally when a breach is suspected
- Who decides whether it qualifies as a notifiable compromise
- How notification to the Regulator is filed
- How notification to data subjects is done (the Regulator may prescribe how)
- Documentation of what happened and what was done
For WordPress sites specifically, the most common breach scenarios are:
- Site compromise via a vulnerable plugin
- Database leak via a backup left in a publicly accessible location
- Customer data leak via a misconfigured WP REST API endpoint
- Credential leak via a phishing attack against a WordPress admin
- Third-party breach (your email provider, your CRM, your CDN) that exposes data you transferred to them
For each, the technical detection layer matters. If you do not know the site has been compromised, you cannot notify within a reasonable time. We typically install file-integrity monitoring, login alerting, and outbound traffic monitoring on production sites so that compromise is detected within hours, not weeks.
What we'd recommend, ordered by risk reduction per hour spent
If you have not started, the order we'd recommend is:
- Register your Information Officer with the Regulator. 20 minutes, free, mandatory.
- Install and properly configure a cookie consent plugin with consent-mode integration for GA4. Half a day, including testing.
- Rewrite the privacy policy to specifically describe your site's data flows. A day with input from whoever runs the business.
- Add consent checkboxes to all contact forms, newsletter signups, and account registrations. A few hours.
- Configure WooCommerce retention policies. Half a day.
- Document cross-border transfers and sign DPAs with major processors. A day or two of paperwork.
- Write a breach response plan. Half a day.
- Implement security monitoring sufficient to detect a compromise within 24 hours. This overlaps with general WordPress security work and is something we do as part of our maintenance retainers.
Most SA WordPress sites can get to a defensible POPIA position in 2-4 days of focused work plus an ongoing few hours a month to keep it current.
What we'd not recommend
We have seen a few patterns we'd avoid:
- Buying a generic compliance package from an online template provider. The privacy policy will not match your actual data flows and the cookie banner will set cookies before consent.
- Ignoring it on the basis that "we are small and the Regulator won't bother us". The Regulator's enforcement curve is steepening. More importantly, your customers can sue you directly for damages, which does not require the Regulator to act.
- Treating POPIA as a once-off project. Compliance is ongoing. Plugin choices change, third-party processors change, retention rules need yearly review.
- Hiding behind a token cookie banner that visitors click without reading. The Regulator's guidance is that consent must be informed and specific. Generic "accept all" buttons that bury the alternatives are not consent in any meaningful sense.
Related reading
- Cape Town WordPress: a performance audit walkthrough. Audits usually surface compliance gaps alongside performance and security gaps.
- WordPress Hosting in South Africa: Xneelo vs Hetzner vs International Hosts. Hosting location affects cross-border transfer analysis.
- WordPress Slow After 2 Years? Here's What's Actually Wrong. When the site has been running long enough to develop performance problems, it has usually accumulated compliance debt too.
- WooCommerce + South African Payment Gateways. Payment gateway choice affects what data you collect and where it flows.

Written by
Barry van Biljon
Full-stack developer specializing in high-performance web applications with React, Next.js, and WordPress.
Ready to Get Started?
Have questions about implementing these strategies? Our team is here to help you build high-performance web applications that drive results.
