Cancel a customer’s subscription

When a customer requests to cancel a subscription, you might want to be able to do it programmatically so you don’t have to go in your dashboard and manually cancel it. ProcessOut provides a convenient way to programmatically cancel subscriptions.


How canceling works internally

The Subscription object has a date attribute cancel_at. This attribute is used by our workers to cancel any subscription that has a cancel_at date set in the past. This also lets merchants automatically cancel subscriptions in the future.

Once a subscription is scheduled for cancellation and picked up by a worker, the worker will set the canceled_at field of the subscription to the current time, effectively marked the subscription as canceled. A canceled subscription becomes immutable, which means that you won’t be able to update it in the future, or re-activate it. If you want to reactive it, you will need to create a new subscription and apply the token you used as a source to activate it the first time, if available.

Cancel immediately

Cancelling a subscription immediately can be done by calling the subscription cancellation endpoint without any cancel_at date. The call will set the cancel_at field to the current time, and the ProcessOut workers will automatically pull the subscription and cancel it.

curl -X DELETE https://api.processout.com/subscriptions/sub_SSpcwpKNSa2WT2pixBRNyOnCrftmJeqR \
    -u test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x:key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8 \
    -d reason="Cancellation reason"
var ProcessOut = require("processout");
var client = new ProcessOut(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8");

client.newSubscription().find("sub_SSpcwpKNSa2WT2pixBRNyOnCrftmJeqR").then(
    function(subscription) {
        subscription.cancel({
            cancellation_reason: "Cancellation reason"
        }).then(function(subscription) {
            // The subscription was successfully marked for cancellation

        }, function(err) {
            // An error occured
        });

    }, function(err) {
        // Could not find the subscription
    });
import processout
client = processout.ProcessOut(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8")

subscription = client.new_subscription().find("sub_SSpcwpKNSa2WT2pixBRNyOnCrftmJeqR")
subscription.cancel({
    "cancellation_reason": "Cancellation reason"
})

# The subscription was successfully marked for cancellation
require "processout"
client = ProcessOut::Client.new(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8")

subscription = client.subscription.find("sub_SSpcwpKNSa2WT2pixBRNyOnCrftmJeqR")
subscription.cancel(
    cancellation_reason: "Cancellation reason"
)

# The subscription was successfully marked for cancellation
<?php
$client = new \ProcessOut\ProcessOut(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8");

$subscription = $client->newSubscription()->find("sub_SSpcwpKNSa2WT2pixBRNyOnCrftmJeqR");
$subscription->cancel(array(
    "cancellation_reason" => "Cancellation reason"
));

// The subscription was successfully marked for cancellation
import "gopkg.in/processout.v4"
client := processout.New(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8")

sub, _ := client.NewSubscription().Find("sub_SSpcwpKNSa2WT2pixBRNyOnCrftmJeqR")
sub, err = sub.Cancel(&processout.SubscriptionCancelParameters{
    Subscription: &processout.Subscription{
        CancellationReason: processout.String("Cancellation reason"),
    },
})
if err != nil {
    panic(err)
}

// The subscription was successfully marked for cancellation

Schedule for cancellation

It is also possible to schedule a subscription for cancellation in the future, at a given date. This can be useful if you want to do installments for instance, where a customer pays a fixed price for certain amount of days (such as $49.00 every month for 3 months).

To set up an installment, simply create and activate ↗ a subscription and set its cancel_at attribute to the desired date. The subscription will automatically be canceled at that date.

curl -X DELETE https://api.processout.com/subscriptions/sub_SSpcwpKNSa2WT2pixBRNyOnCrftmJeqR \
    -u test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x:key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8 \
    -d cancellation_reason="Cancellation reason" \
    -d cancel_at="2022-10-02T15:00:00Z"
var ProcessOut = require("processout");
var client = new ProcessOut(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x",
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8");

client.newSubscription().find("sub_SSpcwpKNSa2WT2pixBRNyOnCrftmJeqR").then(
    function(subscription) {
        subscription.cancel({
            cancellation_reason: "Cancellation reason",
            cancel_at:           "2022-10-02T15:00:00Z"
        }).then(function(subscription) {
            // The subscription was successfully marked for cancellation

        }, function(err) {
            // An error occured
        });

    }, function(err) {
        // Could not find the subscription
    });
import processout
client = processout.ProcessOut(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8")

subscription = client.new_subscription().find("sub_SSpcwpKNSa2WT2pixBRNyOnCrftmJeqR")
subscription.cancel({
    "cancellation_reason": "Cancellation reason",
    "cancel_at":           "2022-10-02T15:00:00Z"
})

# The subscription was successfully marked for cancellation
require "processout"
client = ProcessOut::Client.new(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8")

subscription = client.subscription.find("sub_SSpcwpKNSa2WT2pixBRNyOnCrftmJeqR")
subscription.cancel(
    cancellation_reason: "Cancellation reason",
    cancel_at:           "2022-10-02T15:00:00Z"
)

# The subscription was successfully marked for cancellation
<?php
$client = new \ProcessOut\ProcessOut(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8");

$subscription = $client->newSubscription()->find("sub_SSpcwpKNSa2WT2pixBRNyOnCrftmJeqR");
$subscription->cancel(array(
    "cancellation_reason" => "Cancellation reason",
    "cancel_at"           => "2022-10-02T15:00:00Z"
));

// The subscription was successfully marked for cancellation
import "gopkg.in/processout.v4"
client := processout.New(
    "test-proj_gAO1Uu0ysZJvDuUpOGPkUBeE3pGalk3x", 
    "key_sandbox_jqSPvwq3AG5MlYAgqxlwwgOcAC3Zy7d8")

sub, _ := client.NewSubscription().Find("sub_SSpcwpKNSa2WT2pixBRNyOnCrftmJeqR")
sub, err = sub.Cancel(&processout.SubscriptionCancelParameters{
    Subscription: &processout.Subscription{
        CancellationReason: processout.String("Cancellation reason"),
        CancelAt:           processout.Time(time.Now()),
    },
})
if err != nil {
    panic(err)
}

// The subscription was successfully marked for cancellation