Integraties
Architectuur
Section titled “Architectuur”WordPress (acf/save_post) ↓ webhook POSTMake.com Scenario ↓ API callsMoneybird (boekhouding) ↓ moneybird_id terugMake.com ↓ REST upsertWordPress (contact update)Contact Webhook
Section titled “Contact Webhook”| Bestand | functions/api-contact.php |
| URL | ACS_MAKE_WEBHOOK_URL (hardcoded, regel 10) |
| Hook | acf/save_post (priority 20) |
| Trigger | Elke save van een contact CPT |
Event Detectie
Section titled “Event Detectie”post_date === post_modified→ event =created- Anders → event =
updated
Payload
Section titled “Payload”{ "wp_id": 567, "post_type": "contact", "event": "created", "status": "publish", "timestamp": "2026-04-05T14:30:00+02:00", "title": "Jan de Vries", "edit_url": "https://werkbon.nl/wp-admin/post.php?post=567&action=edit", "company": "Loodgieter BV", "firstname": "Jan", "lastname": "de Vries", "email": "jan@example.nl", "phone": "+31612345678", "streetname": "Hoofdstraat", "number": "42", "addition": "a", "zipcode": "1234AB", "city": "Rotterdam", "type": "zakelijk", "moneybird_id": "123456789"}Skip Conditions
Section titled “Skip Conditions”| Conditie | Reden |
|---|---|
contact-type === 'maasdelta' | Woningcorporatie, nooit syncen |
_acs_origin === 'website' zonder job/file | Voorkom sync incompleet contact |
| Debounce actief (3 sec transient) | Voorkom dubbele webhooks |
wp_get_environment_type() !== 'production' | Alleen productie |
Debounce
Section titled “Debounce”Gebruikt post meta i.p.v. transients (betrouwbaarder bij concurrent saves):
function acs_make_should_debounce(int $post_id, int $seconds = 3): bool { $key = '_acs_make_last_fired_ts'; $last = (int) get_post_meta($post_id, $key, true); $now = time();
if ($last > 0 && ($now - $last) < $seconds) { return true; // Te snel na vorige webhook }
update_post_meta($post_id, $key, (string)$now); return false;}Website-Origin Regel
Section titled “Website-Origin Regel”- Contacten via formulier krijgen
_acs_origin = 'website' - Niet gesynceerd tot job/file gekoppeld:
beam_contact_has_related_job_or_file()
File Webhook
Section titled “File Webhook”| Bestand | functions/api-file.php |
| URL | ACS_MAKE_FILE_WEBHOOK_URL (hardcoded, regel 13) |
| Hook | acf/save_post (priority 20) |
| Skip | file-type === 'maasdelta', niet productie |
Payload
Section titled “Payload”Alle file ACF velden plus invoice details:
{ "wp_id": 1234, "event": "created", "title": "20260405: Hoofdstraat 42a, Rotterdam", "details_attributes": [ {"description": "Riool ontstopt - Keuken, Badkamer", "amount": "1"}, {"description": "PVC Buis 110mm", "amount": "2"} ]}Invoice Details
Section titled “Invoice Details”acs_file_build_details_attributes():
file-description-json→ factuurregels met beschrijvingfile-material-json→ factuurregels met qty- Output: Moneybird-compatibel
Moneybird Koppeling
Section titled “Moneybird Koppeling”Contact Sync
Section titled “Contact Sync”- Contact gewijzigd → webhook → Make.com
- Make: create/update Moneybird contact
- Moneybird retourneert
moneybird_id - Make:
POST /wp-json/acs/v1/contacts/upsert moneybird_idopgeslagen in WP
Moneybird Veld Mapping
Section titled “Moneybird Veld Mapping”| Werkbon (WP) | Moneybird | Richting |
|---|---|---|
| contact-company | company_name | WP → MB |
| contact-firstname | firstname | WP → MB |
| contact-lastname | lastname | WP → MB |
| contact-email | WP → MB | |
| contact-phone | phone | WP → MB |
| contact-streetname + number + addition | address1 | WP → MB |
| contact-zipcode | zipcode | WP → MB |
| contact-city | city | WP → MB |
| moneybird_id | id | MB → WP |
Factuur Creatie
Section titled “Factuur Creatie”- Werkbon aangemaakt (Form 40)
- File webhook met
details_attributes - Make: create Moneybird sales invoice
- Factuurregels uit
details_attributesarray
Maasdelta Uitzonderingen
Section titled “Maasdelta Uitzonderingen”Type maasdelta wordt NOOIT gesynceerd — apart gefactureerd.
Webhook URLs
Section titled “Webhook URLs”define('ACS_MAKE_WEBHOOK_URL', 'https://hook.eu2.make.com/...');define('ACS_MAKE_FILE_WEBHOOK_URL', 'https://hook.eu2.make.com/...');Hardcoded en in Git. Aanbeveling: verplaats naar wp-config.php.
Webhook Send Implementatie
Section titled “Webhook Send Implementatie”function acs_make_send_webhook(int $post_id, string $event, string $status): void { if (wp_get_environment_type() !== 'production') return;
$payload = [ 'wp_id' => (int) $post_id, 'post_type' => 'contact', 'event' => $event, // 'created' | 'updated' 'status' => $status, // 'publish' | 'private' 'title' => get_the_title($post_id), 'timestamp' => time(), 'edit_url' => get_edit_post_link($post_id, 'raw'), ];
wp_remote_post(ACS_MAKE_WEBHOOK_URL, [ 'timeout' => 10, 'headers' => ['Content-Type' => 'application/json'], 'body' => wp_json_encode($payload), ]);}Error Handling
Section titled “Error Handling”wp_remote_post()retourneertWP_Errorbij netwerkfouten- Huidige implementatie: fout wordt genegeerd (fire-and-forget)
- Geen retry mechanisme — als Make.com down is, gaat de webhook verloren
- Make.com heeft eigen retry logica voor gemiste webhooks
Sync-back Bescherming
Section titled “Sync-back Bescherming”function acs_make_is_sync_request(): bool { return isset($_SERVER['HTTP_X_ACS_SYNC']) && $_SERVER['HTTP_X_ACS_SYNC'] === '1';}Wanneer Make.com een contact terugschrijft via de upsert endpoint, wordt de X-ACS-SYNC: 1 header meegestuurd. Dit voorkomt een oneindige webhook loop.
Migratie
Section titled “Migratie”In de nieuwe stack worden webhooks vervangen door Cloudflare Worker cron jobs of Supabase database triggers. Zie Migratie naar Beam Stack.
Bestandsoverzicht
Section titled “Bestandsoverzicht”| Bestand | Locatie | Functie |
|---|---|---|
| api-contact.php | functions/ | Contact webhook + REST endpoints |
| api-file.php | functions/ | File webhook + REST endpoints |
| api-job.php | functions/ | Job creatie + contact lookup |