Getting started with importing subscription data via the API
Follow this tutorial to learn how to import billing data for up-to-date subscription data and real-time metrics in ChartMogul.
Overview
ChartMogul uses billing data to generate subscriptions and calculate metrics. Build an integration with the ChartMogul API to import billing data from multiple sources for up-to-date metrics in ChartMogul.
Alternative import methods
Importing data using the API is the best method for businesses with developer resources. Learn more about non-programmatic import methods in Getting started with importing data for Subscription Analytics.
There are two steps to building an integration:
Importing historical billing data
To import your business’ existing data, create a data source. Use the source’s UUID you’ll receive in the response in subsequent API requests.
# Create a data source
curl -X POST "https://api.chartmogul.com/v1/data_sources" \
-u YOUR_API_KEY: \
-H "Content-Type: application/json" \
-d '{
"name": "In-house billing"
}'
# Create a data source
ChartMogul::DataSource.create!(
name: "In-house billing",
)
// Create a data source
ChartMogul.DataSource.create(config, {
name: "In-house billing",
});
// Create a data source
ChartMogul\DataSource::create([
"name" => "In-house billing"
]);
// Create a data source
api.CreateDataSource("In-house billing")
# Create a data source
chartmogul.DataSource.create(config, data={"name": "In-house billing"})
Then, import customers, plans, invoices, line items, transactions, and subscription event objects using the Import Data in Bulk endpoint. This endpoint allows you to import multiple objects through a single API query and is recommended when importing more than 100 objects.
# Import data in bulk
curl -X POST "https://api.chartmogul.com/v1/data_sources/ds_SOURCE_UUID/json_imports" \
-u YOUR_API_KEY: \
-H "Content-Type: application/json" \
-d '{
"external_id": "ds_import_1",
"customers": [
{
"external_id": "scus_0001",
"name": "Andrew Jones",
"email": "[email protected]",
"country": "US",
"state": "California",
"city": "San Francisco",
"zip": "90210",
"company": "CA Printing Company",
"lead_created_at": "2023-05-14 00:00:00",
"free_trial_started_at": "2023-06-01 00:00:00"
}
],
"plans": [
{
"name": "Gold Biannual",
"external_id": "gold_biannual",
"interval_count": 6,
"interval_unit": "month"
}
],
"invoices": [
{
"external_id": "inv_001",
"date": "2023-04-02 21:37:00",
"due_date": "2023-05-02 21:37:00",
"currency": "USD",
"customer_external_id": "scus_0001"
},
{
"external_id": "inv_002",
"date": "2023-05-02 21:37:00",
"due_date": "2023-06-02 21:37:00",
"currency": "USD",
"customer_external_id": "scus_0001"
},
{
"external_id": "inv_003",
"date": "2023-06-02 21:37:00",
"due_date": "2023-07-02 21:37:00",
"currency": "USD",
"customer_external_id": "scus_0001"
}
],
"line_items": [
{
"type": "subscription",
"amount_in_cents": 1000,
"quantity": 1,
"invoice_external_id": "inv_001",
"plan_external_id": "gold_biannual",
"subscription_external_id": "sub_0001",
"service_period_start": "2023-04-02 21:37:00",
"service_period_end": "2023-05-02 21:37:00"
},
{
"type": "subscription",
"amount_in_cents": 1000,
"quantity": 1,
"invoice_external_id": "inv_002",
"plan_external_id": "gold_biannual",
"subscription_external_id": "sub_0001",
"service_period_start": "2023-05-02 21:37:00",
"service_period_end": "2023-06-02 21:37:00"
},
{
"type": "subscription",
"amount_in_cents": 1500,
"quantity": 1,
"invoice_external_id": "inv_003",
"plan_external_id": "gold_biannual",
"subscription_external_id": "sub_0001",
"service_period_start": "2023-06-02 21:37:00",
"service_period_end": "2023-07-02 21:37:00"
}
],
"transactions": [
{
"invoice_external_id": "inv_001",
"external_id": "trans_0001",
"type": "payments",
"result": "successful",
"date": "2023-04-02 21:37:00"
},
{
"invoice_external_id": "inv_002",
"external_id": "trans_0002",
"type": "payment",
"result": "failed",
"date": "2023-05-02 21:37:00"
},
{
"invoice_external_id": "inv_002",
"external_id": "trans_0003",
"type": "payment",
"result": "successful",
"date": "2005-05-03 21:37:00"
},
{
"invoice_external_id": "inv_003",
"external_id": "trans_0004",
"type": "payment",
"result": "successful",
"date": "2023-06-03 21:37:00"
}
],
"subscription_events": [
{
"external_id": "scus_0001",
"subscription_set_external_id": "sub_0001b",
"subscription_external_id": "evnt_001",
"customer_external_id": "scus_0001",
"plan_external_id": "gold_biannual",
"event_date": "2023-04-02 21:37:00",
"effective_date": "2023-04-02 21:37:00",
"event_type": "subscription_start",
"currency": "USD",
"amount_in_cents": 150000,
"quantity": 1
}
]
}'
Once you’ve successfully completed the above steps, ChartMogul processes your data and generates metrics. Check your import status with the Track Import Status endpoint.
Next, keep new data from your billing system in sync with ChartMogul for up-to-date metrics.
Non-programmatic ways to import data
In addition to the API, you can add subscription billing data to ChartMogul:
Importing subscription updates
Next, prepare your integration to keep ChartMogul updated with events from your billing system. You’ll use the customer and plan UUIDs generated when importing historical data. To retrieve all imported customer and plan objects along with their ChartMogul UUIDs, use the List Customers and List Plans endpoints.
Learn more about importing each type of subscription update:
- New subscription
- Subscription renewal
- Subscription update
- Subscription cancellation
- Subscription reactivation
New subscription
New Business
When a non-paying customer purchases their first subscription, ChartMogul classifies the subscription MRR as New Business.
When a customer starts a new subscription in your billing system, import it to ChartMogul.
New subscribers
When a customer purchases their first subscription:
- Create the customer record using the Create a Customer endpoint.
# Create a customer
curl -X POST "https://api.chartmogul.com/v1/customers" \
-u YOUR_API_KEY: \
-H "Content-Type: application/json" \
-d '{
"data_source_uuid": "ds_SOURCE_UUID",
"external_id": "scus_0002",
"name": "Anna Lopez",
"email": "[email protected]",
"country": "US",
"state": "New York",
"city": "New York",
"zip": "87123",
"company": "Myriapod Labs"
}'
# Create a customer
ChartMogul::Customer.create!(
data_source_uuid: "ds_SOURCE_UUID",
external_id: "scus_0002",
name: "Anna Lopez",
email: "[email protected]",
country: "US",
state: "New York",
city: "New York",
zip: "87123",
company: "Myriapod Labs",
)
// Create a customer
ChartMogul.Customer.create(config, {
data_source_uuid: "ds_SOURCE_UUID",
external_id: "scus_0002",
name: "Anna Lopez",
email: "[email protected]",
country: "US",
state: "New York",
city: "New York",
zip: "87123",
company: "Myriapod Labs",
});
// Create a customer
ChartMogul\Customer::create([
"data_source_uuid" => "ds_SOURCE_UUID",
"external_id" => "scus_0002",
"name" => "Anna Lopez",
"email" => "[email protected]",
"country" => "US",
"state" => "New York",
"city" => "New York",
"zip" => "87123",
"company" => "Myriapod Labs"
]);
// Create a customer
api.CreateCustomer(&cm.NewCustomer{
DataSourceUUID: "ds_SOURCE_UUID",
ExternalID: "scus_0002",
Name: "Anna Lopez",
Email: "[email protected]",
Country: "US",
State: "New York",
City: "New York",
Zip: "87123",
Company: "Myriapod Labs",
})
# Create a customer
chartmogul.Customer.create(
config,
data={
"data_source_uuid": "ds_SOURCE_UUID",
"external_id": "scus_0002",
"name": "Anna Lopez",
"email": "[email protected]",
"country": "US",
"state": "New York",
"city": "New York",
"zip": "87123",
"company": "Myriapod Labs",
},
)
- If the plan that the customer purchased does not exist in ChartMogul, create a new plan object using the Create a Plan endpoint.
# Create a plan
curl -X POST "https://api.chartmogul.com/v1/plans" \
-u YOUR_API_KEY: \
-H "Content-Type: application/json" \
-d '{
"data_source_uuid": "ds_SOURCE_UUID",
"name": "Silver Monthly",
"interval_count": 1,
"interval_unit": "month",
"external_id": "silver_monthly"
}'
# Create a plan
ChartMogul::Plan.create!(
data_source_uuid: "ds_SOURCE_UUID",
name: "Silver Monthly",
interval_count: 1,
interval_unit: "month",
external_id: "silver_monthly",
)
// Create a plan
ChartMogul.Plan.create(config, {
data_source_uuid: "ds_SOURCE_UUID",
name: "Silver Monthly",
interval_count: 1,
interval_unit: "month",
external_id: "silver_monthly",
});
// Create a plan
ChartMogul\Plan::create([
"data_source_uuid" => "ds_SOURCE_UUID",
"name" => "Silver Monthly",
"interval_count" => 1,
"interval_unit" => "month",
"external_id" => "silver_monthly"
]);
// Create a plan
api.CreatePlan(&cm.Plan{
DataSourceUUID: "ds_SOURCE_UUID",
Name: "Silver Monthly",
IntervalCount: 1,
IntervalUnit: "month",
ExternalID: "silver_monthly",
})
# Create a plan
chartmogul.Plan.create(
config,
data={
"data_source_uuid": "ds_SOURCE_UUID",
"name": "Silver Monthly",
"interval_count": 1,
"interval_unit": "month",
"external_id": "silver_monthly",
},
)
- Import invoices for the new subscription using the Import Invoices endpoint.
# Import invoices
curl -X POST "https://api.chartmogul.com/v1/import/customers/cus_CUSTOMER_UUID/invoices" \
-u YOUR_API_KEY: \
-H "Content-Type: application/json" \
-d '{
"invoices": [
{
"external_id": "inv_004",
"date": "2023-05-01 00:00:00",
"currency": "USD",
"due_date": "2023-05-15 00:00:00",
"customer_external_id": "scus_0002",
"data_source_uuid": "ds_SOURCE_UUID",
"line_items": [
{
"type": "subscription",
"subscription_external_id": "sub_0002",
"plan_uuid":"pl_PLAN_UUID",
"service_period_start": "2023-05-01 00:00:00",
"service_period_end": "2023-06-01 00:00:00",
"amount_in_cents": 5000,
"quantity": 1,
"discount_code": "PSO86",
"discount_amount_in_cents": 1000,
"tax_amount_in_cents": 900
}
],
"transactions": [
{
"date": "2023-05-05 00:14:23",
"type": "payment",
"result": "successful"
}
]
},
{
"external_id": "inv_005",
"date": "2023-06-01 00:00:00",
"currency": "USD",
"due_date": "2023-06-15 00:00:00",
"customer_external_id": "scus_0002",
"data_source_uuid": "ds_SOURCE_UUID",
"line_items": [
{
"type": "subscription",
"subscription_external_id": "sub_0002",
"plan_uuid":"pl_PLAN_UUID",
"service_period_start": "2023-06-01 00:00:00",
"service_period_end": "2023-07-01 00:00:00",
"amount_in_cents": 5000,
"quantity": 1,
"discount_code": "PSO86",
"discount_amount_in_cents": 1000,
"tax_amount_in_cents": 900
}
],
"transactions": [
{
"date": "2023-06-05 07:54:02",
"type": "payment",
"result": "successful"
}
]
}
]
}'
# Import invoices
line_item_1 = ChartMogul::LineItems::Subscription.new(
subscription_external_id: "sub_0002",
plan_uuid: "pl_PLAN_UUID",
service_period_start: Time.utc(2023, 5, 1),
service_period_end: Time.utc(2023, 6, 1),
amount_in_cents: 5000,
quantity: 1,
discount_code: "PSO86",
discount_amount_in_cents: 1000,
tax_amount_in_cents: 900,
)
transaction_1 = ChartMogul::Transactions::Payment.new(
date: Time.utc(2023, 5, 5, 0, 14, 23),
result: "successful",
)
invoice_1 = ChartMogul::Invoice.new(
external_id: "inv_004",
date: Time.utc(2023, 5, 1),
currency: "USD",
due_date: Time.utc(2023, 5, 15),
customer_external_id: "scus_0002",
data_source_uuid: "ds_SOURCE_UUID",
line_items: [line_item_1],
transactions: [transaction_1],
)
line_item_2 = ChartMogul::LineItems::Subscription.new(
subscription_external_id: "sub_0002",
plan_uuid: "pl_PLAN_UUID",
service_period_start: Time.utc(2023, 6, 1),
service_period_end: Time.utc(2023, 7, 1),
amount_in_cents: 5000,
quantity: 1,
discount_code: "PSO86",
discount_amount_in_cents: 1000,
tax_amount_in_cents: 900,
)
transaction_2 = ChartMogul::Transactions::Payment.new(
date: Time.utc(2023, 6, 5, 7, 54, 02),
result: "successful",
)
invoice_2 = ChartMogul::Invoice.new(
external_id: "inv_005",
date: Time.utc(2023, 6, 1),
currency: "USD",
due_date: Time.utc(2023, 6, 15),
customer_external_id: "scus_0002",
data_source_uuid: "ds_SOURCE_UUID",
line_items: [line_item_2],
transactions: [transaction_2],
)
ChartMogul::CustomerInvoices.create!(
customer_uuid: "cus_CUSTOMER_UUID",
invoices: [invoice_1, invoice_2],
)
// Import invoices
ChartMogul.Invoice.create(config, "cus_CUSTOMER_UUID", {
invoices: [
{
external_id: "inv_004",
date: "2023-05-01 00:00:00",
currency: "USD",
due_date: "2023-05-15 00:00:00",
customer_external_id: "scus_0002",
data_source_uuid: "ds_SOURCE_UUID",
line_items: [
{
type: "subscription",
subscription_external_id: "sub_0002",
plan_uuid: "pl_PLAN_UUID",
service_period_start: "2023-05-01 00:00:00",
service_period_end: "2023-06-01 00:00:00",
amount_in_cents: 5000,
quantity: 1,
discount_code: "PSO86",
discount_amount_in_cents: 1000,
tax_amount_in_cents: 900,
},
],
transactions: [
{
date: "2023-05-05 00:14:23",
type: "payment",
result: "successful",
},
],
},
{
external_id: "inv_005",
date: "2023-06-01 00:00:00",
currency: "USD",
due_date: "2023-06-15 00:00:00",
customer_external_id: "scus_0002",
data_source_uuid: "ds_SOURCE_UUID",
line_items: [
{
type: "subscription",
subscription_external_id: "sub_0002",
plan_uuid: "pl_PLAN_UUID",
service_period_start: "2023-06-01 00:00:00",
service_period_end: "2023-07-01 00:00:00",
amount_in_cents: 5000,
quantity: 1,
discount_code: "PSO86",
discount_amount_in_cents: 1000,
tax_amount_in_cents: 900,
},
],
transactions: [
{
date: "2023-06-05 07:54:02",
type: "payment",
result: "successful",
},
],
},
],
});
// Import invoices
$line_item_1 = new ChartMogul\LineItems\Subscription([
"subscription_external_id" => "sub_0002",
"plan_uuid" => "pl_PLAN_UUID",
"service_period_start" => "2023-05-01",
"service_period_end" => "2023-06-01",
"amount_in_cents" => 5000,
"quantity" => 1,
"discount_code" => "PSO86",
"discount_amount_in_cents" => 1000,
"tax_amount_in_cents" => 900
]);
$transaction_1 = new ChartMogul\Transactions\Payment([
"date" => "2023-05-05",
"result" => "successful"
]);
$invoice_1 = new ChartMogul\Invoice([
"external_id" => "inv_004",
"date" => "2023-05-01",
"currency" => "USD",
"due_date" => "2023-05-15",
"customer_external_id" => "scus_0002",
"data_source_uuid" => "ds_SOURCE_UUID",
"line_items" => [$line_item_1],
"transactions" => [$transaction_1]
]);
$line_item_2 = new ChartMogul\LineItems\Subscription([
"subscription_external_id" => "sub_0002",
"plan_uuid" => "pl_PLAN_UUID",
"service_period_start" => "2023-06-01",
"service_period_end" => "2023-07-01",
"amount_in_cents" => 5000,
"quantity" => 1,
"discount_code" => "PSO86",
"discount_amount_in_cents" => 1000,
"tax_amount_in_cents" => 900
]);
$transaction_2 = new ChartMogul\Transactions\Payment([
"date" => "2023-06-05",
"result" => "successful"
]);
$invoice_2 = new ChartMogul\Invoice([
"external_id" => "inv_005",
"date" => "2023-06-01",
"currency" => "USD",
"due_date" => "2023-06-15",
"customer_external_id" => "scus_0002",
"data_source_uuid" => "ds_SOURCE_UUID",
"line_items" => [$line_item_2],
"transactions" => [$transaction_2]
]);
ChartMogul\CustomerInvoices::create([
"customer_uuid" => "cus_CUSTOMER_UUID",
"invoices" => [$invoice_1, $invoice_2]
]);
// Import invoices
lineItem1 := &cm.LineItem{
SubscriptionExternalID: "sub_0002",
PlanUUID: "pl_PLAN_UUID",
ServicePeriodStart: "2023-05-01 00:00:00",
ServicePeriodEnd: "2023-06-01 00:00:00",
AmountInCents: 5000,
Quantity: 1,
DiscountCode: "PSO86",
DiscountAmountInCents: 1000,
TaxAmountInCents: 900,
Type: "subscription",
}
transaction1 := &cm.Transaction{
Date: "2023-05-05 00:14:23",
Type: "payment",
Result: "successful",
}
invoice1 := &cm.Invoice{
ExternalID: "inv_004",
Date: "2023-05-01 00:00:00",
Currency: "USD",
DueDate: "2023-05-15 00:00:00",
CustomerExternalID: "scus_0002",
DataSourceUUID: "ds_SOURCE_UUID",
LineItems: []*cm.LineItem{lineItem1},
Transactions: []*cm.Transaction{transaction1},
}
lineItem2 := &cm.LineItem{
SubscriptionExternalID: "sub_0002",
PlanUUID: "pl_PLAN_UUID",
ServicePeriodStart: "2023-06-01 00:00:00",
ServicePeriodEnd: "2023-07-01 00:00:00",
AmountInCents: 5000,
Quantity: 1,
DiscountCode: "PSO86",
DiscountAmountInCents: 1000,
TaxAmountInCents: 900,
Type: "subscription",
}
transaction2 := &cm.Transaction{
Date: "2023-06-05 07:54:02",
Type: "payment",
Result: "successful",
}
invoice2 := &cm.Invoice{
ExternalID: "inv_005",
Date: "2023-06-01 00:00:00",
Currency: "USD",
DueDate: "2023-06-15 00:00:00",
CustomerExternalID: "scus_0002",
DataSourceUUID: "ds_SOURCE_UUID",
LineItems: []*cm.LineItem{lineItem2},
Transactions: []*cm.Transaction{transaction2},
}
api.CreateInvoices(
[]*cm.Invoice{invoice1, invoice2},
"cus_CUSTOMER_UUID",
)
# Import invoices
chartmogul.Invoice.create(
config,
uuid="cus_CUSTOMER_UUID",
data={
"invoices": [
{
"external_id": "inv_004",
"date": datetime(2023, 5, 1, 0, 0, 0),
"currency": "USD",
"due_date": datetime(2023, 5, 15, 0, 0, 0),
"customer_external_id": "scus_0002",
"data_source_uuid": "ds_SOURCE_UUID",
"line_items": [
{
"type": "subscription",
"subscription_external_id": "sub_0002",
"plan_uuid": "pl_PLAN_UUID",
"service_period_start": datetime(2023, 5, 1, 0, 0, 0),
"service_period_end": datetime(2023, 6, 1, 0, 0, 0),
"amount_in_cents": 5000,
"quantity": 1,
"discount_code": "PSO86",
"discount_amount_in_cents": 1000,
"tax_amount_in_cents": 900,
}
],
"transactions": [
{
"date": datetime(2023, 5, 5, 0, 14, 23),
"type": "payment",
"result": "successful",
}
],
},
{
"external_id": "inv_005",
"date": datetime(2023, 6, 1, 0, 0, 0),
"currency": "USD",
"due_date": datetime(2023, 6, 15, 0, 0, 0),
"customer_external_id": "scus_0002",
"data_source_uuid": "ds_SOURCE_UUID",
"line_items": [
{
"type": "subscription",
"subscription_external_id": "sub_0002",
"plan_uuid": "pl_PLAN_UUID",
"service_period_start": datetime(2023, 6, 1, 0, 0, 0),
"service_period_end": datetime(2023, 7, 1, 0, 0, 0),
"amount_in_cents": 5000,
"quantity": 1,
"discount_code": "PSO86",
"discount_amount_in_cents": 1000,
"tax_amount_in_cents": 900,
}
],
"transactions": [
{
"date": datetime(2023, 6, 5, 7, 54, 2),
"type": "payment",
"result": "successful",
}
],
},
]
},
)
Existing subscribers
When an existing subscriber purchases an additional subscription:
- If the plan doesn’t exist in ChartMogul, create it using the Create a Plan endpoint.
- Import an invoice for the purchase using the Import Invoices endpoint.
Subscription renewal
To import a renewal into ChartMogul, use the Import Invoices endpoint and reference the subscription_external_id
of the subscription being renewed.
How ChartMogul references the correct subscription
When an existing
subscription_external_id
is used in an invoice, ChartMogul renews or updates the existing subscription. When a newsubscription_external_id
is used in an invoice, ChartMogul generates a new subscription.
Use the List Customer’s Subscriptions endpoint to retrieve thesubscription_external_id
specified by you, thesubscription_uuid
generated by ChartMogul, and other basic subscription information.
How ChartMogul handles renewals with late invoices
ChartMogul assumes good faith if renewal invoices (or payments for an invoice) are not received on time, and continues to report MRR for a subscription. To change a subscription’s status and reported MRR, you’ll need to explicitly cancel it. Alternatively, use the Handling Past-due Subscriptions setting to churn past-due subscriptions after a specified number of days.
Reporting cash flow metrics in ChartMogul
To report cash flow metrics, import transaction data. Include failed transaction attempts for an invoice to enable reporting on failed charges.
Subscription update
Expansion vs. Contraction
When a customer upgrades an existing subscription or purchases an additional subscription, ChartMogul classifies the net increase in subscription MRR as Expansion.
When a customer downgrades an existing subscription or cancels one or more (but not their last) subscription, ChartMogul classifies the net decrease in subscription MRR as Contraction.
To import a subscription update into ChartMogul, e.g. the plan changes, the price increases or decreases, or the discount amount changes, use the same subscription_external_id
when importing invoices into ChartMogul.
Updates at the end of a previously invoiced service period
Create a new invoice for the subsequent service period using the Import Invoices endpoint and reference the subscription_external_id
of the updated subscription. If the plan has been changed, then specify the UUID of the new plan as the plan_uuid
in the invoice.
Updates in the middle of a service period
It’s common for businesses to charge customers a prorated amount for subscriptions that change in the middle of the service period.
In this case, import an invoice using the Import Invoices endpoint, with the attribute prorated
set to true
, and the prorated service_period_start
and service_period_end
timestamps, on the relevant subscription line item.
For detailed instructions on different prorated billing scenarios, read this tutorial.
Subscription cancellation
Churn
When a customer cancels their last (or only) subscription, ChartMogul classifies the lost subscription MRR as Churn.
To import a cancellation into ChartMogul, use the Cancel a Customer’s Subscription endpoint. Reference the subscription by its UUID and set the cancelled_at
timestamp for the date the subscription ended.
# Cancel a subscription
curl -X PATCH "https://api.chartmogul.com/v1/import/subscriptions/sub_SUBSCRIPTION_UUID" \
-u YOUR_API_KEY: \
-H "Content-Type: application/json" \
-d '{
"cancelled_at": "2023-07-15 00:00:00"
}'
# Cancel a subscription
customer = ChartMogul::Customer.retrieve("cus_CUSTOMER_UUID")
subscription = customer.subscriptions.find { |e| e.uuid == "sub_SUBSCRIPTION_UUID" }
subscription.cancel(Time.utc(2023, 7, 15))
// Cancel a subscription
ChartMogul.Subscription.cancel(config, "sub_SUBSCRIPTION_UUID", {
cancelled_at: "2023-07-15 00:00:00",
});
// Cancel a subscription
$subscription = new ChartMogul\Subscription(["uuid" => "sub_SUBSCRIPTION_UUID"]);
$canceldate = "2023-07-15";
$subscription->cancel($canceldate);
// Cancel a subscription
api.CancelSubscription(
"sub_SUBSCRIPTION_UUID",
&cm.CancelSubscriptionParams{CancelledAt: "2023-07-15 00:00:00"},
)
# Cancel a subscription
chartmogul.Subscription.cancel(
config,
uuid="sub_SUBSCRIPTION_UUID",
data={"cancelled_at": datetime(2023, 7, 15, 0, 0, 0)},
)
If this is a historical subscription that’s already been canceled, you can include the cancellation date on the invoice instead of making a separate API call. For example, if a churned customer had renewed each month for two months and then canceled their monthly subscription, you can use the Import Invoices endpoint and include a line item with the cancelled_at
timestamp on the last invoice.
# Import invoices for a canceled subscription
curl -X POST "https://api.chartmogul.com/v1/import/customers/cus_CUSTOMER_UUID/invoices" \
-u YOUR_API_KEY: \
-H "Content-Type: application/json" \
-d '{
"invoices": [
{
"external_id": "inv_006",
"date": "2023-05-01 00:00:00",
"currency": "USD",
"due_date": "2023-05-15 00:00:00",
"customer_external_id": "scus_0002",
"data_source_uuid": "ds_SOURCE_UUID",
"line_items": [
{
"type": "subscription",
"subscription_external_id": "sub_0003",
"plan_uuid":"pl_PLAN_UUID",
"service_period_start": "2023-05-01 00:00:00",
"service_period_end": "2023-06-01 00:00:00",
"amount_in_cents": 5000,
"quantity": 1,
"discount_code": "PSO86",
"discount_amount_in_cents": 1000,
"tax_amount_in_cents": 900
}
],
"transactions": [
{
"date": "2023-05-05 00:14:23",
"type": "payment",
"result": "successful"
}
]
},
{
"external_id": "inv_007",
"date": "2023-06-01 00:00:00",
"currency": "USD",
"due_date": "2023-06-15 00:00:00",
"customer_external_id": "scus_0002",
"data_source_uuid": "ds_SOURCE_UUID",
"line_items": [
{
"type": "subscription",
"subscription_external_id": "sub_0003",
"plan_uuid":"pl_PLAN_UUID",
"service_period_start": "2023-06-01 00:00:00",
"service_period_end": "2023-07-01 00:00:00",
"amount_in_cents": 5000,
"quantity": 1,
"discount_code": "PSO86",
"discount_amount_in_cents": 1000,
"tax_amount_in_cents": 900,
"cancelled_at": "2023-07-02 00:00:00"
}
],
"transactions": [
{
"date": "2023-06-05 07:54:02",
"type": "payment",
"result": "successful"
}
]
}
]
}'
# Import invoices for a canceled subscription
line_item_1 = ChartMogul::LineItems::Subscription.new(
subscription_external_id: "sub_0003",
plan_uuid: "pl_PLAN_UUID",
service_period_start: Time.utc(2023, 5, 1),
service_period_end: Time.utc(2023, 6, 1),
amount_in_cents: 5000,
quantity: 1,
discount_code: "PSO86",
discount_amount_in_cents: 1000,
tax_amount_in_cents: 900,
)
transaction_1 = ChartMogul::Transactions::Payment.new(
date: Time.utc(2023, 5, 5, 0, 14, 23),
result: "successful",
)
invoice_1 = ChartMogul::Invoice.new(
external_id: "inv_006",
date: Time.utc(2023, 5, 1),
currency: "USD",
due_date: Time.utc(2023, 5, 15),
customer_external_id: "scus_0002",
data_source_uuid: "ds_SOURCE_UUID",
line_items: [line_item_1],
transactions: [transaction_1],
)
line_item_2 = ChartMogul::LineItems::Subscription.new(
subscription_external_id: "sub_0003",
plan_uuid: "pl_PLAN_UUID",
service_period_start: Time.utc(2023, 6, 1),
service_period_end: Time.utc(2023, 7, 1),
amount_in_cents: 5000,
quantity: 1,
discount_code: "PSO86",
discount_amount_in_cents: 1000,
tax_amount_in_cents: 900,
cancelled_at: Time.utc(2023, 7, 2),
)
transaction_2 = ChartMogul::Transactions::Payment.new(
date: Time.utc(2023, 6, 5, 7, 54, 02),
result: "successful",
)
invoice_2 = ChartMogul::Invoice.new(
external_id: "inv_007",
date: Time.utc(2023, 6, 1),
currency: "USD",
due_date: Time.utc(2023, 6, 15),
customer_external_id: "scus_0003",
data_source_uuid: "ds_SOURCE_UUID",
line_items: [line_item_2],
transactions: [transaction_2],
)
ChartMogul::CustomerInvoices.create!(
customer_uuid: "cus_CUSTOMER_UUID",
invoices: [invoice_1, invoice_2],
)
// Import invoices for a canceled subscription
ChartMogul.Invoice.create(config, "cus_CUSTOMER_UUID", {
invoices: [
{
external_id: "inv_006",
date: "2023-05-01 00:00:00",
currency: "USD",
due_date: "2023-05-15 00:00:00",
customer_external_id: "scus_0002",
data_source_uuid: "ds_SOURCE_UUID",
line_items: [
{
type: "subscription",
subscription_external_id: "sub_0003",
plan_uuid: "pl_PLAN_UUID",
service_period_start: "2023-05-01 00:00:00",
service_period_end: "2023-06-01 00:00:00",
amount_in_cents: 5000,
quantity: 1,
discount_code: "PSO86",
discount_amount_in_cents: 1000,
tax_amount_in_cents: 900,
},
],
transactions: [
{
date: "2023-05-05 00:14:23",
type: "payment",
result: "successful",
},
],
},
{
external_id: "inv_007",
date: "2023-06-01 00:00:00",
currency: "USD",
due_date: "2023-06-15 00:00:00",
customer_external_id: "scus_0002",
data_source_uuid: "ds_SOURCE_UUID",
line_items: [
{
type: "subscription",
subscription_external_id: "sub_0003",
plan_uuid: "pl_PLAN_UUID",
service_period_start: "2023-06-01 00:00:00",
service_period_end: "2023-07-01 00:00:00",
amount_in_cents: 5000,
quantity: 1,
discount_code: "PSO86",
discount_amount_in_cents: 1000,
tax_amount_in_cents: 900,
cancelled_at: "2023-07-02 00:00:00",
},
],
transactions: [
{
date: "2023-06-05 07:54:02",
type: "payment",
result: "successful",
},
],
},
],
});
// Import invoices for a canceled subscription
$line_item_1 = new ChartMogul\LineItems\Subscription([
"subscription_external_id" => "sub_0003",
"plan_uuid" => "pl_PLAN_UUID",
"service_period_start" => "2023-05-01",
"service_period_end" => "2023-06-01",
"amount_in_cents" => 5000,
"quantity" => 1,
"discount_code" => "PSO86",
"discount_amount_in_cents" => 1000,
"tax_amount_in_cents" => 900
]);
$transaction_1 = new ChartMogul\Transactions\Payment([
"date" => "2023-05-05",
"result" => "successful"
]);
$invoice_1 = new ChartMogul\Invoice([
"external_id" => "inv_006",
"date" => "2023-05-01",
"currency" => "USD",
"due_date" => "2023-05-15",
"customer_external_id" => "scus_0002",
"data_source_uuid" => "ds_SOURCE_UUID",
"line_items" => [$line_item_1],
"transactions" => [$transaction_1]
]);
$line_item_2 = new ChartMogul\LineItems\Subscription([
"subscription_external_id" => "sub_0003",
"plan_uuid" => "pl_PLAN_UUID",
"service_period_start" => "2023-06-01",
"service_period_end" => "2023-07-01",
"amount_in_cents" => 5000,
"quantity" => 1,
"discount_code" => "PSO86",
"discount_amount_in_cents" => 1000,
"tax_amount_in_cents" => 900,
"cancelled_at" => "2023-07-02"
]);
$transaction_2 = new ChartMogul\Transactions\Payment([
"date" => "2023-06-05",
"result" => "successful"
]);
$invoice_2 = new ChartMogul\Invoice([
"external_id" => "inv_007",
"date" => "2023-06-01",
"currency" => "USD",
"due_date" => "2023-06-15",
"customer_external_id" => "scus_0002",
"data_source_uuid" => "ds_SOURCE_UUID",
"line_items" => [$line_item_2],
"transactions" => [$transaction_2]
]);
ChartMogul\CustomerInvoices::create([
"customer_uuid" => "cus_CUSTOMER_UUID",
"invoices" => [$invoice_1, $invoice_2]
]);
// Import invoices for a canceled subscription
lineItem1 := &cm.LineItem{
SubscriptionExternalID: "sub_0003",
PlanUUID: "pl_PLAN_UUID",
ServicePeriodStart: "2023-05-01 00:00:00",
ServicePeriodEnd: "2023-06-01 00:00:00",
AmountInCents: 5000,
Quantity: 1,
DiscountCode: "PSO86",
DiscountAmountInCents: 1000,
TaxAmountInCents: 900,
Type: "subscription",
}
transaction1 := &cm.Transaction{
Date: "2023-05-05 00:14:23",
Type: "payment",
Result: "successful",
}
invoice1 := &cm.Invoice{
ExternalID: "inv_006",
Date: "2023-05-01 00:00:00",
Currency: "USD",
DueDate: "2023-05-15 00:00:00",
CustomerExternalID: "scus_0002",
DataSourceUUID: "ds_SOURCE_UUID",
LineItems: []*cm.LineItem{lineItem1},
Transactions: []*cm.Transaction{transaction1},
}
lineItem2 := &cm.LineItem{
SubscriptionExternalID: "sub_0003",
PlanUUID: "pl_PLAN_UUID",
ServicePeriodStart: "2023-06-01 00:00:00",
ServicePeriodEnd: "2023-07-01 00:00:00",
AmountInCents: 5000,
Quantity: 1,
DiscountCode: "PSO86",
DiscountAmountInCents: 1000,
TaxAmountInCents: 900,
Type: "subscription",
CancelledAt: "2023-07-02 00:00:00",
}
transaction2 := &cm.Transaction{
Date: "2023-06-05 07:54:02",
Type: "payment",
Result: "successful",
}
invoice2 := &cm.Invoice{
ExternalID: "inv_007",
Date: "2023-06-01 00:00:00",
Currency: "USD",
DueDate: "2023-06-15 00:00:00",
CustomerExternalID: "scus_0002",
DataSourceUUID: "ds_SOURCE_UUID",
LineItems: []*cm.LineItem{lineItem2},
Transactions: []*cm.Transaction{transaction2},
}
api.CreateInvoices(
[]*cm.Invoice{invoice1, invoice2},
"cus_CUSTOMER_UUID",
)
# Import invoices for a canceled subscription
chartmogul.Invoice.create(
config,
uuid="cus_CUSTOMER_UUID",
data={
"invoices": [
{
"external_id": "inv_006",
"date": datetime(2023, 5, 1, 0, 0, 0),
"currency": "USD",
"due_date": datetime(2023, 5, 15, 0, 0, 0),
"customer_external_id": "scus_0002",
"data_source_uuid": "ds_SOURCE_UUID",
"line_items": [
{
"type": "subscription",
"subscription_external_id": "sub_0003",
"plan_uuid": "pl_PLAN_UUID",
"service_period_start": datetime(2023, 5, 1, 0, 0, 0),
"service_period_end": datetime(2023, 6, 1, 0, 0, 0),
"amount_in_cents": 5000,
"quantity": 1,
"discount_code": "PSO86",
"discount_amount_in_cents": 1000,
"tax_amount_in_cents": 900,
}
],
"transactions": [
{
"date": datetime(2023, 5, 5, 0, 14, 23),
"type": "payment",
"result": "successful",
}
],
},
{
"external_id": "inv_007",
"date": datetime(2023, 6, 1, 0, 0, 0),
"currency": "USD",
"due_date": datetime(2023, 6, 15, 0, 0, 0),
"customer_external_id": "scus_0002",
"data_source_uuid": "ds_SOURCE_UUID",
"line_items": [
{
"type": "subscription",
"subscription_external_id": "sub_0003",
"plan_uuid": "pl_PLAN_UUID",
"service_period_start": datetime(2023, 6, 1, 0, 0, 0),
"service_period_end": datetime(2023, 7, 1, 0, 0, 0),
"amount_in_cents": 5000,
"quantity": 1,
"discount_code": "PSO86",
"discount_amount_in_cents": 1000,
"tax_amount_in_cents": 900,
"cancelled_at": datetime(2023, 7, 2, 0, 0, 0),
}
],
"transactions": [
{
"date": datetime(2023, 6, 5, 7, 54, 2),
"type": "payment",
"result": "successful",
}
],
},
]
},
)
Subscription reactivation
Reactivation
When a formerly paying customer (who had previously churned) moves back onto a paid plan, ChartMogul classifies the new subscription MRR as Reactivation.
To import a reactivation into ChartMogul, use the Import Invoices endpoint and reference the subscription_external_id
of the previously canceled subscription.
Once you complete the steps above, your integration is finished and ChartMogul keeps your subscription data and analytics updated in real time.
Support
Don’t see your business use case covered here? Have questions regarding our API? Contact our support team.
Updated 3 months ago