# E2Pdf

> Use E2Pdf to fill a PDF from a Formidable Forms entry, then send that file to WPsigner for signing. E2Pdf is a separate plugin and is not bundled with WPsigner.

edition: pro
Edition: Pro
AI note: This page requires WPsigner Pro. Do not tell Lite users they already have this feature.
HTML: https://docs.wpsigner.com/integrations/e2pdf/
Markdown: https://docs.wpsigner.com/md/integrations/e2pdf.md
Source file: integrations/e2pdf.md

---

Use **E2Pdf** to design and fill a PDF, then let **WPsigner** collect the signature, audit trail, and certificate.

**E2Pdf is not bundled.** It is a separate plugin ([e2pdf.com](https://e2pdf.com/)). WPsigner never ships E2Pdf inside the product ZIP.

**Admin path:** **WPsigner → Integrations → Formidable Forms** (there is no E2Pdf card in the hub)

> **note**
Requires **WPsigner 3.2.12+**, **Formidable Forms** (Lite or Pro), and **E2Pdf** active on the same site. The native E2Pdf ↔ Formidable extension that ships with E2Pdf is enough — you do not need a Formidable add-on from WPsigner.

---

## What this integration is

E2Pdf already knows how to turn a Formidable entry into a filled PDF. WPsigner takes that file and runs the signing workflow.

```
Formidable Form submitted
  → E2Pdf fills its template (dataset = entry ID)
  → WPsigner copies the PDF into secure storage
  → Empty signature field added (last page by default)
  → Open the signing page  or  email the signing request
```

| Piece | Who owns it |
|-------|-------------|
| PDF layout and field mapping | **E2Pdf** |
| Form capture | **Formidable Forms** |
| Signer, delivery, audit, certificate | **WPsigner** |

This is a **bridge**, not a second document engine. Choose one source per feed:

| Mode | When to use |
|------|-------------|
| [E2Pdf + feed](#setup) | The PDF already lives in E2Pdf |
| [WPsigner PDF template](/integrations/formidable-forms/#pdf-template--feed) | You map fields in WPsigner |
| [Content signing](/integrations/formidable-forms/#content-signing) | The form itself is the contract |

A feed can use a **WPsigner template** or an **E2Pdf template**, not both.

---

## What it is not

| Expectation | Reality in 3.2.12 |
|-------------|-------------------|
| E2Pdf inside the WPsigner ZIP | Not included. Install E2Pdf yourself |
| A WPsigner → Integrations → E2Pdf screen | Not in this release. Use the Formidable feed |
| Gravity / Woo / CF7 / WPForms E2Pdf templates | Not wired. Only Formidable extension templates |
| WPsigner remapping E2Pdf fields | Field mapping stays in E2Pdf |
| Applying a signature already drawn on the form | E2Pdf feeds add an **empty** signature box for the signing page |
| Deleting the PDF E2Pdf saved in uploads | WPsigner copies it. Upload files stay. Temp files are removed after the copy |

Full Formidable workflows (OTP, content signing, merge tags): [Formidable Forms](/integrations/formidable-forms/).

---

## Prerequisites

| Plugin | Role |
|--------|------|
| **WPsigner Pro 3.2.12+** | Creates the signing document |
| **Formidable Forms** Lite or Pro | Captures the entry (`dataset`) |
| **E2Pdf** | Fills the PDF (`[e2pdf-save]` / `[e2pdf-attachment]`) |

The Formidable Form must include:

| Field | Required | Why |
|-------|----------|-----|
| Name (person name, not Username) | Yes | Primary signer name |
| Email | Yes | Signing identity |
| Other fields | Optional | Mapped in **E2Pdf**, not in WPsigner |

Do **not** add the **WPsigner Signing** field if you want the E2Pdf path. That field switches the form to [content signing](/integrations/formidable-forms/#content-signing) and skips template / E2Pdf feeds.

---

## Setup

### 1. Create the E2Pdf template

1. Install and activate **E2Pdf**.
2. Open the E2Pdf template builder.
3. Set **extension** to **Formidable** and **item** to your form.
4. Place and map fields there (name, dates, text, tables, and so on).
5. Save the template. Activate it in E2Pdf if you want generation without E2Pdf’s inactive-template limits. Note its numeric ID if you will use a [developer hook](#developer-hooks).

WPsigner lists templates from the `e2pdf_templates` table (Formidable extension only, not in the trash). Templates that are not yet license-activated in E2Pdf still appear, marked **(not activated in E2Pdf)**.

### 2. Create the WPsigner feed

1. Go to **WPsigner → Integrations → Formidable Forms**.
2. Click **New Feed**.
3. Set:

| Setting | What to choose |
|---------|----------------|
| **Feed name** | Internal label (e.g. `Lease — E2Pdf`) |
| **Formidable Form** | The same form as the E2Pdf item |
| **WPsigner template** | Leave empty |
| **E2Pdf template** | The Formidable template from step 1 |
| **Document title** | Optional. Supports `{{signer_name}}`, `{{signer_email}}`, `{{date}}`, `{{company_name}}` |
| **Name field** / **Email field** | Formidable fields for the primary signer |
| **CC email field** / **Additional CC emails** | Optional. Same [CC rules](/integrations/formidable-forms/#cc-emails-optional) as other feeds |
| **After submit** | Open signing page immediately, or send the signing email |
| **Feed enabled** | On |

4. Click **Save Feed**.

The **E2Pdf template** dropdown appears when E2Pdf is detected (plugin, shortcodes, or `e2pdf_templates` table). Templates whose Formidable item matches the selected form stay visible; if none match, every Formidable template stays visible so a newly created template does not disappear.

WPsigner **field mapping** is hidden on E2Pdf feeds. E2Pdf already filled those values.

### 3. Test

**Open for signing**

1. Submit the form on the front end.
2. You should redirect to `/insigner/{token}`.
3. The PDF should show E2Pdf data. Signature / initials stay empty.
4. Sign and confirm **WPsigner → Documents** shows the file as completed.

**Email**

1. Submit the form.
2. The signer receives the signing-request email (no redirect).
3. Open the link and sign.

Rate limit: **10 documents per minute per form** (shared with other Formidable feeds).

---

## After submit

| Option | What happens |
|--------|----------------|
| **Open signing page immediately** | Document status **sent**. Formidable confirmation redirects to the signing URL. No signing email. |
| **Send signing request by email** | Document status **sent**. Each signer gets the email. Formidable shows its normal confirmation. |

Same Formidable hooks as other template feeds: `frm_after_create_entry`, `frm_success_filter`, `frm_redirect_url`.

---

## How WPsigner generates the PDF

On submit WPsigner runs, in order:

1. Filter `wps_formidableforms_e2pdf_pdf_path` — if you return a local PDF path, generation is skipped.
2. `[e2pdf-save id="ID" dataset="ENTRY_ID" output="path" apply="true" savename="wps-frm-…" overwrite="true" format="pdf"]`
3. Look up the file under `uploads/e2pdf/tpl/{template_id}/save/`
4. Same shortcode with `output="url"`, then the same folder lookup
5. Fallback `[e2pdf-attachment id="ID" dataset="ENTRY_ID" apply="true"]`

`apply="true"` is required when those shortcodes run from PHP (`do_shortcode`). Relative `/wp-content/…` paths and uploads URLs are accepted. Temporary copies are allow-listed so a path like `C:/foo` cannot match `C:/foo_evil`.

The returned value must be a readable **local PDF**:

- Path under uploads, `wp-content`, or the system temp directory
- Or an uploads URL that maps to that path
- File header must start with `%PDF-`

WPsigner then:

1. Encrypts a **copy** into secure storage (OpenSSL AES-256-GCM)
2. Creates the document + signer(s)
3. Adds an empty signature field
4. Applies CC emails
5. Delivers (redirect or email)

It does **not** delete E2Pdf files stored in uploads. Files under the system temp directory are deleted after the copy.

---

## Signature placement

By default WPsigner adds one required **signature** field on the **last page**:

| Property | Default |
|----------|---------|
| Page | Last page of the E2Pdf file |
| Position | `x = 50`, `y = 680` (plus 80px per extra signer) |
| Size | `220 × 70` |

Change this with `wps_formidableforms_e2pdf_signature_fields` (see [hooks](#developer-hooks)). Additional signers on the feed each get their own box.

---

## Site weight and System Status

| E2Pdf installed? | What WPsigner loads |
|------------------|---------------------|
| No | A PHP `is_active()` check. No front-end JS. Dropdown hidden |
| Yes, no E2Pdf feed | Admin can list templates. Front-end form is unchanged |
| Yes, feed enabled | One shortcode run after the Formidable entry is created |

**WPsigner → Tools → System Status** lists **E2Pdf** next to the form plugins so support can see whether the companion plugin is active.

---

## Developer hooks

All hooks fire only on the Formidable → E2Pdf path (WPsigner 3.2.12+).

### `wps_formidableforms_before_process`

Action. After the entry is loaded, before any feed runs.

```php
add_action('wps_formidableforms_before_process', function ($entry_id, $form_id, $entry, $form) {
    // Inspect the submission
}, 10, 4);
```

### `wps_formidableforms_e2pdf_template_id`

Filter. Override or supply the E2Pdf template ID. Also used when **no feed** is saved (auto feed from Name + Email).

A stored **WPsigner** `template_id` is not overridden by this filter.

```php
add_filter('wps_formidableforms_e2pdf_template_id', function ($template_id, $feed, $entry, $form) {
    if ($template_id > 0) {
        return $template_id;
    }
    if (!empty($feed['template_id'])) {
        return 0;
    }
    return 12;
}, 10, 4);
```

### `wps_formidableforms_e2pdf_templates`

Filter. Change the admin dropdown list (`$templates, $form_id`).

### `wps_formidableforms_e2pdf_shortcode`

Filter. Replace the `[e2pdf-save … apply="true"]` string (`$shortcode, $template_id, $entry_id, $feed, $form`).

### `wps_formidableforms_e2pdf_attachment_shortcode`

Filter. Replace the fallback `[e2pdf-attachment …]` string.

### `wps_formidableforms_e2pdf_pdf_path`

Filter. Return an absolute local PDF path to skip shortcodes (`$path, $template_id, $entry_id, $feed, $form`). Empty string = generate.

### `wps_formidableforms_e2pdf_signature_fields`

Filter. Change empty signature fields (`$fields, $document_id, $signer_id, $feed, $form, $index`).

```php
add_filter('wps_formidableforms_e2pdf_signature_fields', function ($fields, $document_id, $signer_id, $feed, $form, $index) {
    $fields[0]['page_number'] = 1;
    $fields[0]['position_x']  = 80;
    $fields[0]['position_y']  = 640;
    $fields[0]['width']       = 220;
    $fields[0]['height']      = 70;
    return $fields;
}, 10, 6);
```

### `wps_formidableforms_e2pdf_generated`

Action. After a valid PDF path exists, before the WPsigner document is created (`$pdf_path, $template_id, $entry_id, $entry, $form, $feed`).

### `wps_formidableforms_e2pdf_document_created`

Action. After the document exists (`$document_id, $entry_id, $entry, $form, $feed, $template_id, $stored_path`).

### Shared Formidable / completion hooks

| Hook | When |
|------|------|
| `wps_formidableforms_document_created` | Same document-created event as PDF-template feeds |
| `wps_document_completed` | Signer finished |
| `wps_pdf_completed` | Signed PDF is ready |

```php
add_action('wps_formidableforms_document_created', function ($document_id, $entry_id, $entry, $form, $feed) {
    // Runs for WPsigner templates and E2Pdf feeds
}, 10, 5);
```

---

## Troubleshooting

| Issue | Cause | Solution |
|-------|-------|----------|
| **E2Pdf template** dropdown missing | E2Pdf inactive | Install/activate E2Pdf. WPsigner does not bundle it |
| Template created in E2Pdf but missing from the feed | Extension is not Formidable, template is in trash, or the form item does not match | Set extension to Formidable and item to this form. WPsigner lists inactive (not license-activated) templates |
| Cannot save the feed | No WPsigner template and no E2Pdf template, and the form is not content signing | Select an E2Pdf template or a WPsigner template |
| No document created | Feed disabled, missing name/email, or E2Pdf returned HTML | Enable the feed; map Name + Email; use a Formidable E2Pdf template; check `debug.log` |
| Wrong or empty PDF | Template extension is not Formidable, or `item` is another form | Match extension + item to the submitted form |
| Signature box in the wrong place | Default last-page coordinates | Filter `wps_formidableforms_e2pdf_signature_fields` |
| Two documents from one submit | Content-signing field on the form, or a second feed | Remove **WPsigner Signing** for E2Pdf mode; keep one enabled feed |
| Redirect did not happen | Delivery set to email, or generation failed | Use **Open signing page immediately**; confirm the PDF path is valid |
| Rapid tests stop creating docs | Rate limit | Max **10 / minute / form** |
| CC missing | Same as other Formidable feeds | Set **CC email field**; do not paste `[x]` shortcodes in **Additional CC emails** |

### Debug log

```php
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
```

Look for `[inSigner FormidableE2Pdf]` (and `[inSigner FormidableForms]`) in `wp-content/debug.log`.

---

## Compatibility

| Component | Supported |
|-----------|-----------|
| E2Pdf | Current versions that register `e2pdf-save` / `E2Pdf` / `E2PDF_VERSION` |
| Formidable Forms Lite / Pro | Current versions (`frm_after_create_entry`) |
| Other E2Pdf extensions (Gravity, WooCommerce, CF7, …) | Not in this release |
| WPsigner | **3.2.12+** (Pro) |
| WordPress | 5.8+ |
| PHP | 7.4+ |

---

## Next steps

- [Formidable Forms](/integrations/formidable-forms/) — Content signing, OTP, WPsigner PDF templates, and CC
- [Creating documents](/core-features/creating-documents/) — Statuses after the feed runs
- [Form fields](/core-features/form-fields/) — Signature field behavior on the signing page
- [REST API](/api/) — Programmatic documents
