> For the complete documentation index, see [llms.txt](https://docs.commercelayer.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.commercelayer.io/core-api-reference/order_subscriptions.md).

# Order subscriptions

Order subscriptions allow repeating a given source order according to a specified frequency: smaller is `hourly`, larger is `yearly`. If you need a custom frequency that is not in the list of allowed values, you can use a [crontab expression](https://crontab.guru/).

Order subscriptions can be generated [automatically](#automatic-order-subscription-generation) from the [line items](/core-api-reference/line_items.md#choosing-line-items-that-generate-subscriptions) that have a frequency using a trigger attribute at the [order](/core-api-reference/orders.md#automatic-subscriptions-generation) level (in this case [recurring order copies](/core-api-reference/recurring_order_copies.md) are used as the order factory that generates the target orders) or [manually](#manual-order-subscription-generation) (in this case the process usually leverages [order copies](/core-api-reference/order_copies.md)). You can turn an existing manual order subscription into an automatic one by sending the `_convert` trigger attribute, provided that you previuosly defined a subscription model for the associated market.

To suspend or cancel an order subscription you can use the `_deactivate` and `_cancel` trigger attributes.

Currently, order subscriptions have no retry policy: in case, for any reason, the order copy fails, the `errors_count` counter is incremented, but the subscription is kept `active` (unless expired, deactivated, moved to `pending`, or `cancelled`). As soon as the order copy process starts the order subscription status is moved to `running` and moved back to `active` once the process is successfully completed.

{% hint style="info" %}
The one exception is a renewal failure caused by the payment method's saved wallet no longer being available — [see below](#handling-missing-saved-wallets) for more information.
{% endhint %}

It is possible to check the `succeeded_on_last_run` attribute to inspect subscription last run state: if `false`, you can inspect the last associated `recurring_order_copy` or `order_copy` to fix any missing/bad data.

You can attach [webhooks](/core/real-time-webhooks.md#supported-events) on order subscriptions, recurring order copies, and order copies events, to act promptly in case something unexpected happens. You can also set the `renewal_alert_period` attribute (expressed in **hours** — the minimum value is `1`, the maximum value is `720` e.g. **30 days**) so that the related webhook event is fired accordingly and you can send customers a notification about upcoming recurring orders associated with subscriptions.

## Handling missing saved wallets

A subscription is meant to reuse the customer's saved payment method at every renewal. That saved method — a wallet — only exists if the source order's payment source both supports reuse and actually has one attached, which isn't guaranteed: the customer may not have opted into saving it, or, for some gateways, the saved-method confirmation arrives asynchronously after the order is placed.

To surface this instead of letting it fail silently, whenever a subscription would become `active`, it's checked: if its payment method requires a saved wallet and none is available, the subscription moves to `pending` instead, and a dedicated `order_subscriptions.pending` webhook event is fired. The same check also runs whenever a scheduled renewal fails: if the failure is due to no usable wallet, the subscription is moved to `pending` right away rather than quietly waiting for its next scheduled attempt. Its renewal schedule is left untouched by this (`next_run_at` and `scheduled_run_at` are properties of the subscription's cadence, not of whether a given attempt could be paid for), so a subscription that later recovers resumes on its already-scheduled next run rather than jumping to the current time.

{% hint style="info" %}
This check applies only when Commerce Layer places the renewal order. In that case, Commerce Layer needs a chargeable wallet. If a subscription does not automatically place its target order, the wallet check is skipped. You place and capture each renewal outside Commerce Layer. The subscription then activates and renews normally, whether or not a saved wallet exists.
{% endhint %}

Pending subscriptions aren't a dead end: they can still be deactivated or cancelled like any other subscription, and re-sending the `_activate` trigger attribute re-runs the same wallet check. As soon as a wallet becomes available (the saved-method confirmation arrives, or one is attached manually), activating resolves the subscription back to `active`, with no separate recovery flow needed: the same step handles recovery whether the subscription never activated or lost its wallet mid-life.

{% hint style="info" %}
Subscriptions with a payment method that doesn't require a saved wallet, with no payment method at all (e.g. fully covered by promotions or gift cards), or with `place_target_order` set to `false`, are unaffected by this check and continue to activate and renew exactly as before.
{% endhint %}

## Automatic order subscription generation

To automatically generate order subscriptions based on a source order's line items with frequency you need to associate a [subscription model](/core-api-reference/subscription_models.md) with your market. The source order is considered the subscription's first run, some of its information is copied (e.g. addresses, customer payment source, etc.), the involved [order subscription items](/core-api-reference/order_subscription_items.md) are created and associated with the generated order subscriptions, and — upon successful recurring order copy — the target order is placed using the saved customer payment source (if still valid).

In between each run you can edit the subscription (e.g. changing its frequency, expiration date, status etc.) to dynamically manage the next occurrences.

By default, automatically generated order subscriptions are directly activated, unless [differently specified](/core-api-reference/subscription_models.md#automatic-subscription-activation-and-cancellation) at the subscription model level — or unless the source order's payment method requires a saved wallet that isn't available yet, [in which case](#handling-missing-saved-wallets) the subscription lands in `pending` instead.

{% hint style="warning" %}
When changing the subscription's frequency make sure to also manually update the `next_run_at` attribute with the correct time in the future, otherwise the next subscription run couldn't happen when expected.
{% endhint %}

## Manual order subscription generation

When manually creating an order subscription both types of [order factories](/core-api-reference/order_factories.md) can be used.

### Using order copies

If no subscription model is associated with the market, manually created order subscriptions — simply based on a source order that not contains any line items with frequency — rely on order copies to create recurring orders. In this case, all the source order's information and line items are cloned into the target order, according to the frequency set for the order subscription. An attempt to place the copied order is done at the end of the process. You can set the `place_target_order` option as `false` at creation time if you prefer to place created orders manually.

By default, manually generated order subscriptions activate from a `placed` source order, which is considered the subscription's first run. In this case, the subscription is marked as `active` — or, if `place_target_order` is `true` and its payment method requires a saved wallet that [isn't available yet](#handling-missing-saved-wallets), `pending` — and the next run will be scheduled on the current timestamp. If you want full control over the order subscription, you can specify the `activate_by_source_order` option as `false` at creation time. This way, you are not limited to placed source orders (source order status isn't checked), but must define manually the `starts_at` time (`expires_at` time is optional). Also, remember to use the `_activate` attribute to activate the subscription, otherwise it will miss the next run.

### Using recurring order copies

Order subscriptions that rely on recurring order copies can be created manually too (e.g. if you need to generate subscriptions for some source order's line items only). In this case, you need to set also the relationship with an existing subscription model and a source order, create and associate the order subscription items, and specify the customer payment source.

<details>

<summary>Data model</summary>

Check the related [ER diagram](/data-model/orders/subscriptions-and-order-copies.md) and explore the flowchart that illustrates how the order subscription resource relates to the other API entities.

</details>

<details>

<summary>How-to</summary>

Check the related [guide](/how-tos/placing-orders/subscriptions.md) to learn more about how to generate and automatic subscriptions from a source order.

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.commercelayer.io/core-api-reference/order_subscriptions.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
