> For the complete documentation index, see [llms.txt](https://docs.datajet-app.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.datajet-app.com/functions/functions.md).

# Functions

Functions let you run your own JavaScript **inside Shopify checkout**. Unlike scripts, which run on DataJet's infrastructure in response to events and schedules, functions are deployed to Shopify and executed by Shopify itself — synchronously, while the buyer is checking out. That makes them the right tool for rules that must be enforced before an order can be placed.

You manage functions in the **Functions Console** section of the app.

{% hint style="info" %}
Not to be confused with the Liquid [function](/liquid/tags/function.md) tag, which calls a reusable Liquid script from another script. This section is about Shopify checkout functions.
{% endhint %}

There are five categories of functions:

* [*Cart and Checkout Validation*](/functions/functions/cart-and-checkout-validation.md)*:* block checkout with custom error messages — order limits, address rules, customer restrictions and any other rule you can express in code.
* [*Delivery Customization*](/functions/functions/delivery-customization.md)*:* hide, rename or reorder the delivery options shown at checkout.
* [*Payment Customization*](/functions/functions/payment-customization.md)*:* hide, rename or reorder payment methods.
* [*Discounts*](/functions/functions/discounts.md)*:* apply automatic product and order discounts based on your own rules.
* [*Cart Transform*](/functions/functions/cart-transform.md)*:* merge cart lines into bundles, expand bundle SKUs, update line presentation (one per store).

### Functions vs. scripts

|               | Scripts                           | Functions                         |
| ------------- | --------------------------------- | --------------------------------- |
| Runs on       | DataJet's infrastructure          | Shopify's checkout infrastructure |
| Trigger       | Events, webhooks, schedules, HTTP | Every checkout, automatically     |
| Language      | Liquid                            | JavaScript                        |
| Can call APIs | Yes (graphql, http, rest…)        | No — sandboxed, input data only   |
| Purpose       | Automation and integrations       | Checkout rules and customization  |
| Credits       | Consume credits                   | Free — no credits used            |

### Creating a function

In the Functions Console, open a category folder and click **Add new**. You choose:

* **Title** — up to 100 characters; letters, numbers, spaces and `_-|[]` are allowed.
* **Family** — decides which checkout data your code receives as input. See [Families and Variables](/functions/functions/families-and-variables.md) for the full list. The family can't be changed after creation, so pick the one that covers the data your rule needs.
* **Run on** (validations only) — the checkout steps where your code executes: *Cart*, *Checkout interaction* and/or *Checkout completion*. The default is checkout interaction + completion.

New functions are created **turned off**, with starter code that documents the expected return shape for the category. Turn a function on from its menu in the tree, or with the Active toggle in the editor.

{% hint style="info" %}
The number of functions you can have active at the same time depends on your plan:

Development and sandbox stores get the full limit of 25 (Shopify's maximum). During the free trial you can activate 1 function. You can create and edit any number of functions — the limit only applies to turning them on.

Active discounts additionally count against Shopify's store-wide cap of 25 automatic discounts, shared with the discounts created outside DataJet.
{% endhint %}

| Plan          | Active functions |
| ------------- | ---------------- |
| Basic Plan    | —                |
| Advanced Plan | 1                |
| Pro Plan      | 5                |
| DataJet Plan  | 25               |

### Permissions

Managing functions requires additional access scopes (checkout validations, delivery customizations, payment customizations, discounts and cart transforms). If they haven't been granted yet, the Functions Console shows an **Additional permissions required** banner — click **Grant permissions** and approve the request.

### Writing code

Your code is a JavaScript **function body**. It receives two variables: `input`, containing the checkout data selected by the function's family, and `vars`, holding your [code variables](/functions/functions/families-and-variables.md) (merged global + function scope). It returns a result whose shape depends on the category — validation errors, or delivery/payment/discount/transform operations. The editor's autocomplete knows the exact shape of both — type `input.` or `vars.` to explore them.

```javascript
var errors = [];

if (parseFloat(input.cart.cost.totalAmount.amount) > 5000) {
  errors.push({ message: 'Orders above 5000 are not allowed', target: '$.cart' });
}

return errors;
```

The sandbox is minimal by design:

* ES2020 JavaScript — no browser APIs, no `fetch`, no network access.
* The only data available is the `input` object and your `vars`.
* Execution is synchronous and must be fast — it runs on every checkout.

{% hint style="info" %}
Functions **fail open**: if your code throws an error, checkout continues as if the function returned nothing. Broken code never blocks your buyers — but it also means a faulty rule silently stops being enforced, so test your changes on a real checkout after saving.
{% endhint %}

### The editor

* **Save** (or `Cmd/Ctrl+S`) deploys your code — if the function is active, the new version is live at checkout immediately.
* Unsaved changes are kept as local drafts per function, surviving tab switches.
* **Function / Global / Query** open the three variable scopes — code variables (per function and shared) and the family's query variables. See [Families and Variables](/functions/functions/families-and-variables.md).
* **Last saved** opens the version history (`Cmd/Ctrl+Shift+H`) — every save is committed to git, and you can view and restore previous versions.

Every function can also be opened directly by link: `/functions/<id>` (the ID shown under the tree).

### Managing functions from the dashboard

The main dashboard's **Functions** tab lists all functions. Clicking one expands its **Function configuration** — the merchant-facing form driven by variable `metadata`, for adjusting values without touching code. The tab also supports bulk turn on/off, delete, and **export/import**: selected functions download as a `.datajet` file (code, settings and variables included) that can be imported on another store.

### The Shopify admin panel

Functions appear in the Shopify admin too — validations under **Settings → Checkout → Checkout rules**, customizations under their settings pages, discounts on the **Discounts** page. Cart transforms are the exception: they have no admin surface and are managed only from the Functions Console. Opening a DataJet rule there shows a panel with an **Open in DataJet** button that jumps straight to the function in the Functions Console.

### Runtime errors and logs

There is no in-app test run yet — functions execute live at checkout. If your code throws, the error is recorded in the function's execution logs on Shopify's side and checkout proceeds unaffected. A Logs panel in the Functions Console is coming soon.
