Overview
Section titled “Overview”Each WooCommerce feed uses one WPsigner template and chooses where the signature appears:
- On checkout — the contract and the signature pad are part of checkout. Payment methods stay visible. Place order stays closed until that document is signed.
- Leave checkout to sign — checkout pauses. The customer signs on the WPsigner page, then returns to pay.
- After the purchase — payment is not blocked. After the order is paid, WPsigner emails the signing link.
The document is filled from checkout or the order: billing, shipping, products, line details, and totals. Map Line item details, Amount due now, Full amount, and Balance due when the cart already holds a booking or a deposit. Different products can use different templates. Create one feed per template and select those products.
Prerequisites
Section titled “Prerequisites”- WPsigner v2.0.0 or later (3.3.2.12 or later for the checkout contract and booking fields described here)
- WooCommerce v6.0 or later (HPOS compatible, classic checkout and Checkout Block)
- At least one WPsigner template created
- Go to WPsigner → Integrations
- Find the WooCommerce card and click Configure
- Click New Feed. The feed editor opens. Checkout step, products, template, signer, and field mapping are selected from lists. You do not type a variable name.
In the feed {#when-the-customer-signs}
Section titled “In the feed {#when-the-customer-signs}”New Feed and Edit open the same screen. Work from the top of that screen to the bottom.
Where the signature appears
Section titled “Where the signature appears”The heading is Where the signature appears. Open Checkout step. A drawing of checkout sits beside the list. The purple block is the signature. It moves when you change the step.
| Checkout step | What the drawing shows | What the customer does |
|---|---|---|
| After billing | Signature after Billing, before Order | Sees the contract after the billing address, then the order and payment. |
| Before payments | Signature just above Payment | Sees the contract just above cards, Apple Pay, and Google Pay. |
| After payments | Signature after Payment, before Place order | Chooses a payment method, then signs before Place order. |
| Leave checkout to sign | A separate Sign page next to checkout. Payment and Place order are dimmed | Leaves checkout, signs on the WPsigner page, then returns to pay. |
| After the purchase | Checkout ends on a green Place order, then an Email card | Pays first. The signing link is emailed after payment. |
Trigger on Order Status and After order appear only when the step is After the purchase. They stay hidden for the other four steps.
An older feed keeps the step you already saved until you open it and pick a new Checkout step.
Products, template, and signer
Section titled “Products, template, and signer”After the checkout step, the feed editor continues in this order:
| Control | How you select it |
|---|---|
| Product Filter | Optional. Leave it empty when every product uses this template. Otherwise select the products. Hold Ctrl (Windows) or Cmd (Mac) for more than one. The feed runs when the cart or order contains at least one selected product. |
| WPsigner Template | One template for this feed. Choosing it loads that template’s fields into Field mapping. |
| Document Title | Optional title. You can use {{signer_name}}, {{signer_email}}, {{order_id}}, {{billing_name}}, and {{date}}. |
| Primary Signer → Name Field | Dropdown of checkout and order fields. The usual choice is Billing Full Name. |
| Primary Signer → Email Field | Dropdown of checkout and order fields. The usual choice is Billing Email. |
| Do not create another contract for a remaining-balance order | On by default. Leave it checked when a later order should keep the agreement from an earlier paid order. |
| Ask an administrator to countersign after payment | Optional. After the customer pays, a separate document is emailed to Countersign email. Payment is not blocked. |
| Feed enabled | Leave this checked. A disabled feed does not run. |
Create another feed when a product needs a different template. A cart that matches two checkout feeds must have both documents signed before the order can be placed. A variation matches when its parent product is selected.
Field mapping
Section titled “Field mapping”Field mapping is two dropdowns on each row. The legend reads WPsigner template → WooCommerce checkout. You do not type custom.company or any other variable name.
| Side | What you pick |
|---|---|
| Left, WPsigner template | A field on the template you selected, shown by its name |
| Right, WooCommerce checkout | The checkout or order value that fills it, such as Billing Company or Order Total |
Click Add for another row. A row is saved only when both sides have a selection.
Signature and initials are not in the left list. The customer completes those on checkout or on the signing page.
Name fields you do not map use the billing first and last name. Date fields you do not map use the purchase date. A value you map is kept. The automatic name or date does not replace it.
Booking lines, deposits, and a second signature
Section titled “Booking lines, deposits, and a second signature”The checkout dropdown also includes:
| Checkout field | What it fills |
|---|---|
| Line item details | Each product and the details WooCommerce shows on that line, such as a date, a time, a venue, or an extra. |
| Amount due now | The amount this checkout charges. |
| Full amount | The larger total when the order already stores it. Otherwise it matches the amount due now. |
| Balance due | Full amount minus the amount due now, or the balance stored on the order. |
WPsigner reads what WooCommerce stored. It does not invent a date or a balance that is not on the cart or the order.
Do not create another contract for a remaining-balance order stays on unless you clear it. A later order that points at an earlier paid order keeps that agreement.
Changing the line details or those amounts before payment asks for a new signature. After the order is paid, the same kind of change creates an amendment and emails it. The original sealed PDF stays as it was signed.
Ask an administrator to countersign after payment emails a separate document to Countersign email. If that field is empty, the email goes to the WordPress administration address. The administrator opens the signing link, signs, and finishes. The customer can pay first. The customer’s sealed PDF is not rewritten. Both documents stay on the order.
Apple Pay and Google Pay stay on the page, and they cannot start payment until the agreement is signed. Card methods stay visible. A wallet button that never goes through WooCommerce checkout can still be outside this gate, so try express checkout on a staging site.
Remaining-balance orders
Section titled “Remaining-balance orders”A remaining-balance order is a later WooCommerce order that points at an earlier paid order, for example a parent order ID or a deposit order ID.
When Do not create another contract for a remaining-balance order is on, that later order keeps the original agreement. The customer is not asked to sign the same contract again. Open in WPsigner on both orders opens that same audit trail.
A later order that does not point at an earlier paid order is a normal checkout and can require a new signature.
Amendments after a paid order
Section titled “Amendments after a paid order”WPsigner stores a snapshot of the line details and the three amounts on the paid order. If a shop manager later changes the date, venue, extras, or those amounts on that order, WPsigner creates an amendment document, emails it to the customer, and leaves the original sealed PDF as it was signed. Both documents stay on the order. There is no extra amendment button in the feed. The change happens when the WooCommerce order is saved.
After the purchase only
Section titled “After the purchase only”These two controls appear only for After the purchase:
| Control | How you select it |
|---|---|
| Trigger on Order Status | The order status that creates the document, for example Processing or Completed. |
| After order | Open signing page immediately from the thank-you page, or Send signing request by email. |
If the feed sends the signing request by email and the trigger is Completed, the email also sends when a paid order stays on Processing. Card payments often never reach Completed.
What the customer sees
Section titled “What the customer sees”On checkout
Section titled “On checkout”Use After billing, Before payments, or After payments.
At checkout:
- The contract is already visible. The customer does not have to enter a name or email before the PDF appears.
- The PDF shows the pages only. There is no thumbnail column from the browser. Expand document opens the same pages larger. On a phone the contract stays in the signing area. It does not cover the cart or checkout by itself.
- The line above the contract is Review the filled contract, then sign below. Change that sentence in WPsigner → Custom Texts → WooCommerce checkout → Review the contract.
- When the customer enters a billing first name, last name, and email, the PDF refreshes with those values. Name fields use the billing first and last name. Date fields use the purchase date. Other mapped fields stay in place.
- They draw, type, or upload a signature, confirm they have read the document, and click Sign. If the template uses Initials on Every Page, checkout fills those boxes with the first letter of each word in the customer’s name, up to three letters. Mary Ann Smith becomes MAS. Checkout does not ask them to draw initials.
- Place order then works with the payment method they chose, including Stripe, Apple Pay, and Google Pay.
Sign is the only action while the document is loading. Try again appears only if the PDF failed to load. After a successful signature, neither button stays on the page.
Payment methods stay on the page. Apple Pay and Google Pay cannot start until the document is signed. The order cannot be placed until every required document for that cart is signed. A signature belongs to the order that used it. The next purchase of the same products asks for a new signature. A remaining-balance order that points at this paid order keeps the same agreement. A signature that is finished but not yet paid still lets that checkout place the order.
On iPhone, after Sign, checkout loads again instead of showing the page from before the signature. The cart and the checkout details saved at Sign are still there.
The sealed PDF is attached to the WooCommerce customer email for Processing. If the order skips Processing and goes to Completed, it is attached to that customer email instead. The stored PDF is not rewritten. The shop New order email is unchanged.
Leave checkout to sign
Section titled “Leave checkout to sign”The customer signs on the WPsigner page, then chooses Continue to payment.
They should stay in the same browser until they pay. If the phone restores an older checkout page, WPsigner loads checkout again so Place order can open. Details saved when they started signing are kept.
After the purchase
Section titled “After the purchase”The document is created when the order changes to the trigger status (for example Processing or Completed). The customer can pay first.
If the feed sends the signing request by email and the trigger is Completed, the email also sends when a paid order stays on Processing. Card payments often never reach Completed.
After order chooses what happens when the document is created:
- Open signing page immediately — from the thank-you page, with checkout data already filled. Use this when the trigger status happens at checkout.
- Send signing request by email — when the order hits the trigger status. Use this for a later status, such as Completed.
Feed fields
Section titled “Feed fields”| Field | Description |
|---|---|
| Feed Name | Label for your reference (e.g., “Service Agreement”) |
| Checkout step | Dropdown: After billing, Before payments, After payments, Leave checkout to sign, or After the purchase. The drawing updates with the choice. |
| Trigger Status | Shown only for After the purchase. A Completed email feed also runs when the paid order stays on Processing. |
| Product Filter | Multi-select. Empty means all products. |
| Template | Which WPsigner template to use |
| Document Title | Supports {{signer_name}}, {{signer_email}}, {{order_id}}, {{billing_name}}, {{date}} |
| Signer Name/Email | Dropdowns. Which checkout or order field identifies the signer |
| Field mapping | Dropdown to dropdown: a template field and the checkout field that fills it. Includes line item details, amount due now, full amount, and balance due. |
| Remaining balance | On by default. A later order that points at an earlier paid order keeps the same agreement. |
| Countersign after payment | Optional email to an administrator after the customer has paid. It does not block payment. |
| After order | Shown only for After the purchase: open the signing page, or email the signing link |
Available Order Fields
Section titled “Available Order Fields”These are the choices in the WooCommerce checkout dropdown and in Name Field / Email Field. The feed shows the label, such as Billing Full Name. The key is what WPsigner stores.
All fields are read with the WC_Order API, so the integration stays compatible with HPOS.
Billing
Section titled “Billing”| Field Key | Description |
|---|---|
billing_name | Full name (first + last) |
billing_first_name | First name |
billing_last_name | Last name |
billing_email | Email address |
billing_phone | Phone number |
billing_company | Company name |
billing_address_1 | Address line 1 |
billing_address_2 | Address line 2 |
billing_city | City |
billing_state | State/Province |
billing_postcode | ZIP/Postcode |
billing_country | Country code |
Shipping
Section titled “Shipping”| Field Key | Description |
|---|---|
shipping_name | Full name |
shipping_first_name | First name |
shipping_last_name | Last name |
shipping_company | Company |
shipping_address_1 | Address line 1 |
shipping_city | City |
shipping_state | State/Province |
shipping_postcode | ZIP/Postcode |
shipping_country | Country code |
Order Details
Section titled “Order Details”| Field Key | Description |
|---|---|
order_id | Order ID |
order_number | Order number (may differ from ID) |
order_total | Total amount |
order_subtotal | Subtotal before tax/shipping |
order_tax | Tax total |
order_shipping_total | Shipping total |
order_discount | Discount total |
order_currency | Currency code (e.g., USD) |
order_date | Date created |
customer_note | Customer’s order note |
payment_method | Payment method slug |
payment_method_title | Payment method label |
product_names | Comma-separated product names |
product_skus | Comma-separated SKUs |
Booking and deposit
Section titled “Booking and deposit”| Field Key | Description |
|---|---|
line_item_details | Each product and the details WooCommerce shows on that line, such as a date, a time, a venue, or an extra |
amount_due_now | Amount this checkout charges |
full_amount | Larger rental total when the cart or order already stores it |
balance_due | Remainder, or the balance stored on the order |
Custom meta
Section titled “Custom meta”The dropdown does not list custom order meta. It lists the billing, shipping, order, payment, product, and booking fields above.
Security Measures
Section titled “Security Measures”| Measure | Implementation |
|---|---|
| Nonce verification | All 5 AJAX endpoints verify wps_ajax_nonce |
| Capability check | Admin operations require manage_options |
| Rate limiting | Max 10 documents/minute per order (transient-based) |
| Duplicate prevention | Order meta tracks which feeds have been processed |
| Status validation | Trigger status validated against WC registered statuses |
| Field whitelist | Signer fields validated against allowed order fields |
| Email validation | sanitize_email() + is_email() double check |
| Error logging | Sensitive data redacted, only logs with WP_DEBUG |
Developer Hooks
Section titled “Developer Hooks”wps_woocommerce_prepay_field_values
Section titled “wps_woocommerce_prepay_field_values”Filters the field values used to create or refresh a document during Leave checkout to sign and the other before-payment checkout steps. This runs before the document is created. WC()->cart and WC()->session are already loaded. $order is a WC_Order only when the customer is paying an existing order.
Requires WPsigner 3.3.2.19 or later. The post-purchase hook wps_woocommerce_document_created does not run on this path.
add_filter('wps_woocommerce_prepay_field_values', function ($values, $feed, $feed_id, $order, $context) { if (!function_exists('WC') || !WC()->cart) { return $values; }
foreach (WC()->cart->get_cart() as $item) { if (!is_array($item)) { continue; }
// Replace these keys with the ones your rental plugin stores on the cart item. $values['rental_qty'] = (string) ($item['quantity'] ?? ''); $values['rental_start'] = (string) ($item['rental_start'] ?? $item['start_date'] ?? ''); $values['rental_end'] = (string) ($item['rental_end'] ?? $item['end_date'] ?? ''); $values['rental_duration'] = (string) ($item['rental_duration'] ?? $item['duration'] ?? ''); $values['rental_price'] = (string) ($item['rental_price'] ?? ''); break; }
// $context['fields'] is the WPsigner template payload: field_key, variable, type. return $values;}, 10, 5);Name the WPsigner template variables the same as the keys you add (rental_start, rental_end, and so on). Those extra keys are written onto matching template fields. You can also add mapping rows with wps_woocommerce_prepay_field_mapping.
wps_woocommerce_prepay_document_created
Section titled “wps_woocommerce_prepay_document_created”Fires after that before-payment document exists and the fields have been filled. Use this when you need the document ID. It is not the post-purchase hook.
add_action('wps_woocommerce_prepay_document_created', function ($document_id, $values, $feed, $feed_id, $order, $context) { // $document_id - int // $values - array of field values // $feed - array // $feed_id - string // $order - WC_Order or null // $context - template fields and mapping}, 10, 6);wps_woocommerce_document_created
Section titled “wps_woocommerce_document_created”Fires after a document is created from a WooCommerce order (after the purchase). It does not run during Leave checkout to sign.
add_action('wps_woocommerce_document_created', function($document_id, $order, $feed, $feed_id) { // $document_id - int - The created document ID // $order - WC_Order - The WooCommerce order object // $feed - array - Feed configuration used // $feed_id - string - Feed identifier
// Example: add custom order note $order->add_order_note( sprintf('WPsigner document #%d created.', $document_id) );}, 10, 4);Troubleshooting
Section titled “Troubleshooting”Document not created after order
Section titled “Document not created after order”- Verify the feed is enabled
- If the checkout step is After billing, Before payments, After payments, or Leave checkout to sign, the document is created at checkout, not when the order status changes
- For After the purchase, check the trigger status. An email feed set to Completed also runs when the paid order stays on Processing
- If a product filter is set, ensure the order contains a matching product
- Check the WP debug log for
[WPsigner WooCommerce]entries
Customer can still place the order without signing
Section titled “Customer can still place the order without signing”- Open the feed and confirm the checkout step is not After the purchase, and the feed is enabled
- Confirm the product in the cart is selected in Product Filter (or the filter is empty)
- Update to 3.3.2.12 if the contract is not on the checkout page, or if line details and deposit totals are missing from Field mapping. Uploading the same version again replaces the files. WordPress does not offer an in-place update when the version number stays the same
Place order stays closed after signing
Section titled “Place order stays closed after signing”On iPhone, Safari can show the checkout from before the signature. 3.3.2.12 loads checkout again after Sign. The customer should stay in the same browser. A signature finished but not yet paid still opens Place order for that checkout. The next purchase asks for a new signature.
The signed PDF is not on the order email
Section titled “The signed PDF is not on the order email”The sealed PDF is attached to the customer Processing email, or the customer Completed email when the order skips Processing. It is not added to the shop New order email. The document must already be signed before that customer email is sent. Signing after payment uses the signing email instead.
Open in WPsigner on the order
Section titled “Open in WPsigner on the order”On the WooCommerce order screen, Open in WPsigner opens the document audit trail. The order also links the signed PDF.
Duplicate documents
Section titled “Duplicate documents”On checkout, one unsigned document stays with that feed. Changing the billing email, the cart, or the booking line details updates that same document instead of leaving another one on Awaiting signature. A new document is created for the next purchase, or when the previous one is already signed, declined, expired, or void.
After the purchase, each feed stores a _wps_wc_processed_{feed_id} meta on the order. Changing the order status back and forth does not create another document for the same feed. A remaining-balance order that points at that paid order keeps the same document.
The booking date is empty on the PDF
Section titled “The booking date is empty on the PDF”Map Line item details. WPsigner only fills what WooCommerce already shows on the cart line or the order line. A booking plugin that never writes the date onto that line cannot fill the PDF from settings.
To put rental start, return, duration, or price into separate template fields during Leave checkout to sign, use wps_woocommerce_prepay_field_values in 3.3.2.19 or later. Those values are not listed in the feed dropdown.
The PDF shows $300 instead of $1,000
Section titled “The PDF shows $300 instead of $1,000”Amount due now is the cart total being charged. Map Full amount and Balance due as well. Those two values appear when the order already stores a larger total or a remaining balance. If the deposit plugin never writes those figures onto the order, only the amount due now is available.
A remaining-balance order asked for another signature
Section titled “A remaining-balance order asked for another signature”Open the feed and leave Do not create another contract for a remaining-balance order checked. The later order must point at the earlier paid order. An independent second purchase still requires a new signature.
The administrator did not get a countersignature email
Section titled “The administrator did not get a countersignature email”Open the feed, check Ask an administrator to countersign after payment, and save Countersign email. The email is sent after the customer pays, not before. It uses the usual WPsigner signing request.
An amended booking did not create a new document
Section titled “An amended booking did not create a new document”The original sealed PDF is never rewritten. An amendment is created when a paid order is saved and the line details or the three amounts changed. Draft or unpaid checkouts ask for a new signature instead.
WooCommerce not detected
Section titled “WooCommerce not detected”The integration requires class_exists('WooCommerce') to be true. Ensure WooCommerce is active and not deactivated by another plugin.
HPOS Compatibility {#hpos-compatibility}
Section titled “HPOS Compatibility {#hpos-compatibility}”This integration uses WC_Order getters exclusively ($order->get_billing_email(), etc.) and $order->update_meta_data() + $order->save() for meta storage. It is fully compatible with WooCommerce HPOS (High-Performance Order Storage) and Cart/Checkout Blocks.
WPsigner declares those features on before_woocommerce_init. In 3.2.12+ that declaration runs even if recovery mode skipped the rest of the plugin, so Plugins → Incompatible with WooCommerce features should not list WPsigner after a recovered fatal. Click re-enable the plugin if the recovery notice is still visible, then view All plugins.