> ## Documentation Index
> Fetch the complete documentation index at: https://developers.firmly.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Set Billing Info

> Sets customer billing information for payment processing

## Overview

Sets customer billing information for the cart. This endpoint is typically used when the billing address differs from the shipping address. The billing information is used for payment processing and invoice generation.

<Note>
  If billing address is the same as shipping address, you may skip this endpoint and the shipping address will be used for billing by default.
</Note>

## Request Body

<ParamField body="first_name" type="string" required>
  Customer's first name for billing
</ParamField>

<ParamField body="last_name" type="string" required>
  Customer's last name for billing
</ParamField>

<ParamField body="address1" type="string" required>
  Primary billing address line
</ParamField>

<ParamField body="address2" type="string">
  Secondary billing address line (apartment, suite, etc.)
</ParamField>

<ParamField body="city" type="string" required>
  Billing city name
</ParamField>

<ParamField body="state_or_province" type="string" required>
  Billing state or province code (e.g., "CA", "NY") or full name
</ParamField>

<ParamField body="postal_code" type="string" required>
  Billing ZIP or postal code
</ParamField>

<ParamField body="country" type="string" required>
  Billing country code in ISO 3166-1 alpha-2 format (e.g., "US", "CA")
</ParamField>

<ParamField body="phone" type="string" required>
  Billing contact phone number
</ParamField>

<ParamField body="email" type="string" required>
  Billing contact email address
</ParamField>

## Response

Returns a complete [ShoppingCart](/api-reference/cart-management/get-cart) object with updated billing information. The cart totals remain unchanged as billing address doesn't affect shipping or tax calculations.

## When to Use Billing Info

### Common Scenarios

1. **Different Billing Address**: Customer's credit card billing address differs from shipping
2. **Gift Orders**: Shipping to recipient but billing to purchaser
3. **Business Orders**: Shipping to office but billing to headquarters
4. **Digital Products**: No shipping address but billing address required

### Default Behavior

If this endpoint is not called:

* Shipping address is used as billing address
* Both addresses must match for payment processing

