What's new?
We updated the Paddle API so you can create, update, or preview a transaction with a discount that isn't in your catalog.
How it works
Discounts can be applied to transactions to reduce the amount a customer has to pay. You can create discounts as part of promotions, or as a way to incentivize customers to upgrade or buy more.
Previously, you could only apply a discount from your catalog to transactions by providing the discount_id of that discount. Now, you can apply a non-catalog discount to a transaction by passing a discount object directly to the transaction when creating, updating, or previewing a transaction.
The discount object accepts a selection of the same fields used to create a catalog discount. If you provide a type of flat or flat_per_seat, you must also provide a currency_code on the transaction that specifies the currency for both the transaction and the discount.
The non-catalog discount to apply to a transaction.
Type of discount (flat, flat_per_seat, or percentage).
flat Discounts a transaction by a flat amount, for example -$100. Requires currency_code set on the transaction.
flat_per_seat Discounts a transaction by a flat amount per unit, for example -$100 per user. Requires currency_code set on the transaction.
percentage Discounts a transaction by a percentage of the total, for example -10%. Maximum 100%.
Amount to discount by.
Internal description for the discount.
false Whether the discount repeats for subscription billing periods.
Number of future subscription billing periods the discount repeats for. null for unlimited.
Product or price IDs to limit the discount to.
Custom key-value data attached to the discount.
Listing discounts won't return any non-catalog discounts. However, you can fetch non-catalog discounts individually through the API. Non-catalog discounts have a mode of custom.
When to use non-catalog discounts
Non-catalog discounts are one-off, non-transferable discounts which won't be listed in your discounts catalog. They're useful for when you have targeted discounts only valid for a specific customer on a specific transaction.
If your discount isn't intended to be broadly distributed and used, or you don't need to have a record of the discount to manage or track its performance, you should apply a non-catalog discount. For example, you might offer a discounted price on a high-profile customer's next transaction to prevent churn.
Examples
Request
This example creates a transaction with a non-catalog discount applied directly to the transaction. It includes a currency_code on the transaction because the discount type is flat.
/transactions { "items": [ { "quantity": 10, "price_id": "pri_01gsz8x8sawmvhz1pv30nge1ke" } ], "customer_id": "ctm_01gzgmxdmgkgc7p94b5kgqq82p", "address_id": "add_01gzkce0amtjsqv8xxd1rv3dna", "currency_code": "GBP", "discount": { "type": "flat", "description": "Custom loyalty discount", "amount": "500", "recur": true, "maximum_recurring_intervals": 6 }}{ "data": { "id": "txn_01gzkcdstcwq4cj8waj812v9my", "status": "ready", "customer_id": "ctm_01gzgmxdmgkgc7p94b5kgqq82p", "address_id": "add_01gzkce0amtjsqv8xxd1rv3dna", "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": "GBP", "discount_id": "dsc_01gy7s3d0n20p1m8b8q8v7e5k4", "created_at": "2025-05-04T12:40:07.834144Z", "updated_at": "2025-05-04T12:40:07.834144Z", "billed_at": null, "items": [ { "price": { "id": "pri_01gsz8x8sawmvhz1pv30nge1ke", "description": "Monthly (per seat)", "name": "Monthly (per seat)", "product_id": "pro_01gsz4t5hdjse780zja8vvr7jg", "billing_cycle": { "interval": "month", "frequency": 1 }, "trial_period": null, "tax_mode": "account_setting", "unit_price": { "amount": "3000", "currency_code": "GBP" }, "unit_price_overrides": [], "quantity": { "minimum": 10, "maximum": 999 }, "status": "active" }, "quantity": 10 } ], "details": { "tax_rates_used": [ { "tax_rate": "0.2", "totals": { "subtotal": "30000", "discount": "500", "tax": "5900", "total": "35400" } } ], "totals": { "subtotal": "30000", "tax": "5900", "discount": "500", "total": "35400", "grand_total": "35400", "fee": null, "credit": "0", "balance": "35400", "earnings": null, "currency_code": "GBP" }, "adjusted_totals": { "subtotal": "30000", "tax": "5900", "total": "35400", "grand_total": "35400", "fee": "0", "earnings": "0", "currency_code": "GBP" }, "payout_totals": null, "adjusted_payout_totals": null, "line_items": [ { "id": "txnitm_01h0qjj0ds7arpp88m5b2c399g", "price_id": "pri_01gsz8x8sawmvhz1pv30nge1ke", "quantity": 10, "totals": { "subtotal": "30000", "tax": "5900", "discount": "500", "total": "35400" }, "product": { "id": "pro_01gsz4t5hdjse780zja8vvr7jg", "name": "ChatApp Pro", "description": "Everything in basic, plus access to a suite of powerful tools and features designed to take your team's productivity to the next level.", "tax_category": "standard", "image_url": "https://twemoji.maxcdn.com/v/latest/72x72/2708.png", "status": "active" }, "tax_rate": "0.2", "unit_totals": { "subtotal": "3000", "tax": "590", "discount": "50", "total": "3540" } } ] }, "payments": [], "checkout": { "url": "https://aeroedit.com/pay?_ptxn=txn_01gzkcdstcwq4cj8waj812v9my" } }, "meta": { "request_id": "415a5995-bece-4775-8fb6-54be15c004d6" }}Summary of changes
| Entity | Field | Change | Type |
|---|---|---|---|
| Transaction | transaction.discount | + Added | Field |
| Provide an object with the details of the non-catalog discount you want to apply to the transaction. | |||