Introducing our brand new Rules Engine —
Read the docs
LogoLogo
Core APIOther APIsChangelog
How-tos
How-tos
  • Introduction
  • Product discovery
    • Product listing page
    • Product page
  • Placing orders
    • Shopping cart
      • Creating a shopping cart
      • Adding products to cart
      • Updating cart quantities
      • Removing products from cart
      • Displaying the cart summary
    • Checkout
      • Adding the customer
      • Adding a billing address
      • Adding a shipping address
      • Selecting a shipping method
      • Selecting a payment method
      • Adding a payment source
      • Adding a gift card or coupon
      • Placing the order
    • Subscriptions
      • Configuring a subscription model
      • Selecting the source order
      • Generating the subscriptions
      • Updating the subscriptions
    • Payments
      • Adyen
        • Adding the payment source
        • Sending back the payment details
        • Configuring the notification webhooks
        • Reusing the payment source
      • Axerve
        • Adding the payment source
        • Updating the payment intent
      • Braintree
        • Adding the payment source
        • Sending back the payment method nonce
        • Accepting local payments
        • Reusing the payment source
      • Checkout.com
        • Adding the payment source
        • Getting the payment details
        • Refreshing pending transactions
        • Reusing the payment source
      • Klarna
        • Adding the payment source
        • Sending back the authorization token
        • Reusing the payment source
      • PayPal
        • Adding the payment source
        • Preparing the payment for execution
      • Stripe
        • Adding the payment source
        • Refreshing the payment source
        • Reusing the payment source
      • Manual payments
        • Adding a wire transfer payment source
      • External payments
        • Adding the payment source
        • Reusing the payment source
    • Auto-capture
      • Enabling the auto-capture
      • Limiting the auto-capture amount
  • inventory
    • Inventory strategies
      • No split
      • Split shipments
      • Split by line items
      • Ship from first available (or primary)
      • Ship from primary
  • FAQ
    • Environments and initial setup
    • Authentication and access tokens
On this page
  • Problem
  • Solution
  • Example
  • Additional notes
  • How automatic subscription generation works
  • Managing failed subscriptions
  • Notifying upcoming subscriptions
  • More to read
  1. Placing orders
  2. Subscriptions

Generating the subscriptions

How to trigger the subscription generation based on the source order and the subscription model configuration

PreviousSelecting the source orderNextUpdating the subscriptions

Last updated 1 year ago

Problem

You have , setting the allowed subscription frequencies and choosing the subscription strategy. You also have containing some line items with frequency from which to start generating the subscriptions and placed it. You now want to trigger the subscription generation.

Solution

To start generating the subscription from a placed source order, send a PATCH request to the /api/orders/:id endpoint setting the _create_subscriptions attribute to true.

Make sure to start the subscription generation upon/after the order placement, otherwise no order subscription will be generated even if the source order contains some line items with frequency.

Example

The following request generates the subscriptions from the source order identified by the "NgojhelVGm" ID:

curl -g -X PATCH \
  'https://yourdomain.commercelayer.io/api/orders/NgojhelVGm' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Accept: application/vnd.api+json' \
  -H 'Content-Type: application/vnd.api+json' \
  -d '{
    "data": {
      "type": "orders",
      "id": "NgojhelVGm",
      "attributes": {
        "_create_subscriptions": true
      }
    }
  }'

On success, the API responds with a 200 OK status code, returning the updated order object:

