Feature Specification: DocuSign eSignature API Integration

Overview

Feature Name: DocuSign eSignature Integration for Document Management & Approvals
Category: AP Excellence (Phase 1) + Compliance & Strategic Finance (Phase 4)
Priority: High
Target Users: CFOs, Controllers, Approvers, Vendors, Steuerberater
Dependencies: AI Approval Intelligence, Document & Contract Management V1, GoBD-Compliant Storage


Executive Summary

DocuSign is the world's leading electronic signature platform, offering a comprehensive REST API with 400+ endpoints for programmatic document signing, routing, and tracking. By integrating DocuSign into Orcha, we transform our approval workflow from a digital process to a legally binding, audit-compliant signature system that meets German legal standards (eIDAS, BGB §126a) while dramatically accelerating approval cycles.

Key Value Proposition:


Business Problem

The Challenge: Approvals ≠ Signatures

Current State in Orcha: Our AI Approval Intelligence (Phase 1.1) provides:

What's Missing:

  1. Legal Enforceability: A click in our UI isn't a legally binding signature
  2. External Parties: Vendors and external approvers need secure access
  3. Contract Execution: Purchase orders, master service agreements, amendments
  4. Audit Requirements: Some transactions require qualified electronic signatures (QES)
  5. Non-Repudiation: Proof that a specific person approved at a specific time

The Gap:

Real-World Use Cases

1. Purchase Order Approval (Internal)

2. Master Service Agreement Execution (External)

3. Invoice Approval with Signature (Compliance-Heavy)

4. Steuerberater Handoff (Monthly Close)


Solution: DocuSign eSignature API Integration

What We Build

A bidirectional integration between Orcha and DocuSign that enables:

  1. Outbound: Send documents from Orcha to DocuSign for signature
  2. Inbound: Receive signed documents back into Orcha storage
  3. Status Tracking: Real-time updates on signature status
  4. Template Management: Reusable templates for common documents
  5. Audit Trail: Complete record of all signature events

DocuSign API Architecture

Core Concepts

1. Envelopes

An envelope is a container for documents requiring signatures.

Envelope
├── Documents (1-n): PDFs, Word docs, etc.
├── Recipients (1-n): Signers, approvers, carbon copies
├── Tabs (fields): Signature boxes, date fields, text fields
├── Routing Order: Sequential or parallel signing
└── Status: Created → Sent → Delivered → Completed

Example:

{
  "envelopeId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "sent",
  "emailSubject": "Please sign: Purchase Order PO-2024-1234",
  "documents": [
    {
      "documentId": "1",
      "name": "PO-2024-1234.pdf",
      "order": 1
    }
  ],
  "recipients": {
    "signers": [
      {
        "recipientId": "1",
        "email": "vendor@acmesupplies.de",
        "name": "Johann Schmidt",
        "routingOrder": 1
      }
    ]
  },
  "status": "sent",
  "sentDateTime": "2026-01-05T10:30:00Z"
}

2. Recipients & Routing

Control who signs and in what order.

Recipient Types:

Routing Options:

Orcha Use Case:

Purchase Order Approval Flow:
1. Department Head (Signer) → Approves PO
2. CFO (Signer, if > €10K) → Additional approval
3. Vendor (Signer) → Acknowledges terms
4. AP Team (CC) → Receives final signed copy

3. Templates

Reusable document templates with predefined fields.

Benefits:

Orcha Templates:

Example:

{
  "templateId": "t1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "name": "Purchase Order Approval",
  "documents": [
    {
      "name": "Standard PO",
      "fileExtension": "pdf",
      "order": 1
    }
  ],
  "recipients": {
    "signers": [
      {
        "roleName": "Department Head",
        "routingOrder": 1,
        "tabs": {
          "signHereTabs": [
            {
              "anchorString": "/dept_sig/",
              "anchorXOffset": "0",
              "anchorYOffset": "0"
            }
          ]
        }
      },
      {
        "roleName": "Vendor",
        "routingOrder": 2,
        "tabs": {
          "signHereTabs": [
            {
              "anchorString": "/vendor_sig/",
              "anchorXOffset": "0",
              "anchorYOffset": "0"
            }
          ]
        }
      }
    ]
  }
}

4. Tabs (Fields)

Interactive elements placed on documents.

Common Tab Types:

Anchor-Based Positioning: Instead of pixel coordinates, use text anchors:

{
  "signHereTabs": [
    {
      "anchorString": "Authorized Signature:",
      "anchorXOffset": "100",
      "anchorYOffset": "-5"
    }
  ]
}

5. Webhooks (DocuSign Connect)

Real-time event notifications.

Key Events:

Orcha Webhook Handler:

(defn docusign-webhook-handler
  [request]
  (let [event (parse-docusign-event (:body request))
        envelope-id (:envelopeId event)
        status (:status event)]
    (case status
      "completed" (handle-completed-envelope envelope-id)
      "declined" (handle-declined-envelope envelope-id)
      "voided" (handle-voided-envelope envelope-id)
      (log-event event))))

(defn handle-completed-envelope
  [envelope-id]
  ;; 1. Fetch signed document from DocuSign
  (let [signed-doc (fetch-signed-document envelope-id)]
    ;; 2. Store in Orcha GoBD-compliant storage
    (store-document signed-doc {:type :signed-contract
                                 :docusign-envelope envelope-id})
    ;; 3. Update approval status in database
    (update-approval-status envelope-id :completed)
    ;; 4. Trigger downstream workflows (e.g., activate PO)
    (activate-purchase-order envelope-id)))

DocuSign API: Key Endpoints

Authentication: OAuth 2.0

Authorization Code Grant (Recommended for Orcha):

  1. User Consent: Redirect user to DocuSign login
GET https://account.docusign.com/oauth/auth
  ?response_type=code
  &scope=signature impersonation
  &client_id=YOUR_INTEGRATION_KEY
  &redirect_uri=https://orcha.com/oauth/callback
  1. Exchange Code for Token:
POST https://account.docusign.com/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=AUTHORIZATION_CODE
&client_id=YOUR_INTEGRATION_KEY
&client_secret=YOUR_SECRET_KEY
  1. Response:
{
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
  "token_type": "Bearer",
  "expires_in": 28800,
  "refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGc..."
}

Token Storage in Orcha:

