Skip to content

Contact Form 7

Connect Contact Form 7 with WPsigner to collect legally binding signatures from CF7 submissions. You can either sign the form content inline (recommended) or create documents from a WPsigner PDF template via a feed.


ComponentDescription
WPsigner Signing tagCF7 form-tag [insigner_signing] with Draw / Type / Upload + optional OTP
Content signingBuilds a signed PDF from the submission + signature (no template required)
FeedOptional rules for CC, title, template mode, mappings, extra signers, auto-send
Merge tags{inSigner:signed_pdf_url} and {inSigner:download_button} in CF7 Mail / success message
Auto-sendTemplate mode only — emails the remote signing link after the document is created

Processing runs on CF7’s wpcf7_before_send_mail hook (not wpcf7_mail_sent). That means:

  • The signed PDF is ready before CF7 sends its email, so merge tags work in the same message
  • Document creation does not depend on SMTP succeeding
  • If signing or a required feed fails, WPsigner sets CF7’s $abort flag so the form submission does not complete with a half-built document

ModeBest forRequires template?Requires feed?
Content signingApplications, consents, agreements built from form answersNoNo (feed optional)
Template + feedFixed PDF contracts (NDA, lease, offer letter)YesYes

If the form contains an [insigner_signing] tag, WPsigner always uses content signing for that submission. Template feeds on the same form are skipped. In the feed UI, selecting a form that already has a Signing tag switches the modal to inline options (signature field + CC) and hides template / mappings / additional signers / auto-send.


Generate a signed PDF from the form submission content plus an inline signature. WPsigner builds the PDF automatically — you do not upload a template.

User submits CF7 form
CF7 validates fields (+ reCAPTCHA / Akismet / honeypot as configured)
wpcf7_before_send_mail
WPsigner validates signature (+ OTP if required)
PDF generated from answers → signature applied → Certificate of Completion
Merge tags primed → CF7 Mail / success message can include the download link
  1. Install and activate Contact Form 7 and WPsigner (v3.0.3.2+ recommended for full CF7 parity)
  2. Open Contact → Contact Forms → Edit
  3. Add at least:
    • A name field (e.g. [text* your-name])
    • An email field (e.g. [email* your-email])
    • The WPsigner Signing tag (see tag syntax)
  4. In Mail / Mail (2), optionally add merge tags (see Merge tags)
  5. Save the form and publish it on a page with the CF7 shortcode

When a visitor submits:

  • WPsigner captures the signature and form rows
  • A completed PDF is generated with audit trail and Certificate of Completion
  • Secure download URLs are available via merge tags
  • WPsigner can send its own completion notification according to your email settings

Feeds are optional for content signing. Create one only if you need:

  • CC emails on the signed document
  • A custom document title
  • An explicit Signing field name (when the form has more than one)
  1. WPsigner → Integrations → Contact Form 7 → New Feed
  2. Select a CF7 form that includes a Signing tag
  3. Configure CC / title / signature field as needed
  4. Save the feed

Without a feed, WPsigner builds an automatic content-signing feed (auto) with:

  • Title: {form title} - {{signer_name}}
  • Signature field: first valid signature submitted
  • Name / email: auto-detected from common CF7 tags
  • Owner: see Document owner

If content signing fails (invalid signature, OTP missing/expired, PDF error, rate limit, etc.), WPsigner aborts the CF7 mail pipeline ($abort = true). The visitor sees a CF7 error instead of a “success” email without a document. Partial documents are cleaned up.


  1. Edit the CF7 form
  2. Open the tag generator and choose WPsigner Signing
  3. Configure:
    • Required (recommended)
    • Field name (default signature)
    • OTP method (Disabled / Email / SMS / Email+SMS / WhatsApp — available methods depend on Twilio / WhatsApp setup)
    • Signer email field (default your-email)
    • Label (default Signature)
  4. Insert the generated tag into the form template

Works with CF7 Tag Generator v2 (data-tag-option for otp:, email:, label:) and the classic generator fallback.

