# Deployment Guide **Project**: Salesforce Composite Envelope Builder **Version**: 1.0 **Date**: February 23, 2026 --- ## 1. Prerequisites ### 1.1 Salesforce Requirements - **Edition**: Enterprise Edition or higher (required for API access) - **User Permissions**: - API Enabled - Modify All Data (for deployment) - Manage Flows (for Flow updates) - **Features Enabled**: - Screen Flows - Apex Classes ### 1.2 Docusign Requirements - **Account**: Docusign eSignature (Production or Sandbox) - **API Access**: Enabled - **Templates**: 28 single-form templates created (14 English + 14 Spanish) - **User Role**: Sender or higher ### 1.3 Development Tools - **VS Code** with Salesforce Extension Pack - **Salesforce CLI** (sf CLI version 2.0+) - **Git** for version control --- ## 2. Docusign Configuration ### 2.1 Create Integration Key **Step 1: Navigate to Apps & Keys** 1. Log in to Docusign 2. Go to **Settings → Apps and Keys** 3. Click **Add App and Integration Key** **Step 2: Configure Integration** - **App Name**: Salesforce Composite Envelope Builder - **Integration Type**: JWT (JSON Web Token) - **Redirect URI**: Not required for JWT - **Secret Key**: Save securely (will be shown once) **Step 3: Generate RSA Key Pair** 1. Click **Generate RSA** 2. Download private key (PEM file) 3. Copy public key (will be added to Salesforce) **Step 4: Grant Consent** 1. Click **Grant Consent** button 2. Authenticate as Docusign admin user 3. Accept permissions **Step 5: Note Important Values** - **Integration Key** (GUID): e.g., `a1b2c3d4-...` - **User ID** (GUID of API user): e.g., `f9876543-...` - **Account ID** (GUID): e.g., `12345678-...` - **Base URL**: e.g., `https://na3.docusign.net/restapi/v2.1` ### 2.2 Create Templates **For each of 14 forms, create 2 templates (English + Spanish)**: 1. Go to **Templates → New → Use a Template** 2. Upload PDF document 3. Add fields (signature tabs, text fields, etc.) 4. Define recipients: - **Role 1**: Signer 1 (routing order 1) - **Role 2**: Signer 2 (routing order 2) 5. Name template clearly: - Format: `[Form Name] - [Language]` - Example: `Form A - English`, `Form A - Spanish` 6. Save template 7. Note template ID (GUID) **Template Naming Convention** (for alphabetical sorting): ``` Form A - Credit Application - English Form A - Credit Application - Spanish Form B - Income Verification - English Form B - Income Verification - Spanish ... (continue alphabetically) ``` --- ## 3. Salesforce Configuration ### 3.1 Create Named Credential **Option 1: External Credential (Recommended for JWT)** **Step 1: Create External Credential** 1. Setup → Named Credentials → External Credentials → New 2. **Label**: Docusign JWT Auth 3. **Name**: DocusignJWTAuth 4. **Authentication Protocol**: Custom 5. **Identity Type**: Named Principal 6. Click **Create** **Step 2: Add Custom Headers** 1. Open External Credential → Custom Headers → New 2. Add header: - **Header Field Name**: Authorization - **Header Field Value**: `Bearer {!$Credential.DocusignJWTAuth.AccessToken}` **Step 3: Create Named Credential** 1. Setup → Named Credentials → New Named Credential 2. **Label**: Docusign API 3. **Name**: DocusignAPI 4. **URL**: `https://na3.docusign.net/restapi/v2.1` (or your data center) 5. **External Credential**: DocusignJWTAuth 6. **Enabled for Callouts**: Checked 7. Click **Save** --- **Option 2: Legacy Named Credential (Simpler but less flexible)** 1. Setup → Named Credentials → New Legacy 2. **Label**: Docusign API 3. **Name**: DocusignAPI 4. **URL**: `https://na3.docusign.net/restapi/v2.1` 5. **Identity Type**: Named Principal 6. **Authentication Protocol**: OAuth 2.0 7. **Authentication Provider**: (Create new - see below) 8. **Scope**: `signature impersonation` 9. **Save** **Create Authentication Provider**: 1. Setup → Auth. Providers → New 2. **Provider Type**: Open ID Connect 3. **Name**: Docusign OAuth 4. **Consumer Key**: {Integration Key from Docusign} 5. **Consumer Secret**: {Secret from Docusign} 6. **Authorize Endpoint URL**: `https://account-d.docusign.com/oauth/auth` 7. **Token Endpoint URL**: `https://account-d.docusign.com/oauth/token` 8. **Default Scopes**: `signature impersonation` 9. **Save** ### 3.2 Create Custom Settings (for Account ID) **Step 1: Create Custom Setting** 1. Setup → Custom Settings → New 2. **Label**: Docusign Configuration 3. **Object Name**: Docusign_Configuration 4. **Setting Type**: Hierarchy 5. Add custom fields: - **Account_Id__c** (Text, 255) - **Base_URL__c** (Text, 255) 6. **Save** **Step 2: Manage Custom Setting** 1. Setup → Custom Settings → Docusign Configuration → Manage 2. Click **New** (organization-wide default) 3. **Account Id**: {Docusign Account GUID} 4. **Base URL**: `https://na3.docusign.net/restapi/v2.1` 5. **Save** ### 3.3 Create Remote Site Settings 1. Setup → Remote Site Settings → New Remote Site 2. **Remote Site Name**: Docusign_API 3. **Remote Site URL**: `https://na3.docusign.net` 4. **Active**: Checked 5. **Save** **Add additional sites** (if using sandbox or different data center): - `https://demo.docusign.net` (Docusign Sandbox) - `https://account-d.docusign.com` (OAuth endpoints) --- ## 4. Code Deployment ### 4.1 Clone Repository (if using Git) ```bash git clone https://github.com/your-org/salesforce-composite-envelope-builder.git cd salesforce-composite-envelope-builder/composite-envelope-builder ``` ### 4.2 Authorize Salesforce Org **Sandbox**: ```bash sf org login web --alias my-sandbox --instance-url https://test.salesforce.com ``` **Production**: ```bash sf org login web --alias my-production --instance-url https://login.salesforce.com ``` ### 4.3 Deploy to Sandbox ```bash sf project deploy start --target-org my-sandbox ``` **Expected output**: ``` Deploying v60.0 metadata to my-sandbox using the v60.0 SOAP API Status: Succeeded Component Deployed: ApexClass DocusignCompositeEnvelopeBuilder ApexClass DocusignAPIService ApexClass DocusignCredentials ApexClass DocusignCompositeEnvelopeBuilderTest ApexClass DocusignAPIServiceTest ApexClass DocusignCredentialsTest ``` ### 4.4 Run Unit Tests ```bash sf apex run test --class-names DocusignCompositeEnvelopeBuilderTest --target-org my-sandbox --wait 5 --result-format human ``` **Expected output**: ``` Test Success 1 tests ran, 1 passed, 0 failed, 0 skipped Code Coverage 85% (target: 75%) ``` ### 4.5 Validate Production (without deploying) ```bash sf project deploy validate --target-org my-production --test-level RunLocalTests ``` ### 4.6 Deploy to Production ```bash sf project deploy start --target-org my-production --test-level RunLocalTests ``` --- ## 5. Flow Configuration ### 5.1 Update Existing Screen Flow **Step 1: Open Flow in Flow Builder** 1. Setup → Flows → [Your Form Selection Flow] 2. Click **Edit** **Step 2: Modify Template Loop Logic** **Old Logic** (sends one envelope per template): ``` Loop through selected templates └─ Create envelope for template ``` **New Logic** (sends one envelope with all templates): ``` Get selected templates (checkbox collection) └─ Apex Action: Send Composite Envelope Input: templateIds (checkbox collection) Output: envelopeId ``` **Step 3: Add Apex Action Element** 1. Drag **Action** element onto canvas (after template selection screen) 2. **Action**: `Send Composite Docusign Envelope` 3. **Label**: Send Composite Envelope 4. **API Name**: Send_Composite_Envelope 5. **Set Input Values**: - `templateIds` = `{!SelectedTemplateIds}` (collection from checkboxes) - `recordId` = `{!recordId}` (from flow start) - `language` = `{!SelectedLanguage}` (from language selection) - `emailSubject` = "Please review and sign these forms" 6. **Store Output Values**: - `envelopeId` → `{!EnvelopeId}` (text variable) - `success` → `{!Success}` (boolean variable) - `errorMessage` → `{!ErrorMessage}` (text variable) **Step 4: Add Decision Element (Success/Error)** 1. Drag **Decision** element after Apex Action 2. **Outcome 1: Success** - Condition: `{!Success}` Equals `true` - Next: Show success screen 3. **Outcome 2: Error** - Default outcome - Next: Show error screen (with `{!ErrorMessage}`) **Step 5: Remove Old Loop** 1. Delete old loop element that sent individual envelopes 2. Delete old Apex actions (if any) for single-template sending **Step 6: Save and Activate** 1. Click **Save As** → New version 2. Click **Activate** --- ## 6. Testing ### 6.1 Unit Test Verification **Run all tests**: ```bash sf apex run test --wait 10 --result-format human --code-coverage --target-org my-sandbox ``` **Expected code coverage**: >75% on all classes ### 6.2 Integration Test (Manual) **Test Case 1: Send 3 Templates (Happy Path)** 1. Navigate to Salesforce record 2. Launch Screen Flow 3. Select language: English 4. Check 3 templates: Form A, Form B, Form C 5. Click **Send** 6. **Expected**: - Success message shown - Envelope ID displayed - One envelope created in Docusign - Three documents in envelope - Recipients receive one email **Test Case 2: Send 1 Template (Minimum)** 1. Select 1 template only 2. **Expected**: Envelope created with 1 document **Test Case 3: Send 14 Templates (Maximum)** 1. Select all 14 templates 2. **Expected**: Envelope created with 14 documents **Test Case 4: Spanish Language** 1. Select language: Spanish 2. Select 2 Spanish templates 3. **Expected**: Envelope created with Spanish documents **Test Case 5: Error Handling (Invalid Template)** 1. Manually modify Apex to use invalid template ID 2. **Expected**: Error message displayed, no envelope created ### 6.3 Performance Test **Measure Apex execution time**: 1. Enable Debug Logs (Setup → Debug Logs) 2. Send envelope with 14 templates 3. Review log file 4. **Expected**: Execution time < 10 seconds --- ## 7. Monitoring ### 7.1 Debug Logs **Enable for API User**: 1. Setup → Debug Logs → New 2. **Traced Entity Type**: User 3. **Traced Entity Name**: [API User] 4. **Log Level**: FINEST (for troubleshooting) or INFO (for production) 5. **Expiration**: 1 day (or desired duration) **Review Logs**: 1. Setup → Debug Logs 2. Click **View** on recent log 3. Search for: - `REQUEST_BODY` (Docusign API request JSON) - `RESPONSE_BODY` (Docusign API response) - `CalloutException` (errors) ### 7.2 Custom Logging (Optional) **Create Custom Object for API Logs**: 1. Setup → Object Manager → Create → Custom Object 2. **Object Name**: Docusign API Log 3. **API Name**: Docusign_API_Log__c 4. Add fields: - **Envelope_Id__c** (Text, 255) - **Template_Count__c** (Number, 0 decimals) - **Status__c** (Picklist: Success, Error) - **Error_Message__c** (Long Text Area, 32,000) - **Request_Time__c** (Date/Time) - **Duration_Ms__c** (Number, 0 decimals) **Log API calls in Apex**: ```apex Docusign_API_Log__c log = new Docusign_API_Log__c( Envelope_Id__c = envelopeId, Template_Count__c = templateIds.size(), Status__c = 'Success', Request_Time__c = System.now(), Duration_Ms__c = durationMs ); insert log; ``` --- ## 8. Rollback Plan ### 8.1 Quick Rollback (Deactivate Flow) If issues arise in production: 1. Setup → Flows → [Your Flow] 2. **Deactivate** current version 3. **Activate** previous version (before composite envelope changes) ### 8.2 Full Rollback (Remove Apex) ```bash sf project deploy start --manifest manifest/destructiveChanges.xml --target-org production ``` **destructiveChanges.xml**: ```xml DocusignCompositeEnvelopeBuilder DocusignAPIService DocusignCredentials DocusignCompositeEnvelopeBuilderTest DocusignAPIServiceTest DocusignCredentialsTest ApexClass 60.0 ``` --- ## 9. Post-Deployment Checklist - [ ] Named Credential configured and tested - [ ] Custom Settings populated with Account ID - [ ] Remote Site Settings added - [ ] Apex classes deployed (100% coverage) - [ ] Unit tests pass - [ ] Screen Flow updated and activated - [ ] Integration test completed successfully - [ ] Debug logs reviewed (no errors) - [ ] User training completed - [ ] Documentation updated - [ ] Rollback plan tested --- ## 10. Troubleshooting ### 10.1 Common Issues **Issue**: `USER_AUTHENTICATION_FAILED` error **Cause**: Access token expired or invalid **Solution**: - Verify Named Credential configuration - Check Integration Key and User ID in Docusign - Re-grant consent if needed **Issue**: `INVALID_REQUEST_PARAMETER` - Template ID not found **Cause**: Template doesn't exist or is in different account **Solution**: - Verify template IDs in Docusign - Ensure using correct Docusign account (sandbox vs. production) **Issue**: Governor limit exceeded (Heap size) **Cause**: Too many templates or large JSON payload **Solution**: - Reduce number of templates per envelope - Optimize JSON construction (avoid unnecessary string concatenation) **Issue**: Flow shows no templates **Cause**: Flow query not finding templates **Solution**: - Check Flow SOQL query (if using custom object for template list) - Verify Docusign template naming convention matches Flow filter --- ## 11. Maintenance ### 11.1 Regular Tasks **Weekly**: - Review debug logs for errors - Check Docusign API usage (approaching rate limits?) **Monthly**: - Review custom object logs (if implemented) - Update templates as needed **Quarterly**: - Review access token expiry settings - Update Apex classes if Docusign API changes ### 11.2 Template Updates When adding a new form template: 1. Create template in Docusign (English + Spanish versions) 2. Update Flow template list (if hardcoded) 3. Test envelope creation with new template 4. Update user documentation --- ## 12. Support ### 12.1 Internal Support - **Salesforce Admin**: [Contact info] - **Docusign Admin**: [Contact info] - **Developer**: Paul Huliganga ### 12.2 External Resources - **Salesforce Support**: https://help.salesforce.com - **Docusign Support**: https://support.docusign.com - **Docusign Developer Center**: https://developers.docusign.com --- **Document Version**: 1.0 **Last Updated**: February 23, 2026 **Next Review**: After first production deployment