Broadleaf Microservices
  • v1.0.0-latest-prod

Offer Adjustment

Overview

When an offer is applied, an Adjustment is used to represent the details on the adjustment amount, corresponding offer, and the offer qualifier and target items. These Adjustments are included on the order that is returned from the apply offers flow. The system that interacts with the apply offers flow (in our Microservices stack, this is CartOperationService), must interpret the adjustment details to apply to the order. In this section below, we provide detailed information about the Adjustment payloads in order to provide context on how this data should be mapped.

How Adjustments Are Used

Out of the box, the adjustments are used in CartOperationServices and OrderOperationServices. For details on how they are used, please refer to:

Adjustment Types

Tip
Since Offer Service 3.1.0

Adjustments can be applied at different times in an order’s lifecycle, e.g., during checkout or as a future credit, or to different kinds of prices, e.g., recurring or upfront. As such, Broadleaf defines several default types to indicate the correct behavior to the systems involved.

Default Types
  • ORDER_DISCOUNT: The adjustment will be applied on the order itself at checkout or whenever payment is captured after checkout. This is the most common use-case and default value.

  • RECURRING_DISCOUNT: The adjustment will be applied to future periods typically by a billing or subscription service rather than at initial checkout. These adjustments will also specify the beginning and ending billing periods for when to apply the discount.

  • FREE_TRIAL: The adjustment will be applied as a deferment of payment until a trial period is completed by a billing or subscription service. These adjustments will also specify the length of the free trial.

  • FUTURE_CREDIT: The adjustment should be applied at a future time as a credit to the user. It is up to the implementor to decide how to achieve this. This replaces the isFutureAdjustment boolean field.

Adjustments Payload

Each offer adjustment, regardless of the offer type, has the following payload:

{
    "offerRef": { (1)
      "id": "offer-id",
      "name": "offer",
      "description": "description",
      "totalitarian": false,
      "combinable": false,
      "futureCredit": false,
      "cartLabel": "label",
      "prorationType": "TARGET_AND_QUALIFIER",
      "attributes": {}
    },
    "adjustmentAmount": { "amount": 5.99 }, (2)
    "isFutureCredit": false, (3)
    "codeUsed": "CODE_USED", (4)
    "quantityPerUsage": 1, (5)
    "offerUses": 1, (6)
    "qualifierDetails": [{ (7)
        "offerId": "offerId",
        "itemId": "itemX", (8)
        "quantityPerUsage": 1, (9)
        "offerUses": 1
    }]
    "type": false, (10)
    "freeTrialLength": 1, (11)
    "freeTrialLengthUnits": "DAYS", (12)
    "beginPeriod": 1, (13)
    "endPeriod": null, (14)
    "appliedToSalePrice": null, (15)
}
  1. A reference to the offer

  2. The discounted amount from this offer

  3. Deprecated since Offer Service 3.1.0. Use type instead, setting it to FUTURE_CREDIT. Whether this adjustment is the result of a future credit.

  4. The code used (if any) that triggered the application of the offer for this adjustment

  5. The quantity targeted by each usage of the offer

  6. How many times this offer is applied

  7. A collection of details about its offer qualifier items

  8. The id of the offer qualifier line item

  9. The quantity used as a qualifier for each usage of the offer

  10. Since Offer Service 3.1.0. Defines the type of adjustment. This can particularly impact when the adjustment should be applied to the order or items. This helps distinguish whether the adjustment applies at checkout or later such as for a subscription and what type of price is applies to, whether recurring or upfront. Typically, this will default to ORDER_DISCOUNT.

  11. Since Offer Service 3.1.0. When type is FREE_TRIAL, then this defines the free trial’s length.

  12. Since Offer Service 3.1.0. When type is FREE_TRIAL, then this defines the free trial length’s units.

  13. Since Offer Service 3.1.0. When type is SUBSCRIPTION_DISCOUNT, then this defines what billing period the adjustment should start applying.

  14. Since Offer Service 3.1.0. When type is SUBSCRIPTION_DISCOUNT, hen this defines what billing period the adjustment should stop applying, if ever.

  15. For Order and Fulfillment Item adjustments, this indicates whether the adjustment was applied to the sale or standard price of the item.

Note
Only target items have the adjustment payload stored, which has the relevant properties to help determine how the offers are applied. Refer to Offer Qualifier and Target Details for more details.

