GraphQL Account API: Unified billing
The following examples of queries and mutations use the Unified Billing features of the BigCommerce GraphQL Account API. Use the API by submitting POST requests to https://api.bigcommerce.com/accounts/{{partner_account_uuid}}/graphql
.
Example queries and mutations
Create a checkout
The first step in charging a merchant for a product is to create a checkout. After creating a checkout through the API, the checkout will be in a pending status
, and a checkoutUrl
will be included in the response. The checkoutUrl
routes to the BigCommerce checkout UI where a merchant must complete the checkout in their store's control panel. After checkout completion, a subscription is created and billed to the merchant, and the checkout status moves to complete. When the merchant exits the BigCommerce checkout UI, they will be redirected to the redirectUrl
provided in the request. Use this field to route the merchant back to your app.
When creating a checkout with a product that has a trial period, set the trialDays
field to the number of days the trial should last.
The merchant will not be charged during this period. A subscription only generates an invoice once the trial period ends. No charges are made during the trial.
Checkout links are valid for 24 hours and expire automatically to prevent misuse.
To create a checkout, run the createCheckout
mutation:
mutation ($checkout: CreateCheckoutInput!) {
checkout {
createCheckout(input: $checkout) {
checkout {
id
accountId
status
checkoutUrl
items(first: 1) {
edges {
node {
subscriptionId
status
product {
id
type
productLevel
}
scope {
id
type
}
pricingPlan {
interval
price {
value
currencyCode
}
trialDays
}
redirectUrl
description
}
}
}
}
}
}
}
Fetch a checkout
Once the checkout is created, you can periodically poll the status of the checkout by calling this endpoint. To fetch an existing checkout, copy and run the following query:
Replace the checkoutId
with the following variable:
{
"checkoutId": "bc/account/checkout/ab0a8354-3caf-423b-a3be-42a59c97fcf5"
}
query Account($checkoutId: ID!) {
account {
checkout(id: $checkoutId) {
id
accountId
checkoutUrl
status
items {
edges {
node {
description
status
product {
id
productLevel
type
}
scope {
id
type
}
pricingPlan {
price {
value
currencyCode
}
interval
trialDays
}
subscriptionId
redirectUrl
}
}
}
}
}
}
Update a subscription
The createCheckout
mutation can also be used to update an existing subscription's pricing plan information and product level. A subscriptionId
must be passed in the request for this to be processed as an update.
mutation ($checkout: CreateCheckoutInput!) {
checkout {
createCheckout(input: $checkout) {
checkout {
accountId
status
checkoutUrl
items(first: 1) {
edges {
node {
subscriptionId
status
product {
id
type
productLevel
}
scope {
id
type
}
pricingPlan {
interval
price {
value
currencyCode
}
trialDays
}
redirectUrl
description
}
}
}
}
}
}
}
Cancel a subscription
This mutation cancels the subscription at the end of the merchant's current billing cycle. The cancelledAt
value will be the last day of the merchant's billing cycle (i.e., the day through which they have already paid).
mutation ($subscription: CancelSubscriptionInput!) {
subscription {
cancelSubscription(input: $subscription) {
subscriptionId
cancelledAt
}
}
}
How Cancellations Work During a Free Trial
-
No Billing During Trial
- A subscription only generates an invoice once the trial period ends. No charges are made during the trial.
-
Immediate Cancellation During Trial
- If a subscription is canceled while it's still in the trial period, the cancellation takes effect immediately. The trial ends, and no invoice is ever generated.
-
Post Trial Cancellation Behavior
- Once the trial ends, the subscription begins billing. Any cancellation initiated will take effect at the end of the current billing cycle (e.g., monthly or annual term), not immediately.
Query subscriptions
Subscriptions can be queried using the subscriptions
query endpoint.
Fields that can be retrieved are:
id
- subscription idaccountId
- account id belonging to the merchantactivationDate
- date billing beganbillingInterval
- billing frequencycreatedAt
- date and time the subscription was createdcurrentPeriodEnd
- date of the end of the current billing periodupdatedAt
- date and time the subscription was last updatedpricePerInterval
- amount being billed with the following fields:value
- the scalar amountcurrencyCode
- the currency of the amount
product
- product object with the following fieldsproductLevel
- the level of the product if it was providedid
- product idtype
- product type
status
- subscription statusscope
- scope object with the following fieldstype
- scope typeid
- scope id
In this example, no filters are passed, so the response will include all subscriptions of the partner. The default number of subscriptions returned per page is 10.
query {
account {
subscriptions {
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
edges {
cursor
node {
id
accountId
activationDate
pricePerInterval {
value
currencyCode
}
billingInterval
status
scope {
type
id
}
product {
productLevel
id
type
}
createdAt
currentPeriodEnd
updatedAt
}
}
}
}
}
Pagination info is returned with cursors on every subscription node. The pageInfo
provides information on the next page along with the cursors to use in traversing the graph.
"pageInfo": {
"hasNextPage": true,
"hasPreviousPage": false,
"startCursor": "WzE3MjQ0MzgzODk0MzY0NzYsODhd",
"endCursor": "WzE3MTk3NDYxNzUyNjg2NDUsNzdd"
}
Use the endCursor
to begin the next query. first
can be used to limit how many subscriptions are returned. The max limit is 50 subscriptions at a time.
query {
account {
subscriptions(first: 10, after: "WzE3MTk3NDYxNzUyNjg2NDUsNzdd") {
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
edges {
cursor
node {
id
accountId
activationDate
pricePerInterval {
value
currencyCode
}
billingInterval
status
scope {
type
id
}
product {
productLevel
id
type
}
createdAt
currentPeriodEnd
updatedAt
}
}
}
}
}
Filters can also be used to query subscriptions.
The supported filters are
productId
productType
scopeId
scopeType
updatedAfter
status
ids
query ($filters: SubscriptionFiltersInput) {
account {
subscriptions(filters: $filters) {
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
edges {
cursor
node {
id
accountId
activationDate
pricePerInterval {
value
currencyCode
}
billingInterval
status
scope {
type
id
}
product {
productLevel
id
type
}
createdAt
currentPeriodEnd
updatedAt
}
}
}
}
}