> You are reading the Docusign Developer Documentation. For clean Markdown of any page, append .md to the page URL.
>
> Documentation indexes by section:
> - APIs and SDKs: https://docusign.docs.buildwithfern.com/docs/llms.txt
> - Platform 101: https://docusign.docs.buildwithfern.com/platform/llms.txt
> - Extension Apps: https://docusign.docs.buildwithfern.com/extension-apps/llms.txt
> - Docusign CLI: https://docusign.docs.buildwithfern.com/docusign-cli/llms.txt
>
> Authentication (OAuth, JWT Grant, M2M): https://docusign.docs.buildwithfern.com/platform/auth
> Webhooks and Connect: https://docusign.docs.buildwithfern.com/platform/webhooks
>
> OpenAPI specifications: https://docusign.docs.buildwithfern.com/openapi.json
> MCP server: https://docusign.docs.buildwithfern.com/_mcp/server

# How to send a request for payment

> Demonstrates how to programmatically send a request for payment, including an order form that allows online payment via credit card.

This topic demonstrates how to use [Docusign Payments](https://www.docusign.com/products/payments) to collect payments by envelope. It walks you through the process of configuring a payment gateway that will accept and process the payments from signers. Then it shows you how to collect online credit card payments through an order form that you send in an envelope. You can test this example using one of the  [test credit cards](https://stripe.com/docs/testing#cards) provided by Stripe.

> **Note**
>
> Run this code example from our [Quickstart](/docs/esign-rest-api/quickstart) or launcher projects: [Bash](https://github.com/docusign/code-examples-bash), [C#](https://github.com/docusign/code-examples-csharp), [Java](https://github.com/docusign/code-examples-java), [Node.js](https://github.com/docusign/code-examples-node), [PHP](https://github.com/docusign/code-examples-php), [PowerShell](https://github.com/docusign/code-examples-powershell), [Python](https://github.com/docusign/code-examples-python), or [Ruby](https://github.com/docusign/code-examples-ruby).

## Required data

Running the code in this how-to requires this data:

| Data element                    | Description                                                                                                                                                                                                                                                                                                            |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| \{API_ACCOUNT_ID}               | A [GUID](http://guid.one/) value that identifies your account. This value is automatically generated by Docusign for any account you create. Copy the value from the **API Account ID** field on the [Apps and Keys](https://admindemo.docusign.com/authenticate?goTo=appsAndKeys) page.                               |
| \{BASE_PATH}                    | A string value that forms the root of the URL required to make API calls. The base path value in the example code is set to target the developer environment at https\://\<domain>/restapi Where \<domain> is demo.docusign.net for the developer environment and is the result of the GetUserInfo call in production. |
| \{CC_RECIPIENT_EMAIL}           | A string value for the email address of the carbon copy recipient.                                                                                                                                                                                                                                                     |
| \{CC_RECIPIENT_NAME}            | A string value for the name of the carbon copy recipient.                                                                                                                                                                                                                                                              |
| \{PAYMENT_GATEWAY_ACCOUNT_ID}   | Your payment gateway account ID.                                                                                                                                                                                                                                                                                       |
| \{PAYMENT_GATEWAY_DISPLAY_NAME} | The display name for your payment gateway.                                                                                                                                                                                                                                                                             |
| \{PAYMENT_GATEWAY_NAME}         | The name of your payment gateway.                                                                                                                                                                                                                                                                                      |
| Redirect URI                    | A URL to which the user will be forwarded after authentication. The value for this URL must exactly match one of those pre-registered for the [integration key](/platform/configure-app#integration-key) in your Docusign account. See [redirect URI](/platform/configure-app#redirect-uri) for details.               |
| \{SIGNER_EMAIL}                 | A string value for the email address where the signer will receive a notification of the signing request.                                                                                                                                                                                                              |
| \{SIGNER_NAME}                  | A string value for the full name of the signer.                                                                                                                                                                                                                                                                        |

## Step 1. Obtain your OAuth token

To make the API call shown in this how-to, you need a valid OAuth access token. Docusign supports access tokens for three different recommended OAuth grant types: Public Authorization Code Grant, Confidential Authorization Code Grant, and JSON Web Token (JWT) Grant. Choose the OAuth grant type appropriate for your scenario.

> **Note**
>
> See [Confidential Authorization Code Grant](/platform/auth/authcode#confidential-authorization-code-grant) for guidance on your options to get an Confidential Authorization Code Grant  OAuth token.

![Three icons that represent the three methods a user can use to obtain an OAuth token: JSON Web Token (JWT), Public Authorization Code Grant (ACG), and Confidential Authorization Code grant](/_fern-files/_img/64f473773042ee439449a096bf7673292b1585b86a4ccc55f82ba0dda41f61a1.webp)

## Step 2. Configure a payment gateway

Before you can use Docusign Payments, an account administrator (for this example, you, the developer) must set up one or more payment gateways for your account by following the steps in [Managing Payment Gateways](https://support.docusign.com/s/document-item?language=en_US\&rsc_301\&bundleId=juu1573854950452\&topicId=knc1573854895499.html&).

Docusign offers built-in connections to multiple payment gateways. This example uses a demo account and the Stripe payment gateway service.

Follow these steps:

1. Select the Stripe button on the [Payments](https://admindemo.docusign.com/authenticate?goTo=payments) page.
2. For development, you can skip the Stripe account application by using the **Skip this account form** link at the top of the page. An enabled Stripe payment gateway account is now associated with your developer account and is shown under **Payment Gateway**.
3. Configure your code with the **Gateway Account ID** that displays in Settings. For this example, you will need to include the gateway account ID, gateway name, and gateway display name in the envelope arguments.

![Docusign eSignature payment settings](/_fern-files/_img/184cbf313ab1e55ef754ff70044a86e6bf7fef26cb1d20df6bb054710694da0c.webp)

## Step 3. Create the envelope definition

Next, you create a new envelope definition. The envelope in this example uses an HTML document that contains an order form, formula fields, and multiple tags. The example also sets constants for items related to the order form. (In your integrations, you would pull these items from a product database.) Define a `makeEnvelope` method to create the envelope definition:

1. Read the HTML file for the order form. This example pulls from the `order_form.html` file in the source repository’s `documents` folder.
2. In the form, replace the placeholders for `signerName`, `signerEmail`, `ccName`, and `ccEmail` with the actual values.
3. Create the envelope definition.
4. Add the file containing the order form to the envelope as `doc1`. Create the document as a base64-encoded variable, then use that to create the document object.
5. Create a signer recipient using the signer’s name and email address. The example gives the signer a `signingOrder` of `1` so that they’re the first recipient to receive it, ensuring that the CC recipient receives a signed copy.
6. Create a CC recipient using the CC user’s name and email. In the example, the CC recipient has a `routingOrder` of `2`.
7. Create tabs for signature and quantities. The tabs in this example use [anchor positioning](/docs/esign-rest-api/esign101/concepts/tabs/auto-place).

   1. The first tab is a signHere tab anchored to `/sn1/` in the `order_form.html` file.
   2. The next two tabs are list tabs, both of which use the same list item definitions. They are anchored to `/l1q/` and `/l2q/` in the order form.
8. Create tabs for amounts. These are formula tabs anchored to `/l1e/`, `/l2e/` and `/l3t/` in the order form. The first two calculate values based on the values from the list tabs, multiplied by the item prices. The third calculates the total based on the first two.
9. Create objects for Docusign Payments. These include `PaymentLineItem` objects for each line item, plus a `PaymentDetails` object for capturing the transaction details and gateway information.
10. Create a formula tab for the payment itself. This tab is hidden (note that `x_position` and `y_position` are both `0`).
11. Associate the signer’s tabs with the signer recipient object.
12. Add the recipients to the envelope definition.
13. Set the envelope’s `status`. By default, the `status` is set to `sent`, which indicates that the system will immediately send the envelope. To create the envelope as a draft, set the `status` to `created` instead.

**`Bash`**

```bash title="Bash"
printf \
'{
    "emailSubject": "Please complete your order",
    "documents": [
        {
            "documentBase64": "' > $request_data
            cat $doc1_base64 >> $request_data
            printf '",
            "name": "Order form", "fileExtension": "html",
            "documentId": "1"
        }
    ],
    "recipients": {
        "carbonCopies": [
            {
                "email": "'${CC_EMAIL}'", "name": "'"${CC_NAME}"'",
                "recipientId": "2", "routingOrder": "2"
            }
        ],
        "signers": [
            {
                "email": "'${SIGNER_EMAIL}'", "name": "'"${SIGNER_NAME}"'",
                "recipientId": "1", "routingOrder": "1",
                "tabs": {
                    "formulaTabs": [
                        {
                            "anchorString": "/l1e/", "anchorUnits": "pixels",
                            "anchorXOffset": "105", "anchorYOffset": "-8",
                            "disableAutoSize": "false", "font": "helvetica",
                            "fontSize": "size11", "formula": "[l1q] * 5",
                            "locked": "true", "required": "true",
                            "roundDecimalPlaces": "0", "tabLabel": "l1e"
                        },
                        {
                            "anchorString": "/l2e/", "anchorUnits": "pixels",
                            "anchorXOffset": "105", "anchorYOffset": "-8",
                            "disableAutoSize": "false", "font": "helvetica",
                            "fontSize": "size11", "formula": "[l2q] * 150",
                            "locked": "true", "required": "true",
                            "roundDecimalPlaces": "0", "tabLabel": "l2e"
                        },
                        {
                            "anchorString": "/l3t/", "anchorUnits": "pixels",
                            "anchorXOffset": "50", "anchorYOffset": "-8",
                            "bold": "true", "disableAutoSize": "false",
                            "font": "helvetica", "fontSize": "size12",
                            "formula": "[l1e] + [l2e]", "locked": "true",
                            "required": "true", "roundDecimalPlaces": "0",
                            "tabLabel": "l3t"
                        },
                        {
                            "documentId": "1", "formula": "([l1e] + [l2e]) * 100",
                            "hidden": "true", "locked": "true",
                            "pageNumber": "1",
                            "paymentDetails": {
                                "currencyCode": "USD",
                                "gatewayAccountId": "' >> $request_data
                                printf "${GATEWAY_ACCOUNT_ID}" >> $request_data
                                printf '",
                                "gatewayDisplayName": "Stripe",
                                "gatewayName": "stripe",
                                "lineItems": [
                                    {
                                        "amountReference": "l1e",
                                        "description": "$5 each",
                                        "name": "Harmonica"
                                    },
                                    {
                                        "amountReference": "l2e",
                                        "description": "$150 each",
                                        "name": "Xylophone"
                                    }
                                ]
                            },
                            "required": "true", "roundDecimalPlaces": "0",
                            "tabLabel": "payment",
                            "xPosition": "0", "yPosition": "0"
                        }
                    ],
                    "listTabs": [
                        {
                            "anchorString": "/l1q/", "anchorUnits": "pixels",
                            "anchorXOffset": "0", "anchorYOffset": "-10",
                            "font": "helvetica", "fontSize": "size11",
                            "listItems": [
                                {"text": "none", "value": "0"},
                                {"text": "1", "value": "1"},
                                {"text": "2","value": "2"},
                                {"text": "3","value": "3"},
                                {"text": "4","value": "4"},
                                {"text": "5","value": "5"},
                                {"text": "6","value": "6"},
                                {"text": "7","value": "7"},
                                {"text": "8","value": "8"},
                                {"text": "9","value": "9"},
                                {"text": "10","value": "10"}
                            ],
                            "required": "true", "tabLabel": "l1q"
                        },
                        {
                            "anchorString": "/l2q/", "anchorUnits": "pixels",
                            "anchorXOffset": "0", "anchorYOffset": "-10",
                            "font": "helvetica", "fontSize": "size11",
                            "listItems": [
                                {"text": "none", "value": "0"},
                                {"text": "1", "value": "1"},
                                {"text": "2", "value": "2"},
                                {"text": "3", "value": "3"},
                                {"text": "4", "value": "4"},
                                {"text": "5", "value": "5"},
                                {"text": "6", "value": "6"},
                                {"text": "7", "value": "7"},
                                {"text": "8", "value": "8"},
                                {"text": "9", "value": "9"},
                                {"text": "10", "value": "10"}
                            ],
                            "required": "true", "tabLabel": "l2q"
                        }
                    ],
                    "signHereTabs": [
                        {
                            "anchorString": "/sn1/", "anchorUnits": "pixels",
                            "anchorXOffset": "20", "anchorYOffset": "10"
                        }
                    ]
                }
            }
        ]
    },
    "status": "sent"
}' >> $request_data
```

**`C#`**

```csharp title="C#"
EnvelopeDefinition envelope = MakeEnvelope(signerEmail, signerName, ccEmail, ccName, envStatus, gatawayAccountId, gatewayName, gatewayDisplayName);
        private static EnvelopeDefinition MakeEnvelope(
string signerEmail,
string signerName,
string ccEmail,
string ccName,
string envStatus,
string gatewayAccountId,
string gatewayName,
string gatewayDisplayName)
        {
// Data for this method
// signerEmail
// signerName
// ccEmail
// ccName
// envStatus

// document 1 (html) has multiple tags:
// /l1q/ and /l2q/ -- quantities: drop down
// /l1e/ and /l2e/ -- extended: payment lines
// /l3t/ -- total -- formula
//
// The envelope has two recipients.
// recipient 1 - signer
// recipient 2 - cc
// The envelope will be sent first to the signer.
// After it is signed, a copy is sent to the cc person.

///////////////////////////////////////////////////////////////////
//                                                               //
// NOTA BENA: This method programmatically constructs the        //
//            order form. For many use cases, it would be        //
//            better to create the order form as a template      //
//            using the DocuSign web tool as a WYSIWYG           //
//            form designer.                                     //
//                                                               //
///////////////////////////////////////////////////////////////////

// Order form constants
int l1Price = 5;
int l2Price = 150;
int currencyMultiplier = 100;
string l1Name = "Harmonica";
string l1Description = $"${l1Price} each",
     l2Name = "Xylophone";
string l2Description = $"${l2Price} each";

// Payment line items
PaymentLineItem paymentLineIteml1 = new PaymentLineItem
{
    Name = l1Name,
    Description = l1Description,
    AmountReference = "l1e",
},
paymentLineIteml2 = new PaymentLineItem
{
    Name = l2Name,
    Description = l2Description,
    AmountReference = "l2e",
};
PaymentDetails paymentDetails = new PaymentDetails
{
    GatewayAccountId = gatewayAccountId,
    CurrencyCode = "USD",
    GatewayName = gatewayName,
    GatewayDisplayName = gatewayDisplayName,
    LineItems = new List<PaymentLineItem> { paymentLineIteml1, paymentLineIteml2 },
};

// read file from a local directory
// The read could raise an exception if the file is not available!
string doc1Html1 = System.IO.File.ReadAllText("order_form.html");

// Substitute values into the HTML
// Substitute for: {signerName}, {signerEmail}, {ccName}, {ccEmail}
var doc1Html2 = doc1Html1.Replace("{signerName}", signerName)
        .Replace("{signerEmail}", signerEmail)
        .Replace("{ccName}", ccName)
        .Replace("{ccEmail}", ccEmail);

// create the envelope definition
EnvelopeDefinition env = new EnvelopeDefinition
{
    EmailSubject = "Please complete your order",
};

// add the documents
string doc1B64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(doc1Html2));
Document doc1 = new Document
{
    DocumentBase64 = doc1B64,
    Name = "Order form", // can be different from actual file name
    FileExtension = "html", // Source data format. Signed docs are always pdf.
    DocumentId = "1", // a label used to reference the doc
};
env.Documents = new List<Document> { doc1 };

// create a signer recipient to sign the document, identified by name and email
// We're setting the parameters via the object creation
Signer signer1 = new Signer
{
    Email = signerEmail,
    Name = signerName,
    RecipientId = "1",
    RoutingOrder = "1",
};

// routingOrder (lower means earlier) determines the order of deliveries
// to the recipients. Parallel routing order is supported by using the
// same integer as the order for two or more recipients.

// create a cc recipient to receive a copy of the documents, identified by name and email
// We're setting the parameters via setters
CarbonCopy cc1 = new CarbonCopy
{
    Email = ccEmail,
    Name = ccName,
    RoutingOrder = "2",
    RecipientId = "2",
};

// Create signHere fields (also known as tabs) on the documents,
// We're using anchor (autoPlace) positioning
SignHere signHere1 = new SignHere
{
    AnchorString = "/sn1/",
    AnchorYOffset = "10",
    AnchorUnits = "pixels",
    AnchorXOffset = "20",
};
ListItem listItem0 = new ListItem { Text = "none", Value = "0" },
       listItem1 = new ListItem { Text = "1", Value = "1" },
       listItem2 = new ListItem { Text = "2", Value = "2" },
       listItem3 = new ListItem { Text = "3", Value = "3" },
       listItem4 = new ListItem { Text = "4", Value = "4" },
       listItem5 = new ListItem { Text = "5", Value = "5" },
       listItem6 = new ListItem { Text = "6", Value = "6" },
       listItem7 = new ListItem { Text = "7", Value = "7" },
       listItem8 = new ListItem { Text = "8", Value = "8" },
       listItem9 = new ListItem { Text = "9", Value = "9" },
       listItem10 = new ListItem { Text = "10", Value = "10" }
       ;
List listl1Q = new List
{
    Font = "helvetica",
    FontSize = "size11",
    AnchorString = "/l1q/",
    AnchorYOffset = "-10",
    AnchorUnits = "pixels",
    AnchorXOffset = "0",
    ListItems = new List<ListItem>
    {
        listItem0, listItem1, listItem2,
        listItem3, listItem4, listItem5, listItem6,
        listItem7, listItem8, listItem9, listItem10,
    },
    Required = "true",
    TabLabel = "l1q",
},
listl2Q = new List
{
    Font = "helvetica",
    FontSize = "size11",
    AnchorString = "/l2q/",
    AnchorYOffset = "-10",
    AnchorUnits = "pixels",
    AnchorXOffset = "0",
    ListItems = new List<ListItem>
    {
        listItem0,
        listItem1,
        listItem2,
        listItem3,
        listItem4,
        listItem5,
        listItem6,
        listItem7,
        listItem8,
        listItem9,
        listItem10,
    },
    Required = "true",
    TabLabel = "l2q",
};

// create two formula tabs for the extended price on the line items
FormulaTab formulal1E = new FormulaTab
{
    Font = "helvetica",
    FontSize = "size11",
    AnchorString = "/l1e/",
    AnchorYOffset = "-8",
    AnchorUnits = "pixels",
    AnchorXOffset = "105",
    TabLabel = "l1e",
    Formula = $"[l1q] * {l1Price}",
    RoundDecimalPlaces = "0",
    Required = "true",
    Locked = "true",
    DisableAutoSize = "false",
},
formulal2E = new FormulaTab
{
    Font = "helvetica",
    FontSize = "size11",
    AnchorString = "/l2e/",
    AnchorYOffset = "-8",
    AnchorUnits = "pixels",
    AnchorXOffset = "105",
    TabLabel = "l2e",
    Formula = $"[l2q] * {l2Price}",
    RoundDecimalPlaces = "0",
    Required = "true",
    Locked = "true",
    DisableAutoSize = "false",
},

// Formula for the total
formulal3T = new FormulaTab
{
    Font = "helvetica",
    Bold = "true",
    FontSize = "size12",
    AnchorString = "/l3t/",
    AnchorYOffset = "-8",
    AnchorUnits = "pixels",
    AnchorXOffset = "50",
    TabLabel = "l3t",
    Formula = $"[l1e] + [l2e]",
    RoundDecimalPlaces = "0",
    Required = "true",
    Locked = "true",
    DisableAutoSize = "false",
};

// Hidden formula for the payment itself
FormulaTab formulaPayment = new FormulaTab
{
    TabLabel = "payment",
    Formula = $"([l1e] + [l2e]) * {currencyMultiplier}",
    RoundDecimalPlaces = "0",
    PaymentDetails = paymentDetails,
    Hidden = "true",
    Required = "true",
    Locked = "true",
    DocumentId = "1",
    PageNumber = "1",
    XPosition = "0",
    YPosition = "0",
};

// Tabs are set per recipient / signer
Tabs signer1Tabs = new Tabs
{
    SignHereTabs = new List<SignHere> { signHere1 },
    ListTabs = new List<List> { listl1Q, listl2Q },
    FormulaTabs = new List<FormulaTab> { formulal1E, formulal2E, formulal3T, formulaPayment },
};
signer1.Tabs = signer1Tabs;

// Add the recipients to the envelope object
Recipients recipients = new Recipients
{
    Signers = new List<Signer> { signer1 },
    CarbonCopies = new List<CarbonCopy> { cc1 },
};
env.Recipients = recipients;

// Request that the envelope be sent by setting |status| to "sent".
// To request that the envelope be created as a draft, set to "created"
env.Status = envStatus;

return env;
        }
```

**`Java`**

```java title="Java"

	public static EnvelopeDefinition makeEnvelope(
			String signerEmail,
			String signerName,
			String ccName,
			String ccEmail,
			String gatewayAccountId,
			String gatewayName,
			String gatewayDisplayName,
			WorkArguments args) throws IOException {
		byte[] htmlDoc = EnvelopeHelpers.createHtmlFromTemplateFile(HTML_DOCUMENT_FILE_NAME, "args", args)
				.getBytes(StandardCharsets.UTF_8);

		// create a signer recipient to sign the document, identified by name and email
		// routingOrder (lower means earlier) determines the order of deliveries
		// to the recipients. Parallel routing order is supported by using the
		// same integer as the order for two or more recipients.
		Signer signer = new Signer()
				.email(signerEmail)
				.name(signerName)
				.recipientId("1")
				.routingOrder("1");
		signer.setTabs(createTabs(gatewayAccountId, gatewayName, gatewayDisplayName));

		// create a cc recipient to receive a copy of the documents, identified by name
		// and email
		CarbonCopy cc = new CarbonCopy()
				.email(ccEmail)
				.name(ccName)
				.routingOrder("2")
				.recipientId("2");

		// Create the envelope definition
		// Request that the envelope be sent by setting |status| to "sent".
		// To request that the envelope be created as a draft, set to "created"
		EnvelopeDefinition envelope = new EnvelopeDefinition();
		envelope.setEmailSubject("Please complete your order");
		envelope.setDocuments(Collections.singletonList(EnvelopeHelpers.createDocument(htmlDoc,
				HTML_DOCUMENT_NAME, DocumentType.HTML.getDefaultFileExtention(), "1")));
		envelope.setRecipients(EnvelopeHelpers.createRecipients(signer, cc));
		envelope.setStatus(EnvelopeHelpers.ENVELOPE_STATUS_SENT);

		return envelope;
	}

	// creates tabs per signer
	private static Tabs createTabs(String gatewayAccountId, String gatewayName, String gatewayDisplayName) {
		java.util.List<ListItem> listItems = java.util.List.of(
				new ListItem().text("none").value("0"),
				new ListItem().text("1").value("1"),
				new ListItem().text("2").value("2"),
				new ListItem().text("3").value("3"),
				new ListItem().text("4").value("4"),
				new ListItem().text("5").value("5"),
				new ListItem().text("6").value("6"),
				new ListItem().text("7").value("7"),
				new ListItem().text("8").value("8"),
				new ListItem().text("9").value("9"),
				new ListItem().text("10").value("10"));
		List listl1q = createList("/l1q/", "l1q", listItems);
		List listl2q = createList("/l2q/", "l2q", listItems);

		// Create two formula tabs for the extended price on the line items and formula
		// for the total
		FormulaTab formulal1e = createFormulaTab("/l1e/", "l1e", L1_PRICE);
		FormulaTab formulal2e = createFormulaTab("/l2e/", "l2e", L2_PRICE);
		FormulaTab formulal3t = new FormulaTab()
				.font(DEFAULT_FONT)
				.bold(TRUE)
				.fontSize("size12")
				.anchorString("/l3t/")
				.anchorYOffset("-8")
				.anchorUnits(ANCHOR_UNITS)
				.anchorXOffset("50")
				.tabLabel("l3t")
				.formula("[l1e] + [l2e]")
				.roundDecimalPlaces("0")
				.required(TRUE)
				.locked(TRUE)
				.disableAutoSize(FALSE);
		PaymentLineItem paymentLineIteml1 = new PaymentLineItem()
				.name("Harmonica")
				.description(String.format("${%d} each", L1_PRICE))
				.amountReference("l1e");
		PaymentLineItem paymentLineIteml2 = new PaymentLineItem()
				.name("Xylophone")
				.description(String.format("${%d} each", L2_PRICE))
				.amountReference("l2e");
		PaymentDetails paymentDetails = new PaymentDetails()
				.gatewayAccountId(gatewayAccountId)
				.currencyCode("USD")
				.gatewayName(gatewayName)
				.gatewayDisplayName(gatewayDisplayName)
				.lineItems(Arrays.asList(paymentLineIteml1, paymentLineIteml2));
		// Hidden formula for the payment itself
		FormulaTab formulaPayment = new FormulaTab()
				.tabLabel("payment")
				.formula("([l1e] + [l2e]) * {100}")
				.roundDecimalPlaces("0")
				.paymentDetails(paymentDetails)
				.hidden(TRUE)
				.required(TRUE)
				.locked(TRUE)
				.documentId("1")
				.pageNumber("1")
				.xPosition("0")
				.yPosition("0");

		Tabs signerTabs = EnvelopeHelpers.createSingleSignerTab("/sn1/", ANCHOR_OFFSET_Y, ANCHOR_OFFSET_X);
		signerTabs.listTabs(Arrays.asList(listl1q, listl2q));
		signerTabs.formulaTabs(Arrays.asList(formulal1e, formulal2e, formulal3t, formulaPayment));
		return signerTabs;
	}

	private static List createList(String anchor, String label, java.util.List<ListItem> items) {
		return new List()
				.font(DEFAULT_FONT)
				.fontSize(DEFAULT_FONT_SIZE)
				.anchorString(anchor)
				.anchorYOffset("-10")
				.anchorUnits(ANCHOR_UNITS)
				.anchorXOffset("0")
				.listItems(items)
				.required(TRUE)
				.tabLabel(label);
	}

	private static FormulaTab createFormulaTab(String anchor, String label, int price) {
		return new FormulaTab()
				.font(DEFAULT_FONT)
				.fontSize(DEFAULT_FONT_SIZE)
				.anchorString(anchor)
				.anchorYOffset("-8")
				.anchorUnits(ANCHOR_UNITS)
				.anchorXOffset("105")
				.tabLabel(label)
				.formula(String.format("[l1q] * {%d}", price))
				.roundDecimalPlaces("0")
				.required(TRUE)
				.locked(TRUE)
				.disableAutoSize(FALSE);
	}
```

**`Node.js`**

```javascript title="Node.js"
let envelope = makeEnvelope(args.envelopeArgs);
function makeEnvelope(args) {
// Data for this method
// args.signerEmail
// args.signerName
// args.ccEmail
// args.ccName
// args.status
// args.gatewayAccountId
// args.gatewayName
// args.gatewayDisplayName
// demoDocsPath  -- module global
// doc1File  -- module global

// document 1 (html) has multiple tags:
// /l1q/ and /l2q/ -- quantities: drop down
// /l1e/ and /l2e/ -- extended: payment lines
// /l3t/ -- total -- formula
//
// The envelope has two recipients.
// recipient 1 - signer
// recipient 2 - cc
// The envelope will be sent first to the signer.
// After it is signed, a copy is sent to the cc person.

/// ////////////////////////////////////////////////////////////////
//                                                               //
// NOTA BENA: This method programmatically constructs the        //
//            order form. For many use cases, it would be        //
//            better to create the order form as a template      //
//            using the DocuSign web tool as WYSIWYG             //
//            form designer.                                     //
//                                                               //
/// ////////////////////////////////////////////////////////////////

// Order form constants
let l1Name = 'Harmonica';
  let l1Price = 5;
  let l1Description = `$${l1Price} each`;
  let l2Name = 'Xylophone';
  let l2Price = 150;
  let l2Description = `$${l2Price} each`;
  let currencyMultiplier = 100;
// read file from a local directory
// The read could raise an exception if the file is not available!
let doc1HTML1 = fs.readFileSync(args.docFile, { encoding: 'utf8' });

// Substitute values into the HTML
// Substitute for: {signerName}, {signerEmail}, {ccName}, {ccEmail}
let doc1HTML2 = doc1HTML1
  .replace('{signerName}', args.signerName)
  .replace('{signerEmail}', args.signerEmail)
  .replace('{ccName}', args.ccName)
  .replace('{ccEmail}', args.ccEmail);

// create the envelope definition
let env = new docusign.EnvelopeDefinition();
env.emailSubject = 'Please complete your order';

// add the documents
let doc1 = new docusign.Document();
  let doc1b64 = Buffer.from(doc1HTML2).toString('base64');
doc1.documentBase64 = doc1b64;
doc1.name = 'Order form'; // can be different from actual file name
doc1.fileExtension = 'html'; // Source data format. Signed docs are always pdf.
doc1.documentId = '1'; // a label used to reference the doc
env.documents = [doc1];

// create a signer recipient to sign the document, identified by name and email
// We're setting the parameters via the object creation
let signer1 = docusign.Signer.constructFromObject({
  email: args.signerEmail,
  name: args.signerName,
  recipientId: '1',
  routingOrder: '1',
});
// routingOrder (lower means earlier) determines the order of deliveries
// to the recipients. Parallel routing order is supported by using the
// same integer as the order for two or more recipients.

// create a cc recipient to receive a copy of the documents, identified by name and email
// We're setting the parameters via setters
let cc1 = new docusign.CarbonCopy();
cc1.email = args.ccEmail;
cc1.name = args.ccName;
cc1.routingOrder = '2';
cc1.recipientId = '2';

// Create signHere fields (also known as tabs) on the documents,
// We're using anchor (autoPlace) positioning
let signHere1 = docusign.SignHere.constructFromObject({
    anchorString: '/sn1/',
    anchorYOffset: '10',
    anchorUnits: 'pixels',
    anchorXOffset: '20',
  });
  let listItem0 = docusign.ListItem.constructFromObject({
    text: 'none',
    value: '0',
  });
  let listItem1 = docusign.ListItem.constructFromObject({
    text: '1',
    value: '1',
  });
  let listItem2 = docusign.ListItem.constructFromObject({
    text: '2',
    value: '2',
  });
  let listItem3 = docusign.ListItem.constructFromObject({
    text: '3',
    value: '3',
  });
  let listItem4 = docusign.ListItem.constructFromObject({
    text: '4',
    value: '4',
  });
  let listItem5 = docusign.ListItem.constructFromObject({
    text: '5',
    value: '5',
  });
  let listItem6 = docusign.ListItem.constructFromObject({
    text: '6',
    value: '6',
  });
  let listItem7 = docusign.ListItem.constructFromObject({
    text: '7',
    value: '7',
  });
  let listItem8 = docusign.ListItem.constructFromObject({
    text: '8',
    value: '8',
  });
  let listItem9 = docusign.ListItem.constructFromObject({
    text: '9',
    value: '9',
  });
  let listItem10 = docusign.ListItem.constructFromObject({
    text: '10',
    value: '10',
  });
  let listl1q = docusign.List.constructFromObject({
    font: 'helvetica',
    fontSize: 'size11',
    anchorString: '/l1q/',
    anchorYOffset: '-10',
    anchorUnits: 'pixels',
    anchorXOffset: '0',
    listItems: [
      listItem0,
      listItem1,
      listItem2,
      listItem3,
      listItem4,
      listItem5,
      listItem6,
      listItem7,
      listItem8,
      listItem9,
      listItem10,
    ],
    required: 'true',
    tabLabel: 'l1q',
  });
  let listl2q = docusign.List.constructFromObject({
    font: 'helvetica',
    fontSize: 'size11',
    anchorString: '/l2q/',
    anchorYOffset: '-10',
    anchorUnits: 'pixels',
    anchorXOffset: '0',
    listItems: [
      listItem0,
      listItem1,
      listItem2,
      listItem3,
      listItem4,
      listItem5,
      listItem6,
      listItem7,
      listItem8,
      listItem9,
      listItem10,
    ],
    required: 'true',
    tabLabel: 'l2q',
  });
  // create two formula tabs for the extended price on the line items
  let formulal1e = docusign.FormulaTab.constructFromObject({
    font: 'helvetica',
    fontSize: 'size11',
    anchorString: '/l1e/',
    anchorYOffset: '-8',
    anchorUnits: 'pixels',
    anchorXOffset: '105',
    tabLabel: 'l1e',
    formula: `[l1q] * ${l1Price}`,
    roundDecimalPlaces: '0',
    required: 'true',
    locked: 'true',
    disableAutoSize: 'false',
  });
  let formulal2e = docusign.FormulaTab.constructFromObject({
    font: 'helvetica',
    fontSize: 'size11',
    anchorString: '/l2e/',
    anchorYOffset: '-8',
    anchorUnits: 'pixels',
    anchorXOffset: '105',
    tabLabel: 'l2e',
    formula: `[l2q] * ${l2Price}`,
    roundDecimalPlaces: '0',
    required: 'true',
    locked: 'true',
    disableAutoSize: 'false',
  });
  // Formula for the total
  let formulal3t = docusign.FormulaTab.constructFromObject({
    font: 'helvetica',
    bold: 'true',
    fontSize: 'size12',
    anchorString: '/l3t/',
    anchorYOffset: '-8',
    anchorUnits: 'pixels',
    anchorXOffset: '50',
    tabLabel: 'l3t',
    formula: '[l1e] + [l2e]',
    roundDecimalPlaces: '0',
    required: 'true',
    locked: 'true',
    disableAutoSize: 'false',
  });
  // Payment line items
  let paymentLineIteml1 = docusign.PaymentLineItem.constructFromObject({
    name: l1Name,
    description: l1Description,
    amountReference: 'l1e',
  });
  let paymentLineIteml2 = docusign.PaymentLineItem.constructFromObject({
    name: l2Name,
    description: l2Description,
    amountReference: 'l2e',
  });
  let paymentDetails = docusign.PaymentDetails.constructFromObject({
    gatewayAccountId: args.gatewayAccountId,
    currencyCode: 'USD',
    gatewayName: args.gatewayName,
    gatewayDisplayName: args.gatewayDisplayName,
    lineItems: [paymentLineIteml1, paymentLineIteml2],
  });
  // Hidden formula for the payment itself
  let formulaPayment = docusign.FormulaTab.constructFromObject({
    tabLabel: 'payment',
    formula: `([l1e] + [l2e]) * ${currencyMultiplier}`,
    roundDecimalPlaces: '0',
    paymentDetails: paymentDetails,
    hidden: 'true',
    required: 'true',
    locked: 'true',
    documentId: '1',
    pageNumber: '1',
    xPosition: '0',
    yPosition: '0',
  });
// Tabs are set per recipient / signer
let signer1Tabs = docusign.Tabs.constructFromObject({
  signHereTabs: [signHere1],
  listTabs: [listl1q, listl2q],
  formulaTabs: [formulal1e, formulal2e, formulal3t, formulaPayment],
});
signer1.tabs = signer1Tabs;

// Add the recipients to the envelope object
let recipients = docusign.Recipients.constructFromObject({
  signers: [signer1],
  carbonCopies: [cc1],
});
env.recipients = recipients;

// Request that the envelope be sent by setting |status| to "sent".
// To request that the envelope be created as a draft, set to "created"
env.status = args.status;

return env;
}
```

**`PHP`**

```php title="PHP"
$envelope_definition = CollectPaymentService::makeEnvelope($args["envelope_args"], $demoDocsPath);
    public static function makeEnvelope(array $args, $demoDocsPath): EnvelopeDefinition
    {
# Order form constants
$l1_name = "Harmonica";
$l1_price = 5;
$l1_description = "$l1_price each";
$l2_name = "Xylophone";
$l2_price = 150;
$l2_description = "$l2_price each";
$currency_multiplier = 100;

# read the html file from a local directory
# The read could raise an exception if the file is not available!
$doc1_file = 'order_form.html';
$doc1_html_v1 = file_get_contents($demoDocsPath . $doc1_file);

# Substitute values into the HTML
# Substitute for: {signerName}, {signerEmail}, {cc_name}, {cc_email}
$doc1_html_v2 = str_replace(
    ['{signer_email}'     , '{cc_name}'     , '{cc_email}'     ],
    [$args['signer_email'], $args['cc_name'], $args['cc_email']],
    $doc1_html_v1
);

# create the envelope definition
$envelope_definition = new EnvelopeDefinition([
    'email_subject' => 'Please complete your order',
    'status' => 'sent']);

# add the document
$doc1_b64 = base64_encode($doc1_html_v2);
$doc1 = new Document([
    'document_base64' => $doc1_b64,
    'name' => 'Order form', # can be different from actual file name
    'file_extension' => 'html', # Source data format.
    'document_id' => '1' # a label used to reference the doc
]);
$envelope_definition->setDocuments([$doc1]);

# create a signer recipient to sign the document
$signer1 = new Signer([
    'email' => $args['signer_email'], 'name' => $args['signer_name'],
    'recipient_id' => "1", 'routing_order' => "1"]);
# create a cc recipient to receive a copy of the documents
$cc1 = new CarbonCopy([
    'email' => $args['cc_email'], 'name' => $args['cc_name'],
    'recipient_id' => "2", 'routing_order' => "2"]);

# Create signHere fields (also known as tabs) on the documents,
# We're using anchor (autoPlace) positioning
$sign_here1 = new SignHere([
    'anchor_string' => '/sn1/',
    'anchor_y_offset' => '10', 'anchor_units' => 'pixels',
    'anchor_x_offset' => '20']);

$list1 = new ModelList([
    'font' => "helvetica",
    'font_size' => "size11",
    'anchor_string' => '/l1q/',
    'anchor_y_offset' => '-10', 'anchor_units' => 'pixels',
    'anchor_x_offset' => '0',
    'list_items' => [
        ['text' => "1"   , 'value' => "1"   ], ['text' => "2", 'value' => "2"],
        ['text' => "3", 'value' => "3"], ['text' => "4" , 'value' => "4" ],
        ['text' => "5"  , 'value' => "5"  ], ['text' => "6", 'value' => "6"]
    ],
    'required' => "true",
    'tab_label' => "l1q"
]);

$list2 = new ModelList([
    'font' => "helvetica",
    'font_size' => "size11",
    'anchor_string' => '/l2q/',
    'anchor_y_offset' => '-10', 'anchor_units' => 'pixels',
    'anchor_x_offset' => '0',
    'list_items' => [
        ['text' => "1"   , 'value' => "1"   ], ['text' => "2", 'value' => "2"],
        ['text' => "3", 'value' => "3"], ['text' => "4" , 'value' => "4" ],
        ['text' => "5"  , 'value' => "5"  ], ['text' => "6", 'value' => "6"]
    ],
    'required' => "true",
    'tab_label' => "l2q"
]);

# create two formula tabs for the extended price on the line items
$formulal1e = new FormulaTab([
    'font' => "helvetica",
    'font_size' => "size11",
    'anchor_string' => '/l1e/',
    'anchor_y_offset' => '-8', 'anchor_units' => 'pixels',
    'anchor_x_offset' => '105',
    'tab_label' => "l1e",
    'formula' => "[l1q] * $l1_price",
    'round_decimal_places' => "0",
    'required' => "true",
    'locked' => "true",
    'disable_auto_size' => "false",
    ]);
$formulal2e = new FormulaTab([
    'font' => "helvetica",
    'font_size' => "size11",
    'anchor_string' => '/l2e/',
    'anchor_y_offset' => '-8', 'anchor_units' => 'pixels',
    'anchor_x_offset' => '105',
    'tab_label' => "l2e",
    'formula' => "[l2q] * $l2_price",
    'round_decimal_places' => "0",
    'required' => "true",
    'locked' => "true",
    'disable_auto_size' => "false",
    ]);
# Formula for the total
$formulal3t = new FormulaTab([
    'font' => "helvetica",
    'bold' => "true",
    'font_size' => "size12",
    'anchor_string' => '/l3t/',
    'anchor_y_offset' => '-8', 'anchor_units' => 'pixels',
    'anchor_x_offset' => '50',
    'tab_label' => "l3t",
    'formula' => '[l1e] + [l2e]',
    'round_decimal_places' => "0",
    'required' => "true",
    'locked' => "true",
    'disable_auto_size' => "false",
    ]);
# Payment line items
$payment_line_iteml1 = new PaymentLineItem([
    'name' => $l1_name, 'description' => $l1_description,
    'amount_reference' => "l1e"]);
$payment_line_iteml2 = new PaymentLineItem([
    'name' => $l2_name, 'description' => $l2_description,
    'amount_reference' => "l2e"]);
$payment_details = new PaymentDetails([
    'gateway_account_id' => $args['gateway_account_id'],
    'currency_code' => "USD",
    'gateway_name' => $args['gateway_name'],
    'line_items' => [$payment_line_iteml1, $payment_line_iteml2]]);
# Hidden formula for the payment itself
$formula_payment = new FormulaTab([
    'tab_label' => "payment",
    'formula' => "([l1e] + [l2e]) * $currency_multiplier",
    'round_decimal_places' => "0",
    'payment_details' => $payment_details,
    'hidden' => "true",
    'required' => "true",
    'locked' => "true",
    'document_id' => "1",
    'page_number' => "1",
    'x_position' => "0",
    'y_position' => "0"]);

# Tabs are set per recipient / signer
$signer1_tabs = new Tabs([
    'sign_here_tabs' => [$sign_here1],
    'list_tabs' => [$list1, $list2],
    'formula_tabs' => [$formulal1e, $formulal2e,
        $formulal3t, $formula_payment]]);
$signer1->setTabs($signer1_tabs);

# Add the recipients to the envelope object
$recipients = new Recipients([
    'signers' => [$signer1], 'carbon_copies' => [$cc1]]);
$envelope_definition->setRecipients($recipients);

return $envelope_definition;
    }
```

**`PowerShell`**

```text title="PowerShell"
@{
    emailSubject = "Please complete your order";
    documents    = @(
        @{
            documentBase64 = "$(Get-Content $doc1Base64)";
            name = "Order form"; fileExtension = "html";
            documentId = "1";
        };
    );
    recipients   = @{
        carbonCopies = @(
            @{
                email = $variables.CC_EMAIL; name = $variables.CC_NAME;
                recipientId = "2"; routingOrder = "2";
            }
        );
        signers      = @(
            @{
                email = $variables.SIGNER_EMAIL; name = $variables.SIGNER_NAME;
                recipientId = "1"; routingOrder = "1";
                tabs = @{
                    formulaTabs  = @(
                        @{
                            anchorString = "/l1e/"; anchorUnits = "pixels";
                            anchorXOffset = "105"; anchorYOffset = "-8";
                            disableAutoSize = "false"; font = "helvetica";
                            fontSize = "size11"; formula = "[l1q] * 5";
                            locked = "true"; required = "true";
                            roundDecimalPlaces = "0"; tabLabel = "l1e";
                        };
                        @{
                            anchorString = "/l2e/"; anchorUnits = "pixels";
                            anchorXOffset = "105"; anchorYOffset = "-8";
                            disableAutoSize = "false"; font = "helvetica";
                            fontSize = "size11"; formula = "[l2q] * 150";
                            locked = "true"; required = "true";
                            roundDecimalPlaces = "0"; tabLabel = "l2e";
                        };
                        @{
                            anchorString = "/l3t/"; anchorUnits = "pixels";
                            anchorXOffset = "50"; anchorYOffset = "-8";
                            bold = "true"; disableAutoSize = "false";
                            font = "helvetica"; fontSize = "size12";
                            formula = "[l1e] + [l2e]"; locked = "true";
                            required = "true"; roundDecimalPlaces = "0";
                            tabLabel = "l3t";
                        };
                        @{
                            documentId = "1"; formula = "([l1e] + [l2e]) * 100";
                            hidden = "true"; locked = "true";
                            pageNumber = "1";
                            paymentDetails = @{
                                currencyCode       = "USD";
                                gatewayAccountId   = $GATEWAY_ACCOUNT_ID;
                                gatewayDisplayName = "Stripe";
                                gatewayName        = "stripe";
                                lineItems          = @(
                                    @{
                                        amountReference = "l1e";
                                        description     = "$5 each";
                                        name            = "Harmonica";
                                    };
                                    @{
                                        amountReference = "l2e";
                                        description     = "$150 each";
                                        name            = "Xylophone";
                                    };
                                );
                            };
                            required = "true"; roundDecimalPlaces = "0";
                            tabLabel = "payment";
                            xPosition = "0"; yPosition = "0";
                        };
                    );
                    listTabs     = @(
                        @{
                            anchorString = "/l1q/"; anchorUnits = "pixels";
                            anchorXOffset = "0"; anchorYOffset = "-10";
                            font = "helvetica"; fontSize = "size11";
                            listItems = @(
                                @{text = "none"; value = "0"; };
                                @{text = "1"; value = "1"; };
                                @{text = "2"; value = "2"; };
                                @{text = "3"; value = "3"; };
                                @{text = "4"; value = "4"; };
                                @{text = "5"; value = "5"; };
                                @{text = "6"; value = "6"; };
                                @{text = "7"; value = "7"; };
                                @{text = "8"; value = "8"; };
                                @{text = "9"; value = "9"; };
                                @{text = "10"; value = "10"; };
                            );
                            required = "true"; tabLabel = "l1q";
                        };
                        @{
                            anchorString = "/l2q/"; anchorUnits = "pixels";
                            anchorXOffset = "0"; anchorYOffset = "-10";
                            font = "helvetica"; fontSize = "size11";
                            listItems = @(
                                @{text = "none"; value = "0"; };
                                @{text = "1"; value = "1"; };
                                @{text = "2"; value = "2"; };
                                @{text = "3"; value = "3"; };
                                @{text = "4"; value = "4"; };
                                @{text = "5"; value = "5"; };
                                @{text = "6"; value = "6"; };
                                @{text = "7"; value = "7"; };
                                @{text = "8"; value = "8"; };
                                @{text = "9"; value = "9"; };
                                @{text = "10"; value = "10"; };
                            );
                            required = "true"; tabLabel = "l2q";
                        };
                    );
                    signHereTabs = @(
                        @{
                            anchorString = "/sn1/"; anchorUnits = "pixels";
                            anchorXOffset = "20"; anchorYOffset = "10";
                        };
                    );
                };
            };
        );
    };
    status       = "sent";
} | ConvertTo-Json -Depth 32 > $requestData
```

**`Python`**

```python title="Python"
def make_envelope(cls, args):
    """
    This function creates the envelope definition for the
    order form.
    document 1 (html) has multiple tags:
     /l1q/ and /l2q/ -- quantities: drop down
     /l1e/ and /l2e/ -- extended: payment lines
     /l3t/ -- total -- formula

    The envelope has two recipients.
      recipient 1 - signer
      recipient 2 - cc
    The envelope will be sent first to the signer.
    After it is signed, a copy is sent to the cc person.

    #################################################################
    #                                                               #
    # NOTA BENA: This method programmatically constructs the        #
    #            order form. For many use cases, it would be        #
    #            better to create the order form as a template      #
    #            using the DocuSign web tool as WYSIWYG             #
    #            form designer.                                     #
    #                                                               #
    #################################################################

    """

    # Order form constants
    l1_name = "Harmonica"
    l1_price = 5
    l1_description = f"${l1_price} each"
    l2_name = "Xylophone"
    l2_price = 150
    l2_description = f"${l2_price} each"
    currency_multiplier = 100

    # read the html file from a local directory
    # The read could raise an exception if the file is not available!
    doc1_file = "order_form.html"
    with open(path.join(demo_docs_path, doc1_file), "r") as file:
        doc1_html_v1 = file.read()

    # Substitute values into the HTML
    # Substitute for: {signerName}, {signerEmail}, {cc_name}, {cc_email}
    doc1_html_v2 = doc1_html_v1.replace("{signer_name}", args["signer_name"]) \
        .replace("{signer_email}", args["signer_email"]) \
        .replace("{cc_name}", args["cc_name"]) \
        .replace("{cc_email}", args["cc_email"])

    # create the envelope definition
    envelope_definition = EnvelopeDefinition(
        email_subject="Please complete your order"
    )
    # add the document
    doc1_b64 = base64.b64encode(bytes(doc1_html_v2, "utf-8")).decode("ascii")
    doc1 = Document(
        document_base64=doc1_b64,
        name="Order form",  # can be different from actual file name
        file_extension="html",  # Source data format.
        document_id="1"  # a label used to reference the doc
    )
    envelope_definition.documents = [doc1]
    # create a signer recipient to sign the document
    signer1 = Signer(
        email=args["signer_email"],
        name=args["signer_name"],
        recipient_id="1",
        routing_order="1"
    )
    # create a cc recipient to receive a copy of the documents
    cc1 = CarbonCopy(
        email=args["cc_email"],
        name=args["cc_name"],
        recipient_id="2",
        routing_order="2"
    )
    # Create signHere fields (also known as tabs) on the documents,
    # We"re using anchor (autoPlace) positioning
    sign_here1 = SignHere(
        anchor_string="/sn1/",
        anchor_y_offset="10",
        anchor_units="pixels",
        anchor_x_offset="20"
    )
    list_item0 = ListItem(text="none", value="0")
    list_item1 = ListItem(text="1", value="1")
    list_item2 = ListItem(text="2", value="2")
    list_item3 = ListItem(text="3", value="3")
    list_item4 = ListItem(text="4", value="4")
    list_item5 = ListItem(text="5", value="5")
    list_item6 = ListItem(text="6", value="6")
    list_item7 = ListItem(text="7", value="7")
    list_item8 = ListItem(text="8", value="8")
    list_item9 = ListItem(text="9", value="9")
    list_item10 = ListItem(text="10", value="10")

    listl1q = List(
        font="helvetica",
        font_size="size11",
        anchor_string="/l1q/",
        anchor_y_offset="-10", anchor_units="pixels",
        anchor_x_offset="0",
        list_items=[list_item0, list_item1, list_item2,
                    list_item3, list_item4, list_item5, list_item6,
                    list_item7, list_item8, list_item9, list_item10],
        required="true",
        tab_label="l1q"
    )
    listl2q = List(
        font="helvetica",
        font_size="size11",
        anchor_string="/l2q/",
        anchor_y_offset="-10", anchor_units="pixels",
        anchor_x_offset="0",
        list_items=[list_item0, list_item1, list_item2,
                    list_item3, list_item4, list_item5, list_item6,
                    list_item7, list_item8, list_item9, list_item10],
        required="true",
        tab_label="l2q"
    )
    # create two formula tabs for the extended price on the line items
    formulal1e = FormulaTab(
        font="helvetica",
        font_size="size11",
        anchor_string="/l1e/",
        anchor_y_offset="-8", anchor_units="pixels",
        anchor_x_offset="105",
        tab_label="l1e",
        formula=f"[l1q] * {l1_price}",
        round_decimal_places="0",
        required="true",
        locked="true",
        disable_auto_size="false",
    )
    formulal2e = FormulaTab(
        font="helvetica",
        font_size="size11",
        anchor_string="/l2e/",
        anchor_y_offset="-8", anchor_units="pixels",
        anchor_x_offset="105",
        tab_label="l2e",
        formula=f"[l2q] * {l2_price}",
        round_decimal_places="0",
        required="true",
        locked="true",
        disable_auto_size="false",
    )
    # Formula for the total
    formulal3t = FormulaTab(
        font="helvetica",
        bold="true",
        font_size="size12",
        anchor_string="/l3t/",
        anchor_y_offset="-8", anchor_units="pixels",
        anchor_x_offset="50",
        tab_label="l3t",
        formula="[l1e] + [l2e]",
        round_decimal_places="0",
        required="true",
        locked="true",
        disable_auto_size="false",
    )
    # Payment line items
    payment_line_iteml1 = PaymentLineItem(
        name=l1_name,
        description=l1_description,
        amount_reference="l1e"
    )
    payment_line_iteml2 = PaymentLineItem(
        name=l2_name,
        description=l2_description,
        amount_reference="l2e"
    )
    payment_details = PaymentDetails(
        gateway_account_id=args["gateway_account_id"],
        currency_code="USD",
        gateway_name=args["gateway_name"],
        line_items=[payment_line_iteml1, payment_line_iteml2]
    )
    # Hidden formula for the payment itself
    formula_payment = FormulaTab(
        tab_label="payment",
        formula=f"([l1e] + [l2e]) * {currency_multiplier}",
        round_decimal_places="0",
        payment_details=payment_details,
        hidden="true",
        required="true",
        locked="true",
        document_id="1",
        page_number="1",
        x_position="0",
        y_position="0"
    )

    # Tabs are set per recipient / signer
    signer1_tabs = Tabs(
        sign_here_tabs=[sign_here1],
        list_tabs=[listl1q, listl2q],
        formula_tabs=[formulal1e, formulal2e, formulal3t, formula_payment]
    )
    signer1.tabs = signer1_tabs

    # Add the recipients to the envelope object
    recipients = Recipients(signers=[signer1], carbon_copies=[cc1])
    envelope_definition.recipients = recipients

    # Request that the envelope be sent by setting |status| to "sent".
    # To request that the envelope be created as a draft, set to "created"
    envelope_definition.status = args["status"]

    return envelope_definition
```

**`Ruby`**

```ruby title="Ruby"
def make_envelope(args)
  # This function creates the envelope definition for the order form
  # document 1 (html) has multiple tags:
  # /l1q/ and /l2q/ -- quantities: drop down
  # /l1e/ and /l2e/ -- extended: payment lines
  # /l3t/ -- total -- formula
  #
  # The envelope has two recipients:
  # recipient 1 - signer
  # recipient 2 - cc
  # The envelope will be sent first to the signer
  # After it is signed, a copy is sent to the cc person
  #
  #    #################################################################
  #    #
  #    # NOTA BENE: This method programmatically constructs the
  #    #            order form. For many use cases, it would be
  #    #            better to create the order form as a template
  #    #            using the Docusign web tool as WYSIWYG
  #    #            form designer.
  #    #
  #    #################################################################
  #

  # Order form constants
  l1_name = 'Harmonica'
  l1_price = 5
  l1_description = "#{l1_price} each"
  l2_name = 'Xylophone'
  l2_price = 150
  l2_description = "#{l2_price} each"
  currency_multiplier = 100

  # Read the HTML file from a local directory
  # The read could raise an exception if the file is not available!
  doc1_file = 'order_form.html'
  doc1_html_v1 = File.binread(File.join('data', doc1_file))
  # Substitute values into the HTML
  # Substitute for: {signerName}, {signerEmail}, {ccName}, {ccEmail}
  doc1_html_v2 = doc1_html_v1.gsub('{signerName}', args[:signer_name]) \
                             .gsub('{signerEmail}', args[:signer_email]) \
                             .gsub('{ccName}', args[:cc_name]) \
                             .gsub('{ccEmail}', args[:cc_email])

  # Create the envelope definition
  envelope_definition = DocuSign_eSign::EnvelopeDefinition.new(
    emailSubject: 'Please complete your order',
    status: 'sent'
  )

  # Add the document
  doc1_b64 = Base64.encode64(doc1_html_v2)
  doc1 = DocuSign_eSign::Document.new(
    documentBase64: doc1_b64,
    name: 'Order form', # Can be different from actual file name
    fileExtension: 'html', # Source data format
    documentId: '1' # A label used to reference the doc
  )
  envelope_definition.documents = [doc1]

  # Create a signer recipient to sign the document
  signer1 = DocuSign_eSign::Signer.new(
    email: args[:signer_email], name: args[:signer_name],
    recipientId: '1', routingOrder: '1'
  )
  # Create a cc recipient to receive a copy of the documents
  cc1 = DocuSign_eSign::CarbonCopy.new(
    email: args[:cc_email], name: args[:cc_name],
    routingOrder: '2', recipientId: '2'
  )

  # Create signHere fields (also known as tabs) on the documents,
  # We're using anchor (autoPlace) positioning
  sign_here1 = DocuSign_eSign::SignHere.new(
    anchorString: '/sn1/', anchorUnits: 'pixels',
    anchorYOffset: '10', anchorXOffset: '20'
  )
  list_item0 = DocuSign_eSign::ListItem.new(text: 'none', value: '0')
  list_item1 = DocuSign_eSign::ListItem.new(text: '1', value: '1')
  list_item2 = DocuSign_eSign::ListItem.new(text: '2', value: '2')
  list_item3 = DocuSign_eSign::ListItem.new(text: '3', value: '3')
  list_item4 = DocuSign_eSign::ListItem.new(text: '4', value: '4')
  list_item5 = DocuSign_eSign::ListItem.new(text: '5', value: '5')
  list_item6 = DocuSign_eSign::ListItem.new(text: '6', value: '6')
  list_item7 = DocuSign_eSign::ListItem.new(text: '7', value: '7')
  list_item8 = DocuSign_eSign::ListItem.new(text: '8', value: '8')
  list_item9 = DocuSign_eSign::ListItem.new(text: '9', value: '9')
  list_item10 = DocuSign_eSign::ListItem.new(text: '10', value: '10')

  listl1q = DocuSign_eSign::List.new(
    font: 'helvetica', fontSize: 'size11',
    anchorString: '/l1q/', anchorUnits: 'pixels',
    anchorYOffset: '-10', anchorXOffset: '0',
    listItems: [list_item0, list_item1, list_item2,
                list_item3, list_item4, list_item5, list_item6,
                list_item7, list_item8, list_item9, list_item10],
    required: 'true', tabLabel: 'l1q'
  )
  listl2q = DocuSign_eSign::List.new(
    font: 'helvetica', fontSize: 'size11',
    anchorString: '/l2q/', anchorUnits: 'pixels',
    anchorYOffset: '-10', anchorXOffset: '0',
    listItems: [list_item0, list_item1, list_item2,
                list_item3, list_item4, list_item5, list_item6,
                list_item7, list_item8, list_item9, list_item10],
    required: 'true', tabLabel: 'l2q'
  )

  # Create two formula tabs for the extended price on the line items
  formulal1e = DocuSign_eSign::FormulaTab.new(
    font: 'helvetica', fontSize: 'size11',
    anchorString: '/l1e/', anchorUnits: 'pixels',
    anchorYOffset: '-8', anchorXOffset: '105',
    tabLabel: 'l1e', formula: "[l1q] * #{l1_price}",
    roundDecimalPlaces: '0', required: 'true',
    locked: 'true', disableAutoSize: 'false'
  )
  formulal2e = DocuSign_eSign::FormulaTab.new(
    font: 'helvetica', fontSize: 'size11',
    anchorString: '/l2e/', anchorUnits: 'pixels',
    anchorYOffset: '-8', anchorXOffset: '105',
    tabLabel: 'l2e', formula: "[l2q] * #{l2_price}",
    roundDecimalPlaces: '0', required: 'true',
    locked: 'true', disableAutoSize: 'false'
  )

  # Formula for the total
  formulal3t = DocuSign_eSign::FormulaTab.new(
    font: 'helvetica', fontSize: 'size11',
    anchorString: '/l3t/', anchorUnits: 'pixels',
    anchorYOffset: '-8', anchorXOffset: '50',
    tabLabel: 'l3t', formula: '[l1e] + [l2e]',
    roundDecimalPlaces: '0', required: 'true',
    locked: 'true', disableAutoSize: 'false'
  )

  # Payment line items
  payment_line_iteml1 = DocuSign_eSign::PaymentLineItem.new(
    name: l1_name, description: l1_description,
    amountReference: 'l1e'
  )
  payment_line_iteml2 = DocuSign_eSign::PaymentLineItem.new(
    name: l2_name, description: l2_description,
    amountReference: 'l2e'
  )
  payment_details = DocuSign_eSign::PaymentDetails.new(
    gatewayAccountId: args[:gateway_account_id],
    currencyCode: 'USD',
    gatewayName: args[:gateway_name],
    lineItems: [payment_line_iteml1, payment_line_iteml2]
  )
  # Hidden formula for the payment itself
  formula_payment = DocuSign_eSign::FormulaTab.new(
    tabLabel: 'payment',
    formula: "([l1e] + [l2e]) * #{currency_multiplier}",
    roundDecimalPlaces: '0',
    paymentDetails: payment_details,
    hidden: 'true', required: 'true', locked: 'true',
    documentId: '1', pageNumber: '1',
    xPosition: '0', yPosition: '0'
  )

  # Tabs are set per recipient / signer
  signer1_tabs = DocuSign_eSign::Tabs.new(
    signHereTabs: [sign_here1],
    listTabs: [listl1q, listl2q],
    formulaTabs: [formulal1e, formulal2e,
                  formulal3t, formula_payment]
  )
  signer1.tabs = signer1_tabs

  # Add the recipients to the envelope object
  recipients = DocuSign_eSign::Recipients.new(
    signers: [signer1], carbonCopies: [cc1]
  )
  envelope_definition.recipients = recipients
  envelope_definition
end
```

## Step 4. Call the eSignature REST API

Next, create the envelope from the definition that you created in the previous step.

1. Instantiate the Docusign API client.
2. Set the following default request header to add your access token. `"Authorization" : "Bearer {ACCESS_TOKEN}"`
3. Initialize the eSignature REST API.
4. Create an envelope by passing in the generated envelope definition and your API account ID.

> **Note**
>
> View the source code for this how-to on GitHub: [Bash](https://github.com/docusign/code-examples-bash/blob/master/examples/eSignature/eg014CollectPayment.sh), [C#](https://github.com/docusign/code-examples-csharp/blob/master/launcher-csharp/eSignature/Examples/CollectPaymentInEnvelope.cs), [Java](https://github.com/docusign/code-examples-java/blob/master/src/main/java/com/docusign/controller/eSignature/services/CollectPaymentService.java), [Node.js](https://github.com/docusign/code-examples-node/blob/master/lib/eSignature/examples/collectPayment.js), [PHP](https://github.com/docusign/code-examples-php/blob/master/src/Services/Examples/eSignature/CollectPaymentService.php), [PowerShell](https://github.com/docusign/code-examples-powershell/blob/master/examples/eSignature/eg014CollectPayment.ps1), [Python](https://github.com/docusign/code-examples-python/blob/master/app/eSignature/examples/eg014_collect_payment.py), or [Ruby](https://github.com/docusign/code-examples-ruby/blob/main/app/services/e_sign/eg014_collect_payment_service.rb).

**`Bash`**

```bash title="Bash"
curl --header "Authorization: Bearer ${ACCESS_TOKEN}" \
     --header "Content-Type: application/json" \
     --data-binary @${request_data} \
     --request POST ${base_path}/v2.1/accounts/${account_id}/envelopes \
     --output $response
```

**`C#`**

```csharp title="C#"
var results = envelopesApi.CreateEnvelopeWithHttpInfo(accountId, envelope);
results.Headers.TryGetValue("X-RateLimit-Remaining", out string remaining);
results.Headers.TryGetValue("X-RateLimit-Reset", out string reset);

if (reset != null && remaining != null)
{
    DateTime resetDate = DateTimeOffset.FromUnixTimeSeconds(long.Parse(reset)).UtcDateTime;
    Console.WriteLine("API calls remaining: " + remaining);
    Console.WriteLine("Next Reset: " + resetDate);
}
```

**`Java`**

```java title="Java"
	public static EnvelopeSummary collectPayment(
			EnvelopesApi envelopesApi,
			EnvelopeDefinition envelope,
			String accountId) throws ApiException {
		// Call Envelopes::create API method
		var createdEnvelope = envelopesApi.createEnvelopeWithHttpInfo(accountId, envelope,
				envelopesApi.new CreateEnvelopeOptions());
		Map<String, java.util.List<String>> headers = createdEnvelope.getHeaders();
		java.util.List<String> remaining = headers.get("X-RateLimit-Remaining");
		java.util.List<String> reset = headers.get("X-RateLimit-Reset");

		if (remaining != null & reset != null) {
			Instant resetInstant = Instant.ofEpochSecond(Long.parseLong(reset.get(0)));
			System.out.println("API calls remaining: " + remaining);
			System.out.println("Next Reset: " + resetInstant);
		}
		return createdEnvelope.getData();
	}
```

**`Node.js`**

```javascript title="Node.js"
let results = await envelopesApi.createEnvelope(args.accountId, {
  envelopeDefinition: envelope,
}, (error, data, response) => {
    const headers = response?.headers;

    const remaining = headers?.['x-ratelimit-remaining'];
    const reset = headers?.['x-ratelimit-reset'];

    if (remaining && reset) {
      const resetInstant = new Date(Number(reset) * 1000);

      console.log(`API calls remaining: ${remaining}`);
      console.log(`Next Reset: ${resetInstant.toISOString()}`);
    }
});
```

**`PHP`**

```php title="PHP"
$envelope_api = $clientService->getEnvelopeApi();
$createdEnvelope = $envelope_api->createEnvelopeWithHttpInfo($args['account_id'], $envelope_definition);

$remaining = $createdEnvelope[2]['X-RateLimit-Remaining'] ?? null;
$reset = $createdEnvelope[2]['X-RateLimit-Reset'] ?? null;

if ($remaining !== null && $reset !== null) {
    $resetInstant = (new DateTime())->setTimestamp((int)$reset);
    error_log("API calls remaining: $remaining");
    error_log("Next Reset: " . $resetInstant->format(\DateTime::ATOM));
}

return ['envelope_id' => $createdEnvelope[0]->getEnvelopeId()];
```

**`PowerShell`**

```text title="PowerShell"
Invoke-RestMethod `
    -Uri "${apiUri}/v2.1/accounts/${accountId}/envelopes" `
    -Method 'POST' `
    -Headers @{
    'Authorization' = "Bearer $accessToken";
    'Content-Type'  = "application/json";
} `
    -InFile (Resolve-Path $requestData).Path `
    -OutFile $response
```

**`Python`**

```python title="Python"
api_client = create_api_client(base_path=args["base_path"], access_token=args["access_token"])

envelope_api = EnvelopesApi(api_client)
(results, status, headers) = envelope_api.create_envelope_with_http_info(account_id=args["account_id"], envelope_definition=envelope_definition)

remaining = headers.get("X-RateLimit-Remaining")
reset = headers.get("X-RateLimit-Reset")

if remaining is not None and reset is not None:
    reset_date = dt.fromtimestamp(int(reset), tz=timezone.utc)
    print(f"API calls remaining: {remaining}")
    print(f"Next Reset: {reset_date}")
```

**`Ruby`**

```ruby title="Ruby"
def worker
  envelope_definition = make_envelope(args[:envelope_args])
  # Create and send the envelope
  # Exceptions will be caught by the calling function
  envelope_api = create_envelope_api(args)
  results, _status, headers = envelope_api.create_envelope_with_http_info args[:account_id], envelope_definition

  remaining = headers['X-RateLimit-Remaining']
  reset = headers['X-RateLimit-Reset']

  if remaining && reset
    reset_date = Time.at(reset.to_i).utc
    puts "API calls remaining: #{remaining}"
    puts "Next Reset: #{reset_date}"
  end

  envelope_id = results.envelope_id
  { envelope_id: envelope_id }
end
```

## Expected response

If you run this code example from our Quickstart or launcher projects, you should see a JSON response similar to the code shown.

**`Sample response`**

```json title="Sample response"
{
  "envelopeId": "27a1bdd8-xxxx-xxxx-xxxx-66836ad6876b",
  "uri": "/envelopes/27a1bdd8-xxxx-xxxx-xxxx-66836ad6876b",
  "statusDateTime": "2020-08-13T19:15:02.8870000Z",
  "status": "sent"
}
```

## Next steps

* Run this code example from our [Quickstart](/docs/esign-rest-api/quickstart) or launcher projects:    [Bash](https://github.com/docusign/code-examples-bash), [C#](https://github.com/docusign/code-examples-csharp), [Java](https://github.com/docusign/code-examples-java), [Node.js](https://github.com/docusign/code-examples-node), [PHP](https://github.com/docusign/code-examples-php), [PowerShell](https://github.com/docusign/code-examples-powershell), [Python](https://github.com/docusign/code-examples-python), or [Ruby](https://github.com/docusign/code-examples-ruby).
* Find out more about [Docusign payments](/docs/esign-rest-api/esign101/concepts/tabs/payment).
* See how to [Go-Live](/docs/esign-rest-api/go-live) with a completed app and find the base path for API calls in the production environment.