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

# Paddle.Retain.initCancellationFlow()

Use to start a Paddle Retain cancellation flow for a subscription.

---

Use `Paddle.Retain.initCancellationFlow()` to start a Paddle Retain cancellation flow for a subscription.

[Cancellation Flows](https://developer.paddle.com/build/retain/configure-cancellation-flows-surveys.md) help you save customers from canceling by presenting them with dynamic salvage attempts while gathering cancellation insights. Retain automatically schedules a cancellation for the subscription in Paddle Billing if a customer proceeds to cancel.

Typically used as part of [a cancel subscription workflow](https://developer.paddle.com/build/retain/configure-cancellation-flows-surveys.md).

{% callout type="warning" %}
Paddle Retain only works with live data. While you can initialize Paddle.js with Retain in sandbox accounts, Retain features aren't loaded there.
{% /callout %}

{% callout type="info" %}
This method is for Paddle Billing only. If you use Cancellation Flows with another billing platform, use the `profitwell` method in the ProfitWell.js snippet instead. To learn more, see [Configure Cancellation Flows and salvage offers](https://developer.paddle.com/build/retain/configure-cancellation-flows-surveys.md)
{% /callout %}

To specify a subscription to cancel, pass a `subscriptionId` parameter. This is recommended, but not required where customers only have one subscription and you passed `pwCustomer` to [`Paddle.Initialize()`](https://developer.paddle.com/paddle-js/methods/paddle-initialize.md) or [`Paddle.Update()`](https://developer.paddle.com/paddle-js/methods/paddle-update.md).

## Parameters

```yaml
title: Paddle.Retain.initCancellationFlow() parameters
type: object
properties:
  subscriptionId:
    type: string
    description: >-
      Paddle ID of the subscription to cancel. Required where a customer has multiple subscriptions and where
      `pwCustomer` has not been passed to `Paddle.Initialize()` or `Paddle.Update()`. Paddle Billing only.
```

## Returns

```yaml
title: Paddle.Retain.initCancellationFlow() return object
type: object
properties:
  status:
    type: string
    description: Status of the cancellation flow.
    enum:
      - aborted
      - chose_to_cancel
      - retained
      - error
    x-enum-descriptions:
      aborted:
        description: >-
          Customer started the cancellation flow, but chose not to cancel by clicking the 'Never mind, I don't want to
          cancel' option.
      chose_to_cancel:
        description: Customer started the cancellation flow, rejected salvage attempts and salvage offers, and proceeded to cancel.
      retained:
        description: >-
          Customer started the cancellation flow, and accepted a salvage attempt or a salvage offer. They did not
          cancel.
      error:
        description: There was a problem starting the cancellation flow.
  salvageAttemptResult:
    type:
      - object
      - "null"
    description: >-
      Information about the salvage attempts that the customer was shown. `null` if salvage attempts not presented, like
      if they chose not to cancel or closed the modal.
    properties:
      decision:
        type: string
        description: Whether the customer decided to accept or reject salvage attempts.
        enum:
          - accepted
          - rejected
        x-enum-descriptions:
          accepted:
            description: Customer accepted a salvage attempt.
          rejected:
            description: Customer rejected a salvage attempt.
      resolution:
        type: string
        description: >-
          Whether the customer chose to cancel. Customers may accept a salvage attempt but still choose to cancel. For
          example, customers may choose to accept a contact support salvage attempt, but still proceed to cancel their
          subscription.
        enum:
          - accepted
          - rejected
        x-enum-descriptions:
          accepted:
            description: Salvage attempt prevented a customer from canceling.
          rejected:
            description: Customer chose to cancel.
      hasErrors:
        type: boolean
        description: Whether the salvage attempt encountered an error. For example, there was a problem pausing a subscription.
  salvageOfferResult:
    type:
      - object
      - "null"
    description: >-
      Information about the salvage offer that the customer was shown. `null` if salvage offers not presented, like if
      they chose not to cancel or closed the modal.
    properties:
      decision:
        type: string
        description: Whether the customer decided to accept or reject a salvage offer.
        enum:
          - accepted
          - rejected
        x-enum-descriptions:
          accepted:
            description: Customer accepted a salvage offer.
          rejected:
            description: Customer rejected a salvage offer.
      hasErrors:
        type: boolean
        description: Whether the salvage offer encountered an error. For example, there was a problem applying a discount.
  additionalFeedback:
    type:
      - string
      - "null"
    description: Additional feedback left by the customer. `null` if no feedback or not presented to the customer.
  cancelReason:
    type:
      - string
      - "null"
    description: >-
      Reason for cancellation left by the customer. This is the first question on the survey presented to the customer.
      `null` if customer chose not to cancel or closed the modal.
    enum:
      - Not useful right now
      - Didn't see the value
      - Poor support
      - Missing features/hard to use
      - Other
    x-enum-descriptions:
      Not useful right now:
        description: >-
          Customer selected the 'Not useful right now' option. Designed to be the inverse of the 'Many things, I'll be
          back' option in question 2.
      Didn't see the value:
        description: >-
          Customer selected the 'Didn't see the value' option. Designed to be the inverse of the 'Good value' option in
          question 2.
      Poor support:
        description: >-
          Customer selected the 'Poor support' option. Designed to be the inverse of the 'Helpful support' option in
          question 2.
      Missing features/hard to use:
        description: >-
          Customer selected the 'Missing features/hard to use' option. Designed to be the inverse of the 'Easy to use'
          option in question 2.
      Other:
        description: Customer selected the 'Other' option. Designed to be the inverse of the 'Other' option in question 2.
  satisfactionInsight:
    type:
      - string
      - "null"
    description: >-
      Satisfaction insight selected by the customer. This is the second question on the survey presented to the
      customer. `null` if customer chose not to cancel or closed the modal.
    enum:
      - Many things, I'll be back
      - Good value
      - Helpful support
      - Easy to use
      - Other
    x-enum-descriptions:
      Many things, I'll be back:
        description: >-
          Customer selected the 'Many things, I'll be back' option. Designed to be the inverse of the 'Not useful right
          now' option in question 1.
      Good value:
        description: >-
          Customer selected the 'Good value' option. Designed to be the inverse of the 'Didn't see the value' option in
          question 1.
      Helpful support:
        description: >-
          Customer selected the 'Helpful support' option. Designed to be the inverse of the 'Poor support' option in
          question 1.
      Easy to use:
        description: >-
          Customer selected the 'Easy to use' option. Designed to be the inverse of the 'Missing features/hard to use'
          option in question 1.
      Other:
        description: Customer selected the 'Other' option. Designed to be the inverse of the 'Other' option in question 1.
  salvageAttemptIntended:
    type:
      - string
      - "null"
    description: >-
      Salvage attempt presented to the customer based on their satisfaction insight. `null` if customer chose not to
      cancel or closed the modal.
    enum:
      - contact_support_email_notification
      - contact_support_meeting_scheduler
      - pause_subscription
      - plan_switch
    x-enum-descriptions:
      contact_support_email_notification:
        description: >-
          Presented where the satisfaction insight is 'Other'. Customer is prompted to send a message to your support
          team to chat more about this.
      contact_support_meeting_scheduler:
        description: >-
          Presented where the satisfaction insight is 'Helpful support'. Customer is prompted to schedule a meeting
          using [Calendly](https://calendly.com/).
      pause_subscription:
        description: >-
          Presented where the satisfaction insight is 'Many things, I'll be back'. Customer is prompted to pause their
          subscription for three months.
      plan_switch:
        description: >-
          Presented where the satisfaction insight is 'Good value, I'll be back'. Customer is prompted to switch to
          another plan.
  salvageAttemptUsed:
    type:
      - string
      - "null"
    description: >-
      Salvage attempt accepted by the customer.  `null` if customer chose not to cancel, closed the modal, or does not
      accept a salvage attempt.
    enum:
      - contact_support_email_notification
      - contact_support_meeting_scheduler
      - pause_subscription
      - plan_switch
    x-enum-descriptions:
      contact_support_email_notification:
        description: >-
          Presented where the satisfaction insight is 'Other'. Customer is prompted to send a message to your support
          team to chat more about this.
      contact_support_meeting_scheduler:
        description: >-
          Presented where the satisfaction insight is 'Helpful support'. Customer is prompted to schedule a meeting
          using Calendly.
      pause_subscription:
        description: >-
          Presented where the satisfaction insight is 'Many things, I'll be back'. Customer is prompted to pause their
          subscription for three months.
      plan_switch:
        description: >-
          Presented where the satisfaction insight is 'Good value, I'll be back'. Customer is prompted to switch to
          another plan.
```

## Examples

{% accordion %}
{% accordion-item title="Launch a cancellation flow" %}

This example shows how you can use `Paddle.Retain.initCancellationFlow()` to start a cancellation flow.

`subscriptionId` is passed to `Paddle.Retain.initCancellationFlow()` to specify the subscription to cancel.

`pwCustomer` is passed to [`Paddle.Initialize()`](https://developer.paddle.com/paddle-js/methods/paddle-initialize.md) to identify the customer to Paddle Retain, but this isn't required. Paddle Retain infers the customer from the `subscriptionId` passed and presents a cancellation flow.

Retain automatically schedules a cancellation for the subscription in Paddle Billing if a customer proceeds to cancel, so you don't need to build logic to handle this yourself.

{% tabs sync="paddlejs-preference" %}
{% tab-item title="Using a script tag" %}

```html
<!-- Cancellation button -->
<button onclick="cancelSubscription()">Cancel my subscription</button>

<script type="text/javascript">
  function cancelSubscription() {
    Paddle.Retain.initCancellationFlow({
      subscriptionId: "sub_01h8bqcrwp0vjd1p3bv20y7323",
    });
  }
</script>
```

{% /tab-item %}
{% tab-item title="Using a JavaScript package manager" %}

```ts
import { initializePaddle } from "@paddle/paddle-js";

const paddle = await initializePaddle({
  token: "live_7d279f61a3499fed520f7cd8c08",
});

paddle?.Retain.initCancellationFlow({
  subscriptionId: "sub_01h8bqcrwp0vjd1p3bv20y7323",
});
```

{% /tab-item %}
{% /tabs %}

To learn more, see [Build cancellation surveys and offers](https://developer.paddle.com/build/retain/configure-cancellation-flows-surveys.md)

{% /accordion-item %}

{% accordion-item title="Attach a callback to a cancellation flow" %}

This example shows how you can attach a callback to a cancellation flow.

It uses the `.then()` method to attach a callback that logs a message to the console:

- **Customer retained**  
  The customer accepted a salvage attempt or a salvage offer, or chose not to cancel.
- **There was a problem starting the cancellation flow.**  
  Something went wrong while starting the cancellation flow. The customer wasn't given the chance to cancel.
- **Customer proceeded with cancellation.**  
  The customer rejected salvage attempts and salvage offers and proceeded to cancel.

{% tabs sync="paddlejs-preference" %}
{% tab-item title="Using a script tag" %}

```html
<!-- Cancellation button -->
<button onclick="cancelSubscription()">Cancel my subscription</button>

<script type="text/javascript">
  // Cancel subscription
  function cancelSubscription() {
    Paddle.Retain.initCancellationFlow({
      subscriptionId: "sub_01h8bqcrwp0vjd1p3bv20y7323",
    })
      .then((result) => {
        if (result.status === "retained" || result.status === "aborted") {
          console.log("Customer retained!");
        } else if (result.status === "error") {
          console.log("There was a problem starting the cancellation flow.");
        } else {
          console.log("Customer proceeded with cancellation.");
        }
      })
      .catch((error) => {
        console.error(error);
      });
  }
</script>
```

{% /tab-item %}
{% tab-item title="Using a JavaScript package manager" %}

```ts
import { initializePaddle } from "@paddle/paddle-js";

const paddle = await initializePaddle({
  token: "live_7d279f61a3499fed520f7cd8c08",
});

paddle?.Retain.initCancellationFlow({
  subscriptionId: "sub_01h8bqcrwp0vjd1p3bv20y7323",
})
  .then((result) => {
    if (result.status === "retained" || result.status === "aborted") {
      console.log("Customer retained!");
    } else if (result.status === "error") {
      console.log("There was a problem starting the cancellation flow.");
    } else {
      console.log("Customer proceeded with cancellation.");
    }
  })
  .catch((error) => {
    console.error(error);
  });
```

{% /tab-item %}
{% /tabs %}

To learn more, see [Build cancellation surveys and offers](https://developer.paddle.com/build/retain/configure-cancellation-flows-surveys.md)

{% /accordion-item %}

{% /accordion %}