> For the complete documentation index, see [llms.txt](https://developer.paddle.com/llms.txt).

# Add non-catalog products and prices to a transaction

Charge for an item without having to add it to your product catalog by passing price or product attributes when working with a transaction.

---

## What's new?

We updated the Paddle platform so that now you can [create transactions](https://developer.paddle.com/build/transactions/create-transaction.md) for [products](https://developer.paddle.com/api-reference/products/overview.md) and [prices](https://developer.paddle.com/api-reference/prices/overview.md) that aren't in your catalog.

When creating or updating a transaction, you can now pass price and product attributes directly to a transaction, as well as passing existing price IDs.

{% callout type="info" %}
In future updates, we'll release functionality to [let you bill one-time non-catalog items to a subscription](https://developer.paddle.com/changelog/2023/bill-custom-items-one-time-subscription-charge.md), then work with recurring non-catalog items on a subscription. These changes are scheduled for Q1 2024.
{% /callout %}

## How it works

As well as creating transactions for items in [your product catalog](https://developer.paddle.com/build/products/create-products-prices.md), you can create transactions for non-catalog items by passing [a price](https://developer.paddle.com/api-reference/prices/overview.md) and (optionally) [a product object](https://developer.paddle.com/api-reference/products/overview.md) directly to a transaction when creating or updating.

Adding [non-catalog items](https://developer.paddle.com/build/transactions/bill-create-custom-items-prices-products.md) to a transaction is great for one-off or bespoke items that are specific to that transaction. They let you manage your product catalog outside of Paddle. When adding a custom item to a transaction, you can:

* Pass a price object for an existing product to charge for a custom price for a catalog product
* Pass a price object and a product object to charge for a custom price for a custom product

This means you have the flexibility to manage your catalog in the way that best suits the way that you work. For example:

* If you work with third-party app stores, you can manage your product catalog centrally and pass custom prices and products to transactions.
* When invoicing enterprise customers, you can agree custom prices for existing products when negotiating.
* You can use Paddle to bill for large product catalogs where prices may change daily, like eBook resellers or customers who may show personalized prices to different users.

## Examples

### Create a transaction for a one-time item

This example creates a draft transaction for a one-time non-catalog item. It's for a custom product.

If successful, Paddle responds with a copy of the new transaction entity.

The created transaction is `draft`. You can [pass this transaction to a checkout](https://developer.paddle.com/build/transactions/pass-transaction-checkout.md) to capture customer and address information, and collect for payment.

{% api-example method="POST" path="/transactions" %}

```json {% title="Request" %}
{
  "items": [
    {
      "quantity": 1,
      "price": {
        "description": "New user price (FTUE)",
        "name": "Welcome price",
        "unit_price": {
          "amount": "999",
          "currency_code": "USD"
        },
        "product": {
          "name": "Invigaron Berries Hoard",
          "tax_category": "standard",
          "description": "Start the game with 20 extra seconds play time!"
        }
      }
    }
  ],
  "currency_code": "USD"
}
```

```json {% title="Response" %}
{
  "data": {
    "id": "txn_01hj3s8yt41c6kaqm8rx9zfgtf",
    "status": "draft",
    "customer_id": null,
    "address_id": null,
    "business_id": null,
    "custom_data": null,
    "origin": "api",
    "collection_mode": "automatic",
    "subscription_id": null,
    "invoice_id": null,
    "invoice_number": null,
    "billing_details": null,
    "billing_period": null,
    "currency_code": "USD",
    "discount_id": null,
    "created_at": "2023-12-20T14:15:04.47996325Z",
    "updated_at": "2023-12-20T14:15:04.47996325Z",
    "billed_at": null,
    "items": [
      {
        "price": {
          "id": "pri_01hj3s8yyfhtfvv9z9amcp6m55",
          "description": "New user price (FTUE)",
          "type": "custom",
          "name": "Welcome price",
          "product_id": "pro_01hj3s8yw3rpmp1y1n1sy8ty2x",
          "billing_cycle": null,
          "trial_period": null,
          "tax_mode": "account_setting",
          "unit_price": {
            "amount": "999",
            "currency_code": "USD"
          },
          "unit_price_overrides": [],
          "custom_data": null,
          "quantity": {
            "minimum": 1,
            "maximum": 100
          },
          "status": "active"
        },
        "quantity": 1
      }
    ],
    "details": {
      "tax_rates_used": [
        {
          "tax_rate": "0",
          "totals": {
            "subtotal": "999",
            "discount": "0",
            "tax": "0",
            "total": "999"
          }
        }
      ],
      "totals": {
        "subtotal": "999",
        "tax": "0",
        "discount": "0",
        "total": "999",
        "grand_total": "999",
        "fee": null,
        "credit": "0",
        "credit_to_balance": "0",
        "balance": "999",
        "earnings": null,
        "currency_code": "USD"
      },
      "adjusted_totals": {
        "subtotal": "999",
        "tax": "0",
        "total": "999",
        "grand_total": "999",
        "fee": "0",
        "earnings": "0",
        "currency_code": "USD"
      },
      "payout_totals": null,
      "adjusted_payout_totals": null,
      "line_items": [
        {
          "id": "txnitm_01hj3s8z0gswx71j2agzgp42zz",
          "price_id": "pri_01hj3s8yyfhtfvv9z9amcp6m55",
          "quantity": 1,
          "totals": {
            "subtotal": "999",
            "tax": "0",
            "discount": "0",
            "total": "999"
          },
          "product": {
            "id": "pro_01hj3s8yw3rpmp1y1n1sy8ty2x",
            "name": "Invigaron Berries Hoard",
            "description": "Start the game with 20 extra seconds play time!",
            "type": "custom",
            "tax_category": "standard",
            "image_url": null,
            "custom_data": null,
            "status": "active"
          },
          "tax_rate": "0",
          "unit_totals": {
            "subtotal": "999",
            "tax": "0",
            "discount": "0",
            "total": "999"
          }
        }
      ]
    },
    "payments": [],
    "checkout": {
      "url": "https://aeroedit.com/pay?_ptxn=txn_01hj3s8yt41c6kaqm8rx9zfgtf"
    }
  },
  "meta": {
    "request_id": "0ebcb490-0a6e-42ad-9d1d-b35d5a772030"
  }
}
```

{% /api-example %}

### Create a transaction for a recurring item

This example creates [a draft invoice](https://developer.paddle.com/build/invoices/create-issue-invoices.md) for a 50-user enterprise plan. It's for an existing product, related using the `product_id` field.

Collection mode is `manual`, meaning this transaction is an invoice. Once [issued](https://developer.paddle.com/build/invoices/create-issue-invoices#issue-invoice.md), Paddle sends an invoice that must be paid manually.

If successful, Paddle responds with a copy of the new transaction entity.

The created invoice is `ready`, since it includes all the required fields for it to be issued. [Issue it](https://developer.paddle.com/build/invoices/create-issue-invoices#issue-invoice.md) to send it the customer.

{% api-example method="POST" path="/transactions" %}

```json {% title="Request" %}
{
  "items": [
    {
      "quantity": 50,
      "price": {
        "product_id": "pro_01gsz4vmqbjk3x4vvtafffd540",
        "description": "Globex annual 2024",
        "name": "Annual (per seat) deal for Globex",
        "billing_cycle": {
          "interval": "year",
          "frequency": 1
        },
        "unit_price": {
          "amount": "50000",
          "currency_code": "USD"
        }
      }
    }
  ],
  "customer_id": "ctm_01h8441jn5pcwrfhwh78jqt8hk",
  "address_id": "add_01h848pep46enq8y372x7maj0p",
  "currency_code": "USD",
  "collection_mode": "manual",
  "billing_details": {
    "enable_checkout": false,
    "purchase_order_number": "PO-2400",
    "payment_terms": {
      "interval": "day",
      "frequency": 14
    },
    "additional_information": "Price agreed with Sam. Looking forward to working together in the year ahead!"
  },
  "billing_period": {
    "starts_at": "2024-04-01T00:00:00Z",
    "ends_at": "2025-03-31T23:59:00Z"
  }
}
```

```json {% title="Response" %}
{
  "data": {
    "id": "txn_01hj3ryktw234aj7s0wt5sp69g",
    "status": "ready",
    "customer_id": "ctm_01h8441jn5pcwrfhwh78jqt8hk",
    "address_id": "add_01h848pep46enq8y372x7maj0p",
    "business_id": null,
    "custom_data": null,
    "origin": "api",
    "collection_mode": "manual",
    "subscription_id": null,
    "invoice_id": null,
    "invoice_number": null,
    "billing_details": {
      "enable_checkout": false,
      "payment_terms": {
        "interval": "day",
        "frequency": 14
      },
      "purchase_order_number": "PO-2400",
      "additional_information": "Price agreed with Sam. Looking forward to working together in the year ahead!"
    },
    "billing_period": null,
    "currency_code": "USD",
    "discount_id": null,
    "created_at": "2023-12-20T14:09:25.78998194Z",
    "updated_at": "2023-12-20T14:09:25.78998194Z",
    "billed_at": null,
    "items": [
      {
        "price": {
          "id": "pri_01hj3rykvg0r83rnpwp5h87wy8",
          "description": "Globex annual 2024",
          "type": "custom",
          "name": "Annual (per seat) renewal deal for Globex",
          "product_id": "pro_01gsz4vmqbjk3x4vvtafffd540",
          "billing_cycle": {
            "interval": "year",
            "frequency": 1
          },
          "trial_period": null,
          "tax_mode": "account_setting",
          "unit_price": {
            "amount": "50000",
            "currency_code": "USD"
          },
          "unit_price_overrides": [],
          "custom_data": null,
          "quantity": {
            "minimum": 1,
            "maximum": 100
          },
          "status": "active"
        },
        "quantity": 50
      }
    ],
    "details": {
      "tax_rates_used": [
        {
          "tax_rate": "0.08875",
          "totals": {
            "subtotal": "2500000",
            "discount": "0",
            "tax": "221875",
            "total": "2721875"
          }
        }
      ],
      "totals": {
        "subtotal": "2500000",
        "tax": "221875",
        "discount": "0",
        "total": "2721875",
        "grand_total": "2721875",
        "fee": null,
        "credit": "0",
        "credit_to_balance": "0",
        "balance": "2721875",
        "earnings": null,
        "currency_code": "USD"
      },
      "adjusted_totals": {
        "subtotal": "2500000",
        "tax": "221875",
        "total": "2721875",
        "grand_total": "2721875",
        "fee": "0",
        "earnings": "0",
        "currency_code": "USD"
      },
      "payout_totals": null,
      "adjusted_payout_totals": null,
      "line_items": [
        {
          "id": "txnitm_01hj3rym8ff2yrkv43vstzfrx5",
          "price_id": "pri_01hj3rykvg0r83rnpwp5h87wy8",
          "quantity": 50,
          "totals": {
            "subtotal": "2500000",
            "tax": "221875",
            "discount": "0",
            "total": "2721875"
          },
          "product": {
            "id": "pro_01gsz4vmqbjk3x4vvtafffd540",
            "name": "ChatApp Enterprise",
            "description": "The ultimate solution for businesses that require top-of-the-line features and customizations. Includes all the features of the Pro plan, plus personalized onboarding, dedicated account management, and the ability to pay via invoice.",
            "type": "standard",
            "tax_category": "standard",
            "image_url": "https://paddle-sandbox.s3.amazonaws.com/user/10889/2nmP8MQSret0aWeDemRw_icon1.png",
            "custom_data": null,
            "status": "active"
          },
          "tax_rate": "0.08875",
          "unit_totals": {
            "subtotal": "50000",
            "tax": "4437",
            "discount": "0",
            "total": "54437"
          }
        }
      ]
    },
    "payments": [],
    "checkout": {
      "url": null
    }
  },
  "meta": {
    "request_id": "ade613b5-d62e-4f0a-93cb-a64516598fee"
  }
}
```

{% /api-example %}

## Next steps

This change is available in version `1` of the Paddle API.

It's a non-breaking change, meaning it doesn't impact existing integrations. You can continue creating transactions by passing price IDs for items in your product catalog. We recommend this for customers who sell a set of digital products at the same price points.

You can [create or update transactions](https://developer.paddle.com/build/transactions/bill-create-custom-items-prices-products.md) using the API to start charging for non-catalog items.

This is part of a set of changes around non-catalog items. In future updates, we'll release functionality to let you bill one-time non-catalog items to a subscription, then work with recurring non-catalog items on a subscription. These changes are scheduled for Q1 2024.
## Summary of changes

| Name | Type | Change | Entity | Description |
| --- | --- | --- | --- | --- |
| `items[].price_id` | Field | updated | transaction | This field is no longer required if you include a price object instead. |
| `items[].price` | Field | added | transaction | You can send a price object instead of a price_id to bill for a non-catalog item. |