{
  "data": {
    "id": "NgojhelVGm",
    "type": "orders",
    "links": {
      "self": "https://yourdomain.commercelayer.io/api/orders/NgojhelVGm"
    },
    "attributes": {
      "number": 35589030,
      "autorefresh": true,
      "status": "placed",
      "payment_status": "authorized",
      "fulfillment_status": "unfulfilled",
      "guest": false,
      "editable": false,
      "customer_email": "bob@example.com",
      "language_code": "en",
      "currency_code": "USD",
      "tax_included": false,
      "tax_rate": null,
      "freight_taxable": null,
      "requires_billing_info": false,
      "country_code": "US",
      "shipping_country_code_lock": null,
      "coupon_code": null,
      "gift_card_code": null,
      "gift_card_or_coupon_code": null,
      "subtotal_amount_cents": 13249,
      "subtotal_amount_float": 132.49,
      "formatted_subtotal_amount": "$132.49",
      "shipping_amount_cents": 0,
      "shipping_amount_float": 0.0,
      "formatted_shipping_amount": "$0.00",
      "payment_method_amount_cents": 0,
      "payment_method_amount_float": 0.0,
      "formatted_payment_method_amount": "$0.00",
      "discount_amount_cents": 0,
      "discount_amount_float": 0.0,
      "formatted_discount_amount": "$0.00",
      "adjustment_amount_cents": 0,
      "adjustment_amount_float": 0.0,
      "formatted_adjustment_amount": "$0.00",
      "gift_card_amount_cents": 0,
      "gift_card_amount_float": 0.0,
      "formatted_gift_card_amount": "$0.00",
      "total_tax_amount_cents": 0,
      "total_tax_amount_float": 0.0,
      "formatted_total_tax_amount": "$0.00",
      "subtotal_tax_amount_cents": 0,
      "subtotal_tax_amount_float": 0.0,
      "formatted_subtotal_tax_amount": "$0.00",
      "shipping_tax_amount_cents": 0,
      "shipping_tax_amount_float": 0.0,
      "formatted_shipping_tax_amount": "$0.00",
      "payment_method_tax_amount_cents": 0,
      "payment_method_tax_amount_float": 0.0,
      "formatted_payment_method_tax_amount": "$0.00",
      "adjustment_tax_amount_cents": 0,
      "adjustment_tax_amount_float": 0.0,
      "formatted_adjustment_tax_amount": "$0.00",
      "total_amount_cents": 13249,
      "total_amount_float": 132.49,
      "formatted_total_amount": "$132.49",
      "total_taxable_amount_cents": 13249,
      "total_taxable_amount_float": 132.49,
      "formatted_total_taxable_amount": "$132.49",
      "subtotal_taxable_amount_cents": 13249,
      "subtotal_taxable_amount_float": 132.49,
      "formatted_subtotal_taxable_amount": "$132.49",
      "shipping_taxable_amount_cents": 0,
      "shipping_taxable_amount_float": 0.0,
      "formatted_shipping_taxable_amount": "$0.00",
      "payment_method_taxable_amount_cents": 0,
      "payment_method_taxable_amount_float": 0.0,
      "formatted_payment_method_taxable_amount": "$0.00",
      "adjustment_taxable_amount_cents": 0,
      "adjustment_taxable_amount_float": 0.0,
      "formatted_adjustment_taxable_amount": "$0.00",
      "total_amount_with_taxes_cents": 13249,
      "total_amount_with_taxes_float": 132.49,
      "formatted_total_amount_with_taxes": "$132.49",
      "fees_amount_cents": 0,
      "fees_amount_float": 0.0,
      "formatted_fees_amount": "$0.00",
      "duty_amount_cents": null,
      "duty_amount_float": null,
      "formatted_duty_amount": null,
      "skus_count": 5,
      "line_item_options_count": 0,
      "shipments_count": 1,
      "tax_calculations_count": 0,
      "payment_source_details": {
        "type": "stripe_payment",
        "payment_method_id": "pm_1MoVlPJG2nIhpilUloZdYYXx",
        "payment_method_type": "card",
        "payment_method_details": {
          "brand": "visa",
          "last4": "4242",
          "checks": {
            "cvc_check": "pass",
            "address_line1_check": "pass",
            "address_postal_code_check": "pass"
          },
          "wallet": null,
          "country": "US",
          "funding": "credit",
          "exp_year": 2034,
          "networks": {
            "available": [ "visa" ],
            "preferred": null
          },
          "exp_month": 12,
          "fingerprint": "5YQL9g2QjCF96IJS",
          "generated_from": null,
          "three_d_secure_usage": {
              "supported": true
          }
        }
      },
      "token": "t0k3N0d6984d36e330c002862d91XXx",
      "cart_url": null,
      "return_url": null,
      "terms_url": null,
      "privacy_url": null,
      "checkout_url": "https://your-checkout-url/NgojhelVGm",
      "placed_at": "2023-03-22T17:47:57.794Z",
      "approved_at": null,
      "cancelled_at": null,
      "payment_updated_at": "2023-03-22T17:47:57.230Z",
      "fulfillment_updated_at": null,
      "refreshed_at": "2023-03-22T17:43:54.246Z",
      "archived_at": null,
      "expires_at": null,
      "subscription_created_at": "2023-03-22T17:56:38.199Z",
      "created_at": "2023-03-22T16:01:44.159Z",
      "updated_at": "2023-03-22T17:47:57.804Z",
      "reference": "",
      "reference_origin": "",
      "metadata": {}
    },
    "relationships": {
      "market": { ... },
      "customer": { ... },
      "shipping_address": { ... },
      "billing_address": { ... },
      "available_payment_methods": { ... },
      "available_customer_payment_sources": { ... },
      "available_free_skus": { ... },
      "available_free_bundles": { ... },
      "payment_method": { ... },
      "payment_source": { ... },
      "line_items": { ... },
      "shipments": { ... },
      "transactions": { ... },
      "authorizations": { ... },
      "captures": { ... },
      "voids": { ... },
      "refunds": { ... },
      "returns": { ... },
      "order_subscriptions": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/orders/NgojhelVGm/relationships/order_subscriptions",
          "related": "https://yourdomain.commercelayer.io/api/orders/NgojhelVGm/order_subscriptions"
        }
      },
      "order_factories": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/orders/NgojhelVGm/relationships/order_factories",
          "related": "https://yourdomain.commercelayer.io/api/orders/NgojhelVGm/order_factories"
        }
      },
      "order_copies": { ... },
      "recurring_order_copies": {
        "links": {
          "self": "https://yourdomain.commercelayer.io/api/orders/NgojhelVGm/relationships/recurring_order_copies",
          "related": "https://yourdomain.commercelayer.io/api/orders/NgojhelVGm/recurring_order_copies"
        }
      },
      "attachments": { ... },
      "events": { ... }
    },
    "meta": {
      "mode": "test",
      "organization_id": "EnAvaFOrRe"
    }
  }
}

