Broadleaf Microservices
  • v1.0.0-latest-prod

CSR Interactions

Beyond customer interactions to modify carts, CSRs have the ability to also modify subscriptions via price changes and adding discounts (aka adjustments).

Price Changes

Price changes can be applied to PriceData such that the updated prices are applied to all, or subsets of, existing subscriptions at targeted points in the subscription’s lifecycle.

Admin UI Integration

In the Admin UI, when viewing Price Data, the edit row-level action will open a new form with fields for the application timing type, excluded segments/accounts, and the price fields (base, recurring, usage). The target of the Price Data (e.g., the SKU targeted), the terms, and the payment strategy (prepaid, postpaid) cannot be changed at this time.

Handling a PriceChangeRequest

This price change admin interaction submits a PriceChangeRequest to SubscriptionPricingEndpoint#updatePriceData). The new endpoint requires the ALL_ or UPDATE_PRICE_LIST permission same as normal for modifying a Price Data.

This endpoint accepts a PriceChangeRequest which contains the following information:

  • id: The ID of the Price Data to update.

  • priceListId: The context ID of the parent price list.

  • price: The one-time price.

  • recurringPrice: The amount of the recurring price.

  • usagePrice: The amount of the usage price.

  • applicationDateType: Dictates when the price data change should be applied onto the subscription. The out-of-the-box supported option is NEXT_BILL_DATE, meaning the price change is applied on the next billing period.

  • appliesTo: Whether the Price Data applies to ALL_CUSTOMERS or specific SEGMENTS.

  • includedSegments / excludedSegments: Identifies users via customer segments if appliesTo is set to SEGMENTS.

This endpoint processes the request and subsequently triggers the subscriptionBulkPricingUpdateWorkflow.

Price Change Workflows

Two main workflows handle the application of price data changes to existing subscriptions:

  1. subscriptionBulkPricingUpdateWorkflow: Modifies the Price Data entity and orchestrates finding affected subscriptions to log PriceDataChange records.

  2. subscriptionPriceChange: Takes the newly logged PriceDataChange and actually modifies the active Subscription and generates appropriate Billing Events.

broadleaf:
  workflow:
    client:
      flows:
        subscriptionBulkPricingUpdateWorkflow:
          description: Subscription Bulk Pricing Update Workflow
          historical-reset-enabled: true
          retry-enabled: true
        subscriptionPriceChange:
          description: Subscription Price Change Workflow
          historical-reset-enabled: false
          retry-enabled: true
      steps:
        subscriptionBulkPricingUpdateWorkflow:
          updatePriceDataActivity:
            admin-selectable: true
            decisions:
              ok: processPriceDataChangeActivity
          processPriceDataChangeActivity:
            admin-selectable: true
        subscriptionPriceChange:
          lockSubscriptionActivity:
            admin-selectable: true
            decisions:
              ok: subscriptionModificationActivity
              subscriptionLockFailure: waitStep
          waitStep:
            admin-selectable: false
            wait: true
            waitDuration: 1m
            decisions:
              ok: lockSubscriptionActivity
          subscriptionModificationActivity:
            admin-selectable: true
            decisions:
              ok: releaseSubscriptionLockActivity
          releaseSubscriptionLockActivity:
            admin-selectable: true

1. subscriptionBulkPricingUpdateWorkflow

Initial Workflow Context Parameters

  • PriceData.id

  • Application.id

  • Tenant.id

  • BulkPriceUpdateSubscriptionRequest details (e.g., included/excluded segments, target date type)

