Ga naar inhoud

Formulieren in de headless rebuild (Gravity Forms REST API v2)

Dit hoofdstuk beschrijft hoe de Next.js-frontend de bestaande Gravity Forms-formulieren rendert en verstuurt. Uitgangspunt: de formulierdefinities, validatie, notificaties en add-on-gedrag (User Registration, Mailchimp/Listmonk, Mollie) blijven in WordPress; de frontend praat met de GF REST API v2 (/wp-json/gf/v2/…).

Huidige stand

  • Namespace gf/v2 is actief (GF 2.9 registreert de v2-routes altijd).
  • Web API-instellingen: enabled=1; er bestaan al API-keys in wp_gf_rest_api_keys (3× "dynamics" read_write — in gebruik door de Dynamics 365-koppeling die entries uitleest — en 2× "gb-mail-overzicht" read). Voor de rebuild een eigen key aanmaken.
  • GET /wp-json/gf/v2/forms401 zonder authenticatie; formulierdefinities ophalen vereist een API-key.
  • POST /wp-json/gf/v2/forms/{id}/submissions is publiek (geverifieerd): zonder auth levert een ongeldige inzending is_valid:false plus veldvalidatiefouten op.

Formulierdefinitie ophalen (server-side)

GET /wp-json/gf/v2/forms/{id}
Authorization: Basic base64(consumer_key:consumer_secret)
  • Alleen server-side aanroepen (Next.js server component / route handler) — nooit de key naar de browser sturen. De response bevat óók gevoelige configuratie (notificatie-adressen, confirmations); geef alleen de benodigde velden door aan de client.
  • De response bevat per veld: type, label, isRequired, choices, inputs (subvelden), conditionalLogic, visibility, pageNumber, prijsinformatie (product-velden) en prepopulate-instellingen (allowsPrepopulate + inputName).
  • Definities zijn cachebaar (ISR/revalidate); ze wijzigen alleen bij beheer in wp-admin.

De frontend moet zelf implementeren (gedrag dat GF nu server-side rendert):

