Implement your app business model with the Billing API
You can implement your billing model using the AppPurchaseOneTime, AppSubscription, and AppCredit resources. To use any of these resources, you'll also need to implement a merchant trigger for the charge, such as app installation, service plan upgrade, or individual purchase.
Implement the AppPurchaseOneTime resource
The AppPurchaseOneTime resource supports two billing models:
- Pay one time
- Pay as you go
Pay one time
You can create the charge by using the appPurchaseOneTimeCreate mutation. Provide the name
, price
and returnUrl
for the one-time purchase. The only possible currencyCode
is USD
. The returnUrl
is where the merchant is redirected after accepting the charge and also includes the charge ID.
POST /admin/api/unstable/graphql.json
mutation {
appPurchaseOneTimeCreate(
name: "Email template"
price: { amount: 100.00, currencyCode: USD}
returnUrl: "http://super-duper.shopifyapps.com"
) {
userErrors {
field
message
}
confirmationUrl
appPurchaseOneTime {
id
}
}
}
JSON response:
{
"data": {
"appPurchaseOneTimeCreate": {
"userErrors": [],
"confirmationUrl": "https://domain.myshopify.com/admin/charges/406454328/confirm_application_charge?signature=BAh7BzoHaWRpBDgAOhg6EmF1dG9fYWN0aXZhdGVU--59c04b2c6b0f73f10f97ae24af2f248c5831a3e8",
"appPurchaseOneTime": {
"id": "gid://shopify/AppPurchaseOneTime/406454328"
}
}
},
...
}
Pay as you go
You can use the appPurchaseOneTimeCreate mutation to create many charges:
POST /admin/api/unstable/graphql.json
mutation {
appPurchaseOneTimeCreate(
name: "100 emails for $1"
price: { amount: 1.00, currencyCode: USD}
returnUrl: "http://super-duper.shopifyapps.com"
) {
userErrors {
field
message
}
confirmationUrl
appPurchaseOneTime {
id
}
}
}
JSON response:
{
"data": {
"appPurchaseOneTimeCreate": {
"userErrors": [],
"confirmationUrl": "https://domain.myshopify.com/admin/charges/406454328/confirm_application_charge?signature=BAh7BzoHaWRpBDgAOhg6EmF1dG9fYWN0aXZhdGVU--59c04b2c6b0f73f10f97ae24af2f248c5831a3e8",
"appPurchaseOneTime": {
"id": "gid://shopify/AppPurchaseOneTime/406454328"
}
}
},
...
}
Implement the AppSubscription resource
The AppPurchaseOneTime resource supports two billing models:
- Recurring billing
- Usage billing
Recurring billing
You can use the appSubscriptionCreate
mutation to create a recurring charge. You can specify the details of the plan by using the apprecurringPricingDetails
field on the line item's plan. Provide the name
, price
, returnUrl
, and interval
. The interval
field accepts two values: EVERY_30_DAYS or ANNUAL. If the interval field is not provided, then the interval defaults to EVERY_30_DAYS.
The only supported currencyCode
input is USD. The returnUrl
is where the merchant is redirected after accepting the charge and also includes the charge ID.
mutation {
appSubscriptionCreate(
name: "Super Duper Recurring Plan"
returnUrl: "http://super-duper.shopifyapps.com"
lineItems: [{
plan: {
appRecurringPricingDetails: {
price: { amount: 10.00, currencyCode: USD }
interval: EVERY_30_DAYS
}
}
}]
) {
userErrors {
field
message
}
confirmationUrl
appSubscription {
id
}
}
}
JSON response:
The mutation returns the app subscription ID.
{
"data": {
"appSubscriptionCreate": {
"userErrors": [],
"confirmationUrl": "https://domain.myshopify.com/admin/charges/4019552312/confirm_recurring_application_charge?signature=BAh7BzoHaWRsKwc4gJXvOhJhdXRvX2FjdGl2YXRlVA%3D%3D--74e39487ff00313ca4409dea7ab00081001c45d5",
"appSubscription": {
"id": "gid://shopify/AppSubscription/4019552312"
}
}
},
...
}
Usage billing
Setting up usage based billing requires two steps:
- Create a usage pricing plan with
appSubscriptionCreate
mutation. - Create a usage record.
Create a usage pricing plan
You can use the appSubscriptionCreate
mutation to create a usage pricing plan. You need to include the cappedAmount
parameter, which indicates the maximum amount of usage the merchant is billed for within the Shopify 30-day billing cycle. You must also include the terms
field, which is reviewed by the merchant when they accept your pricing plan. The app subscription ID and line item ID included in the payload are used later to create usage records.
mutation {
appSubscriptionCreate(
name: "Super Duper Capped Pricing Plan"
returnUrl: "http://super-duper.shopifyapps.com"
lineItems: [{
plan: {
appUsagePricingDetails: {
terms: "$1 for 100 emails"
cappedAmount: { amount: 20.00, currencyCode: USD }
interval: EVERY_30_DAYS
}
}
}]
){
userErrors {
field
message
}
confirmationUrl
appSubscription {
id
lineItems {
id
plan {
pricingDetails {
__typename
}
}
}
}
}
}
JSON response:
The mutation returns the app subscription ID and line item ID that you can use to create usage records.
{
"data": {
"appSubscriptionCreate": {
"userErrors": [],
"confirmationUrl": "https://domain.myshopify.com/admin/charges/4019585080/confirm_recurring_application_charge?signature=BAh7BzoHaWRsKwc4AJbvOhJhdXRvX2FjdGl2YXRlVA%3D%3D--924efed32be5c4af3c94c427ecbf380aef88f123",
"appSubscription": {
"id": "gid://shopify/AppSubscription/4019585080",
"lineItems": [
{
"id": "gid://shopify/AppSubscriptionLineItem/4019585080?v=1&index=0",
"plan": {
"pricingDetails": {
"__typename": "AppUsagePricing"
}
}
}
]
}
}
},
...
}
You can also create a recurring pricing plan and a usage pricing plan using a single mutation:
mutation {
appSubscriptionCreate(
name: "Super Duper Capped Pricing Plan",
returnUrl: "http://super-duper.shopifyapps.com",
lineItems: [{
plan: {
appUsagePricingDetails: {
terms: "$1 for 100 emails"
cappedAmount: { amount: 20.00, currencyCode: USD }
interval: EVERY_30_DAYS
}
}
},
{
plan: {
appRecurringPricingDetails: {
price: { amount: 10.00, currencyCode: USD }
}
}
}]
){
userErrors {
field
message
}
confirmationUrl
appSubscription {
id
lineItems {
id
plan {
pricingDetails {
__typename
}
}
}
}
}
}
JSON response:
{
"data": {
"appSubscriptionCreate": {
"userErrors": [],
"confirmationUrl": "https://domain.myshopify.com/admin/charges/4028497976/confirm_recurring_application_charge?signature=BAh7BzoHaWRsKwc4AB7wOhJhdXRvX2FjdGl2YXRlVA%3D%3D--987b3537018fdd69c50f13d6cbd3fba468e0e9a6",
"appSubscription": {
"id": "gid://shopify/AppSubscription/4028497976",
"lineItems": [
{
"id": "gid://shopify/AppSubscriptionLineItem/4028497976?v=1&index=0",
"plan": {
"pricingDetails": {
"__typename": "AppRecurringPricing"
}
}
},
{
"id": "gid://shopify/AppSubscriptionLineItem/4028497976?v=1&index=1",
"plan": {
"pricingDetails": {
"__typename": "AppUsagePricing"
}
}
}
]
}
}
},
...
}
Create a usage record
After you've created the usage pricing plan and the merchant has accepted the plan, you can create a usage record. The usage record needs to include the line item ID of the app subscription returned by the appSubscriptionCreate
mutation.
mutation {
appUsageRecordCreate(
subscriptionLineItemId: "gid://shopify/AppSubscriptionLineItem/4019585080?v=1&index=0"
description: "Super Mega Plan 1000 emails",
price:{ amount: 1.00, currencyCode: USD}
) {
userErrors {
field
message
}
appUsageRecord {
id
}
}
}
JSON response:
The mutation returns the app usage record ID for the created usage record.
{
"data": {
"appUsageRecordCreate": {
"userErrors": [],
"appUsageRecord": {
"id": "gid://shopify/AppUsageRecord/14518231"
}
}
},
...
}
Implement the AppCredit resource
To create an app credit, you can use the appCreditCreate
mutation:
mutation {
appCreditCreate(
description: "application credit"
amount: { amount: 5.00, currencyCode: USD}
) {
userErrors {
field
message
}
appCredit {
id
}
}
}
JSON response:
In the event that the credit exceeds the shop credit issue limit or pending receivable credit issue limit, then the appropriate error message is returned.
{
"data": {
"appCreditCreate": {
"userErrors": [
{
"field": null,
"message": "Amount exceeded 30 day shop credit issue limit and Amount exceeded pending receivable credit issue limit"
}
],
"appCredit": null
}
},
...
}
Where to go from here
Learn how to manage subscription-based billing.