Basic embedded signing

This example shows how a paying DocuSign customer can login, send, and sign an envelope.

by Larry Kluger

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.3/css/bootstrap.min.css">
<container class="c">
  <!-- top element -->
  <container class="ctop">
    <container class="fixh">
      <container class="col2parent">
        <h3 class="child1">
          Basic Embedded Signing</h3>
        <div id="login" class="child2">
          <a id="btnOauth" class="btn btn-primary" type="button" role="button">
            Login with DocuSign</a>
          <p>
            Use your DocuSign Developer Account. Don't have one?
            <a href="https://go.docusign.com/o/sandbox/?utm_campaign=GBL_XX_DEV_NEW_2208_ExternalProgrammingTools&utm_medium=display&utm_source=jsfiddle" target="_blank">Free signup!</a>
          </p>
        </div>


      </container>
      <p>
        This example shows how a DocuSign customer can login and send a basic envelope. <br />Then sign the envelope with an embedded signing ceremony.
      </p>
      <p><small>
          If the signer does not have a DocuSign account, then either use a PowerForm, or use JWT authentication with a server-based application.
          This example uses Implicit Grant authentication and CORS. Therefore the user must have their own login with a DocuSign account.
        </small></p>
      <section id="spinner" class="hide">
        <div class="spinner">
          <div class="rect1"></div>
          <div class="rect2"></div>
          <div class="rect3"></div>
          <div class="rect4"></div>
          <div class="rect5"></div>
        </div>
      </section>
      <div id="doit" class="hide">
        <a id="btnDoit" class="btn btn-primary" type="button" role="button">
          Send and Sign an Envelope</a>
      </div>

    </container>
  </container>

  <!-- The resizer -->
  <div class="resizer" id="dragMe"></div>
  <!-- Right element -->
  <container class="cbottom">
    <container class="fixh">
      <h3>
        Log
      </h3>
      <p id="log">
        You can adjust the...

CSS

html,
body {
  height: 100%;
  margin: 0;
}

container.c {
  display: flex;
  flex: 1;
  flex-direction: column;
  border: 1px solid #cbd5e0;
  height: 100%;
  width: 100%;
}

container.ctop {
  display: flex;
  height: 25rem;
  padding: 1em;
  overflow-y: scroll;
}

container.cbottom {
  display: flex;
  flex: 1;
  padding: 1em;
  overflow-y: scroll;
}

container.fixh {
  width: 100%;
}

container.col2parent {
  display: flex;
  flex-direction: row;
}

.child1 {
  width: 50%;
}

.child2 {
  width: 50%;
}


div.resizer {
  width: 100%;
  cursor: row-resize;
  height: 3px;
  background-color: #cbd5e0;
}

pre {
  text-align: left;
  background-color: aliceblue;
  font-size: smaller;
  margin: 15px;
}

.panel {
  margin: 50px 75px;
}

.hide {
  display: none;
}

/* From http://tobiasahlin.com/spinkit/ */
.spinner {
  margin: auto;
  width: 150px;
  height: 140px;
  text-align: center;
  font-size: 10px;
}

.spinner>div {
  background-color: blueviolet;
  height: 100%;
  width: 6px;
  display: inline-block;
  -webkit-animation: sk-stretchdelay 1.2s infinite ease-in-out;
  animation: sk-stretchdelay 1.2s infinite ease-in-out;
}

.spinner .rect2 {
  -webkit-animation-delay: -1.1s;
  animation-delay: -1.1s;
}

.spinner .rect3 {
  -webkit-animation-delay: -1.0s;
  animation-delay: -1.0s;
}

.spinner .rect4 {
  -webkit-animation-delay: -0.9s;
  animation-delay: -0.9s;
}

.spinner .rect5 {
  -webkit-animation-delay: -0.8s;
  animation-delay: -0.8s;
}

@-webkit-keyframes sk-stretchdelay {

  0%,
  40%,
  100% {
    -webkit-transform: scaleY(0.4)
  }

  20% {
    -webkit-transform: scaleY(1.0)
  }
}

@keyframes sk-stretchdelay {

  0%,
  40%,
  100% {
    transform: scaleY(0.4);
    -webkit-transform: scaleY(0.4);
  }

  20% {
    transform: scaleY(1.0);
    -webkit-transform: scaleY(1.0);
  }
}

JavaScript

// Copyright © 2022 DocuSign, Inc.
// License: MIT Open Source https://opensource.org/licenses/MIT
$(function() {

  // Set basic variables
  const oAuthServiceProvider = "https://account-d.docusign.com";
  // const oAuthServiceProvider = "https://account-s.docusign.com";
  const implicitGrantPath = "/oauth/auth";
  const userInfoPath = "/oauth/userinfo";
  // Client IDs are NOT secrets. See
  // https://www.rfc-editor.org/rfc/rfc6749.html#section-2.2
  const oAuthClientID = "d70c3a89-97b9-48d1-8bf3-5401cbbd6f82";
  const oAuthScopes = "signature";
  const eSignBase = '/restapi/';
  const oAuthReturnUrl = "https://docusign.github.io/jsfiddleImplicitGrantReturn.html";
  const dsReturnUrl = "https://docusign.github.io/jsfiddleDsResponse.html";
  const logLevel = 1; // 0 is terse; 9 is verbose
  const apiBaseUrl = "https://demoproxy.worldwidecorp.us/restapi/v2.1";
  // const apiBaseUrl = "https://stage.docusign.net/restapi/v2.1";
  let signingCeremonyWindow = null;

  // Example settings
  const docUrl = "https://docusign.github.io/examples/docs/anchorfields.pdf";
  const docViewUrl = "https://docusign.github.io/examples/docs/anchorfields_view.pdf"

  debugger; // uncomment with debugger open to find the right JS file.

  /*
   * The doit function is the example that is triggered by the
   * button. The user is already logged in (we have an access token).
   */
  let doit = async function doitf(event) {
    $("#doit").addClass("hide");
    if (!checkToken()) { // Check that we have a valid token
      return
    }
    workingUpdate(true);
    const signer = {
      name: data.userInfo.name,
      email: data.userInfo.email,
      clientUserId: 1000
    }
    const envelopeId = await createEnvelope(signer);
    if (envelopeId) {
      msg(`Envelope ${envelopeId} created.`);
      await embeddedSigningCeremony({
        envelopeId: envelopeId,
        signer: signer
      })
    }
    $("#doit").removeClass("hide");
    workingUpdate(false);
  }
  doit =...