# Collect customer signature at checkout

Source: https://support.storeconnect.com/articles/collect-an-e-signature-at-checkout · Last modified 21 August 2026

To collect an e-signature during the checkout process, you'll need to integrate a custom form that allows customers to digitally sign an agreement. This feature is useful for terms acceptance, donation authorization, or any other legal acknowledgment required before payment.

Below are the procedure steps to successfully configure and render this feature using StoreConnect and Salesforce.

## Before you begin

-   Check that you are using StoreConnect **version 19 or later**.


## Set up a checkout form with an e-signature

### Add a checkout form

1.  In Salesforce, go to **App Launcher** and search **Forms**.
2.  Select the **Form Type** as **Checkout Form**.
3.  Give the form a **Name** and select **Save**. 

See the [Checkout forms](https://support.getstoreconnect.com/article/Checkout-Form "Checkout forms") topic for more information.

### Add the e-signature form question

1.  In the **Related** tab of the new form, select **New** in the **Form Questions** section.
2.  Set the **Data Type** as **Text.** (This is required because the signature is saved as a Base64 PNG string.)
3.  Set the **Required** field as **True**.
4.  Set the **Hidden** field as **True**.
5.  Copy this markdown code and paste it in the **Question (Markdown)** field.
    
6.  Select **Save**.

This adds the signature field to the form in the checkout flow.

### Add the e-signature snippet to your theme

You also need to update your theme, so that the signature block appears correctly on the checkout page.

1.  Open the theme that you want to add the signature block to.
2.  In the **Theme Template** section, select **New**.
3.  Enter snippets/shared/e\_signature as the **Key.**
4.  Copy and paste the code below into the **Content** area of the template record, then select **Save**. Make sure to include the full code snippet.

```javascript

  E-Signature










        Signature is required.


        Signed!





        Clear


        Save







    // Shared selector for submit buttons
    const SC_SUBMIT_BUTTON_SELECTORS = [
      'button[data-payment-info-submit]',
      'button[data-disable-with]',
      'button[type="submit"]',
      'input[type="submit"]',
      'button.SC-Button-primary'
    ].join(', ');

    // Initialise one signature block
    function initSignatureBlock(signatureEl) {
      if (!signatureEl || signatureEl.dataset.initialized === 'true') return;
      signatureEl.dataset.initialized = 'true';

      const signatureCanvas = signatureEl.querySelector('[data-signature-canvas]');
      if (!signatureCanvas) return;

      const signaturePad = new SignaturePad(signatureCanvas, {
        backgroundColor: 'rgb(255,255,255)',
        penColor: 'rgb(0,0,0)'
      });

      const signaturePreview = signatureEl.querySelector('[data-signature-preview]');
      const signatureClear   = signatureEl.querySelector('[data-signature-clear]');
      const signatureSave    = signatureEl.querySelector('[data-signature-save]');
      const signatureSubmit  = signatureEl.querySelector('[data-signature-submit]');
      const alertRequired    = signatureEl.querySelector('[data-signature-alert-required]');
      const alertSigned      = signatureEl.querySelector('[data-signature-alert-signed]');

      // Hide the backing answer input for THIS question
      const container = signatureEl.closest('label, section');
      const signatureAnswerInput = container
        ? container.querySelector('input[name^="answers["][name$="][answer]"]')
        : null;
      if (signatureAnswerInput) signatureAnswerInput.classList.add('sc-hide');

      function showAlert(el) {
        if (!el) return;
        el.classList.remove('sc-hide');
        setTimeout(() => el.classList.add('sc-hide'), 5000);
      }

      function hideAlerts() {
        if (alertRequired) alertRequired.classList.add('sc-hide');
        if (alertSigned)   alertSigned.classList.add('sc-hide');
      }

      // Clear button
      signatureClear?.addEventListener('mousedown', () => {
        signaturePad.clear();
        if (signaturePreview) {
          signaturePreview.classList.add('sc-hide');
          signaturePreview.removeAttribute('src');
        }
        signatureCanvas.classList.remove('sc-hide');
        signatureSave?.classList.remove('sc-hide');
        signatureSubmit?.classList.add('sc-hide');
        hideAlerts();
        if (signatureAnswerInput) signatureAnswerInput.value = '';
      });

      // Save button
      signatureSave?.addEventListener('click', () => {
        hideAlerts();

        if (signaturePad.isEmpty()) {
          showAlert(alertRequired);
          return;
        }

        const dataURL = signaturePad.toDataURL('image/png');

        if (signaturePreview) {
          signaturePreview.src = dataURL;
          signaturePreview.classList.remove('sc-hide');
        }
        signatureCanvas.classList.add('sc-hide');

        signatureSave.classList.add('sc-hide');
        signatureSubmit?.classList.remove('sc-hide');

        if (signatureAnswerInput) {
          signatureAnswerInput.value = dataURL;
        }

        showAlert(alertSigned);
      });

      // Require a signature on submit for THIS form
      const form = signatureEl.closest('form');
      if (form) {
        form.addEventListener('submit', (e) => {
          if (signaturePad.isEmpty() && !(signatureAnswerInput && signatureAnswerInput.value)) {
            e.preventDefault();
            showAlert(alertRequired);
          }
        });

        // Move this signature block above this form's submit button
        const submitBtn = form.querySelector(SC_SUBMIT_BUTTON_SELECTORS);
        if (submitBtn && !signatureEl.dataset.moved) {
          submitBtn.parentNode.insertBefore(signatureEl, submitBtn);
          signatureEl.dataset.moved = 'true';
        }
      }
    }

    // Initialise all signature blocks currently in the DOM
    function initAllSignatures() {
      document.querySelectorAll('.SC-Signature').forEach(initSignatureBlock);
    }

    if (document.readyState === 'loading') {
      document.addEventListener('DOMContentLoaded', initAllSignatures);
    } else {
      initAllSignatures();
    }

    // Watch for payment provider DOM changes (tabs switching, etc.)
    const observer = new MutationObserver(() => {
      setTimeout(initAllSignatures, 50);
    });
    observer.observe(document.body, { childList: true, subtree: true });

    window.addEventListener('beforeunload', () => observer.disconnect());

    // Auto-click "Save" when any submit-like button is clicked
    document.addEventListener('click', (e) => {
      if (!e.target.closest(SC_SUBMIT_BUTTON_SELECTORS)) return;

      document.querySelectorAll('.SC-Signature [data-signature-save]').forEach((btn) => {
        if (!(btn instanceof HTMLButtonElement)) return;
        btn.click();
      });
    });

    if (window.location.pathname.includes('/account/orders')) {
      function hideSignaturePanel() {
        document.querySelectorAll('[data-e-signature]').forEach((field) => {
          const panel = field.closest('.Panel');
          if (panel) panel.classList.add('sc-hide');
        });
      }

      if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', hideSignaturePanel);
      } else {
        hideSignaturePanel();
      }

      const observer = new MutationObserver(() => {
        setTimeout(hideSignaturePanel, 100);
      });
      observer.observe(document.body, { childList: true, subtree: true });
    }
```

## Preview the change in your store

We recommend checking the template element in your own store's checkout, to verify that it looks correct and works. Here's an example of what the signature block might look.

![Store checkout showing e-signature field](https://res.cloudinary.com/hzkr6fi81/image/upload/v1763686945/knowledge/themes/Theme_AddEsignature_xxwmwt.png)

## Manage e-signatures

### The user experience

The user draws their signature in the E-Signature block area.

-   To re-draw the signature, the user can click **Clear.**
-   The form **cannot be submitted** unless a signature is saved.
-   To save the signature, the user clicks **Save**. The signature image is stored as a Base64 PNG in Salesforce.
-   If the user tries to submit their order without a signature, an error will show.
-   If the user enter their signature and tries to submit the form, a background script automatically attempts to save the signature first.

### Image storage and visibility

When saved, the signature is stored in a hidden field in Salesforce and Base64 encoded.

-   The underlying form’s hidden answer input is automatically filled.
-   The signature UI is moved above the checkout submit button.

If you want to be able to view a customer's signature as an image in Salesforce, you need to create a Salesforce Flow to:

-   Display the PNG image

-   Store the signature elsewhere.

If you decide to set this up, the signature is saved as standard **Custom Form Answer** text data.

---

## Follow StoreConnect

- [Email Newsletter](https://getstoreconnect.com/c/lp-newsletter)
- [LinkedIn Newsletter](https://www.linkedin.com/build-relation/newsletter-follow?entityUrn=7444956928444862464)
- [YouTube](https://www.youtube.com/channel/UCngKdP2x8l1wcbAKW3tvU8g)
- [LinkedIn](https://www.linkedin.com/company/storeconnect)
- [X / Twitter](https://x.com/storeconnecthq)

## Popular Links

- [Partners](https://getstoreconnect.com/partners)
- [News](https://getstoreconnect.com/articles/news)
- [Events](https://getstoreconnect.com/articles/events)
- [Feature Comparison](https://getstoreconnect.com/how-we-compare)
- [Download a free trial](https://appexchange.salesforce.com/appxListingDetail?listingId=a0N3A00000FMkeKUAT)
- [Book a Demo](https://getstoreconnect.com/contact)

## Documentation

- [Help documentation](https://support.storeconnect.com/help-documentation)
- [AI agents](https://support.storeconnect.com/ai)
- [Videos & tutorials](https://support.storeconnect.com/videos-tutorials)
- [Developer reference](https://support.storeconnect.com/developer-reference)
- [Release notes](https://support.storeconnect.com/release-notes)
- [Troubleshooting](https://support.storeconnect.com/troubleshooting)
- [Trust Center](https://trust.getstoreconnect.com/)
- [Status Page](https://status.storeconnect.com/)

## Contact

- info@getstoreconnect.com
- US +1 415 745 3230
- AUS +61 2 8365 2308

100 S Ashley Dr, Suite 600-2461
Tampa FL 33602-600 USA

Level 22, Sydney Place
180 George Street
Sydney, NSW, 2000, AUS

---

StoreConnect Support — https://support.storeconnect.com/articles/collect-an-e-signature-at-checkout