1. Introduction
  2. Glossary
  3. How it works
    1. Subscription event lifecycle
    2. License Validation flow
    3. License provisioning flow
  4. Infrastructure API
  5. HTTP API
    1. Authentication
    2. Requesting test webhooks
    3. Supporting endpoints

Introduction

The Store Licensing API enables WordPress plugin/theme vendors to get licensing information for their products sold through WordPress.com. If you are a vendor interested in selling your products through WordPress.com, please reach us through https://wordpress.com/partners/.

If you are already onboarded, you need to integrate with the Store Licensing API so that you show your product as licensed in customer WP Admin and unlock all of their functionalities.

Glossary

  • Vendor - Plugin or theme developer partnering with WordPress.com to sell their product through the WordPress.com store.
  • Vendor product - The plugin or theme code.
  • Subscription - Each vendor product is related to a subscription that is added to the customer site and it renews on a specific billing cycle. It can be monthly or annual.
  • Customer - Site owner who purchased the subscription.
  • Subscription event - Subscription creation, refund, cancellation, renewal, and domain change are supported events.
  • Vendor systems - Infrastructure the vendor uses to verify vendor product licenses.

How it works

WordPress.com handles all the billing ( the subscription purchase, renewal, refund, cancelation ) as also the installation, activation, and removal of the vendor product upon subscription events. The vendor needs to listen to these events to provision or update a license in the vendor systems.

Subscription event lifecycle

  1. After each subscription event, WordPress.com sends a webhook to the webhook URL you have registered when submitting the product.
  2. This webhook contains all the information regarding the event that triggered it, the site, the vendor product, and the subscription dates.
  3. Vendor systems should receive this webhook and immediately return 200 OK. Webhooks failing to be received will be retried a certain amount of times - not indefinitely.
  4. Upon webhook being received, the vendor should take all necessary actions in the vendor systems like:
    • Account creation
    • License provisioning
    • License update
Webhook sent

License Validation flow

The vendor's product should require license status from the Vendor systems and preferably cache the response locally ( in Site WP Options ).

License validation through WP Options

In case of vendor systems don't have the related license info ( eg the webhook is missed ), the vendor can request the subscription information from find subscription API and update their systems accordingly. This API is regarded as the source of truth.

License full validation through calling APIs

License provisioning flow

WordPress.com offers an optional licensing provisioning flow that intermediates the communication between a vendor back-end and a customer site, without the vendor to have to implement an authentication layer.

A provision flow starts from the provision_license webhook that's triggered when a purchase is made and the software is installed on a target site. The purpose of this webhook event is to request a new licensing payload from the vendor API.

After the request is made, the response containing the license payload received from the vendor API request will then be pushed to the customer's site where a wpcom_marketplace_webhook_response_$product_slug filter will be triggered locally.

The purpose of this filter is to allow vendors to execute their own licensing logic on a customer site for a given product that was purchased on WordPress.com.

A basic implementation of this filter can be observed below:

function activate_product_license_for_acme_product( bool $result, array $license_payload, string $event_type ) {
    if ( 'provision_license' !== $event_type ) {
        return $result;
    }
    // Plugin license activation logic
}

add_filter( 'wpcom_marketplace_webhook_response_acme_product', 'activate_product_license_for_acme_product', 10, 3 );

To get a better understanding of the license provision flow, please check the below diagram:


Infrastructure API

1.get_option( 'wpcom_active_subscriptions', array() )['my-plugin-slug'] will return

stdClass Object
(
    [product_slug] => my-plugin-slug
    [product_id] => 915
    [subscribed_date] => 2022-05-02T09:10:52+00:00
    [expiry_date] => 2022-04-02T00:00:00+00:00
    [ownership_id] => 32646841
)

Only active subscriptions are returned.

2.If is needed you can check out to find out if the product is running within the WordPress.com context

if ( defined( 'IS_ATOMIC' ) && IS_ATOMIC && defined( 'ATOMIC_CLIENT_ID' )  && '2' === ATOMIC_CLIENT_ID ) {
  ...
}

HTTP API

Authentication

Each endpoint requires authentication via access tokens. Currently, you need to contact us to get an access token. The access token is issued to a specific WordPress.com user who should be the same user who logs in to WooCommerce.com and submits the product.

To secure your vendor API requests, every webhook request contains an Authorization header with your vendor access token.

Requesting test webhooks

We have built an API that vendors can input all necessary details and request test webhooks. These webhook responses do not use production data. They return test data with the correct schema and format. You can find the relative endpoint in the Webhook API.

Supporting endpoints

For your convenience there are two supporting endpoints:

  1. /subscriptions/{ownership_id} will return a specific subscription. While subscriptions are uniquely identified by the combination of the domain and product_slug there are chances that the domain changes and you might miss the related webhook. The ownership_id is included in the initial subscription_created webhook and can be used for subsequent calls to get subscription status if needed.
  2. /subscriptions will return a list of active subscriptions.
  3. /subscriptions/{wpcom_site}/{product_slug} will return a specific subscription for the product_slug provided.