Offer Qualifier and Target Details

Applied offers may also include offer qualifier and target items. Offer qualifier items are the items that serve as qualifiers for the applied offers, while the offer target items are the items that are discounted from the applied offers.

By default, only OrderItem and FulfillmentItem offers have offer qualifier and target items.

Example Payloads

These are examples of the adjustment payload for different kinds of offer applied.

Buy 1X Get 1Y

ItemX

{
    "quantity": 1,
    "itemAdjustments": []
}

ItemY

{
    "quantity": 1,
    "itemAdjustments": [{
        "offerRef": {}, // some offer ref
        "adjustmentAmount": { "amount": 5.99 },
        "appliedToSalePrice": false,
        "isFutureCredit": false,
        "quantityPerUsage": 1,
        "offerUses": 1,
        "qualifierDetails": [
          {
            "offerId": "offerId",
            "itemId": "itemX",
            "quantityPerUsage": 1,
            "offerUses": 1
          }
        ]
    }]
}
Buy 1X Get 1Y Applied Twice

ItemX

{
    "quantity": 2,
    "itemAdjustments": []
}

ItemY

{
    "quantity": 1,
    "itemAdjustments": [{
        "offerRef": {}, // some offer ref
        "adjustmentAmount": { "amount": 5.99 },
        "appliedToSalePrice": false,
        "isFutureCredit": false,
        "quantityPerUsage": 1,
        "offerUses": 2, // note the offer uses are 2
        "qualifierDetails": [
          {
            "offerId": "offerId",
            "itemId": "itemX",
            "quantityPerUsage": 1,
            "offerUses": 2
          }
        ]
    }]
}
Buy One Get One

BogoItem

{
    "quantity": 2,
    "itemAdjustments": [{
        "offerRef": {}, // some offer ref
        "adjustmentAmount": { "amount": 5.99 },
        "appliedToSalePrice": false,
        "isFutureCredit": false,
        "quantityPerUsage": 1,
        "offerUses": 1,
        "qualifierDetails": [
          {
            "offerId": "offerId",
            "itemId": "BogoItem",
            "quantityPerUsage": 1,
            "offerUses": 1
          }
        ]
    }]
}
Buy One Get One Applied Twice

BogoItem

{
    "quantity": 4,
    "itemAdjustments": [{
        "offerRef": {}, // some offer ref
        "adjustmentAmount": { "amount": 5.99 },
        "appliedToSalePrice": false,
        "isFutureCredit": false,
        "quantityPerUsage": 1,
        "offerUses": 2,
        "qualifierDetails": [
          {
            "offerId": "offerId",
            "itemId": "BogoItem",
            "quantityPerUsage": 1,
            "offerUses": 2
          }
        ]
    }]
}
Buy 2X Get 1Y

ItemX

{
    "quantity": 2,
    "itemAdjustments": []
}

ItemY

{
    "quantity": 1,
    "itemAdjustments": [{
        "offerRef": {}, // some offer ref
        "adjustmentAmount": { "amount": 5.99 },
        "appliedToSalePrice": false,
        "isFutureCredit": false,
        "quantityPerUsage": 1,
        "offerUses": 1,
        "qualifierDetails": [
          {
            "offerId": "offerId",
            "itemId": "itemX",
            "quantityPerUsage": 2,
            "offerUses": 1
          }
        ]
    }]
}

Prorated Offer Adjustments

Offer adjustments are also prorated across items, fulfillment groups, or orders depending on the offer type. This proration is often used in OMS systems when returning or refunding items, so that the amounts refunded can be calculated accurately.

Example Payloads

These are examples of the adjustment payload with proration for various offer types:

Order Offer Proration

Given an order with two items:

  • ItemX has quantity 1 with a unit price of $8.99

  • ItemY has quantity 1 with a unit price of $5.99

The order subtotal is $14.98 and the offer to be applied is 15% off, creating a total discount value of $2.25.

Order offer adjustment prorated to items

ItemX

{
"proratedOrderOfferAdjustments": [
    {
      "offerRef": {
        "id": "01GPPEWPJB7VE608FY2T8Q17MY",
        "name": "15 percent off order",
        "description": null,
        "cartLabel": null,
        "prorationType": "TARGET_AND_QUALIFIER",
        "attributes": {}
      },
      "amount": {
        "amount": 1.35,
        "currency": "USD"
      },
      "itemProrationDetails": [
        {
          "unitAmount": {
            "amount": 1.35,
            "currency": "USD"
          },
          "quantity": 1
        }
      ]
    }
  ]
}

