Getting started with the Import 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 Import 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.

There are two steps to building an integration:

  1. Importing historical billing data
  2. Importing subscription updates

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"
})
.then(res => {
  console.log(res);
})
.catch(e => console.error(e.message, e.httpStatus, e.response));
<?php

// 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(lambda ds: print(ds)).get()

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. Log in to ChartMogul to view the status of the import and your charts.

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

When a customer starts a new subscription in your billing system, import it to ChartMogul.

New subscribers

When a customer purchases their first subscription:

  1. 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"
})
.then(res => {
  console.log(res);
})
.catch(e => console.error(e.message, e.httpStatus, e.response));
<?php

// 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",    
}).then(lambda cus: print(cus)).get()
  1. 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"
})
.then(res => {
  console.log(res);
})
.catch(e => console.error(e.message, e.httpStatus, e.response));
<?php

// 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"
}).then(lambda result: print(result)).get()
  1. 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"
            }]
        }]
    })
.then(res => {
  console.log(res);
})
.catch(e => console.error(e.message, e.httpStatus, e.response));
<?php

// 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"
            }]
        }]
    }).then(lambda result: print(result)).get()

Existing subscribers

When an existing subscriber purchases an additional subscription:

  1. If the plan doesn’t exist in ChartMogul, create it using the Create a Plan endpoint.
  2. 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 new subscription_external_id is used in an invoice, ChartMogul generates a new subscription.
Use the List Customer’s Subscriptions endpoint to retrieve the subscription_external_id specified by you, the subscription_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

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

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"
   })
.then(res => {
  console.log(res);
})
.catch(e => console.error(e.message, e.httpStatus, e.response));
<?php

// 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)
    }).then(lambda result: print(result)).get()

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"
            }]
        }]
    })
.then(res => {
  console.log(res);
})
.catch(e => console.error(e.message, e.httpStatus, e.response));
<?php

// 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"
            }]
        }]
    }).then(lambda result: print(result)).get()

Subscription 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.