Shopify Functions for Custom Discount and Shipping Logic
Shopify Functions — mechanism for running user code directly in Shopify infrastructure. Unlike webhook apps, Functions execute synchronously during checkout: Shopify calls the function, gets a response, and applies the result.
Where Functions Work
| Function API | Purpose |
|---|---|
cart_transform |
Modify cart lines before checkout (bundles, modifications) |
discounts |
Custom discounts (fixed, percentage, BXGY) |
payment_customization |
Hide/rename payment methods |
shipping_discount |
Shipping discounts |
delivery_customization |
Hide/rename/sort delivery methods |
fulfillment_constraints |
Warehouse split restrictions |
order_routing |
Route orders to warehouses |
Functions written in Rust (official language, compiles to WebAssembly) or JavaScript/TypeScript (Javy runtime). Rust preferred for complex logic—faster and more economical.
Installation and Initialization
shopify app generate extension --template discount --name custom-volume-discount
cd extensions/custom-volume-discount
Structure: src/run.ts (or run.rs), input.graphql, shopify.extension.toml, package.json.
Example: Volume Discount Function (JavaScript)
input.graphql describes what data Shopify passes:
query RunInput {
cart {
lines {
id
quantity
merchandise {
... on ProductVariant {
id
product {
id
tags
}
}
}
}
}
}
src/run.ts function logic:
export function run(input: RunInput): FunctionRunResult {
const discounts = [];
for (const line of input.cart.lines) {
const variant = line.merchandise;
if (variant.__typename !== "ProductVariant") continue;
if (!variant.product.tags.includes("volume-eligible")) continue;
discounts.push({
targets: [{ cartLine: { id: line.id } }],
value: { percentage: { value: String(line.quantity > 5 ? 10 : 5) } },
message: `${line.quantity > 5 ? 10 : 5}% bulk discount`,
});
}
return { discounts, discountApplicationStrategy: "FIRST" };
}
Activation via Shopify Admin
Functions don't work automatically—create a Discount in Admin and select the function:
const CREATE_DISCOUNT = `
mutation discountAutomaticAppCreate($automaticAppDiscount: DiscountAutomaticAppInput!) {
discountAutomaticAppCreate(automaticAppDiscount: $automaticAppDiscount) {
automaticAppDiscount { discountId title startsAt }
userErrors { field message }
}
}
`;
Function Limitations
- Execution time: 5ms for Rust/WASM, 10ms for JS
- Memory: 10 MB
-
No network requests: all data via
input.graphql - No database access: complex config via Metafields
- No Checkout UI Extensions: separate mechanism
Testing
npm run test
shopify app deploy
shopify app logs
Timeline
Simple discount function (percentage by tag/collection): 2–4 days. Complex multi-level function with metafield config and Admin UI: 1–2 weeks. Shipping function with geologic and external tariff integration: 1–2 weeks.