Workflow Activity Descriptions

  1. updatePriceDataActivity (broadleaf-subscription-operation-services-workflow) - Sends the updates to the Pricing Service to persist against the Price Data entity.

  2. processPriceDataChangeActivity (broadleaf-subscription-operation-services-workflow) - This activity is responsible for identifying the relevant subscriptions that need to be updated and initiating their price changes. It sends a request to SubscriptionPricingEndpoint#bulkUpdateSubscriptionPricing. The logic executed within this endpoint is as follows:

    • It looks up all the Subscriptions with items referencing the modified Price Data by ID (SubscriptionItem#priceDataId & SubscriptionItem#priceListId) and retrieves the IDs of the Customers/Accounts that own them. Batch size is controlled via broadleaf.subscriptionoperation.pricing.bulk-update-batch-size (default is 100).

    • It sends those Customer/Account IDs to Customer Service to filter the list of Customers/Accounts based on the desired segments.

    • Once the filtered list of customers/accounts is retrieved, it sends a PriceDataChangeRequest to SubscriptionEndpoint#addPriceDataChanges which adds a PriceDataChange record to the target Subscriptions (SUBSCRIPTION.PRICE_DATA_CHANGES column).

    • If the price change should be applied immediately (e.g., NEXT_BILL_DATE), this activity then triggers the subscriptionPriceChange workflow for each affected Subscription ahead of the subscription’s next bill date. (For prices taking effect at Next Term Auto Renewal, no additional action is needed as the auto-renew workflow handles it).

2. subscriptionPriceChange Workflow

Initial Workflow Context Parameters

  • Subscription.id

  • LockStatus.lockId (the subscription lock)

  • Application.id

  • Tenant.id

  • parentWorkflowReference (the ID of the PriceDataChange)

  • subscriptionActionFlow (PRICE_CHANGE)

Workflow Activity Descriptions

  1. lockSubscriptionActivity (broadleaf-subscription-operation-services-workflow) - Attempts to acquire a lock on the subscription to ensure thread safety. If the lock cannot be acquired (e.g., because another process is currently modifying it), it transitions to the waitStep.

  2. waitStep (broadleaf-workflow-services-core) - A pause activity that waits for a configured duration (e.g., 1 minute) before returning to the lockSubscriptionActivity to retry acquiring the lock.

  3. subscriptionModificationActivity (broadleaf-subscription-operation-services-workflow) - This delegates to the PriceChangeSubscriptionModificationHandler. It processes the price change by:

    • Identifying the PriceDataChange record on the subscription matching the parentWorkflowReference with a NEXT_BILL_DATE effective type.

    • Finding all SubscriptionItem`s whose `priceDataId matches the change record.

    • Updating each matching SubscriptionItem’s `itemUnitPrice to the new afterRecurringPrice.

    • Recalculating the adjustmentAmount for any PERCENT_OFF adjustments applied to the item based on the new unit price.

    • Creating an AuditEvent of type SUBSCRIPTION_PRICE_CHANGE against the SubscriptionItem to record the before and after itemUnitPrice.

  4. releaseSubscriptionLockActivity (broadleaf-subscription-operation-services-workflow) - Completes the workflow execution by closing out the transaction, clearing the subscription lock, and saving the sandboxed modifications.

Note
The subscriptionBillingEventGenerationActivity is not included since the generation of BillingEvents is not expected with price changes being applied at the next subscription bill date.

Add/Remove Subscription Discounts

A Customer Service Representative (CSR) can manually add or remove adjustments (discounts) for an existing subscription.

Admin UI Integration

In the Broadleaf Admin UI, the ability to add an adjustment is exposed as an action on the Subscription view. Specifically, the SubscriptionMetadataAutoConfiguration#addAdjustmentAction injects an "Add Adjustment" button for subscriptions that are in the ACTIVE state. This action pulls up a modal allowing the CSR to look up and select an offer.

Endpoint Entrypoint

The action triggers a request to the Subscription Operation Service endpoint: SubscriptionOperationEndpoint#addAdjustment. This endpoint accepts an AddAdjustmentRequest.

The AddAdjustmentRequest contains:

  • offerRef & offerRefType: To identify the offer/discount being applied.

  • replaceExisting: A boolean to indicate whether all existing adjustments on the subscription should be wiped out before applying the new one.

  • applicationDateType: To dictate when the adjustment should take effect (e.g., CURRENT_PERIOD or NEXT_BILL_DATE).

When called, this endpoint acquires a lock on the subscription, builds the context necessary for the workflow, and triggers the subscriptionCsrAddAdjustmentWorkflow.

CSR Add Adjustment Workflow

The subscriptionCsrAddAdjustmentWorkflow manages the application of the new adjustment, alongside the generation of any necessary BillingEvents.

broadleaf:
  workflow:
    client:
      flows:
        subscriptionCsrAddAdjustmentWorkflow:
          description: Subscription CSR Add Adjustment Workflow
          historical-reset-enabled: false
          retry-enabled: true
      steps:
        subscriptionCsrAddAdjustmentWorkflow:
          prepareSubscriptionFulfillmentActivity:
            admin-selectable: true
            decisions:
              ok: subscriptionModificationActivity
          subscriptionModificationActivity:
            admin-selectable: true
            decisions:
              ok: subscriptionBillingEventGenerationActivity
          subscriptionBillingEventGenerationActivity:
            admin-selectable: true
            decisions:
              ok: releaseSubscriptionLockActivity
          releaseSubscriptionLockActivity:
            admin-selectable: true

Initial Workflow Context Parameters

  • Subscription.id

  • LockStatus.lockId (the subscription lock)

  • Application.id

  • Tenant.id

  • subscriptionActionFlow (CSR_ADD_ADJUSTMENT)

  • subscriptionActionDate

  • offerRef, offerRefType, replaceExisting, applicationDateType (from the AddAdjustmentRequest)

Workflow Activity Descriptions

  1. prepareSubscriptionFulfillmentActivity (broadleaf-subscription-operation-services-workflow) - Sets the state indicating an active modification.

  2. subscriptionModificationActivity (broadleaf-subscription-operation-services-workflow) - This delegates to the SubscriptionAddAdjustmentModificationHandler. The handler leverages the SubscriptionOfferService to retrieve the targeted offer (using the OfferProvider) and builds the new SubscriptionItemAdjustment records. It applies these adjustments to the subscription items.

  3. subscriptionBillingEventGenerationActivity (broadleaf-subscription-operation-services-workflow) - Handled by CsrAddAdjustmentBillingEventGenerationHandler. It generates new BillingEvents to reflect the new pricing. If replaceExisting is set to true on the request, it will negate existing billing event adjustments.

  4. releaseSubscriptionLockActivity (broadleaf-subscription-operation-services-workflow) - Completes the workflow execution by closing out the transaction, clearing the subscription lock, and saving the sandboxed modifications.