FormMeaning
[insigner_signing name]Optional signing field
[insigner_signing* name]Required signing field
otpRequire OTP (default method: email)
otp:emailOTP by email
otp:smsOTP by SMS (Twilio required)
otp:bothOTP by email + SMS (Twilio required)
otp:whatsappOTP by WhatsApp (WhatsApp integration required)
email:your-emailCF7 tag name used as the signer / OTP email
label:SignatureVisible label (_ becomes a space)
[insigner_signing* signature]
[insigner_signing* signature otp:email email:your-email]
[insigner_signing* signature otp:sms email:your-email label:Firma]
[insigner_signing* signature otp:whatsapp email:work-email label:Authorized_Signature]

If a content-signing feed is active for the same form, the feed’s Signer Email Field overrides the tag’s email: option for OTP delivery when the feed targets that signature field (or uses auto-detect).

The field renders a shared signature pad:

TabBehavior
DrawStylus / mouse pad (colors: black, blue, navy)
TypeTyped signature with script fonts
UploadPNG/JPG upload (converted to a PNG data URI)

If OTP is enabled:

  1. User completes the signature
  2. OTP panel appears (Identity verification)
  3. User requests a 6-digit code, enters it, and verifies
  4. Submit is blocked until the signature and OTP token are present

On successful CF7 reset / resubmit, the pad and OTP state clear.

Assets load automatically when the tag is present (wps-signature-pad, wps-cf7-signature, wps-cf7-form-otp).


MethodRequirements
EmailEmail field on the form (email: option or auto-detect)
SMSPhone on the form + Twilio configured
Email + SMSEmail + phone + Twilio
WhatsAppPhone + WhatsApp Business configured

Phone numbers should use international E.164 format (example: +15551234567).

  • 6-digit code, expires in 10 minutes, max 5 verify attempts
  • Session binding uses a secure browser cookie (HttpOnly, SameSite=Strict) — not the client IP (works behind proxies / CDNs)
  • OTP context is scoped to CF7 + form ID (isolated from Fluent Forms / other builders)
  • On successful content signing the OTP proof is consumed (one-time use)
  • Phone used for SMS/WhatsApp is bound into the OTP token for integrity
ActionAuthNonce
wps_cf7_send_otpLogged-in + guestswps_public_nonce
wps_cf7_verify_otpLogged-in + guestswps_public_nonce
ActionScopeLimit
SendPer form + IP15 / 5 minutes
SendPer form + email + IP5 / 1 minute
VerifyPer form + IP30 / 5 minutes
VerifyPer form + email + IP10 / 1 minute

The CF7 form must be published. Draft forms reject OTP requests.


Use these tags in CF7 Mail, Mail (2), and the messages that CF7 displays after submit:

TagOutput
{inSigner:signed_pdf_url}Secure URL to download the completed signed PDF
{inSigner:download_button}HTML button (“Download Signed PDF”) in HTML mail bodies; plain URL in subjects / non-HTML contexts
<p>Thank you. Your signed document is ready:</p>
<p>{inSigner:download_button}</p>
<p>Or open this link: {inSigner:signed_pdf_url}</p>
SurfaceMechanism
Mail subject, body, additional headerswpcf7_mail_components
On-screen success / error messageswpcf7_display_message

The Signing field itself never dumps base64 into email: the mail tag is replaced with the text Signed.

Download links use WPsigner’s secure expiring download URLs for the completed PDF (Certificate of Completion included in the completed package).


Use this when you have a fixed PDF template with pre-placed signature fields and the form does not include [insigner_signing].

User submits CF7 form (no Signing tag)
wpcf7_before_send_mail
Matching template feeds run
Document created from template + mappings
(Optional) Auto-send signing emails to primary + additional signers
  1. WPsigner v3.0.3.2+ (recommended)
  2. Contact Form 7 active
  3. A CF7 form with name + email tags
  4. A WPsigner Template with signature fields positioned
  1. WPsigner → New Document → upload PDF
  2. Add a placeholder signer
  3. Place Signature / Name / Email / Date / Text fields
  4. Save as Template
  1. WPsigner → Integrations → Contact Form 7 → New Feed
  2. Configure:
SettingRequiredNotes
Feed NameYesLabel in the admin list
CF7 FormYesTarget form (must not rely on Signing tag for this mode)
WPsigner TemplateYesTemplate with fields
Document TitleNoSupports {{signer_name}}, {{signer_email}}, {{date}}, {{company_name}}, …
Primary Signer → Name FieldYesCF7 tag name (e.g. your-name)
Primary Signer → Email FieldYesCF7 tag name (e.g. your-email)
Variable MappingNocustom.* → CF7 tag
Additional SignersNoExtra name/email tag pairs
Auto-send document after creationNoDefault on in the UI
Feed enabledNoDefault on
  1. Save Feed

Both primary Name and Email tag names are required for template feeds. If either is empty at submit time, that feed is skipped.

[text* your-name] → your-name
[email* your-email] → your-email
[tel your-phone] → your-phone
[textarea your-message] → your-message

The tag name is the second token inside the brackets (after the field type).

  1. Open Variable Mapping in the feed modal
  2. Add a row
  3. Left: variable name with custom.* prefix (e.g. custom.company)
  4. Right: CF7 tag name (e.g. your-company)
  5. Use {{custom.company}} (or your template’s mapped field keys) in the PDF / prefill setup
VariableCF7 TagExample use
custom.companyyour-companyCompany on contract
custom.phoneyour-phonePhone line
custom.amountcontract-amountPricing

Variable names allow [a-zA-Z0-9_.] only.

VariableExample
{{signer_name}}John Smith
{{signer_email}}john@example.com
{{date}}2026-07-22
{{company_name}}Acme Corp (when available)

Example: NDA - {{signer_name}} - {{date}}

Add rows with name field + email field tag names. With Auto-send enabled, each additional signer receives a signing request. Partial send progress is tracked so retries do not re-mail signers who already received the link.

SettingResult
EnabledSigning emails go out after the document is created; status moves toward Sent
DisabledDocument stays available in WPsigner → Documents for manual send

Content-signing mode does not use this toggle (the form was already signed inline).


WPsigner → Integrations → Contact Form 7

  • Connection status and form / feed counts
  • Feed list (name, Active/Disabled, form, mode: Inline signing vs template name, mapping count)
  • New Feed, Edit, Enable/Disable, Delete

Admin AJAX uses nonce wps_cf7_nonce and requires manage_options (save capped at ~20 requests/minute per admin).

There is no owner dropdown in the feed modal. Ownership resolves in this order:

  1. Feed owner_user_id (set to the admin who saved the feed)
  2. Option wps_options['cf7_default_owner_id'] if configured
  3. Author of the page/post that contains the form (_wpcf7_container_post)
  4. Currently logged-in user
  5. First WordPress administrator

  • Document status suitable for a completed embedded signature
  • Signer marked signed
  • Signature image stored as evidence
  • generate_completed → completed PDF + Certificate of Completion
  • Document meta: _wps_cf7_form_id, _wps_cf7_feed_id, _wps_cf7_content_signing
  • Audit events such as document_sent, consent_accepted, otp_verified (when OTP used), embedded_signing_completed
  • Document from template + field prefills
  • Audit document_created
  • Optional auto-send → signing emails + wps_document_sent
  • Signers complete the document on the WPsigner signing page (not inline)

MechanismDetail
Content rate limit10 content-signing operations / minute / form+IP
Template rate limit10 template documents / minute / form+IP
Dedupe (content)Same form + browser binding + posted data → reuse result for ~5 minutes (no duplicate PDFs on double-submit)
Concurrency locksAtomic locks prevent two parallel requests from creating two documents
Template send stateDurable state tracks sent_signer_ids for safe Auto-send retries
OTP one-time claimVerified token can be reserved/consumed only once
Abort on failureCF7 mail aborted; partial documents removed

/**
* After a template-feed document is created.
*
* @param int $document_id
* @param int $form_id CF7 form ID.
* @param array $feed Sanitized feed config.
* @param array $posted_data CF7 posted data.
*/
do_action( 'wps_cf7_document_created', $document_id, $form_id, $feed, $posted_data );
/**
* After inline content signing finishes (PDF + certificate ready).
*
* @param int $document_id
* @param int $signer_id
* @param array $posted_data
* @param \WPCF7_ContactForm $contact_form
* @param array $feed Configured or auto feed.
*/
do_action(
'wps_cf7_content_signing_completed',
$document_id,
$signer_id,
$posted_data,
$contact_form,
$feed
);
/**
* When template Auto-send finishes sending to signers.
*/
do_action( 'wps_document_sent', $document_id, $signers );

