Signing & E-Signature Audit

ClientCove's E-Signature system is browser-based: signers verify their identity with a one-time passcode, draw their signature directly in the browser, and the system generates a cryptographically hashed signed PDF with a complete audit trail. No external e-sign account needed.

The Signing Flow

A recipient's path from email to signed contract:

  1. Receive the notification email with a "View Contract" link
  2. Click the link — auto-authenticates and lands on the contract's view page
  3. Status flips from Pending → Viewed in the recipients table; viewed_date is stamped
  4. Review the PDF in the embedded viewer
  5. Click Sign Contract
  6. OTP request — choose Email or SMS (if both are enabled), receive a 6-digit code
  7. Enter the code on screen — verification is logged with timestamp + IP
  8. Signature pad opens — draw signature with mouse or touch
  9. Confirm — ClientCove generates the signed PDF, applies the signature image to all your placed fields, and computes the SHA-256 hash
  10. Status flips to Signed, sign_date is stamped, sender is notified
  11. Signer sees a confirmation page with download link to the signed PDF

The whole flow takes 60–90 seconds for most signers.

OTP Verification

A one-time passcode confirms the signer is who the contract was sent to (not someone who happened to get the email forwarded).

How it works

  1. Signer clicks Sign Contract
  2. ClientCove generates a 6-digit code, stores it in wp_ccesign_otps with a 10-minute expiry
  3. The code is delivered via the configured method (Email or SMS)
  4. Signer enters the code on the contract page
  5. ClientCove verifies — match + not expired = success
  6. The verification is logged in the audit table with timestamp, IP, and user agent

What if the code expires?

The signer can request a new code from the OTP entry screen. The new code invalidates the old one.

What if delivery fails?

If email delivery is configured wrong (no SMTP) or SMS isn't set up, the OTP send will silently fail and the signer will see "Code sent" without receiving anything. Verify your email/SMS configuration in Settings → Email and Settings → SMS before going live.

OTP Methods: Email vs SMS

The OTP delivery method is set per contract via the esign_otp_method field:

MethodSetup RequiredBest For
Email (default)WP Mail SMTP + a transactional sender (SendGrid, Mailgun, SES)Default — works for any signer with an email address
SMSTwilio configured in Settings → SMSSigners who want a phone-based 2FA experience
BothBoth configuredSigner picks per-sign

When Both is enabled, the signing page shows a method picker:

  • Email — code sent to the signer's profile email
  • SMS — code sent to the signer's profile phone

If you want SMS, the signer needs a phone number in their WordPress user profile.

Drawing the Signature

After OTP verification, the signature pad opens.

The pad

  • A blank canvas sized to roughly match a real signature
  • Mouse / trackpad / touch — draw with continuous strokes
  • Clear button — wipe the canvas if you make a mistake
  • Cancel — bails out of the signing flow without saving

Behavior on confirm

  1. The drawn signature is captured as a PNG
  2. ClientCove applies the PNG to every signature field placed for this signer
  3. Initial fields are auto-filled from the first letter(s) of each name part
  4. Name fields get the signer's full display name typed in
  5. Date fields get the current date

The same signature image is reused across all signature fields for this signer in this contract — they only draw it once, no matter how many places need their signature.

Multi-Signer Contracts

When a contract has multiple signers, each signer signs independently in their own browser session.

Per-signer state

The contract page intelligently shows different content based on who's viewing:

Viewer stateWhat they see
Hasn't signedSign Contract button, signing flow available
Already signedTheir signed PDF + audit certificate
Doesn't have signing permissionView-only access to the original PDF

For multi-recipient template sends, each recipient has their own submission post — so signing one recipient's copy doesn't affect another's.

Order of signing

Multi-signer contracts don't enforce a signing order — any signer can sign first, second, or last. The contract status only flips to Signed when all signers complete.

If you need ordered signing (signer 2 only sees the contract after signer 1 finishes), implement that with separate contracts: send contract A to signer 1, configure a content access grant on signing that unlocks contract B for signer 2.

Declining a Contract

A signer who doesn't want to sign can decline:

  1. On the contract page, click Decline
  2. A reason prompt appears (optional but recommended)
  3. Submit
  4. Status flips to Declined for this signer
  5. The rejection is logged: who, when, reason
  6. The sender is notified

For multi-signer contracts, declining by one signer doesn't void the entire contract. The contract stays open for other signers, but the contract status will never reach Signed until either:

  • The declining signer reverses (rare; usually you'd void and re-send)
  • An admin removes the declining signer from the contract

The Signed PDF

ClientCove generates the signed PDF on the server-side after each signer completes:

  1. Take the original PDF template
  2. Composite each placed field with the signer's signature image, initial, name, or date
  3. Flatten the layers into a single signed PDF
  4. Store in cloud storage (Google Cloud Storage by default)
  5. Save the public/signed URL to the signed_pdf (or submission_signed_pdf for submissions) field
  6. Compute the SHA-256 hash of the resulting PDF

The signed PDF is what recipients download — the original template is preserved separately.

PDF Hash & Integrity

After signing, ClientCove stores a SHA-256 hash of the signed PDF in the esign_pdf_hash field.

This hash:

  • Is computed once at signing time
  • Is stored alongside the signature record
  • Can be re-computed at any time on the stored PDF and compared to the original hash to prove the file hasn't been altered

If you ever need to defend the contract in a dispute, the hash gives you a cryptographic proof that the PDF on file is byte-for-byte identical to what was signed.

To verify manually:

  1. Download the signed PDF
  2. Compute its SHA-256 hash with shasum -a 256 <file> or any hash tool
  3. Compare to the esign_pdf_hash value in the contract record
  4. Match = file is intact; mismatch = file has been altered after signing

The Audit Trail

Every event in the signing flow is logged to the wp_ccesign_audits table:

FieldPurpose
post_idThe contract or submission
eventWhat happened (viewed, otp_requested, otp_verified, signed, declined, resent)
actor_idThe user who triggered the event
ip_addressTheir IP at the time
user_agentTheir browser/OS string
metadataJSON blob with event-specific details (OTP method, signature dimensions, etc.)
timestampWhen it happened

The audit table is append-only — entries are never modified or deleted.

Signing Certificate

After signing, the contract page displays a Signing Certificate section showing the audit trail in human-readable form.

For each signer, the certificate shows:

  • Signer name and email
  • Date and time of signature
  • IP address and approximate location
  • OTP delivery method used
  • A list of audit events with timestamps

The certificate is included with the signed PDF when the recipient downloads — they get both the signed document and the proof of signing.

For multi-recipient contracts, each submission has its own certificate showing only that recipient's events.

Was this page helpful?