Additional notes

How automatic subscription generation works

  • For each automatically generated order subscription, some source order information is copied (e.g. addresses, customer payment source, etc.), the related order subscription items are created and associated with the order subscriptions, and the target order is placed at the scheduled time using the saved customer payment source (if still valid).

During an automatic order subscription generation, the source order is never reused to generate any next runs, which are built on top of the associated order subscription and related order subscription items only.

Which and how many order subscriptions and order subscription items are generated depends on the subscription strategy and source order's line items.

Order subscriptions

  • by_frequency — as many order subscriptions as the different frequencies specified for the source order’s line items are generated, each with the related order subscription items (default strategy).

  • by_line_items — an order subscription is generated for any source order’s line item that has a frequency, each with the related order subscription item.

Order subscription items

  • by_frequency — for each automatically generated order subscription as many order subscription items as the source order’s line items that have that specific frequency are generated.

  • by_line_items — for each automatically generated order subscription a single order subscription item is generated.

Example

Let's look at the source order we used throughout this guide:

The following request fetches the source order, requesting some basic fields and including the line items to check their frequency:

curl -g -X GET \
  'http://yourdomain.commercelayer.io/api/orders/NgojhelVGm?include=line_items&fields[orders]=number,customer_email,formatted_total_amount_with_taxes,skus_count&fields[line_items]=name,sku_code,quantity,formatted_unit_amount,formatted_total_amount,frequency' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Accept: application/vnd.api+json'