CREATE TABLE docusign_tokens (
  user_id UUID PRIMARY KEY REFERENCES users(id),
  access_token TEXT NOT NULL,
  refresh_token TEXT NOT NULL,
  expires_at TIMESTAMP NOT NULL,
  account_id TEXT NOT NULL,
  base_uri TEXT NOT NULL,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

Core API Endpoints

1. Create Envelope from Document

Endpoint: POST /v2.1/accounts/{accountId}/envelopes

Request:

{
  "emailSubject": "Please sign: Purchase Order PO-2024-1234",
  "status": "sent",
  "documents": [
    {
      "documentBase64": "JVBERi0xLjQKJeLjz9MKMy...",
      "name": "PO-2024-1234.pdf",
      "fileExtension": "pdf",
      "documentId": "1"
    }
  ],
  "recipients": {
    "signers": [
      {
        "email": "dept.head@company.de",
        "name": "Maria Weber",
        "recipientId": "1",
        "routingOrder": "1",
        "tabs": {
          "signHereTabs": [
            {
              "anchorString": "/dept_sig/",
              "anchorXOffset": "0",
              "anchorYOffset": "0"
            }
          ],
          "dateSignedTabs": [
            {
              "anchorString": "/date/",
              "anchorXOffset": "0",
              "anchorYOffset": "0"
            }
          ]
        }
      }
    ]
  }
}

Response:

{
  "envelopeId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "sent",
  "uri": "/envelopes/a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}

2. Create Envelope from Template

Endpoint: POST /v2.1/accounts/{accountId}/envelopes

Request:

{
  "templateId": "t1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "templateRoles": [
    {
      "roleName": "Department Head",
      "name": "Maria Weber",
      "email": "maria.weber@company.de",
      "tabs": {
        "textTabs": [
          {
            "tabLabel": "PO_Number",
            "value": "PO-2024-1234"
          },
          {
            "tabLabel": "Amount",
            "value": "€8,450.00"
          }
        ]
      }
    },
    {
      "roleName": "Vendor",
      "name": "Johann Schmidt",
      "email": "johann@acmesupplies.de"
    }
  ],
  "status": "sent"
}

3. Get Envelope Status

Endpoint: GET /v2.1/accounts/{accountId}/envelopes/{envelopeId}

Response:

{
  "envelopeId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "completed",
  "statusChangedDateTime": "2026-01-05T14:22:15Z",
  "emailSubject": "Please sign: Purchase Order PO-2024-1234",
  "recipients": {
    "signers": [
      {
        "email": "maria.weber@company.de",
        "name": "Maria Weber",
        "status": "completed",
        "signedDateTime": "2026-01-05T11:15:30Z"
      },
      {
        "email": "johann@acmesupplies.de",
        "name": "Johann Schmidt",
        "status": "completed",
        "signedDateTime": "2026-01-05T14:22:10Z"
      }
    ]
  }
}

4. Download Signed Document

Endpoint: GET /v2.1/accounts/{accountId}/envelopes/{envelopeId}/documents/{documentId}

Headers:

Authorization: Bearer {access_token}
Accept: application/pdf

Response: Binary PDF data

Orcha Implementation:

(defn download-signed-document
  [account-id envelope-id document-id]
  (let [url (str "https://demo.docusign.net/restapi/v2.1/accounts/"
                 account-id "/envelopes/" envelope-id
                 "/documents/" document-id)
        response (http/get url
                           {:headers {"Authorization" (str "Bearer " (get-access-token))
                                      "Accept" "application/pdf"}
                            :as :byte-array})]
    (:body response)))

5. Get Audit Trail (Certificate of Completion)

Endpoint: GET /v2.1/accounts/{accountId}/envelopes/{envelopeId}/documents/certificate

Response: PDF with complete audit trail including:

GoBD Compliance: This certificate is legally recognized in Germany for audit purposes.

6. Void Envelope (Cancel)

Endpoint: PUT /v2.1/accounts/{accountId}/envelopes/{envelopeId}

Request:

{
  "status": "voided",
  "voidedReason": "Purchase order canceled by department head"
}

Integration Architecture

System Design: Orcha ↔ DocuSign

┌──────────────────────────────────────────────────────────────────┐
│  ORCHA PLATFORM                                                  │
├──────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌────────────────────────────────────────────────────────┐    │
│  │  AI APPROVAL INTELLIGENCE                              │    │
│  │  (Existing Phase 1.1)                                  │    │
│  │                                                        │    │
│  │  • 4-way match validation                             │    │
│  │  • AI explainability                                  │    │
│  │  • Decision consequences                              │    │
│  │  • Policy checks                                      │    │
│  └─────────────────┬──────────────────────────────────────┘    │
│                    │                                            │
│                    │ Approval decision made                     │
│                    │                                            │
│                    ▼                                            │
│  ┌────────────────────────────────────────────────────────┐    │
│  │  DOCUSIGN INTEGRATION SERVICE (NEW)                    │    │
│  ├────────────────────────────────────────────────────────┤    │
│  │                                                        │    │
│  │  📤 OUTBOUND                                           │    │
│  │  ├─ Create envelope from document                     │    │
│  │  ├─ Create envelope from template                     │    │
│  │  ├─ Add recipients & routing rules                    │    │
│  │  ├─ Position signature tabs                           │    │
│  │  └─ Send for signature                                │    │
│  │                                                        │    │
│  │  📥 INBOUND                                            │    │
│  │  ├─ Receive webhook events                            │    │
│  │  ├─ Download signed documents                         │    │
│  │  ├─ Fetch audit trail (Certificate of Completion)     │    │
│  │  └─ Update Orcha approval status                      │    │
│  │                                                        │    │
│  │  🔄 STATUS TRACKING                                    │    │
│  │  ├─ Real-time status dashboard                        │    │
│  │  ├─ Reminder automation                               │    │
│  │  └─ Escalation workflows                              │    │
│  │                                                        │    │
│  └─────────────────┬──────────────────────────────────────┘    │
│                    │                                            │
│                    ▼                                            │
│  ┌────────────────────────────────────────────────────────┐    │
│  │  DOCUMENT MANAGEMENT (Existing Phase 1.2)              │    │
│  │                                                        │    │
│  │  • GoBD-compliant storage                             │    │
│  │  • Immutable audit trail                              │    │
│  │  • Version control                                    │    │
│  │  • Search & retrieval                                 │    │
│  └────────────────────────────────────────────────────────┘    │
│                                                                  │
└──────────────────────────────────────────────────────────────────┘
                              ↕ HTTPS (OAuth 2.0)
┌──────────────────────────────────────────────────────────────────┐
│  DOCUSIGN eSignature REST API                                   │
├──────────────────────────────────────────────────────────────────┤
│                                                                  │
│  • 400+ API Endpoints                                           │
│  • Envelope Management                                          │
│  • Template Management                                          │
│  • Recipient Routing                                            │
│  • Webhook Events (DocuSign Connect)                            │
│  • Certificate of Completion (Audit Trail)                      │
│  • eIDAS Compliance (EU)                                        │
│                                                                  │
└──────────────────────────────────────────────────────────────────┘
                              ↕
┌──────────────────────────────────────────────────────────────────┐
│  RECIPIENTS                                                      │
├──────────────────────────────────────────────────────────────────┤
│                                                                  │
│  • Department Heads (Internal)                                  │
│  • CFO / Controllers (Internal)                                 │
│  • Vendors (External)                                           │
│  • Steuerberater (External)                                     │
│  • External Auditors (External)                                 │
│                                                                  │
└──────────────────────────────────────────────────────────────────┘

Data Model

-- DocuSign Configuration
CREATE TABLE docusign_config (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES tenants(id),
  integration_key TEXT NOT NULL,
  secret_key_encrypted TEXT NOT NULL,
  account_id TEXT NOT NULL,
  base_uri TEXT NOT NULL,
  is_active BOOLEAN DEFAULT TRUE,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

-- DocuSign Tokens (per user)
CREATE TABLE docusign_tokens (
  user_id UUID PRIMARY KEY REFERENCES users(id),
  access_token TEXT NOT NULL,
  refresh_token TEXT NOT NULL,
  expires_at TIMESTAMP NOT NULL,
  account_id TEXT NOT NULL,
  base_uri TEXT NOT NULL,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

-- Templates
CREATE TABLE docusign_templates (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES tenants(id),
  template_id TEXT NOT NULL, -- DocuSign template ID
  name TEXT NOT NULL,
  description TEXT,
  document_type TEXT NOT NULL, -- 'purchase_order', 'contract', 'invoice_approval', etc.
  roles JSONB NOT NULL, -- Array of role definitions
  is_active BOOLEAN DEFAULT TRUE,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

-- Envelopes
CREATE TABLE docusign_envelopes (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  tenant_id UUID NOT NULL REFERENCES tenants(id),
  envelope_id TEXT NOT NULL UNIQUE, -- DocuSign envelope ID
  
  -- Link to Orcha entities
  approval_id UUID REFERENCES approvals(id),
  invoice_id UUID REFERENCES invoices(id),
  purchase_order_id UUID REFERENCES purchase_orders(id),
  contract_id UUID REFERENCES contracts(id),
  
  -- Envelope details
  template_id UUID REFERENCES docusign_templates(id),
  subject TEXT NOT NULL,
  status TEXT NOT NULL, -- 'created', 'sent', 'delivered', 'completed', 'declined', 'voided'
  
  -- Recipients
  recipients JSONB NOT NULL, -- Array of recipient objects
  
  -- Documents
  documents JSONB NOT NULL, -- Array of document metadata
  
  -- Audit trail
  sent_at TIMESTAMP,
  delivered_at TIMESTAMP,
  completed_at TIMESTAMP,
  voided_at TIMESTAMP,
  voided_reason TEXT,
  
  -- Signed document storage
  signed_document_url TEXT, -- S3 URL
  certificate_url TEXT, -- Certificate of Completion URL
  
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

CREATE INDEX idx_envelopes_status ON docusign_envelopes(status);
CREATE INDEX idx_envelopes_approval_id ON docusign_envelopes(approval_id);
CREATE INDEX idx_envelopes_invoice_id ON docusign_envelopes(invoice_id);

-- Envelope Events (from webhooks)
CREATE TABLE docusign_envelope_events (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  envelope_id TEXT NOT NULL REFERENCES docusign_envelopes(envelope_id),
  event_type TEXT NOT NULL, -- 'sent', 'delivered', 'completed', 'declined', 'voided', etc.
  recipient_email TEXT,
  recipient_name TEXT,
  status TEXT,
  ip_address INET,
  user_agent TEXT,
  timestamp TIMESTAMP NOT NULL,
  raw_payload JSONB NOT NULL,
  created_at TIMESTAMP DEFAULT NOW()
);

CREATE INDEX idx_envelope_events_envelope ON docusign_envelope_events(envelope_id);
CREATE INDEX idx_envelope_events_type ON docusign_envelope_events(event_type);

Use Cases: Orcha + DocuSign

Use Case 1: Purchase Order Approval & Vendor Acknowledgment

Flow:

1. Department Head creates PO in Orcha
2. Orcha AI validates PO (budget check, policy compliance)
3. PO requires signature → Orcha creates DocuSign envelope
4. DocuSign sends PO to:
   a. Department Head (signer, routing order 1)
   b. CFO (signer, routing order 2, if > €10K)
   c. Vendor (signer, routing order 3)
5. Recipients sign in sequence
6. DocuSign webhook → Orcha: "envelope completed"
7. Orcha downloads signed PO
8. Orcha stores in GoBD-compliant storage
9. Orcha activates PO (now legally binding)
10. Invoice matching can proceed against signed PO

Value:

UI in Orcha:

┌────────────────────────────────────────────────────────────────┐
│  PURCHASE ORDER PO-2024-1234                                   │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│  Status: Pending Signatures (2 of 3 completed)                │
│                                                                │
│  ✅ Maria Weber (Dept Head) - Signed Jan 5, 11:15 AM          │
│  ✅ Klaus Müller (CFO) - Signed Jan 5, 11:42 AM               │
│  ⏳ Johann Schmidt (Vendor) - Sent Jan 5, 11:45 AM            │
│                                                                │
│  [View Document] [Send Reminder] [Cancel Envelope]            │
│                                                                │
└────────────────────────────────────────────────────────────────┘

Use Case 2: Master Service Agreement (MSA) Execution

Scenario: CFO negotiates annual contract with office supplies vendor (€250K/year spend).

Flow:

1. CFO uploads MSA draft to Orcha
2. Legal review (internal or external)
3. CFO clicks "Send for Signature" in Orcha
4. Orcha creates DocuSign envelope from MSA Template
5. Sequential routing:
   a. CFO (signer, routing order 1)
   b. Vendor Legal (signer, routing order 2)
   c. Vendor CFO (signer, routing order 3)
6. All parties sign electronically
7. Signed MSA returned to Orcha
8. Orcha extracts contract terms (pricing, volume discounts, payment terms)
9. Contract terms feed into invoice validation rules
10. Procurement Intelligence monitors compliance

Value:

Orcha + DocuSign + AI:

Signed MSA → AI extracts terms → Contract compliance rules

Example:
"Vendor X must provide 2% early payment discount for payment within 10 days"
→ Orcha automatically flags invoices without discount
→ AP team follows up with vendor

Use Case 3: High-Value Invoice Approval (€50K+)

Scenario: German compliance requirements for large expenditures.

Flow:

1. Invoice arrives (€75K for IT equipment)
2. Orcha AI validates:
   ✓ 4-way match (invoice ↔ PO ↔ GR ↔ contract)
   ✓ Budget available
   ✓ No fraud signals
3. Orcha: "This invoice requires CFO signature (amount > €50K)"
4. Orcha creates DocuSign envelope with:
   - Original invoice PDF
   - 4-way match report
   - Budget impact summary
5. CFO receives email with full context
6. CFO signs electronically
7. Signed approval returned to Orcha
8. Orcha posts to GL and schedules payment

Value:

Use Case 4: Monthly Close Sign-Off (Festschreibung)

Scenario: German GoBD requires period locking with authorized signature.

Flow:

1. Controller completes month-end close in Orcha
2. All transactions reconciled (AP, bank, GL)
3. Controller clicks "Finalize Period" → Orcha creates envelope
4. Sequential routing:
   a. Controller (signer, routing order 1)
   b. CFO (signer, routing order 2)
   c. Steuerberater (CC, routing order 3)
5. Controller and CFO sign Festschreibung certificate
6. Steuerberater receives signed certificate + DATEV export
7. Period locked in Orcha (no further edits)

Value:

Use Case 5: Vendor Self-Service Payment Requests

Scenario: Dynamic discounting (Phase 3.2) - vendor requests early payment.

Flow:

1. Vendor logs into Orcha vendor portal
2. Vendor sees unpaid invoices (€45K due in 25 days)
3. Vendor clicks "Request Early Payment"
4. Vendor offers 2% discount for payment in 5 days
5. Orcha calculates APR: 2% for 20 days = 36% APR
6. Orcha creates DocuSign envelope:
   - Early payment agreement
   - Amended invoice with discount
7. Routing:
   a. Vendor (signer, confirms discount offer)
   b. Orcha Treasurer (signer, accepts offer)
8. Both parties sign → Payment scheduled for day 5
9. Vendor receives payment early, Orcha saves €900

Value:


Technical Implementation

Phase 1: Core Integration (Months 1-2)

Sprint 1: Authentication & Basic Envelope Creation

Deliverables:

  1. OAuth 2.0 flow for DocuSign
  2. Token storage and refresh logic
  3. Create envelope from PDF
  4. Basic status tracking

Code Example: OAuth Flow

(ns orcha.docusign.auth
  (:require [clj-http.client :as http]
            [cheshire.core :as json]
            [orcha.config :refer [config]]
            [orcha.db.docusign :as db]))

(def auth-base-url "https://account.docusign.com")
(def api-base-url "https://demo.docusign.net/restapi")

(defn get-authorization-url
  "Generate DocuSign OAuth authorization URL"
  [redirect-uri state]
  (str auth-base-url "/oauth/auth"
       "?response_type=code"
       "&scope=signature%20impersonation"
       "&client_id=" (:docusign-integration-key config)
       "&redirect_uri=" redirect-uri
       "&state=" state))

(defn exchange-code-for-token
  "Exchange authorization code for access token"
  [code]
  (let [response (http/post (str auth-base-url "/oauth/token")
                            {:form-params {:grant_type "authorization_code"
                                           :code code
                                           :client_id (:docusign-integration-key config)
                                           :client_secret (:docusign-secret-key config)}
                             :content-type :x-www-form-urlencoded
                             :as :json})]
    (:body response)))

(defn refresh-access-token
  "Refresh expired access token"
  [refresh-token]
  (let [response (http/post (str auth-base-url "/oauth/token")
                            {:form-params {:grant_type "refresh_token"
                                           :refresh_token refresh-token
                                           :client_id (:docusign-integration-key config)
                                           :client_secret (:docusign-secret-key config)}
                             :content-type :x-www-form-urlencoded
                             :as :json})]
    (:body response)))

(defn get-user-info
  "Fetch DocuSign user info (includes account ID and base URI)"
  [access-token]
  (let [response (http/get (str auth-base-url "/oauth/userinfo")
                           {:headers {"Authorization" (str "Bearer " access-token)}
                            :as :json})]
    (:body response)))

(defn store-tokens
  "Store access and refresh tokens for user"
  [user-id token-response]
  (let [user-info (get-user-info (:access_token token-response))
        account (first (:accounts user-info))
        expires-at (java.time.Instant/ofEpochSecond
                     (+ (System/currentTimeMillis) (* (:expires_in token-response) 1000)))]
    (db/upsert-token {:user-id user-id
                      :access-token (:access_token token-response)
                      :refresh-token (:refresh_token token-response)
                      :expires-at expires-at
                      :account-id (:account_id account)
                      :base-uri (:base_uri account)})))

(defn get-valid-token
  "Get valid access token for user (refresh if expired)"
  [user-id]
  (let [token (db/get-token user-id)]
    (if (and token (> (.getEpochSecond (:expires-at token))
                      (System/currentTimeMillis)))
      (:access-token token)
      (let [refreshed (refresh-access-token (:refresh-token token))]
        (store-tokens user-id refreshed)
        (:access_token refreshed)))))

Code Example: Create Envelope

(ns orcha.docusign.envelopes
  (:require [clj-http.client :as http]
            [cheshire.core :as json]
            [clojure.java.io :as io]
            [orcha.docusign.auth :as auth]
            [orcha.db.docusign :as db]
            [orcha.storage :as storage]))

(defn create-envelope
  "Create and send DocuSign envelope"
  [{:keys [user-id document-url subject recipients template-id template-data]}]
  (let [token (auth/get-valid-token user-id)
        token-info (db/get-token user-id)
        account-id (:account-id token-info)
        base-uri (:base-uri token-info)
        
        ;; Download document if URL provided
        document-base64 (when document-url
                          (-> (storage/download document-url)
                              (java.util.Base64/getEncoder)
                              (.encodeToString)))
        
        ;; Build envelope definition
        envelope-def (if template-id
                       ;; Template-based envelope
                       {:templateId template-id
                        :templateRoles recipients
                        :status "sent"}
                       ;; Document-based envelope
                       {:emailSubject subject
                        :documents [{:documentBase64 document-base64
                                     :name "document.pdf"
                                     :fileExtension "pdf"
                                     :documentId "1"}]
                        :recipients {:signers recipients}
                        :status "sent"})
        
        response (http/post (str base-uri "/v2.1/accounts/" account-id "/envelopes")
                            {:headers {"Authorization" (str "Bearer " token)
                                       "Content-Type" "application/json"}
                             :body (json/generate-string envelope-def)
                             :as :json})]
    (:body response)))

(defn get-envelope-status
  "Fetch envelope status from DocuSign"
  [user-id envelope-id]
  (let [token (auth/get-valid-token user-id)
        token-info (db/get-token user-id)
        account-id (:account-id token-info)
        base-uri (:base-uri token-info)
        
        response (http/get (str base-uri "/v2.1/accounts/" account-id
                                "/envelopes/" envelope-id)
                           {:headers {"Authorization" (str "Bearer " token)}
                            :as :json})]
    (:body response)))

(defn download-completed-document
  "Download signed document from DocuSign"
  [user-id envelope-id document-id]
  (let [token (auth/get-valid-token user-id)
        token-info (db/get-token user-id)
        account-id (:account-id token-info)
        base-uri (:base-uri token-info)
        
        response (http/get (str base-uri "/v2.1/accounts/" account-id
                                "/envelopes/" envelope-id
                                "/documents/" document-id)
                           {:headers {"Authorization" (str "Bearer " token)
                                      "Accept" "application/pdf"}
                            :as :byte-array})]
    (:body response)))

(defn download-certificate
  "Download Certificate of Completion (audit trail)"
  [user-id envelope-id]
  (let [token (auth/get-valid-token user-id)
        token-info (db/get-token user-id)
        account-id (:account-id token-info)
        base-uri (:base-uri token-info)
        
        response (http/get (str base-uri "/v2.1/accounts/" account-id
                                "/envelopes/" envelope-id
                                "/documents/certificate")
                           {:headers {"Authorization" (str "Bearer " token)
                                      "Accept" "application/pdf"}
                            :as :byte-array})]
    (:body response)))

Sprint 2: Webhook Integration & Status Tracking

Deliverables:

  1. Webhook endpoint for DocuSign Connect
  2. Event handler for envelope status changes
  3. Automatic download of signed documents
  4. Status dashboard UI

Code Example: Webhook Handler

(ns orcha.docusign.webhooks
  (:require [ring.middleware.json :refer [wrap-json-body]]
            [cheshire.core :as json]
            [orcha.db.docusign :as db]
            [orcha.docusign.envelopes :as envelopes]
            [orcha.storage :as storage]
            [orcha.workflows.approvals :as approvals]
            [clojure.tools.logging :as log]))

(defn verify-docusign-signature
  "Verify HMAC signature from DocuSign Connect"
  [payload signature secret]
  ;; DocuSign signs webhook payloads with HMAC-SHA256
  (let [calculated-sig (-> (javax.crypto.Mac/getInstance "HmacSHA256")
                           (doto (.init (javax.crypto.spec.SecretKeySpec.
                                          (.getBytes secret) "HmacSHA256")))
                           (.doFinal (.getBytes payload))
                           (java.util.Base64/getEncoder)
                           (.encodeToString))]
    (= calculated-sig signature)))

(defn handle-envelope-completed
  "Handle envelope completion event"
  [envelope-data]
  (let [envelope-id (:envelopeId envelope-data)
        envelope-record (db/get-envelope-by-envelope-id envelope-id)]
    
    (when envelope-record
      ;; 1. Download signed document
      (let [user-id (:user-id envelope-record)
            signed-doc (envelopes/download-completed-document
                         user-id envelope-id "1")
            certificate (envelopes/download-certificate user-id envelope-id)
            
            ;; 2. Store in S3 (GoBD-compliant)
            signed-url (storage/upload-document
                         signed-doc
                         {:type :signed-document
                          :envelope-id envelope-id
                          :tenant-id (:tenant-id envelope-record)})
            
            cert-url (storage/upload-document
                       certificate
                       {:type :certificate-of-completion
                        :envelope-id envelope-id
                        :tenant-id (:tenant-id envelope-record)})]
        
        ;; 3. Update envelope record
        (db/update-envelope envelope-id
                            {:status "completed"
                             :completed-at (java.time.Instant/now)
                             :signed-document-url signed-url
                             :certificate-url cert-url})
        
        ;; 4. Trigger downstream workflows
        (when (:approval-id envelope-record)
          (approvals/mark-approved (:approval-id envelope-record)))
        
        (when (:purchase-order-id envelope-record)
          (activate-purchase-order (:purchase-order-id envelope-record)))
        
        (log/info "Envelope completed and processed" {:envelope-id envelope-id})))))

(defn handle-envelope-declined
  "Handle envelope declined event"
  [envelope-data]
  (let [envelope-id (:envelopeId envelope-data)
        declined-by (:recipients envelope-data)
        reason (:declinedReason envelope-data)]
    
    (db/update-envelope envelope-id
                        {:status "declined"
                         :voided-at (java.time.Instant/now)
                         :voided-reason (str "Declined by: " reason)})
    
    ;; Notify stakeholders
    (send-notification {:type :envelope-declined
                        :envelope-id envelope-id
                        :reason reason})
    
    (log/warn "Envelope declined" {:envelope-id envelope-id :reason reason})))

(defn docusign-webhook-handler
  "Main webhook handler endpoint"
  [request]
  (let [payload (slurp (:body request))
        signature (get-in request [:headers "x-docusign-signature-1"])
        secret (:docusign-webhook-secret config)]
    
    ;; Verify signature
    (if (verify-docusign-signature payload signature secret)
      (let [event-data (json/parse-string payload true)
            envelope-status (get-in event-data [:envelopeStatus :status])]
        
        ;; Log event
        (db/insert-envelope-event
          {:envelope-id (get-in event-data [:envelopeStatus :envelopeId])
           :event-type envelope-status
           :raw-payload event-data
           :timestamp (java.time.Instant/now)})
        
        ;; Handle based on status
        (case envelope-status
          "completed" (handle-envelope-completed (:envelopeStatus event-data))
          "declined" (handle-envelope-declined (:envelopeStatus event-data))
          "voided" (handle-envelope-voided (:envelopeStatus event-data))
          (log/debug "Unhandled envelope status" {:status envelope-status}))
        
        {:status 200 :body "OK"})
      
      ;; Invalid signature
      (do
        (log/error "Invalid DocuSign webhook signature")
        {:status 401 :body "Unauthorized"}))))

(def webhook-routes
  ["/api/webhooks/docusign"
   {:post {:handler docusign-webhook-handler
           :middleware [wrap-json-body]}}])

Phase 2: Template Management & Advanced Workflows (Months 3-4)

Sprint 3: Template Creation & Management

Deliverables:

  1. UI for creating/editing templates
  2. Template library (PO, MSA, Invoice Approval, etc.)
  3. Merge fields for dynamic data
  4. Template versioning

Code Example: Template Service

(ns orcha.docusign.templates
  (:require [orcha.docusign.auth :as auth]
            [clj-http.client :as http]
            [cheshire.core :as json]
            [orcha.db.docusign :as db]))

(defn create-template
  "Create reusable DocuSign template"
  [{:keys [user-id name description roles documents]}]
  (let [token (auth/get-valid-token user-id)
        token-info (db/get-token user-id)
        account-id (:account-id token-info)
        base-uri (:base-uri token-info)
        
        template-def {:name name
                      :description description
                      :emailSubject (str "Please sign: " name)
                      :shared "false"
                      :documents documents
                      :recipients {:signers roles}}
        
        response (http/post (str base-uri "/v2.1/accounts/" account-id "/templates")
                            {:headers {"Authorization" (str "Bearer " token)
                                       "Content-Type" "application/json"}
                             :body (json/generate-string template-def)
                             :as :json})]
    (:body response)))

(defn list-templates
  "List all templates for account"
  [user-id]
  (let [token (auth/get-valid-token user-id)
        token-info (db/get-token user-id)
        account-id (:account-id token-info)
        base-uri (:base-uri token-info)
        
        response (http/get (str base-uri "/v2.1/accounts/" account-id "/templates")
                           {:headers {"Authorization" (str "Bearer " token)}
                            :as :json})]
    (get-in response [:body :envelopeTemplates])))

;; Example: Purchase Order Template
(def purchase-order-template
  {:name "Purchase Order Approval"
   :description "Standard PO approval workflow with vendor acknowledgment"
   :roles [{:roleName "Department Head"
            :routingOrder "1"
            :tabs {:signHereTabs [{:anchorString "/dept_sig/"
                                   :anchorXOffset "0"
                                   :anchorYOffset "0"}]
                   :dateSignedTabs [{:anchorString "/dept_date/"
                                     :anchorXOffset "0"
                                     :anchorYOffset "0"}]
                   :textTabs [{:tabLabel "PO_Number"
                               :value ""
                               :anchorString "/po_number/"
                               :anchorXOffset "0"
                               :anchorYOffset "0"}
                              {:tabLabel "Amount"
                               :value ""
                               :anchorString "/amount/"
                               :anchorXOffset "0"
                               :anchorYOffset "0"}]}}
           {:roleName "CFO"
            :routingOrder "2"
            :tabs {:signHereTabs [{:anchorString "/cfo_sig/"
                                   :anchorXOffset "0"
                                   :anchorYOffset "0"}]
                   :dateSignedTabs [{:anchorString "/cfo_date/"
                                     :anchorXOffset "0"
                                     :anchorYOffset "0"}]}}
           {:roleName "Vendor"
            :routingOrder "3"
            :tabs {:signHereTabs [{:anchorString "/vendor_sig/"
                                   :anchorXOffset "0"
                                   :anchorYOffset "0"}]
                   :dateSignedTabs [{:anchorString "/vendor_date/"
                                     :anchorXOffset "0"
                                     :anchorYOffset "0"}]
                   :textTabs [{:tabLabel "Vendor_Name"
                               :value ""
                               :anchorString "/vendor_name/"
                               :anchorXOffset "0"
                               :anchorYOffset "0"}]}}]})

Sprint 4: Advanced Routing & Conditional Logic

Deliverables:

  1. Conditional routing rules
  2. Escalation workflows (reminders, auto-escalate if not signed)
  3. Bulk envelope creation
  4. Analytics dashboard

Code Example: Conditional Routing

(defn create-approval-envelope
  "Create envelope with conditional routing based on amount"
  [{:keys [invoice approval-amount department-head cfo vendor]}]
  (let [requires-cfo? (> approval-amount 10000)
        
        recipients (cond-> []
                     ;; Always include department head
                     true (conj {:roleName "Department Head"
                                 :name (:name department-head)
                                 :email (:email department-head)
                                 :routingOrder "1"})
                     
                     ;; Add CFO if amount > €10K
                     requires-cfo? (conj {:roleName "CFO"
                                          :name (:name cfo)
                                          :email (:email cfo)
                                          :routingOrder "2"})
                     
                     ;; Vendor always last
                     true (conj {:roleName "Vendor"
                                 :name (:name vendor)
                                 :email (:email vendor)
                                 :routingOrder (if requires-cfo? "3" "2")}))]
    
    (envelopes/create-envelope
      {:user-id (:user-id invoice)
       :template-id (get-template-id :purchase-order)
       :recipients recipients
       :subject (str "Purchase Order Approval - " (:invoice-number invoice))})))

Business Value & ROI

Quantified Value (500-employee SME)

1. Time Savings

Before DocuSign:

After DocuSign:

Time Saved:

Total: 990 days/year = €100,000-150,000 in productivity gains

2. Audit & Compliance Value

Audit Defense:

Value: €20,000-50,000/year in audit cost savings

Compliance Confidence:

Value: Risk mitigation (unquantified, but critical)

3. Vendor Relationship Value

Early Payment Discounts (Phase 3.2):

Value: Enables €200,000/year in early payment discounts

Contract Compliance (Phase 2.1):

Value: Reduces disputes, improves vendor scorecards

4. Growth Enablement

Scale Approvals:

Value: €50,000-100,000/year in avoided headcount costs (at scale)


Total ROI

Annual Value:

Implementation Cost:

ROI: 5-8x in Year 1, 10-15x in Year 2+


eIDAS Regulation (EU)

DocuSign provides three levels of electronic signatures under eIDAS:

  1. Simple Electronic Signature (SES)

  2. Advanced Electronic Signature (AES)

  3. Qualified Electronic Signature (QES)

Orcha Recommendation:

BGB §126a (German Civil Code)

German law recognizes electronic signatures as equivalent to handwritten signatures if:

  1. Signature is uniquely linked to the signer
  2. Signer can be identified with certainty
  3. Signature is created using means under signer's sole control
  4. Signature is linked to the data in such a way that any subsequent change is detectable

DocuSign Compliance: ✅ Yes, DocuSign AES meets all requirements.

GoBD Compliance

DocuSign integrates with GoBD requirements:

  1. Immutability: Certificate of Completion includes document hash (tamper detection)
  2. Audit Trail: Complete record of all actions (viewed, signed, timestamp, IP)
  3. Retention: Signed documents stored in Orcha GoBD-compliant storage
  4. Festschreibung: Period lock includes DocuSign-signed certificate

Orcha Implementation:


Competitive Advantage

Why DocuSign > Alternatives?

1. Market Leader

2. Legal Recognized

3. API Maturity

4. Integration Ecosystem

5. User Experience

Alternatives Considered

SignNow (barracuda):

Adobe Sign:

Build In-House:

Decision: DocuSign is the best balance of features, cost, legal compliance, and market acceptance for German SMEs.


Implementation Roadmap

Timeline: 4 Months

Month 1: Core Integration

Month 2: Approval Workflows

Month 3: Templates & Contracts

Month 4: Advanced Features


Success Metrics

Phase 1 (Months 1-2):

Phase 2 (Months 3-4):

Long-Term (12 months):


User Experience: Key Screens

Screen 1: Approval with DocuSign Integration

┌────────────────────────────────────────────────────────────────┐
│  🤖 APPROVAL REQUEST: Purchase Order PO-2024-1234              │
│  Vendor: Acme Office Supplies | Amount: €8,450                │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│  ✅ 4-WAY MATCH VALIDATION                                     │
│  ✓ Invoice matches PO (variance: -0.6%)                       │
│  ✓ Goods received and confirmed                               │
│  ✓ Contract terms compliant                                   │
│                                                                │
│  🤖 AI RECOMMENDATION: AUTO-APPROVE (98% confidence)           │
│                                                                │
│  ⚠️  SIGNATURE REQUIRED (Amount > €5,000)                      │
│                                                                │
│  This purchase order requires your electronic signature       │
│  to create a legally binding agreement with the vendor.       │
│                                                                │
│  By signing, you:                                             │
│  • Authorize the purchase of goods/services as specified      │
│  • Commit to payment terms (net 30 days)                      │
│  • Create enforceable contract with vendor                    │
│                                                                │
│  ┌──────────────────────────────────────────────────────────┐ │
│  │  [✍️ SIGN WITH DOCUSIGN]                                  │ │
│  │                                                           │ │
│  │  Signing process:                                         │ │
│  │  1. You sign electronically                               │ │
│  │  2. CFO signs (if applicable)                             │ │
│  │  3. Vendor acknowledges terms                             │ │
│  │  4. Signed PO returned to Orcha                           │ │
│  └──────────────────────────────────────────────────────────┘ │
│                                                                │
│  [❌ REJECT] [⏸️ HOLD] [📄 VIEW DETAILS]                       │
│                                                                │
└────────────────────────────────────────────────────────────────┘

Screen 2: Envelope Status Tracking

┌────────────────────────────────────────────────────────────────┐
│  DOCUSIGN ENVELOPES - ACTIVE                                   │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│  PO-2024-1234 | Acme Office Supplies | €8,450                 │
│  Status: Waiting for signatures (2 of 3 completed)            │
│                                                                │
│  ✅ Maria Weber (Dept Head) - Signed Jan 5, 11:15 AM          │
│  ✅ Klaus Müller (CFO) - Signed Jan 5, 11:42 AM               │
│  ⏳ Johann Schmidt (Vendor) - Sent Jan 5, 11:45 AM            │
│     Last viewed: Jan 5, 2:30 PM                                │
│                                                                │
│  [📧 Send Reminder] [❌ Cancel] [📄 View Document]             │
│                                                                │
│  ─────────────────────────────────────────────────────────────  │
│                                                                │
│  MSA-2024-0045 | IT Services GmbH | Annual Contract           │
│  Status: Completed ✅ (Jan 3, 4:15 PM)                         │
│                                                                │
│  ✅ Klaus Müller (CFO) - Signed Jan 3, 10:22 AM               │
│  ✅ Hans Becker (Vendor Legal) - Signed Jan 3, 2:15 PM        │
│  ✅ Anna Schmidt (Vendor CFO) - Signed Jan 3, 4:12 PM         │
│                                                                │
│  [📥 Download] [🔍 View Certificate] [📊 Extract Terms]        │
│                                                                │
└────────────────────────────────────────────────────────────────┘

Screen 3: Template Library

┌────────────────────────────────────────────────────────────────┐
│  DOCUSIGN TEMPLATES                                            │
├────────────────────────────────────────────────────────────────┤
│                                                                │
│  Purchase Order Approval                                       │
│  Roles: Department Head → CFO (conditional) → Vendor          │
│  Used: 147 times | Avg completion: 18 hours                   │
│  [📝 Edit] [📋 Use Template] [📊 Analytics]                    │
│                                                                │
│  ─────────────────────────────────────────────────────────────  │
│                                                                │
│  Master Service Agreement                                      │
│  Roles: CFO → Vendor Legal → Vendor CFO                       │
│  Used: 23 times | Avg completion: 2.3 days                    │
│  [📝 Edit] [📋 Use Template] [📊 Analytics]                    │
│                                                                │
│  ─────────────────────────────────────────────────────────────  │
│                                                                │
│  High-Value Invoice Approval (>€50K)                           │
│  Roles: Controller → CFO                                       │
│  Used: 89 times | Avg completion: 4 hours                     │
│  [📝 Edit] [📋 Use Template] [📊 Analytics]                    │
│                                                                │
│  ─────────────────────────────────────────────────────────────  │
│                                                                │
│  [➕ CREATE NEW TEMPLATE]                                      │
│                                                                │
└────────────────────────────────────────────────────────────────┘

Risk Analysis & Mitigation

Technical Risks

1. DocuSign API Downtime

2. Webhook Delivery Failure

3. Token Expiration

Business Risks

1. User Adoption

2. External Party Resistance

3. Legal Challenges

Compliance Risks

1. GoBD Non-Compliance

2. Data Privacy (GDPR)


White-Labeling, User Experience & Licensing Strategy

1. White-Labeling Capabilities

DocuSign is NOT fully white-labeled, but offers significant branding customization:

What You CAN Customize

Email Branding

Signing Page Branding

Email Templates

What You CANNOT Hide

"Powered by DocuSign" Branding

DocuSign URLs

DocuSign Mobile App

Example: What Recipients See

Email:

From: Orcha Approvals <noreply@orcha.com>
Subject: Please sign: Purchase Order PO-2024-1234

[ORCHA LOGO]

Hi Johann,

Maria Weber from Acme GmbH has requested your signature 
on a purchase order (€8,450.00).

[REVIEW AND SIGN BUTTON]

This document is managed by Orcha and secured by DocuSign.

---
Powered by DocuSign | View in DocuSign App

Assessment: The branding is professional and acceptable. Most recipients recognize DocuSign as a trusted platform, which actually increases trust rather than detracting from Orcha's brand.


2. User Experience: Embedded vs External Signing

For Internal Users (Orcha Customers):

Users never leave the Orcha platform:

┌────────────────────────────────────────────────────────┐
│  ORCHA PLATFORM (orcha.com)                            │
│  ┌──────────────────────────────────────────────────┐  │
│  │ APPROVAL REQUEST PO-2024-1234                    │  │
│  │ Amount: €8,450                                   │  │
│  │                                                  │  │
│  │ ✅ 4-Way Match Complete                          │  │
│  │ 🤖 AI Recommends: APPROVE                        │  │
│  │                                                  │  │
│  │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  │  │
│  │                                                  │  │
│  │ [Embedded DocuSign Signing Iframe Below]        │  │
│  │ ┌──────────────────────────────────────────────┐│  │
│  │ │ Please sign to approve this purchase order   ││  │
│  │ │                                              ││  │
│  │ │ ┌──────────────────────────────────────┐    ││  │
│  │ │ │ [Your Signature Here]                │    ││  │
│  │ │ └──────────────────────────────────────┘    ││  │
│  │ │                                              ││  │
│  │ │ Date: January 5, 2026                       ││  │
│  │ │                                              ││  │
│  │ │ [✅ SIGN AND APPROVE]                        ││  │
│  │ │                                              ││  │
│  │ │ Small "Powered by DocuSign" footer          ││  │
│  │ └──────────────────────────────────────────────┘│  │
│  └──────────────────────────────────────────────────┘  │
└────────────────────────────────────────────────────────┘

Implementation:

(defn get-embedded-signing-url
  "Generate embedded signing URL for display in Orcha iframe"
  [envelope-id recipient-id user-email user-name]
  (let [token (auth/get-valid-token)
        response (http/post 
                   (str base-uri "/envelopes/" envelope-id 
                        "/views/recipient")
                   {:headers {"Authorization" (str "Bearer " token)
                              "Content-Type" "application/json"}
                    :body (json/generate-string
                            {:returnUrl "https://orcha.com/approvals/complete"
                             :authenticationMethod "email"
                             :email user-email
                             :userName user-name
                             :clientUserId recipient-id})
                    :as :json})]
    (-> response :body :url)))

;; Frontend: Display in iframe
;; <iframe src={embeddedSigningUrl} 
;;         width="100%" 
;;         height="600px"
;;         frameborder="0" />

User Experience:

For External Users (Vendors, Steuerberater):

They must use DocuSign's signing pages:

  1. Vendor receives email from DocuSign (with Orcha branding)
  2. Clicks link → Opens docusign.net signing page
  3. Signs document on DocuSign page
  4. Receives confirmation email
  5. Orcha receives webhook notification

User Experience:

Why This is Actually Good:


3. License Costs & Pricing Models

How It Works:

DocuSign Pricing:

Base Account:
├─ DocuSign Business Pro: $40-50/user/month
├─ Minimum: 3 users required = $120-150/month base
└─ API access included

Envelope Fees:
├─ Standard envelopes: $0.50 per envelope
├─ Advanced envelopes: $1.00 per envelope (complex routing)
└─ Volume discounts kick in at 5,000+/month

Example Calculation (50 Orcha customers):
├─ Base: $150/month
├─ Average: 200 envelopes/customer/month = 10,000 envelopes
├─ Cost: $150 + (10,000 × $0.50) = $5,150/month
└─ Per customer: $103/month average

Volume Pricing (Negotiable at Scale):

Tier 1: 0-5,000 envelopes/month
  → $0.50 per envelope

Tier 2: 5,000-20,000 envelopes/month
  → $0.35 per envelope (30% discount)

Tier 3: 20,000-50,000 envelopes/month
  → $0.25 per envelope (50% discount)

Enterprise: 50,000+ envelopes/month
  → Flat fee negotiation (e.g., $10K/month unlimited)
  → Effective: $0.10-0.20 per envelope

Orcha's Pricing to Customers:

Option 1: Add-On Pricing
├─ Base Orcha subscription: €299/month
├─ DocuSign Electronic Signatures: +€89/month
│   ├─ Includes: 200 envelopes/month
│   └─ Additional: €0.50 per envelope
└─ Total: €388/month

Option 2: Bundled Pricing
├─ Orcha Premium: €349/month
│   ├─ AP Automation
│   ├─ Procurement Intelligence
│   ├─ DocuSign Signatures (200 envelopes)
│   └─ All features included
└─ Simplifies sales (one price)

Profitability Analysis:

At Launch (50 customers, no volume discount):

Revenue: 50 customers × €89/month = €4,450/month
Cost: $150 base + (10,000 × $0.50) = $5,150/month (€4,850)
Margin: -€400/month (8% loss initially)

At Scale (100 customers, Tier 2 volume discount):

Revenue: 100 customers × €89/month = €8,900/month
Cost: $150 base + (20,000 × $0.35) = $7,150/month (€6,700)
Margin: +€2,200/month (25% profit)

At Enterprise Scale (200+ customers, flat fee deal):

Revenue: 200 customers × €89/month = €17,800/month
Cost: $10,000/month flat (€9,400)
Margin: +€8,400/month (47% profit)

Recommendation: Accept initial loss leader to gain market share, negotiate volume discount at 100+ customers.

How It Works:

Pricing:

Per Customer:
├─ DocuSign Business Pro: $40-65/user/month
├─ Typical: 2-5 users (CFO, Controller, Approvers)
├─ Total: $80-325/month paid to DocuSign
└─ Orcha integration fee: €25/month

Why NOT Recommended:

Complex Onboarding

Support Nightmare

Higher Perceived Cost

Competitive Disadvantage

Only Advantage: Orcha has zero DocuSign costs

Decision: Model A (Orcha as master account) is strongly recommended despite initial loss leader.


4. Do Customers Need Their Own DocuSign Account?

Answer: NO - Orcha creates "virtual users" for them

JWT Grant Authentication (Best Approach)

How It Works:

┌─────────────────────────────────────────────────────────┐
│  ORCHA'S DOCUSIGN MASTER ACCOUNT                        │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  Virtual User 1: maria@customer-a.de (CFO)              │
│  Virtual User 2: klaus@customer-a.de (Controller)       │
│  Virtual User 3: anna@customer-b.de (CFO)               │
│  Virtual User 4: thomas@customer-b.de (Controller)      │
│  ...                                                    │
│  Virtual User N: [Unlimited users]                      │
│                                                         │
└─────────────────────────────────────────────────────────┘

Implementation Steps:

  1. One-Time Setup: Orcha Gets DocuSign Account
1. Orcha signs up for DocuSign Business Pro
2. Orcha creates integration (gets Integration Key + Secret)
3. Orcha enables JWT Grant in DocuSign admin
4. Orcha generates RSA key pair for JWT signing
  1. Per Customer: Create Virtual User
(defn create-virtual-docusign-user
  "Create virtual DocuSign user for Orcha customer (no real account)"
  [orcha-user-id email name]
  (let [;; Generate JWT token for Orcha's account
        jwt-token (generate-jwt-token 
                    {:integration-key orcha-integration-key
                     :user-id orcha-docusign-account-id
                     :scopes ["signature" "impersonation"]
                     :expires-in 3600})
        
        ;; Get access token
        access-token (exchange-jwt-for-token jwt-token)
        
        ;; Create impersonation consent (one-time per user)
        consent (grant-impersonation-consent 
                  access-token 
                  {:email email 
                   :name name
                   :client-user-id (str "orcha-" orcha-user-id)})]
    
    ;; Store mapping in Orcha database
    (db/insert :docusign-virtual-users
               {:orcha-user-id orcha-user-id
                :docusign-user-id (:user-id consent)
                :email email
                :name name
                :client-user-id (str "orcha-" orcha-user-id)
                :consent-granted-at (now)})))
  1. Per Envelope: Send on Behalf of User
(defn send-envelope-as-user
  "Send DocuSign envelope impersonating Orcha user"
  [orcha-user-id envelope-data]
  (let [virtual-user (db/get-virtual-user orcha-user-id)
        
        ;; Generate JWT for this specific user
        jwt-token (generate-jwt-token 
                    {:integration-key orcha-integration-key
                     :user-id (:docusign-user-id virtual-user)
                     :account-id orcha-docusign-account-id
                     :scopes ["signature" "impersonation"]
                     :expires-in 3600})
        
        access-token (exchange-jwt-for-token jwt-token)]
    
    ;; Create envelope (appears to come from virtual-user)
    (docusign/create-envelope access-token envelope-data)))

User Experience:

First Time Only (One-Time Consent):

┌────────────────────────────────────────────────────────┐
│  DOCUSIGN CONSENT REQUEST                              │
├────────────────────────────────────────────────────────┤
│                                                        │
│  Orcha would like to send documents for signature     │
│  on your behalf using DocuSign.                        │
│                                                        │
│  By approving, you allow:                              │
│  • Orcha to send envelopes from your email            │
│  • Recipients to see your name as sender               │
│  • DocuSign to process documents securely              │
│                                                        │
│  [APPROVE] [LEARN MORE]                                │
│                                                        │
└────────────────────────────────────────────────────────┘

After Approval:

Cost Impact:


Phase 1: Embedded Signing for Internal Users

Month 1-2:

  1. Orcha gets DocuSign Business Pro account
  2. Implement JWT Grant authentication
  3. Create virtual users for each Orcha user (one-time consent)
  4. Embed signing ceremony in Orcha UI (iframe)
  5. Handle webhooks for completion events

Customer Experience:

Cost:

Phase 2: External Party Signing

Month 3-4:

  1. Send envelopes to external parties (vendors, Steuerberater)
  2. They receive branded emails with DocuSign links
  3. Sign on DocuSign pages (full DocuSign branding)
  4. Webhook notifies Orcha of completion

Vendor Experience:

Cost: Same per-envelope fee ($0.50)

Phase 3: Volume Negotiation

Month 6+ (at 10,000+ envelopes/month):

  1. Contact DocuSign sales for volume pricing
  2. Negotiate $0.30-0.35 per envelope (Tier 2)
  3. At 100+ customers, negotiate flat fee ($10K/month unlimited)

Profitability:


6. Competitive Pricing Comparison

Factor DocuSign Direct Orcha + DocuSign
Setup Customer must buy DocuSign Included in Orcha
Monthly Cost $80-325/customer €89/customer
User Seats $40-65 per user Unlimited users
Envelopes 100-500 included, then $1 each 200 included, then €0.50
Integration Manual (no API) Seamless (embedded)
Support Two vendors (Orcha + DocuSign) One vendor (Orcha)
Onboarding 2-4 weeks Instant
Signing Experience Always external Embedded for internal

Customer Savings: €111-236/month (40-75% cheaper through Orcha)

Why Customers Choose Orcha:


7. Go-To-Market Messaging

Don't Say:

Do Say:

Positioning:

"Orcha includes legally binding electronic signatures (powered by DocuSign) at no extra cost. Sign purchase orders, contracts, and approvals directly in Orcha—no separate accounts, no complexity, just secure signatures that are legally recognized across the EU."

Pricing:

Competitive Advantage:


Conclusion

Why DocuSign for Orcha?

Strategic Fit:

  1. Complements AI Approval Intelligence: Adds legal enforceability to workflow approvals
  2. Enables Phase 2 Procurement: Signed MSAs feed contract compliance monitoring
  3. Scales Phase 3 Treasury: Dynamic discounting requires legally binding discount agreements
  4. De-Risks Phase 4 Compliance: eIDAS + GoBD compliance strengthens audit defense

Customer Value:

Market Positioning:

Recommendation

Proceed with Integration (Priority: High)

Rationale:

  1. Low technical risk: Mature API, extensive documentation
  2. High business value: €320-400K/year for typical customer
  3. Competitive advantage: Differentiates Orcha from "invoice OCR" competitors
  4. Enables future phases: Procurement, Treasury, Compliance all benefit

Timeline: 4 months to full production

Investment: €30-50K development + €40-60/user/year

Expected Outcome: 95%+ electronic signature adoption, €320-400K annual value per customer


Appendix: API Reference Summary

Authentication

Envelopes

Templates

Recipients

Webhooks (Connect)


Additional Resources

Official Documentation:

Legal & Compliance:

SDKs:

Orcha Internal:


Document Version: 1.0
Last Updated: January 5, 2026
Author: Orcha Product Team
Status: Approved for Development