Discounts and Coupons

Charge Discounts

In Stax Bill, a discount is an object that describes how to reduce the amount charged by a subscription product or finalized purchase. While a discount can be applied directly to a draft charge through the PATCH ready draft invoice endpoint, it is more common to apply a discount to a subscription product or draft purchase. The fields in a discount that relate to how much is discounted are in bold below:

{
"name": "discount name",
"description": "custom text",
"code": "firstdaysale",
"discountType": "Amount",
"remainingUsagesUntilStart": 2,
"remainingUsage": 4,
"amount": 100,
"status": "Active",
"id": 1157,
"uri": "https: //secure.fusebill.com/v1/Discounts/1157"
}

discountType is an enum that can be Amount, AmountPerUnit, or Percentage. They work as follows:

  • Amount: the value (measured in the currency of the customer) in amount is taken off the charge.
  • AmountPerUnit: the product of the value (measured in the currency of the customer) in amount and the value of the charge’s quantity is taken off the charge
  • Percentage: the value in amount is interpreted as a percentage and taken off the total for the charge

There is no interplay between a Percent discount and an Amount/AmountPerUnit discount, since the Percent discount is based on the charge total. If a charge is $10 with a $5 discount and a 10% discount, then the percent discount takes $1 off and the fixed discount takes $5 off, resulting in $4 charged to the customer. Stax Bill would not take $5 off, then take $0.50 off, and then charge the customer $4.50. Additionally, if the total discounted amount exceeds the charge total, then $0 is charged to the customer.

If the discount is applied to a purchase or an invoice charge, then there is no notion of remainingUsage or remainingUsagesUntilStart. Those fields exclusively relate to subscription products, which are the entities in Stax Bill which generate charges at regular intervals.

remainingUsagesUntilStart dictates how many recharges are to elapse before the discount starts. Zero is interpreted as immediately.

remainingUsage dictates the duration of the discount, measured in recharges. If the discount is to be applied on every recharge indefinitely, a null value is interpreted as infinity.

It is possible to configure plan products (which are the basis for subscription products) to charge at activation or quantity change. Plan products are also configured to charge at either the start or end of a period.

Suppose you have a subscription product on a one month subscription frequency, which charges at activation, charges at start of period, is included, and is for a subscription that activated on May 1st. That subscription was set with the following discount:

{
    "discountType": "Amount",
    "remainingUsagesUntilStart": 1,
    "remainingUsage": 2,
    "amount": 10
}

On May 1st, the activation will create a charge with no discount and will set remainingUsagesUntilStart to 0. The subscription is updated to reflect the $10 reduction.

On June 1st, the next period starts, and a recharge occurs. This time $10 is taken off the charge and remainingUsage is set to 1.

On July 1st, another recharge occurs, and the discount is used one last time. remainingUsage is 0 and the subscription no longer reflects the $10 reduction.

Catalog Coupons

Catalog discounts and coupons are read-only via the API and must be configured in the Stax Bill UI. This is because coupons are preconfigured delivery mechanisms for discounts. Coupons can be set with time-limited availability and global limits on usage. They can be used to apply multiple catalog discounts to a specified set of plans. They can even preconfigure which plan products on the plan to which the discounts are to be applied. This is a convenient way to bundle discounts together so that a user can easily apply them in one action using the unique coupon code.

Since a coupon is preconfigured to apply discounts to specific plan products on a plan, the coupon is used on the subscription, not the subscription products.

Apply a coupon to a subscription

If your company is configuring coupons which are not always eligible, the first step is to validate that the coupon can be applied to the given plan:

POST https://secure.fusebill.com/v1/Coupons/Validate
{
  "couponCode": "YouthDiscount2020",
  "planId": 212345
}

Here are the possible responses:

//Valid:
{ 
   "valid":true,
   "reason":"Coupon is valid"
}

//Invalid:
{
    "valid": false,
    "reason": "Coupon not applicable to plan"
}

Use the value of valid to determine that the coupon is applicable to the plan, in an eligible time period, and has not exhausted its usage limit.

After the coupon is deemed valid, create the subscription with the coupon code:

POST https://secure.fusebill.com/v1/subscriptionCoupons
{
    "subscriptionId": 12345,
    "couponCodes": [
	"YouthDiscount2020"
	]
}

This will apply all the configured discounts to the appropriate subscription products.
An alternate way to apply coupons to a subscription is by including them at the time of subscription creation:

POST https://secure.fusebill.com/v1/subscriptions
{
    "CustomerID": 659163,
    "planFrequencyID": 22145,
    "couponCodes": [
        "YouthDiscount2020"
    ]
}

Ad-hoc discounting

Rather than using the API to apply discounts via coupon codes, ad-hoc discounts can be applied directly.

Case 1: Ad-hoc subscription product discounts

One approach is to do a GET/PUT on the subscription product:

GET https://secure.fusebill.com/v1/subscriptions/5000

Set subscriptionProductDiscount to null, then add an element to the subscriptionProductDiscounts list for use in a PUT call:

PUT https://secure.fusebill.com/v1/subscriptionProducts
{
//unrelated fields removed for brevity. Include them when doing the actual PUT request
//explicitly set this field to null
"subscriptionProductDiscount": null,

    "subscriptionProductDiscounts": [
//leave the other discounts in the list alone. Removed for brevity
        {
            "discountType": "Percentage",
            "amount": 30.00,
            "remainingUsagesUntilStart": 4,
            "remainingUsage": 3,
        }
    ],
    //unrelated fields removed for brevity. Include them when doing the actual PUT request
}

More broadly, a GET/PUT can be done on the subscription:

GET https://secure.fusebill.com/v1/subscriptions/6000

For every element in the subscriptionProducts list, set subscriptionProductDiscount to null, then add an element to the subscriptionProductDiscounts list for use in a PUT call:

PUT https://secure.fusebill.com/v1/subscriptions
{
	//unrelated fields removed for brevity. Include them when doing the actual PUT request
	“subscriptionProducts”: [
	//for simplicity, assume there is only one subscription product in the list
		{
		//unrelated fields removed for brevity. Include them when doing the actual PUT request
//explicitly set this field to null
"subscriptionProductDiscount": null,

    "subscriptionProductDiscounts": [
//leave the other discounts in the list alone. Removed for brevity
        {
            "discountType": "Percentage",
            "amount": 30.00,
            "remainingUsagesUntilStart": 4,
            "remainingUsage": 3,
        }
    ],
    //unrelated fields removed for brevity. Include them when doing the actual PUT request

		}

	]
	    //unrelated fields removed for brevity. Include them when doing the actual PUT request
}

Case 2: Ad-hoc purchase discounts

A GET/PUT can be done just like in case 1, or the Add Purchase Discount call can be used:

POST v1/purchaseDiscount
{
  "purchaseId": 165549,
  "discountType": "AmountPerUnit",
  "amount": 10.50
}

Using a purchase discount ID (retrievable by reading the purchase with GET https://secure.fusebill.com/v1/purchases/{{purchaseId}}), the discount can be deleted or edited as follows.:

Delete (for a purchase discount with ID 8000):

DELETE v1/PurchaseDiscounts/8000

Edit (for a purchase discount with ID 8000):

PUT v1/purchaseDiscounts
{
    "discountType": "Percentage",
    "amount": 15.0,
    "id": 8000
}

Case 3: Ad-hoc charge discounts

This can be done through the PATCH draft invoice call. Only ready draft charges (ones that can be posted) are editable.

Call GET https://secure.fusebill.com/v1/DraftInvoices/7000 to get the draft invoice, which will have the list of draftCharges

Use the id of the charge to be edited for the following call:

{
    "id": 7000,
    "draftCharges": [
        {
            "id": 12345,
            "operation": "update",
            "draftDiscounts": [
                {
                    "configuredDiscountAmount": 3,
                    "discountType": "Amount",
                    "description": "$3 off",
                    "operation": "insert"
                }
            ]
        }
    ]
}

The configuredDiscountAmount in the draft discount is the equivalent of the Amount property used elsewhere. Since this discount directly relates to an invoice line item, it has an editable description which is what gets displayed on the invoice.