On success, the API responds with a 200 OK status code, returning the source order object with the requested fields and included items:

{
  "data": {
    "id": "NgojhelVGm",
    "type": "orders",
    "links": { ... },
    "attributes": {
      "number": 35589030,
      "customer_email": "bob@example.com",
      "formatted_total_amount_with_taxes": "$132.49",
      "skus_count": 5
    },
    "meta": { ... }
  },
  "included": [
    {
      "id": "yDBVtlPZWw",
      "type": "line_items",
      "links": { ... },
      "attributes": {
        "sku_code": "LENSPACKL125",
        "quantity": 1,
        "formatted_unit_amount": "$39.90",
        "formatted_total_amount": "$39.90",
        "name": "Pack of 30 lenses -1.25",
        "frequency": "monthly"
      },
      "meta": { ... }
    },
    {
      "id": "kJbZtLlxKQ",
      "type": "line_items",
      "links": { ... },
      "attributes": {
        "sku_code": "LENSPACKR075",
        "quantity": 1,
        "formatted_unit_amount": "$39.99",
        "formatted_total_amount": "$39.99",
        "name": "Pack of 30 lenses -0.75",
        "frequency": "monthly"
      },
      "meta": { ... }
    },
    {
      "id": "vRrYtlbGmx",
      "type": "line_items",
      "links": { ... },
      "attributes": {
        "sku_code": "RAZRFILLPACK4",
        "quantity": 2,
        "formatted_unit_amount": "$14.90",
        "formatted_total_amount": "$29.80",
        "name": "4-Pack Razorblade Refill",
        "frequency": "weekly"
      },
      "meta": { ... }
    },
    {
      "id": "NYEAtLObAd",
      "type": "line_items",
      "links": { ... },
      "attributes": {
        "sku_code": "MUGXXXAUFFFFFF00000011OZ",
        "quantity": 1,
        "formatted_unit_amount": "$22.80",
        "formatted_total_amount": "$22.80",
        "name": "White Glossy Mug with Black Logo (11OZ)",
        "frequency": null
      },
      "meta": { ... }
    }
  ]
}

As you can see inspecting the above response it contains 4 line items of type skus for a total of 5 SKUs:

  • 2 SKUs with monthly frequency (both with quantity 1 — SKU codes LENSPACKL125 and LENSPACKR075)

  • 1 SKU with weekly frequency (with quantity 2 and SKU code RAZRFILLPACK4)

  • 1 SKU with no specified frequency (with quantity 1 and SKU code MUGXXXAUFFFFFF00000011OZ)