FeatureDetails
Hook timingRuns after CF7 validation; still before mail so merge tags work
Signature validationPNG data-URI only; header / dimensions / GD checks; max payload size enforced
No base64 in emailSigning mail-tag replaced with Signed
Secure downloadsCompleted PDF links use expiring public tokens
OTP session cookieHttpOnly + SameSite=Strict; not IP-bound
Admin AJAXwps_cf7_nonce + manage_options
Public OTP AJAXwps_public_nonce + per-IP / per-email rate limits
LogsDebug logs avoid raw PII (IDs / flags); phone hashes may be stored on the document

ScenarioModeSetup
Website consent / waiverContent signing[insigner_signing* … otp:email] + merge tags in Mail
Support intake with signed acknowledgmentContent signingOptional feed for CC to legal@
NDA from contact formTemplate feedTemplate + Auto-send
Multi-party service agreementTemplate feedAdditional signers + Auto-send
Quote → contract PDFTemplate feedVariable mapping for amount / company

  • One form, multiple templates — all active template feeds for that form run (when no Signing tag is present)
  • Multiple forms, one template — reuse the same PDF layout
  • Inline + feed — Signing tag present → content signing only; template feeds on that form do not run

IssueCauseSolution
Critical error on CF7 settings pageOutdated WPsigner without global \WPCF7_* class refsUpdate to 3.0.3.2+
No document / form shows errorContent signing abortedCheck signature PNG, OTP, debug log ([inSigner CF7])
Template document not createdFeed disabled / wrong form / missing templateVerify feed Enabled, form ID, template
Template skipped silentlyMissing name or email tag valueConfirm tag names and required fields
Merge tags emptyTags used without successful content signingConfirm Signing tag + successful submit; tags only resolve after PDF generation
OTP not sendingChannel or field misconfiguredEmail field / Twilio / WhatsApp; check 429 rate limits
OTP verify fails after proxyOld builds used IP fingerprintUpdate plugin; ensure cookies allowed for the site
Duplicate documentsRare race / old versionUpdate; dedupe + locks handle double-click / retries
Signer email never arrives (template)Auto-send off or SMTP failureEnable Auto-send; configure FluentSMTP / SMTP
Wrong signer mappedTag name mismatchNames are case-sensitive (your-emailYour-Email)
“Contact Form 7 is not installed”CF7 inactiveActivate CF7
Base64 spam in CF7 mailCustom mail-tag misuseUse merge tags above; do not print the raw signing field
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );

Check wp-content/debug.log for [inSigner CF7] / [inSigner CF7 Content].

  1. CF7 active; form published
  2. Content mode: [insigner_signing*] present with valid Draw/Type/Upload value
  3. OTP (if enabled): cookie not blocked; method available; email/phone mapped
  4. Template mode: no Signing tag; feed enabled; template + name/email tags
  5. Merge tags placed in Mail HTML body for content signing
  6. SMTP working if you expect CF7 or Auto-send emails
  7. Not hitting 10/min form rate limits while testing

ComponentSupported
Contact Form 75.0+ (Tag Generator v2 / SWV tested on 5.9–6.x)
WPsigner3.0.3.2+ for full parity (inline signing, OTP, merge tags, before_send_mail)
WordPress5.8+
PHP7.4+

TopicContact Form 7Fluent Forms
Field UIForm-tag + tag generatorNative builder field
Processing hookwpcf7_before_send_mail + $abortFluent validation / before-insert hooks
Merge tagsCF7 Mail + display messageFluent email / confirmation parsers
Submission historyCF7 has no native entries; WPsigner document is the recordFluent entry + meta
OTP AJAXwps_cf7_send_otp / wps_cf7_verify_otpwps_ff_*
Public hookswps_cf7_*wps_fluentforms_*

Shared: Draw/Type/Upload pad, PNG rules, OTP cookie model, Certificate of Completion, merge tag strings, optional feeds for CC/title/template mode.