ItemY

{
"proratedOrderOfferAdjustments": [
    {
      "offerRef": {
        "id": "01GPPEWPJB7VE608FY2T8Q17MY",
        "name": "15 percent off order",
        "description": null,
        "cartLabel": null,
        "prorationType": "TARGET_AND_QUALIFIER",
        "attributes": {}
      },
      "amount": {
        "amount": 0.9,
        "currency": "USD"
      },
      "itemProrationDetails": [
        {
          "unitAmount": {
            "amount": 0.9,
            "currency": "USD"
          },
          "quantity": 1
        }
      ]
    }
  ]
}

Item Offer Proration

Given an order with two items:

  • ItemX has quantity 2 with a unit price of $8.99

  • ItemY has quantity 3 with a unit price of $5.99

The order subtotal is $35.95 and the offer to be applied is $5 off.

Item offer prorated across target items

ItemX

{
  "itemAdjustments": [
    {
      "offerRef": {
        "id": "01GPPEWPJB7VE608FY2T8Q17MY",
        "name": "5 dollars off 5 items",
        "description": null,
        "cartLabel": null,
        "prorationType": "TARGET_AND_QUALIFIER",
        "attributes": {}
      },
      "offerCodeRef": null,
      "amount": {
        "amount": 1.25,
        "currency": "USD"
      },
      "codeUsed": null,
      "alternateAdjustmentSource": null,
      "qualifierDetails": [],
      "quantityPerUsage": 5,
      "offerUses": 1,
      "campaignTrackingId": null
    }
  ]
}

ItemY

{
  "itemAdjustments": [
    {
      "offerRef": {
        "id": "01GPPEWPJB7VE608FY2T8Q17MY",
        "name": "5 dollars off 5 items",
        "description": null,
        "cartLabel": null,
        "prorationType": "TARGET_AND_QUALIFIER",
        "attributes": {}
      },
      "offerCodeRef": null,
      "amount": {
        "amount": 0.83,
        "currency": "USD"
      },
      "codeUsed": null,
      "alternateAdjustmentSource": null,
      "qualifierDetails": [],
      "quantityPerUsage": 5,
      "offerUses": 1,
      "campaignTrackingId": null
    }
  ]
}

Fulfillment Offer Proration

Given an order with two items:

  • ItemX has quantity 2 with an unit item fulfillment price of $1.90

  • ItemY has quantity 2 with an unit item fulfillment price of $1.60

  • Base shipping price of the group is $5.

The total shipping price is the sum of the base price plus the item prices.

$5 + (2 * $1.90) + (2 * $1.60) = $12

Using an offer with 50% off the shipping price, we expect the total discount to be $6.

Fulfillment group offer prorated across fulfillment items

FulfillmentGroup

{
  "proratedFulfillmentAdjustments": {
    "amount": 2.5,
    "currency": "USD"
  }
}

FulfillmentItemX

{
  "proratedFulfillmentGroupAdjustments": {
    "amount": 1.9,
    "currency": "USD"
  }
}

FulfillmentItemY

{
  "proratedFulfillmentGroupAdjustments": {
    "amount": 1.6,
    "currency": "USD"
  }
}

Bundle Item Offer Proration

Given an order with one items:

  • ItemX has quantity 3 with a unit price of $9.99

The order subtotal is $29.97 and the offer to be applied is buy a bundle of three for $25.

Bundle item offer prorated across items

ItemX

{
  "itemAdjustments": [
    {
      "offerRef": {
        "id": "01GPPEWPJB7VE608FY2T8Q17MY",
        "name": "Bundle item offer",
        "description": null,
        "cartLabel": null,
        "prorationType": "TARGET_AND_QUALIFIER",
        "attributes": {}
      },
      "offerCodeRef": null,
      "amount": {
        "amount": 3.32333,
        "currency": "USD"
      },
      "codeUsed": null,
      "alternateAdjustmentSource": null,
      "qualifierDetails": [],
      "quantityPerUsage": 3,
      "offerUses": 1,
      "campaignTrackingId": null
    }
  ]
}