## Code Examples

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.firmly.work/api/v2/domains/staging.luma.gift/cart/billing-info \
    -H "x-firmly-authorization: Bearer YOUR_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "first_name": "Jane",
      "last_name": "Doe",
      "address1": "456 Billing Street",
      "address2": "Suite 100",
      "city": "Billing City",
      "state_or_province": "NY",
      "postal_code": "10001",
      "country": "US",
      "phone": "555-987-6543",
      "email": "jane.doe@staging.luma.gift"
    }'
  ```

  ```javascript JavaScript theme={null}
  const billingInfo = {
    first_name: "Jane",
    last_name: "Doe",
    address1: "456 Billing Street",
    address2: "Suite 100",
    city: "Billing City",
    state_or_province: "NY",
    postal_code: "10001",
    country: "US",
    phone: "555-987-6543",
    email: "jane.doe@staging.luma.gift"
  };

  const response = await fetch('https://api.firmly.work/api/v2/domains/staging.luma.gift/cart/billing-info', {
    method: 'POST',
    headers: {
      'x-firmly-authorization': 'Bearer YOUR_TOKEN',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(billingInfo)
  });

  const updatedCart = await response.json();
  ```

  ```python Python theme={null}
  import requests

  billing_info = {
      "first_name": "Jane",
      "last_name": "Doe",
      "address1": "456 Billing Street",
      "address2": "Suite 100",
      "city": "Billing City",
      "state_or_province": "NY",
      "postal_code": "10001",
      "country": "US",
      "phone": "555-987-6543",
      "email": "jane.doe@staging.luma.gift"
  }

  response = requests.post(
      'https://api.firmly.work/api/v2/domains/staging.luma.gift/cart/billing-info',
      headers={
          'x-firmly-authorization': 'Bearer YOUR_TOKEN',
          'Content-Type': 'application/json'
      },
      json=billing_info
  )

  updated_cart = response.json()
  ```

  ```php PHP theme={null}
  $billingInfo = [
      'first_name' => 'Jane',
      'last_name' => 'Doe',
      'address1' => '456 Billing Street',
      'address2' => 'Suite 100',
      'city' => 'Billing City',
      'state_or_province' => 'NY',
      'postal_code' => '10001',
      'country' => 'US',
      'phone' => '555-987-6543',
      'email' => 'jane.doe@example.com'
  ];

  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, 'https://api.firmly.work/api/v2/domains/staging.luma.gift/cart/billing-info');
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'x-firmly-authorization: Bearer YOUR_TOKEN',
      'Content-Type: application/json'
  ]);
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($billingInfo));
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

  $response = curl_exec($ch);
  $updatedCart = json_decode($response, true);
  curl_close($ch);
  ```
</CodeGroup>

## Response Example

```json theme={null}
{
  "line_items": [...],
  "shipments": [...],
  "shipping_info": {
    "first_name": "John",
    "last_name": "Smith",
    "address1": "123 Main Street",
    "address2": "Apt 4B",
    "city": "Anytown",
    "state_or_province": "CA",
    "postal_code": "12345",
    "country": "US",
    "phone": "555-123-4567",
    "email": "john.smith@staging.luma.gift"
  },
  "billing_info": {
    "first_name": "Jane",
    "last_name": "Doe",
    "address1": "456 Billing Street",
    "address2": "Suite 100",
    "city": "Billing City",
    "state_or_province": "NY",
    "postal_code": "10001",
    "country": "US",
    "phone": "555-987-6543",
    "email": "jane.doe@staging.luma.gift"
  },
  "sub_total": {
    "currency": "USD",
    "value": 44.00,
    "number": 4400,
    "symbol": "$"
  },
  "shipping_total": {
    "currency": "USD",
    "value": 9.99,
    "number": 999,
    "symbol": "$"
  },
  "tax_total": {
    "currency": "USD",
    "value": 4.40,
    "number": 440,
    "symbol": "$"
  },
  "total": {
    "currency": "USD",
    "value": 58.39,
    "number": 5839,
    "symbol": "$"
  },
  "schema_version": "2.0"
}
```

## Billing Address Validation

Similar to shipping address, the billing address undergoes validation:

1. **Country Support**: Verifies billing country is supported
2. **State/Province**: Validates state/province for the country
3. **Required Fields**: Ensures all required fields are present
4. **Email Format**: Validates email address format

<Warning>
  Billing address validation is primarily for data integrity. Payment processors may perform additional address verification (AVS) during payment processing.
</Warning>

## Billing Address Behavior

1. **Independent from Shipping**: Billing info can be set independently of shipping
2. **No Tax Impact**: Billing address doesn't affect tax calculations (taxes based on shipping destination)
3. **Schema Compatibility**: Uses the same address schema as shipping for consistency
4. **Session Storage**: Billing info is stored in the cart session

## Error Responses

<ResponseExample>
  ```json theme={null}
  {
    "code": 400,
    "error": "ErrorCountryNotSupported",
    "description": "Country 'XX' is not supported by this merchant"
  }
  ```
</ResponseExample>

### Common Errors

| Error Code                 | Description                        | Resolution                     |
| -------------------------- | ---------------------------------- | ------------------------------ |
| `ErrorCartNotFound`        | Cart does not exist                | Verify cart ID and domain      |
| `ErrorCountryNotSupported` | Billing country not supported      | Use supported country          |
| `ErrorInvalidState`        | Invalid state/province for country | Verify state code              |
| `ErrorInvalidInputBody`    | Request body validation failed     | Check request format           |
| `MissingAuthHeader`        | Missing authorization header       | Include x-firmly-authorization |
| `InvalidToken`             | Invalid JWT token                  | Refresh authentication token   |

## Checkout Flow Integration

The typical checkout flow sequence:

1. [Add Items to Cart](/api-reference/cart-management/add-line-item) - Build the cart
2. [Set Shipping Info](/api-reference/checkout/set-shipping-info) - Add shipping address
3. **Set Billing Info** - Add billing address (this endpoint)
4. [Set Consents](/api-reference/checkout/set-consents) - Handle consent management
5. [Complete Order](/api-reference/checkout/complete-order-v3) - Complete the purchase
