Skip to main content

Core Shopify Subscriptions Reference app components


The application is using metaobjects and a sqlite database with Prisma for data persistence.

  • Metaobjects are used to store shop-specific data such as application settings.
  • Prisma is used to store cross-shop data such as billing schedules.

Anchor to Metaobjects as shop-specific data persistenceMetaobjects as shop-specific data persistence

Metaobjects are custom data structures that your app can define and create to store your app's information. In the application, metaobjects are used to persist shop-specific data, so to delegate the responsibility of data persistence to Shopify, allowing for a flexible data schema. This approach also allows for robust data access, as the application doesn't need to know about the infrastructure used to persist the data, and Shopify takes care of the scalability and reliability of the data.

In the application, metaobject data access is managed using the MetaobjectRepository. The repository has no knowledge of the metaobject's schema or the application's domain, and only knows how to access the metaobject's data. It can be used to create, read, update, and delete metaobjects of any shapes. Any data access for shop-specific data can easily be found by finding references to the repository.

An example of how metaobjects are used in the application is to store the application settings for each shop. To understand how it is used to create the shop specific application settings after authentication, see the createSettingsMetaobject function. The function uses the metaobject repository to create the metaobject for the shop and is responsible for creating its schema.

The metaobject repository can also be used to update a metaobject's schema using the createOrUpdateMetaobjectDefinition function. The EnqueueAddFieldsToMetaobjectJob and AddFieldsToMetaobjectJob are examples of how the function can be leveraged to add new fields in a background job.

Metaobjects are a powerful data persistence mechanism that can be used to store any information needed by applications. For more information, see metaobjects.


The application uses webhooks to handle events from Shopify. Visit the webhooks documentation to learn more.


This app includes a custom Job Runner to schedule and run background jobs. See the Job Runner readme for more info. By default, this application is configured to use an inline scheduler, but it also comes with a Google Cloud Tasks scheduler. You can opt to use Google Cloud scheduler by changing the jobs setting in the config/index.ts file.


Anchor to Automatic re-billing of subscription contractsAutomatic re-billing of subscription contracts

In the application, a job scheduler is used to manage and automate the execution of subscription-related tasks on Shopify. For instance, a job is defined to run every hour to find shops that should be billed. Then that job calls subscriptionBillingCycleBulkCharge to bill contracts on each shop. The scheduler enqueues the following billing actions:

  • RecurringBillingChargeJob

  • RecurringBillingReminderJob

  • RebillSubscriptionJob

    These recurring jobs handle billing for subscription contracts.


In the application, dunning handles the process of retrying failed billing attempts. When a billing attempt fails, the application checks if it is the final attempt. Based on this, the system decides whether to initiate another billing attempt in the future and notify the buyer via email. If it is the final attempt, the application will notify both the merchant and the buyer via email and update the contracts according to the actions specified in the application settings.

A diagram showing the dunning flow of the Subscriptions app.

This application is not configured to send customer or merchant emails, but the logic for when to send the emails is in place. You can plug in your own email service to CustomerSendEmailService and MerchantSendEmailService.


The app can handle billing attempt failures due to inventory problems. When a billing attempt fails due to inventory, the app displays an error on the billing attempt and notify the merchant. The error can be ignored, and the billing attempt can be retried or skipped.

Dunning is also performed as per usual, with the only difference being that it checks the user's inventory settings.

The application also has a view specifically designed to display all subscription contracts that have failed due to inventory errors:

An image of the subscription contract inventory error view.

Learn more about subscription extensions.


Was this page helpful?