--- title: Add review requirement description: Add a review requirement to a checkout based on the cart total. source_url: html: 'https://shopify.dev/docs/apps/build/checkout/payments/review-requirements' md: 'https://shopify.dev/docs/apps/build/checkout/payments/review-requirements.md' --- ExpandOn this page * [What you'll learn](https://shopify.dev/docs/apps/build/checkout/payments/review-requirements.md#what-youll-learn) * [Requirements](https://shopify.dev/docs/apps/build/checkout/payments/review-requirements.md#requirements) * [Step 1: Configure the function](https://shopify.dev/docs/apps/build/checkout/payments/review-requirements.md#step-1-configure-the-function) * [Step 2: Test the payment customization](https://shopify.dev/docs/apps/build/checkout/payments/review-requirements.md#step-2-test-the-payment-customization) * [Next steps](https://shopify.dev/docs/apps/build/checkout/payments/review-requirements.md#next-steps) # Add review requirement A review requirement enables you to control whether an order is submitted as a [draft](https://shopify.dev/docs/apps/build/b2b/draft-orders) for review. This tutorial shows you how to use the `orderReviewAdd` operation in the [Payment Customization API](https://shopify.dev/docs/api/functions/reference/payment-customization#CartPaymentMethodsTransformRunResult.fields.operations.orderReviewAdd) to dynamically add a review requirement during checkout based on business rules. *** ## What you'll learn In this tutorial, you'll learn foundational concepts and techniques for customizing checkout behaviour using Shopify Functions and the [Payment Customization API](https://shopify.dev/docs/api/functions/latest/payment-customization). * How to query and use cart data in a function's input to drive decisions. * Conditionally using operations (such as `orderReviewAdd`) to modify checkout flows, including creating draft orders for review. * Testing and validating function logic in development environments. ![A B2B checkout with a review requirement](https://shopify.dev/assets/assets/images/apps/checkout/b2b-checkout-with-review-requirement-BBucxTBQ.png) *** ## Requirements * You've completed at least the first tutorial in this [series](https://shopify.dev/docs/apps/build/checkout/payments#tutorial-series). *** ## Step 1: Configure the function First, start a developement server if you haven't already (see [CLI reference](https://shopify.dev/docs/api/shopify-cli/app/app-dev)): ## terminal ```terminal shopify app dev ``` In this example, a review requirement is added based on the cart total. You'll implement the following behaviour: * No review is required for any order where the cart total is less than $5000. * If the cart total is $5000 or more: * B2B orders will checkout as a Draft Order. * D2C orders aren't affected (see [limitations](https://shopify.dev/docs/apps/build/checkout/payments#limitations-and-considerations)). 1. Navigate to your function in `extensions/payment-customization`: ## Terminal ```terminal cd extensions/payment-customization ``` 2. Replace the code in the `src/run.graphql` file with the following code. The input query retrieves the [`cart`](https://shopify.dev/docs/api/functions/reference/payment-customization#Input.fields.cart) object, which includes a `cost` object with the total value of the cart. The query differs slightly in Rust and JavaScript due to code generation requirements. ## run.graphql ## src/run.graphql ```graphql query Input { cart { cost { totalAmount { amount } } } } ``` ```graphql query RunInput { cart { cost { totalAmount { amount } } } } ``` ##### Rust input query ``` query Input { cart { cost { totalAmount { amount } } } } ``` ##### JavaScript input query ``` query RunInput { cart { cost { totalAmount { amount } } } } ``` 3. If you're using JavaScript, then run the following command to regenerate types based on your input query: ## Terminal ```terminal shopify app function typegen ``` 4. Implement business logic for the function to add a review requirement when the cart total exceeds $5000. Replace the contents of`src/run.rs` or `src/run.js` file with the following code: ## File ## src/run.rs ```rust use crate::schema; use shopify_function::prelude::*; use shopify_function::Result; #[shopify_function] fn cart_payment_methods_transform_run(input: schema::cart_payment_methods_transform_run::Input) -> Result { let cart_total: f64 = input.cart().cost().total_amount().amount().as_f64(); let operations = if cart_total > 5000.0 { vec![schema::Operation::OrderReviewAdd( schema::OrderReviewAddOperation { reason: "An order over $5000 requires review.".to_string() } )] } else { vec![] }; Ok(schema::CartPaymentMethodsTransformRunResult { operations }) } ``` ```javascript // @ts-check /** * @typedef {import("../generated/api").RunInput} RunInput * @typedef {import("../generated/api").FunctionRunResult} FunctionRunResult */ /** * @type {FunctionRunResult} */ /** * Sets payment terms based on cart total and buyer identity * @param {RunInput} input - Function input * @returns {FunctionRunResult} Function result with operations to apply */ export function run(input) { const operations = []; const totalAmount = input.cart.cost.totalAmount.amount; if (totalAmount > 5000) { operations.push({ orderReviewAdd: { reason: "An order over $5000 requires review." } }); } return { operations }; } ``` ##### Rust ``` use crate::schema; use shopify_function::prelude::*; use shopify_function::Result; #[shopify_function] fn cart_payment_methods_transform_run(input: schema::cart_payment_methods_transform_run::Input) -> Result { let cart_total: f64 = input.cart().cost().total_amount().amount().as_f64(); let operations = if cart_total > 5000.0 { vec![schema::Operation::OrderReviewAdd( schema::OrderReviewAddOperation { reason: "An order over $5000 requires review.".to_string() } )] } else { vec![] }; Ok(schema::CartPaymentMethodsTransformRunResult { operations }) } ``` ##### JavaScript ``` // @ts-check /** * @typedef {import("../generated/api").RunInput} RunInput * @typedef {import("../generated/api").FunctionRunResult} FunctionRunResult */ /** * @type {FunctionRunResult} */ /** * Sets payment terms based on cart total and buyer identity * @param {RunInput} input - Function input * @returns {FunctionRunResult} Function result with operations to apply */ export function run(input) { const operations = []; const totalAmount = input.cart.cost.totalAmount.amount; if (totalAmount > 5000) { operations.push({ orderReviewAdd: { reason: "An order over $5000 requires review." } }); } return { operations }; } ``` *** ## Step 2: Test the payment customization Test how the review requirement is added based on the cart total. ### Test with a B2B checkout with a cart total under $5000 1. Open your dev store and log in as a B2B customer. 2. Build a cart with a total (including shipping and tax) under $5000. 3. The review requirement threshold is not met in this scenario. Verify that the function does not add a review requirement. 4. Complete the checkout and verify an order is created. ![B2B checkout with cart total under $5000 showing no review requirement](https://shopify.dev/assets/assets/images/apps/checkout/b2b-checkout-with-no-function-run-D4dLLOKx.png) ### Test with a B2B checkout with a cart total over $5000 1. Open your dev store and log in as a B2B customer. 2. Build a cart with a total (including shipping and tax) over $5000. 3. Since the review requirement threshold is met, verify that the function adds a review requirement. 4. Submit the checkout for review and verify a Draft Order is created as a result. ![B2B checkout with cart total over $5000 showing review requirement and submit for review option](https://shopify.dev/assets/assets/images/apps/checkout/b2b-checkout-with-function-run-udS44zqY.png) ### Test with a direct-to-consumer checkout 1. Open your dev store and log in as a direct-to-consumer customer. 2. Build a cart with a total (including shipping and tax) over $5000. 3. Since review requirements aren't [applicable to D2C checkouts](https://shopify.dev/docs/apps/build/checkout/payments#limitations-and-considerations), the function doesn't add a review requirement. 4. Verify that the checkout is not modified, and can be completed as normal. ![Direct-to-consumer checkout with cart total over $5000 showing no review requirement](https://shopify.dev/assets/assets/images/apps/checkout/d2c-no-review-requirement-DqjbGrBK.png) *** ## Next steps * Build a [payment customization user interface](https://shopify.dev/docs/apps/build/checkout/payments/build-ui) with App Bridge. * Learn how to use [variables](https://shopify.dev/docs/apps/build/functions/input-queries/use-variables-input-queries) in your input query. * Explore more [payment customization options](https://shopify.dev/docs/api/functions/reference/payment-customization) in the API reference. *** * [What you'll learn](https://shopify.dev/docs/apps/build/checkout/payments/review-requirements.md#what-youll-learn) * [Requirements](https://shopify.dev/docs/apps/build/checkout/payments/review-requirements.md#requirements) * [Step 1: Configure the function](https://shopify.dev/docs/apps/build/checkout/payments/review-requirements.md#step-1-configure-the-function) * [Step 2: Test the payment customization](https://shopify.dev/docs/apps/build/checkout/payments/review-requirements.md#step-2-test-the-payment-customization) * [Next steps](https://shopify.dev/docs/apps/build/checkout/payments/review-requirements.md#next-steps)