> For the complete documentation index, see [llms.txt](https://docs.2checkout.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.2checkout.com/json-rpc-api-reference/json-rpc-api-6.0/api-requests/place-orders-with-catalog-products/place-order-with-addons.md).

# Place order with addons

Use the **placeOrder** method to buy addons together with a main product, or to add an addon to a subscription your customer already has. This page lists the order parameters and errors that are specific to addons. The other placeOrder parameters are unchanged.

An addon can only be purchased if it is associated with the main product, and it cannot be sold on its own.

## Request parameters

<table><thead><tr><th width="389.39990234375">Parameters</th><th>Type / Description</th></tr></thead><tbody><tr><td><code>sessionID</code></td><td><p><strong>Required (string)</strong></p><p>Session identifier, the output of the <strong>Login</strong> method. Include <code>sessionID</code> into all your requests. 2Checkout throws an exception if the values are incorrect. The <code>sessionID</code> expires in <strong>10 minutes</strong>.</p></td></tr><tr><td><code>Items.OrderItem.MainProductCode</code></td><td><p><strong>Optional (string)</strong></p><p>Required for addon products purchased together with a main product. The product code of the main product in the same order that the addon is linked to. It must match the <code>Code</code> of a non-addon item in <code>Items</code>.</p></td></tr><tr><td><code>Items.OrderItem.MainSubscriptionReference</code></td><td><p><strong>Optional (string)</strong></p><p>Use it to add an addon to an existing, active subscription. The reference of the main subscription. 2Checkout prorates the first billing cycle of the addon to the remaining time until the main subscription expires. You can reference different main subscriptions in the same order. Can be NULL.</p></td></tr><tr><td><code>Items.OrderItem.Quantity</code></td><td><p><strong>Optional (integer)</strong></p><p>Number of units. The quantity of an addon cannot be higher than the quantity of its main product.</p></td></tr></tbody></table>

## Buy an addon with a main product

Send the main product and its addon as two items in the same order, and set MainProductCode on the addon item. 2Checkout processes the order as a whole.

•       An order cannot contain only addon items. It needs at least one main product.

•       The main product cannot have delayed activation and cannot generate an instant subscription.

•       The addon must have a price configured in the order currency.

### Request sample

```php
<?php
require ('PATH_TO_AUTH');

$Order = array(
    'Currency' => 'USD',
    'Country' => 'US',
    'Language' => 'en',
    'CustomerIP' => '91.220.121.21',
    'Source' => 'testAPI.com',
    'BillingDetails' => array(
        'Address1' => 'Test Address',
        'City' => 'London',
        'CountryCode' => 'US',
        'Email' => 'customer@2Checkout.com',
        'FirstName' => 'Customer',
        'LastName' => '2Checkout',
        'Phone' => '556133127400',
        'State' => 'DF',
        'Zip' => '70403-900'
    ),
    'PaymentDetails' => array(
        'Type' => 'CC',
        'Currency' => 'USD',
        'CustomerIP' => '91.220.121.21',
        'PaymentMethod' => array(
            'CCID' => '123',
            'CardNumber' => '4111111111111111',
            'CardNumberTime' => '12',
            'CardType' => 'Visa',
            'ExpirationMonth' => '12',
            'ExpirationYear' => '2030',
            'HolderName' => 'John Doe',
            'HolderNameTime' => '12',
            'RecurringEnabled' => true,
            'Vendor3DSReturnURL' => 'www.test.com',
            'Vendor3DSCancelURL' => 'www.test.com'
        )
    ),
    'Items' => array(
        array('Code' => 'MAIN_PRODUCT_CODE', 'Quantity' => '1'),
        array('Code' => 'ADDON_PRODUCT_CODE', 'Quantity' => '1', 'MainProductCode' => 'MAIN_PRODUCT_CODE')
    )
);

$jsonRpcRequest = array (
'jsonrpc' => '2.0',
'method' => 'placeOrder',
'params' => array($sessionID, $Order),
'id' => $i++
);

var_dump (callRPC((Object)$jsonRpcRequest, $host));

```

## Error codes

<table><thead><tr><th width="391.63330078125">Error codes</th><th>Description</th></tr></thead><tbody><tr><td>ORDER_ADDON_ONLY_NOT_ALLOWED</td><td>An order cannot contain only addon items. At least one main product is required.</td></tr><tr><td>ORDER_ADDON_MAIN_PRODUCT_NOT_FOUND</td><td>Addon product [addon code] references main product [main product code] which is not present in the order.</td></tr><tr><td>ORDER_ADDON_QUANTITY_EXCEEDS_MAIN</td><td>Addon product [addon code] quantity [quantity] cannot exceed the quantity [quantity] of its main product [main product code].</td></tr><tr><td>ORDER_ADDON_NOT_ASSOCIATED</td><td>Addon product [addon code] is not associated to main product [main product code].</td></tr><tr><td>ORDER_ADDON_DELAYED_ACTIVATION_NOT_ALLOWED</td><td>Main product [main product code] has delayed activation and cannot be purchased with addons.</td></tr><tr><td>ORDER_ADDON_INSTANT_SUBSCRIPTION_NOT_ALLOWED</td><td>Main product [main product code] generates an instant subscription and cannot be purchased with addons.</td></tr><tr><td>ORDER_ADDON_PRICE_NOT_FOUND</td><td>Could not determine the catalogue price for addon product [addon code] in currency [currency]. Ensure the product has a price configured for this currency.</td></tr></tbody></table>

## Add an addon to an existing subscription

To add an addon to a subscription your customer already has, send the addon as an item and set MainSubscriptionReference to the main subscription. 2Checkout prorates the first billing cycle of the addon to the remaining time until the main subscription expires.

•       The main subscription must be active, have automatic renewal enabled, and not be paused.

•       The order currency must match the currency of the main subscription.

•       The billing email must match the customer of the main subscription.

•       Accepted payment methods: CC, EXISTING\_PAYMENT\_DATA, EES\_TOKEN\_PAYMENT, PAYPAL, PAYPAL\_EXPRESS and PAYPAL\_CREDIT.

## Request sample

```php
<?php
require ('PATH_TO_AUTH');

$Order = array(
    'Currency' => 'USD',
    'Country' => 'US',
    'Language' => 'en',
    'CustomerIP' => '91.220.121.21',
    'Source' => 'testAPI.com',
    'BillingDetails' => array(
        'Address1' => 'Test Address',
        'City' => 'London',
        'CountryCode' => 'US',
        'Email' => 'customer@2Checkout.com',
        'FirstName' => 'Customer',
        'LastName' => '2Checkout',
        'Phone' => '556133127400',
        'State' => 'DF',
        'Zip' => '70403-900'
    ),
    'PaymentDetails' => array(
        'Type' => 'CC',
        'Currency' => 'USD',
        'CustomerIP' => '91.220.121.21',
        'PaymentMethod' => array(
            'CCID' => '123',
            'CardNumber' => '4111111111111111',
            'CardNumberTime' => '12',
            'CardType' => 'Visa',
            'ExpirationMonth' => '12',
            'ExpirationYear' => '2030',
            'HolderName' => 'John Doe',
            'HolderNameTime' => '12',
            'RecurringEnabled' => true,
            'Vendor3DSReturnURL' => 'www.test.com',
            'Vendor3DSCancelURL' => 'www.test.com'
        )
    ),
    'Items' => array(
        array('Code' => 'ADDON_PRODUCT_CODE', 'Quantity' => '1', 'MainSubscriptionReference' => 'MAIN_SUBSCRIPTION_REFERENCE')
    )
);

$jsonRpcRequest = array (
'jsonrpc' => '2.0',
'method' => 'placeOrder',
'params' => array($sessionID, $Order),
'id' => $i++
);

var_dump (callRPC((Object)$jsonRpcRequest, $host));

```

## Error codes

| Error code                                                     | Description                                                                                                                                                                       |
| -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **ORDER\_MAIN\_SUBSCRIPTION\_NOT\_FOUND**                      | The main subscription reference \[subscription reference] was not found.                                                                                                          |
| **ORDER\_MAIN\_SUBSCRIPTION\_NOT\_ACTIVE**                     | The main subscription \[subscription reference] is not active.                                                                                                                    |
| **ORDER\_MAIN\_SUBSCRIPTION\_NOT\_RECURRING**                  | The main subscription \[subscription reference] is not set to auto-renew and cannot be used for addon purchase.                                                                   |
| **ORDER\_MAIN\_SUBSCRIPTION\_CUSTOMER\_MISMATCH**              | The billing email does not match the customer on the main subscription \[subscription reference].                                                                                 |
| **ORDER\_MAIN\_SUBSCRIPTION\_CURRENCY\_MISMATCH**              | The order currency does not match the main subscription \[subscription reference] currency \[currency].                                                                           |
| **ORDER\_MAIN\_SUBSCRIPTION\_PAYMENT\_METHOD\_NOT\_SUPPORTED** | Payment method \[payment method] is not supported for prorated addon purchases. Use CC, EXISTING\_PAYMENT\_DATA, EES\_TOKEN\_PAYMENT, PAYPAL, PAYPAL\_EXPRESS, or PAYPAL\_CREDIT. |
| **ORDER\_MAIN\_SUBSCRIPTION\_PAUSED**                          | The main subscription \[subscription reference] is paused and cannot have addons added while paused.                                                                              |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.2checkout.com/json-rpc-api-reference/json-rpc-api-6.0/api-requests/place-orders-with-catalog-products/place-order-with-addons.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
