Learn how to cancel a subscription with the Stripe API, including immediate, scheduled, and prorated cancellations, plus webhook handling and status verification.
Book a call with an Expert
Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.
How to Cancel a Subscription with Stripe API
Introduction
Canceling subscriptions is an essential part of subscription management in any business. Stripe provides a robust API to handle subscription cancellations efficiently. This tutorial will guide you through the process of canceling a subscription using the Stripe API, covering different scenarios and options.
Prerequisites
Step 1: Set Up Your Environment
First, you need to set up the Stripe library in your project. Here are examples in different programming languages:
For Node.js:
// Install Stripe via npm
npm install stripe
// Require Stripe in your file
const stripe = require('stripe')('your_stripe_secret\_key');
For Python:
# Install Stripe via pip
pip install stripe
# Import Stripe in your script
import stripe
stripe.api_key = 'your_stripe_secret_key'
For PHP:
// Install Stripe via Composer
composer require stripe/stripe-php
// Require the Stripe library in your file
require\_once 'vendor/autoload.php';
\Stripe\Stripe::setApiKey('your_stripe_secret\_key');
For Ruby:
# Install Stripe via gem
gem install stripe
# Require and configure Stripe
require 'stripe'
Stripe.api_key = 'your_stripe_secret_key'
Step 2: Retrieve the Subscription to Cancel
Before canceling a subscription, you may want to retrieve it to confirm its details. You need the subscription ID for this.
In Node.js:
async function getSubscription(subscriptionId) {
try {
const subscription = await stripe.subscriptions.retrieve(subscriptionId);
console.log('Subscription details:', subscription);
return subscription;
} catch (error) {
console.error('Error retrieving subscription:', error);
throw error;
}
}
In Python:
def get_subscription(subscription_id):
try:
subscription = stripe.Subscription.retrieve(subscription\_id)
print(f"Subscription details: {subscription}")
return subscription
except Exception as e:
print(f"Error retrieving subscription: {e}")
raise
In PHP:
function getSubscription($subscriptionId) {
try {
$subscription = \Stripe\Subscription::retrieve($subscriptionId);
echo "Subscription details: " . json\_encode($subscription);
return $subscription;
} catch (\Exception $e) {
echo "Error retrieving subscription: " . $e->getMessage();
throw $e;
}
}
In Ruby:
def get_subscription(subscription_id)
begin
subscription = Stripe::Subscription.retrieve(subscription\_id)
puts "Subscription details: #{subscription}"
return subscription
rescue Stripe::StripeError => e
puts "Error retrieving subscription: #{e.message}"
raise e
end
end
Step 3: Cancel the Subscription - Basic Cancellation
The simplest way to cancel a subscription is to use the cancel method. By default, this will cancel the subscription immediately.
In Node.js:
async function cancelSubscription(subscriptionId) {
try {
const canceledSubscription = await stripe.subscriptions.cancel(subscriptionId);
console.log('Subscription canceled:', canceledSubscription);
return canceledSubscription;
} catch (error) {
console.error('Error canceling subscription:', error);
throw error;
}
}
In Python:
def cancel_subscription(subscription_id):
try:
canceled_subscription = stripe.Subscription.cancel(subscription_id)
print(f"Subscription canceled: {canceled\_subscription}")
return canceled\_subscription
except Exception as e:
print(f"Error canceling subscription: {e}")
raise
In PHP:
function cancelSubscription($subscriptionId) {
try {
$canceledSubscription = \Stripe\Subscription::retrieve($subscriptionId);
$canceledSubscription->cancel();
echo "Subscription canceled: " . json\_encode($canceledSubscription);
return $canceledSubscription;
} catch (\Exception $e) {
echo "Error canceling subscription: " . $e->getMessage();
throw $e;
}
}
In Ruby:
def cancel_subscription(subscription_id)
begin
canceled_subscription = Stripe::Subscription.cancel(subscription_id)
puts "Subscription canceled: #{canceled\_subscription}"
return canceled\_subscription
rescue Stripe::StripeError => e
puts "Error canceling subscription: #{e.message}"
raise e
end
end
Step 4: Cancel the Subscription - With Options
Stripe allows you to specify options when canceling a subscription, such as canceling at the end of the billing period.
In Node.js:
async function cancelSubscriptionAtPeriodEnd(subscriptionId) {
try {
// Instead of canceling immediately, update the subscription to cancel at period end
const subscription = await stripe.subscriptions.update(subscriptionId, {
cancel_at_period\_end: true
});
console.log('Subscription will be canceled at period end:', subscription);
return subscription;
} catch (error) {
console.error('Error updating subscription:', error);
throw error;
}
}
In Python:
def cancel_subscription_at_period_end(subscription\_id):
try:
subscription = stripe.Subscription.modify(
subscription\_id,
cancel_at_period\_end=True
)
print(f"Subscription will be canceled at period end: {subscription}")
return subscription
except Exception as e:
print(f"Error updating subscription: {e}")
raise
In PHP:
function cancelSubscriptionAtPeriodEnd($subscriptionId) {
try {
$subscription = \Stripe\Subscription::update($subscriptionId, [
'cancel_at_period\_end' => true
]);
echo "Subscription will be canceled at period end: " . json\_encode($subscription);
return $subscription;
} catch (\Exception $e) {
echo "Error updating subscription: " . $e->getMessage();
throw $e;
}
}
In Ruby:
def cancel_subscription_at_period_end(subscription\_id)
begin
subscription = Stripe::Subscription.update(
subscription\_id,
{ cancel_at_period\_end: true }
)
puts "Subscription will be canceled at period end: #{subscription}"
return subscription
rescue Stripe::StripeError => e
puts "Error updating subscription: #{e.message}"
raise e
end
end
Step 5: Cancel the Subscription with Proration Options
You can also specify proration behavior when canceling a subscription.
In Node.js:
async function cancelSubscriptionWithProration(subscriptionId) {
try {
const canceledSubscription = await stripe.subscriptions.cancel(subscriptionId, {
prorate: true, // Prorates the subscription amount
invoice\_now: true // Creates a final invoice immediately
});
console.log('Subscription canceled with proration:', canceledSubscription);
return canceledSubscription;
} catch (error) {
console.error('Error canceling subscription with proration:', error);
throw error;
}
}
In Python:
def cancel_subscription_with_proration(subscription_id):
try:
canceled\_subscription = stripe.Subscription.cancel(
subscription\_id,
prorate=True,
invoice\_now=True
)
print(f"Subscription canceled with proration: {canceled\_subscription}")
return canceled\_subscription
except Exception as e:
print(f"Error canceling subscription with proration: {e}")
raise
In PHP:
function cancelSubscriptionWithProration($subscriptionId) {
try {
$canceledSubscription = \Stripe\Subscription::retrieve($subscriptionId);
$canceledSubscription->cancel([
'prorate' => true,
'invoice\_now' => true
]);
echo "Subscription canceled with proration: " . json\_encode($canceledSubscription);
return $canceledSubscription;
} catch (\Exception $e) {
echo "Error canceling subscription with proration: " . $e->getMessage();
throw $e;
}
}
In Ruby:
def cancel_subscription_with_proration(subscription_id)
begin
canceled\_subscription = Stripe::Subscription.cancel(
subscription\_id,
{ prorate: true, invoice\_now: true }
)
puts "Subscription canceled with proration: #{canceled\_subscription}"
return canceled\_subscription
rescue Stripe::StripeError => e
puts "Error canceling subscription with proration: #{e.message}"
raise e
end
end
Step 6: Cancel the Subscription at a Specific Date
You might want to schedule a subscription to be canceled at a specific date in the future.
In Node.js:
async function cancelSubscriptionAtDate(subscriptionId, cancelDate) {
try {
// cancelDate should be a Unix timestamp (seconds since the epoch)
const subscription = await stripe.subscriptions.update(subscriptionId, {
cancel\_at: cancelDate
});
console.log(`Subscription will be canceled at ${new Date(cancelDate * 1000)}:`, subscription);
return subscription;
} catch (error) {
console.error('Error scheduling subscription cancellation:', error);
throw error;
}
}
// Example usage:
// const oneMonthFromNow = Math.floor(Date.now() / 1000) + (30 _ 24 _ 60 \* 60);
// cancelSubscriptionAtDate('sub\_12345', oneMonthFromNow);
In Python:
import time
def cancel_subscription_at_date(subscription_id, cancel\_date):
try:
# cancel\_date should be a Unix timestamp (seconds since the epoch)
subscription = stripe.Subscription.modify(
subscription\_id,
cancel_at=cancel_date
)
print(f"Subscription will be canceled at {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(cancel\_date))}: {subscription}")
return subscription
except Exception as e:
print(f"Error scheduling subscription cancellation: {e}")
raise
# Example usage:
# import time
# one_month_from\_now = int(time.time()) + (30 _ 24 _ 60 \* 60)
# cancel_subscription_at_date('sub_12345', one_month_from\_now)
In PHP:
function cancelSubscriptionAtDate($subscriptionId, $cancelDate) {
try {
// $cancelDate should be a Unix timestamp (seconds since the epoch)
$subscription = \Stripe\Subscription::update($subscriptionId, [
'cancel\_at' => $cancelDate
]);
echo "Subscription will be canceled at " . date('Y-m-d H:i:s', $cancelDate) . ": " . json\_encode($subscription);
return $subscription;
} catch (\Exception $e) {
echo "Error scheduling subscription cancellation: " . $e->getMessage();
throw $e;
}
}
// Example usage:
// $oneMonthFromNow = time() + (30 _ 24 _ 60 \* 60);
// cancelSubscriptionAtDate('sub\_12345', $oneMonthFromNow);
In Ruby:
require 'time'
def cancel_subscription_at_date(subscription_id, cancel\_date)
begin
# cancel\_date should be a Unix timestamp (seconds since the epoch)
subscription = Stripe::Subscription.update(
subscription\_id,
{ cancel_at: cancel_date }
)
puts "Subscription will be canceled at #{Time.at(cancel\_date).strftime('%Y-%m-%d %H:%M:%S')}: #{subscription}"
return subscription
rescue Stripe::StripeError => e
puts "Error scheduling subscription cancellation: #{e.message}"
raise e
end
end
# Example usage:
# one_month_from_now = Time.now.to_i + (30 _ 24 _ 60 \* 60)
# cancel_subscription_at_date('sub_12345', one_month_from\_now)
Step 7: Verify the Subscription Status
After canceling a subscription, you should verify its status to confirm the cancellation.
In Node.js:
async function verifySubscriptionStatus(subscriptionId) {
try {
const subscription = await stripe.subscriptions.retrieve(subscriptionId);
console.log('Subscription status:', subscription.status);
console.log('Cancel at period end:', subscription.cancel_at_period\_end);
console.log('Cancel at:', subscription.cancel_at ? new Date(subscription.cancel_at \* 1000) : 'Not set');
return subscription;
} catch (error) {
console.error('Error verifying subscription status:', error);
throw error;
}
}
In Python:
import time
def verify_subscription_status(subscription\_id):
try:
subscription = stripe.Subscription.retrieve(subscription\_id)
print(f"Subscription status: {subscription.status}")
print(f"Cancel at period end: {subscription.cancel_at_period\_end}")
if subscription.get('cancel\_at'):
cancel_date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(subscription.cancel_at))
print(f"Cancel at: {cancel\_date}")
else:
print("Cancel at: Not set")
return subscription
except Exception as e:
print(f"Error verifying subscription status: {e}")
raise
In PHP:
function verifySubscriptionStatus($subscriptionId) {
try {
$subscription = \Stripe\Subscription::retrieve($subscriptionId);
echo "Subscription status: " . $subscription->status . "\n";
echo "Cancel at period end: " . ($subscription->cancel_at_period\_end ? 'Yes' : 'No') . "\n";
if ($subscription->cancel\_at) {
echo "Cancel at: " . date('Y-m-d H:i:s', $subscription->cancel\_at) . "\n";
} else {
echo "Cancel at: Not set\n";
}
return $subscription;
} catch (\Exception $e) {
echo "Error verifying subscription status: " . $e->getMessage();
throw $e;
}
}
In Ruby:
def verify_subscription_status(subscription\_id)
begin
subscription = Stripe::Subscription.retrieve(subscription\_id)
puts "Subscription status: #{subscription.status}"
puts "Cancel at period end: #{subscription.cancel_at_period\_end}"
if subscription.cancel\_at
puts "Cancel at: #{Time.at(subscription.cancel\_at).strftime('%Y-%m-%d %H:%M:%S')}"
else
puts "Cancel at: Not set"
end
return subscription
rescue Stripe::StripeError => e
puts "Error verifying subscription status: #{e.message}"
raise e
end
end
Step 8: Handle Webhooks for Subscription Cancellation Events
To properly track subscription cancellations in your system, you should set up webhook handlers for relevant events.
In Node.js (using Express):
const express = require('express');
const app = express();
// This is your Stripe CLI webhook secret for testing
const endpointSecret = 'whsec\_...';
app.post('/webhook', express.raw({type: 'application/json'}), (request, response) => {
const sig = request.headers['stripe-signature'];
let event;
try {
event = stripe.webhooks.constructEvent(request.body, sig, endpointSecret);
} catch (err) {
response.status(400).send(`Webhook Error: ${err.message}`);
return;
}
// Handle the event
switch (event.type) {
case 'customer.subscription.deleted':
const subscription = event.data.object;
console.log('Subscription canceled:', subscription.id);
// Perform actions like updating your database
// handleSubscriptionCanceled(subscription);
break;
case 'customer.subscription.updated':
const updatedSubscription = event.data.object;
// Check if the subscription is marked to be canceled at period end
if (updatedSubscription.cancel_at_period\_end) {
console.log('Subscription marked for cancellation at period end:', updatedSubscription.id);
// handleSubscriptionMarkedForCancellation(updatedSubscription);
}
break;
default:
console.log(`Unhandled event type ${event.type}`);
}
// Return a 200 response to acknowledge receipt of the event
response.send();
});
app.listen(3000, () => console.log('Running on port 3000'));
In Python (using Flask):
from flask import Flask, request, jsonify
import stripe
app = Flask(**name**)
# This is your Stripe CLI webhook secret for testing
endpoint_secret = 'whsec_...'
@app.route('/webhook', methods=['POST'])
def webhook():
event = None
payload = request.data
sig\_header = request.headers.get('Stripe-Signature')
try:
event = stripe.Webhook.construct\_event(
payload, sig_header, endpoint_secret
)
except ValueError as e:
# Invalid payload
return jsonify(success=False), 400
except stripe.error.SignatureVerificationError as e:
# Invalid signature
return jsonify(success=False), 400
# Handle the event
if event['type'] == 'customer.subscription.deleted':
subscription = event\['data']\['object']
print(f"Subscription canceled: {subscription['id']}")
# Perform actions like updating your database
# handle_subscription_canceled(subscription)
elif event['type'] == 'customer.subscription.updated':
subscription = event\['data']\['object']
# Check if the subscription is marked to be canceled at period end
if subscription.get('cancel_at_period\_end'):
print(f"Subscription marked for cancellation at period end: {subscription['id']}")
# handle_subscription_marked_for_cancellation(subscription)
else:
print(f"Unhandled event type {event['type']}")
return jsonify(success=True)
if **name** == '**main**':
app.run(port=3000)
In PHP:
type) {
case 'customer.subscription.deleted':
$subscription = $event->data->object;
echo "Subscription canceled: " . $subscription->id;
// Perform actions like updating your database
// handleSubscriptionCanceled($subscription);
break;
case 'customer.subscription.updated':
$subscription = $event->data->object;
// Check if the subscription is marked to be canceled at period end
if ($subscription->cancel_at_period\_end) {
echo "Subscription marked for cancellation at period end: " . $subscription->id;
// handleSubscriptionMarkedForCancellation($subscription);
}
break;
default:
echo "Unhandled event type " . $event->type;
}
http_response_code(200);
?>
In Ruby (using Sinatra):
require 'sinatra'
require 'stripe'
require 'json'
Stripe.api_key = 'your_stripe_secret_key'
endpoint_secret = 'whsec_...'
post '/webhook' do
payload = request.body.read
sig_header = request.env['HTTP_STRIPE\_SIGNATURE']
event = nil
begin
event = Stripe::Webhook.construct\_event(
payload, sig_header, endpoint_secret
)
rescue JSON::ParserError => e
# Invalid payload
status 400
return
rescue Stripe::SignatureVerificationError => e
# Invalid signature
status 400
return
end
# Handle the event
case event.type
when 'customer.subscription.deleted'
subscription = event.data.object
puts "Subscription canceled: #{subscription.id}"
# Perform actions like updating your database
# handle_subscription_canceled(subscription)
when 'customer.subscription.updated'
subscription = event.data.object
# Check if the subscription is marked to be canceled at period end
if subscription.cancel_at_period\_end
puts "Subscription marked for cancellation at period end: #{subscription.id}"
# handle_subscription_marked_for_cancellation(subscription)
end
else
puts "Unhandled event type: #{event.type}"
end
status 200
end
Step 9: Implement a Complete Subscription Cancellation Workflow
Now, let's put everything together into a complete workflow for subscription cancellation:
In Node.js:
async function handleSubscriptionCancellation(subscriptionId, cancellationType, options = {}) {
try {
// First, retrieve the subscription to check its current status
const subscription = await stripe.subscriptions.retrieve(subscriptionId);
console.log(`Current subscription status: ${subscription.status}`);
let result;
switch (cancellationType) {
case 'immediate':
// Cancel immediately
result = await stripe.subscriptions.cancel(subscriptionId);
console.log('Subscription canceled immediately');
break;
case 'period\_end':
// Cancel at period end
result = await stripe.subscriptions.update(subscriptionId, {
cancel_at_period\_end: true
});
console.log('Subscription will be canceled at period end');
break;
case 'specific\_date':
// Cancel at a specific date
if (!options.cancelDate) {
throw new Error('Cancel date is required for specific\_date cancellation type');
}
result = await stripe.subscriptions.update(subscriptionId, {
cancel\_at: options.cancelDate
});
console.log(`Subscription will be canceled at ${new Date(options.cancelDate * 1000)}`);
break;
case 'prorate':
// Cancel with proration
result = await stripe.subscriptions.cancel(subscriptionId, {
prorate: true,
invoice\_now: options.invoiceNow || false
});
console.log('Subscription canceled with proration');
break;
default:
throw new Error(`Unknown cancellation type: ${cancellationType}`);
}
// Verify the result
await verifySubscriptionStatus(subscriptionId);
return result;
} catch (error) {
console.error('Error during subscription cancellation workflow:', error);
throw error;
}
}
// Example usage:
// handleSubscriptionCancellation('sub\_12345', 'immediate');
// handleSubscriptionCancellation('sub_12345', 'period_end');
// handleSubscriptionCancellation('sub_12345', 'specific_date', { cancelDate: Math.floor(Date.now() / 1000) + (7 _ 24 _ 60 \* 60) });
// handleSubscriptionCancellation('sub\_12345', 'prorate', { invoiceNow: true });
In Python:
import time
def handle_subscription_cancellation(subscription_id, cancellation_type, options=None):
if options is None:
options = {}
try:
# First, retrieve the subscription to check its current status
subscription = stripe.Subscription.retrieve(subscription\_id)
print(f"Current subscription status: {subscription.status}")
if cancellation\_type == 'immediate':
# Cancel immediately
result = stripe.Subscription.cancel(subscription\_id)
print("Subscription canceled immediately")
elif cancellation_type == 'period_end':
# Cancel at period end
result = stripe.Subscription.modify(
subscription\_id,
cancel_at_period\_end=True
)
print("Subscription will be canceled at period end")
elif cancellation_type == 'specific_date':
# Cancel at a specific date
if 'cancel\_date' not in options:
raise ValueError("Cancel date is required for specific\_date cancellation type")
result = stripe.Subscription.modify(
subscription\_id,
cancel_at=options['cancel_date']
)
cancel_date_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(options['cancel\_date']))
print(f"Subscription will be canceled at {cancel_date_str}")
elif cancellation\_type == 'prorate':
# Cancel with proration
result = stripe.Subscription.cancel(
subscription\_id,
prorate=True,
invoice_now=options.get('invoice_now', False)
)
print("Subscription canceled with proration")
else:
raise ValueError(f"Unknown cancellation type: {cancellation\_type}")
# Verify the result
verify_subscription_status(subscription\_id)
return result
except Exception as e:
print(f"Error during subscription cancellation workflow: {e}")
raise
# Example usage:
# handle_subscription_cancellation('sub\_12345', 'immediate')
# handle_subscription_cancellation('sub_12345', 'period_end')
# handle_subscription_cancellation('sub_12345', 'specific_date', {'cancel\_date': int(time.time()) + (7 _ 24 _ 60 \* 60)})
# handle_subscription_cancellation('sub_12345', 'prorate', {'invoice_now': True})
In PHP:
function handleSubscriptionCancellation($subscriptionId, $cancellationType, $options = []) {
try {
// First, retrieve the subscription to check its current status
$subscription = \Stripe\Subscription::retrieve($subscriptionId);
echo "Current subscription status: " . $subscription->status . "\n";
$result = null;
switch ($cancellationType) {
case 'immediate':
// Cancel immediately
$result = \Stripe\Subscription::retrieve($subscriptionId);
$result->cancel();
echo "Subscription canceled immediately\n";
break;
case 'period\_end':
// Cancel at period end
$result = \Stripe\Subscription::update($subscriptionId, [
'cancel_at_period\_end' => true
]);
echo "Subscription will be canceled at period end\n";
break;
case 'specific\_date':
// Cancel at a specific date
if (!isset($options['cancelDate'])) {
throw new \Exception('Cancel date is required for specific\_date cancellation type');
}
$result = \Stripe\Subscription::update($subscriptionId, [
'cancel\_at' => $options['cancelDate']
]);
echo "Subscription will be canceled at " . date('Y-m-d H:i:s', $options['cancelDate']) . "\n";
break;
case 'prorate':
// Cancel with proration
$result = \Stripe\Subscription::retrieve($subscriptionId);
$result->cancel([
'prorate' => true,
'invoice\_now' => isset($options['invoiceNow']) ? $options['invoiceNow'] : false
]);
echo "Subscription canceled with proration\n";
break;
default:
throw new \Exception("Unknown cancellation type: $cancellationType");
}
// Verify the result
verifySubscriptionStatus($subscriptionId);
return $result;
} catch (\Exception $e) {
echo "Error during subscription cancellation workflow: " . $e->getMessage() . "\n";
throw $e;
}
}
// Example usage:
// handleSubscriptionCancellation('sub\_12345', 'immediate');
// handleSubscriptionCancellation('sub_12345', 'period_end');
// handleSubscriptionCancellation('sub_12345', 'specific_date', ['cancelDate' => time() + (7 _ 24 _ 60 \* 60)]);
// handleSubscriptionCancellation('sub\_12345', 'prorate', ['invoiceNow' => true]);
In Ruby:
def handle_subscription_cancellation(subscription_id, cancellation_type, options = {})
begin
# First, retrieve the subscription to check its current status
subscription = Stripe::Subscription.retrieve(subscription\_id)
puts "Current subscription status: #{subscription.status}"
case cancellation\_type
when 'immediate'
# Cancel immediately
result = Stripe::Subscription.cancel(subscription\_id)
puts "Subscription canceled immediately"
when 'period\_end'
# Cancel at period end
result = Stripe::Subscription.update(
subscription\_id,
{ cancel_at_period\_end: true }
)
puts "Subscription will be canceled at period end"
when 'specific\_date'
# Cancel at a specific date
unless options[:cancel\_date]
raise "Cancel date is required for specific\_date cancellation type"
end
result = Stripe::Subscription.update(
subscription\_id,
{ cancel_at: options[:cancel_date] }
)
cancel_date_str = Time.at(options[:cancel\_date]).strftime('%Y-%m-%d %H:%M:%S')
puts "Subscription will be canceled at #{cancel_date_str}"
when 'prorate'
# Cancel with proration
result = Stripe::Subscription.cancel(
subscription\_id,
{
prorate: true,
invoice_now: options[:invoice_now] || false
}
)
puts "Subscription canceled with proration"
else
raise "Unknown cancellation type: #{cancellation\_type}"
end
# Verify the result
verify_subscription_status(subscription\_id)
return result
rescue => e
puts "Error during subscription cancellation workflow: #{e.message}"
raise e
end
end
# Example usage:
# handle_subscription_cancellation('sub\_12345', 'immediate')
# handle_subscription_cancellation('sub_12345', 'period_end')
# handle_subscription_cancellation('sub_12345', 'specific_date', { cancel_date: Time.now.to_i + (7 _ 24 _ 60 \* 60) })
# handle_subscription_cancellation('sub_12345', 'prorate', { invoice_now: true })
Conclusion
You've now learned how to cancel subscriptions using the Stripe API in different scenarios. The key points to remember are:
Proper subscription cancellation handling is crucial for maintaining good customer relationships and ensuring accurate billing. By following this guide, you should be able to implement a robust subscription cancellation system using Stripe's API.
When it comes to serving you, we sweat the little things. That’s why our work makes a big impact.