GF-gedrag Rebuild-verantwoordelijkheid
Conditionele logica (SHOW/HIDE, EN/OF) client-side evalueren; verborgen velden niet meesturen en niet valideren
Meerstaps-formulieren (page-velden, formulieren 21 en 45) stappen + voortgangsindicator client-side; validatie per stap; de REST-submission is één POST met alle velden
Product-/totaalvelden bedragen client-side optellen voor weergave; het server-side berekende totaal is leidend voor de betaling
Prepopulate (queryparameters actie, adres, betalingskenmerk, email) query → veldwaarde mappen
Nederlandse sublabels (Voornaam, Plaats, …) het thema vertaalt die bij render; de REST-definitie bevat de Engelse sublabels tenzij een customLabel is gezet — vertaling in de frontend-componentlaag
Verborgen admin-velden (known_user, hidden radio's) niet renderen en niet meesturen; WordPress vult ze server-side

Versturen

POST /wp-json/gf/v2/forms/{id}/submissions
Content-Type: application/json

{
  "input_1": "waarde",
  "input_33_3": "Voornaam",   // subveld 33.3 → underscore-notatie
  "input_11_1": "1"           // consent-checkbox
}
  • Veldsleutels: input_{veldId}, subvelden met underscore (input_33_3 voor veld 33.3).
  • Succesvolle response: is_valid: true + confirmation_message (HTML) of confirmation_type: "redirect" met confirmation_redirect-URL.
  • De server-side hooks vuren gewoon bij REST-submissions: notificaties, User Registration-feeds (synchroon), Mailchimp/Listmonk, known_user, Excel-bijlagen.

Validatiefout-afhandeling

Bij een ongeldige inzending:

{
  "is_valid": false,
  "validation_messages": { "2": "Dit veld is vereist.", "9": "…" },
  "page_number": 1
}
  • validation_messages is gekeyed op veld-ID → mappen op de betreffende formuliervelden, focus naar het eerste foutveld, ingevulde waarden behouden.
  • Bij meerstaps-formulieren geeft page_number aan op welke stap de fout zit — de frontend navigeert naar die stap.
  • Custom validaties draaien mee (NL-IBAN op formulier 45, Gemeenten-list op 24): de foutteksten komen uit WordPress en moeten getoond worden zoals ontvangen.

reCAPTCHA — aandachtspunt

De meeste publieke formulieren bevatten een captcha-veld (Google reCAPTCHA v2 checkbox, sitekey 6Lcnym8bAAAAAFAebeRVziCoEiXwR-uXRZVTLQ-L). Voor de rebuild:

  • de frontend rendert zelf de reCAPTCHA-widget (of een v3/enterprise-opvolger — beslispunt) en stuurt het token mee in de submission (input_{captchaVeldId} / g-recaptcha-response); WordPress valideert server-side;
  • verifiëren dat de GF REST-submission de captcha daadwerkelijk afdwingt — in de huidige situatie is dit niet expliciet getest. Zolang dat niet vaststaat, geldt de frontend-captcha niet als spam-bescherming;
  • het thema skipt captcha-validatie voor formulier 46 in development — gedrag behouden voor e2e-tests of vervangen door een test-sitekey;
  • de honeypot-instelling van GF geldt ook voor REST-submissions: geen extra (honeypot-)velden meesturen die niet in de definitie staan.

Twee thema-hooks doen bij een klassieke page-submit iets wat via REST niet bij de client aankomt:

  • Paywall-formulier 29: setcookie('subscribed-to-newsletter', …) + wp_redirect — headers van een REST-response bereiken de Next.js-gebruiker niet als paginacookie/redirect. De frontend moet na een geslaagde submission zelf het cookie (of een eigen equivalent) zetten, het betreffende artikel ontgrendelen en de paywall-teksten omschakelen (zie Nieuwsbrief).
  • Confirmations van het type page/redirect (formulieren 18, 20, 21, 34, 35, 37, 38, 41, 42, 45): de frontend leest confirmation_redirect uit de response en navigeert client-side; de WP-URL's moeten daarbij naar Next.js-routes worden gemapt.

Mollie-redirect-flow — open punt

Nog te verifiëren vóór de bouw van de betaalformulieren

Bij de 8 Mollie-formulieren maakt de Mollie-add-on na een geldige submission een betaling aan en redirect de gebruiker naar de Mollie-checkout; de webhook werkt daarna de entry bij (complete_payment). Niet vastgesteld is of de REST-submission-response de Mollie-checkout-URL bevat, en hoe het mollie-veld (Mollie Components/methode-keuze, gekoppeld aan het Mollie-profiel) zich zonder de GF-frontend-scripts gedraagt. Vereiste spike vóór de bouw:

  1. testbetaling via POST /gf/v2/forms/34/submissions in Mollie-testmode;
  2. vastleggen: checkout-URL in de response? return-URL? entry-status bij paid/canceled/failed/expired? vuurt complete_payment (incl. de bestelbevestiging + downloadlink van formulier 40)?
  3. zo nodig een eigen server-side endpoint bouwen dat de Mollie-betaling aanmaakt en de checkout-URL teruggeeft (de GF-entry blijft dan de bron voor BC-omschrijving en webhookverwerking).

Tot die tijd gelden de betaal-acceptatiecriteria in Donaties (Mollie) als functioneel kader, niet als bewezen technisch pad.

Accountformulieren (18/24/25)

De update-feeds van User Registration werken op de ingelogde gebruiker. Headless betekent dat de submission met de identiteit van de gebruiker bij WordPress moet aankomen (cookie-proxy of de JWT-laag gb-app/v1 + server-side submission met user-context). De huidige site schermt alleen de pagína af, niet het formulier — de rebuild moet dit server-side afdwingen. Zie Account.

Acceptatiecriteria (API-laag)

  • Als Next.js-server kan ik met de nieuwe API-key GET /wp-json/gf/v2/forms/{id} aanroepen voor elk ge-embed formulier en bevat de response velden, condities en pagina-indeling.
  • Als anonieme client kan ik POST /wp-json/gf/v2/forms/2/submissions doen; met geldige invoer krijg ik is_valid: true en de confirmation-tekst, met ontbrekende verplichte velden is_valid: false met validation_messages per veld-ID.
  • Als anonieme client krijg ik op GET /wp-json/gf/v2/forms zonder key een 401.
  • Als client die een submission doet op een formulier met redirect-confirmation (bijv. 20), dan bevat de response het redirect-doel en navigeert de frontend daarheen.
  • Als systeem: een REST-submission op formulier 22 leidt tot een Mailchimp- én Listmonk-inschrijving (hooks vuren server-side).
  • Als systeem: een REST-submission op formulier 17 met onbekend e-mailadres maakt een niet-geactiveerd wv-subscriber-account aan (known_user-hook werkt via REST).
  • Als client zonder geldig reCAPTCHA-token op een captcha-formulier: de submission wordt geweigerd (te bevestigen in de spike; zo niet, dan is aanvullende spam-bescherming vereist vóór livegang).
  • Als beheerder wijzig ik een veldlabel in wp-admin; na cache-revalidatie toont de frontend het nieuwe label zonder deploy.

Bekende afwijkingen

NIET nabouwen — wel vermelden in het testrapport

  • De GF Web API v1 (legacy public/private key) staat nog geconfigureerd; niet overnemen — alleen v2 met keys gebruiken.
  • De bestaande "dynamics"-keys (read_write) en testformulier 43 horen bij de Dynamics 365-entry-uitlezing; deze koppeling moet blijven werken en valt buiten de frontend-rebuild.