Based on the subscription strategy these are the subscriptions and subscription items that will be generated (remember that line items without frequency don't generate subscriptions):

By frequency

2 order subscriptions and 3 order subscription items:

  • 1 for the monthly frequency, associated with 2 order subscription items (SKU codes LENSPACKL125 and LENSPACKR075, both with quantity 1)

  • 1 for the weekly frequency, associated with 1 order subscription item (SKU code RAZRFILLPACK4 with quantity 2)

In this case, in terms of generated recurring target orders:

  • every month, 1 order with 2 line items of type skus will be placed (codes LENSPACKL125 and LENSPACKR075, both with quantity 1)

  • every week, 1 order with 1 line item of type skus will be placed (code RAZRFILLPACK4 with quantity 2)

By line items

3 order subscriptions and 3 order subscription items

  • 1 for the LENSPACKL125 line item, associated with 1 order subscription item (with quantity 1 and frequency monthly)

  • 1 for the LENSPACKR075 line item, associated with 1 order subscription item (with quantity 1 and frequency monthly)

  • 1 for the RAZRFILLPACK4 line item, associated with 1 order subscription item (with quantity 2 and frequency weekly)

In this case, in terms of generated recurring target orders:

  • every month 2 orders with 1 line item of type skus will be placed (one for the product with code LENSPACKL125, the other for the product with code LENSPACKR075, both with quantity 1)

  • every week 1 order with 1 line item of type skus will be placed (code RAZRFILLPACK4 with quantity 2)

The generated recurring target orders cannot be used as source orders from which to trigger a new subscription generation.

You can check the generated order subscriptions and related order subscription items in the Subscriptions section of our admin dashboard, or via API by sending a GET request to the /api/order_subscriptions endpoint, filtered by the source order ID with order subscription items included (the following request is related to the by_frequency example above):

The following request fetches all the order subscriptions associated with the customer identified by the "nDNahABVZR" ID and generated by the source order identified by the "NgojhelVGm" ID, including the related order subscription items:

curl -g -X GET \
  'http://yourdomain.commercelayer.io/api/customers/nDNahABVZR/order_subscriptions?filter[q][source_order_id_eq]=NgojhelVGm&include=order_subscription_items' \
  -H 'Authorization: Bearer your-access-token' \
  -H 'Accept: application/vnd.api+json'

On success, the API responds with a 200 OK status code, returning a paginated collection of the order subscription objects that match the filter query, including the related order subscription items:

{
  "data": [
    {
      "id": "RkRGoFmRyp",
      "type": "order_subscriptions",
      "links": { ... },
      "attributes": {
        "number": "820",
        "status": "active",
        "frequency": "monthly",
        "activate_by_source_order": true,
        "customer_email": "bob@example.com",
        "starts_at": "2023-03-22T17:56:38.137Z",
        "expires_at": null,
        "next_run_at": "2023-04-22T17:56:00.000Z",
        "occurrencies": 0,
        "errors_count": 0,
        "succeeded_on_last_run": true,
        "options": {
          "place_target_order": true,
          "activate_by_source_order": true
        },
        "created_at": "2023-03-22T17:56:38.140Z",
        "updated_at": "2023-03-22T17:56:38.153Z",
        "reference": null,
        "reference_origin": null,
        "metadata": {}
      },
      "relationships": {
        "market": { ... },
        "subscription_model": { ... },
        "source_order": { ... },
        "customer": { ... },
        "customer_payment_source": { ... },
        "order_subscription_items": {
          "links": { ... },
          "data": [
            {
              "type": "order_subscription_items",
              "id": "WMNdKqFqnd"
            },
            {
              "type": "order_subscription_items",
              "id": "qZzPwPFYNa"
            }
          ]
        },
        "order_factories": { ... },
        "order_copies": { ... },
        "recurring_order_copies": { ... },
        "orders": { ... },
        "events": { ... }
      },
      "meta": { ... }
    },
    {
      "id": "xPwDMFYljK",
      "type": "order_subscriptions",
      "links": { ... },
      "attributes": {
        "number": "821",
        "status": "active",
        "frequency": "weekly",
        "activate_by_source_order": true,
        "customer_email": "bob@example.com",
        "starts_at": "2023-03-22T17:56:38.184Z",
        "expires_at": null,
        "next_run_at": "2023-03-29T17:56:00.000Z",
        "occurrencies": 0,
        "errors_count": 0,
        "succeeded_on_last_run": true,
        "options": {
          "place_target_order": true,
          "activate_by_source_order": true
        },
        "created_at": "2023-03-22T17:56:38.186Z",
        "updated_at": "2023-03-22T17:56:38.193Z",
        "reference": null,
        "reference_origin": null,
        "metadata": {}
      },
      "relationships": {
        "market": { ... },
        "subscription_model": { ... },
        "source_order": { ... },
        "customer": { ... },
        "customer_payment_source": { ... },
        "order_subscription_items": {
          "links": { ... },
          "data": [
            {
              "type": "order_subscription_items",
              "id": "adkLKwFVzG"
            }
          ]
        },
        "order_factories": { ... },
        "order_copies": { ... },
        "recurring_order_copies": { ... },
        "orders": { ... },
        "events": { ...}
      },
      "meta": { ... }
    }
  ],
  "included": [
    {
      "id": "WMNdKqFqnd",
      "type": "order_subscription_items",
      "links": { ... },
      "attributes": {
        "quantity": 1,
        "unit_amount_cents": 3990,
        "unit_amount_float": 39.9,
        "formatted_unit_amount": "$39.90",
        "total_amount_cents": 3990,
        "total_amount_float": 39.9,
        "formatted_total_amount": "$39.90",
        "created_at": "2023-03-22T17:56:38.171Z",
        "updated_at": "2023-03-22T17:56:38.171Z",
        "reference": null,
        "reference_origin": null,
        "metadata": {}
      },
      "relationships": {
        "order_subscription": { ... },
        "item": { ... }
      },
      "meta": { ... 
    },
    {
      "id": "qZzPwPFYNa",
      "type": "order_subscription_items",
      "links": { ... },
      "attributes": {
        "quantity": 1,
        "unit_amount_cents": 3999,
        "unit_amount_float": 39.99,
        "formatted_unit_amount": "$39.99",
        "total_amount_cents": 3999,
        "total_amount_float": 39.99,
        "formatted_total_amount": "$39.99",
        "created_at": "2023-03-22T17:56:38.182Z",
        "updated_at": "2023-03-22T17:56:38.182Z",
        "reference": null,
        "reference_origin": null,
        "metadata": {}
      },
      "relationships": {
        "order_subscription": { ... },
        "item": { ... }
      },
      "meta": { ... }
    },
    {
      "id": "adkLKwFVzG",
      "type": "order_subscription_items",
      "links": { ... },
      "attributes": {
        "quantity": 2,
        "unit_amount_cents": 1490,
        "unit_amount_float": 14.9,
        "formatted_unit_amount": "$14.90",
        "total_amount_cents": 2980,
        "total_amount_float": 29.8,
        "formatted_total_amount": "$29.80",
        "created_at": "2023-03-22T17:56:38.198Z",
        "updated_at": "2023-03-22T17:56:38.198Z",
        "reference": null,
        "reference_origin": null,
        "metadata": {}
      },
      "relationships": {
          "order_subscription": { ... },
          "item": { ... }
      },
      "meta": { ... }
    }
  ],
  "meta": {
    "record_count": 2,
    "page_count": 1
  },
  "links": {
    "first": "https://yourdomain.commercelayer.io/api/order_subscriptions?filter[q][source_order_id_eq]=NgojhelVGm&include=order_subscription_items&page[number]=1&page[size]=10",
    "last": "https://yourdomain.commercelayer.io/api/order_subscriptions?filter[q][source_order_id_eq]=NgojhelVGm&include=order_subscription_items&page[number]=1&page[size]=10"
  }
}

Managing failed subscriptions

The order_subscriptions.last_run_succeeded event is available as well.

Notifying upcoming subscriptions

The renewal alert period must be expressed in hours (e.g. if you want to send the notification 3 days before, set it to 72). The minimum value is 1.

More to read

The automatic order subscription generation process is triggered manually by using a specific attribute. The necessary order subscriptions are automatically generated ’s line item for which you’ve specified a frequency, accordingly to the strategy set .

The source order’s customer email is stored, that order is considered the subscription's first run, and the generated order subscriptions are activated (unless differently specified by setting the auto_activate attribute to true).

You can track subscriptions' renewal failures by activating a listening for the order_subscriptions.last_run_failed event and acting accordingly (e.g. setting up an automatic notification system for the customer).

You can notify customers about upcoming recurring orders associated with subscriptions by properly setting the renewal_alert_period attribute at the order subscription level and leveraging the order_subscriptions.renewal event that will be fired accordingly.

See our API reference if you need more information on how to and , , , , or about how and work.

associated a subscription model with your market
selected a source order
based on the source order
at the subscription model level
webhook
webhook
filter data
include associations
fetch relationships
retrieve
update an order
order subscriptions
order subscription items
at the subscription model level