WooCommerce

Checkout Page

Start checkout pages with the native {{ checkout }} tag so WooCommerce can own fields, validation, shipping, payment gateways, terms, and order submission.

Use the full native checkout first. Customize the checkout shape only when CSS and normal wrappers are not enough.

Safest Checkout Page#

Create a page template that wraps WooCommerce's full checkout:

phpresources/views/page-checkout.php
<main class="checkout-page">  <h1>Checkout</h1>  {{ notices }}  {{ checkout }}</main>

This is the best starting point for production stores. WooCommerce renders the checkout form, gateway markup, hidden fields, order review, payment methods, and submit button.

{{ checkout }} is a value-style commerce tag when used alone. It does not need a closing tag in the full native checkout version.

Add Theme Layout Around Checkout#

You can wrap checkout in normal markup:

phpresources/views/page-checkout.php
<main class="checkout-page">  <header class="checkout-page__header">    <h1>Checkout</h1>    <p>Review your details before placing the order.</p>  </header>  {{ notices }}  <section class="checkout-page__body">    {{ checkout }}  </section></main>

Do not wrap {{ checkout }} in your own <form>. WooCommerce renders and manages the checkout form.

Custom Checkout Shape#

Use paired {{ checkout }} when you need to move field groups or write your own field wrappers:

phpresources/views/page-checkout.php
<main class="checkout-page">  {{ notices }}  {{ checkout class="checkout-shell" }}    {{ checkout:form class="checkout-form" }}      <section>        <h2>Billing details</h2>        {{ checkout:billing }}          <div class="field field-{{ key }}">            <label for="{{ id }}">              {{ label }}{{ if required }} *{{ /if }}            </label>            {{ input }}            {{ if description }}<small>{{ description }}</small>{{ /if }}          </div>        {{ /checkout:billing }}      </section>      <section>        <h2>Order notes</h2>        {{ checkout:fields group="order" }}          {{ field }}        {{ /checkout:fields }}      </section>      <section>        <h2>Your order</h2>        {{ checkout:order }}        {{ checkout:payment }}        {{ checkout:submit }}Place order{{ /checkout:submit }}      </section>    {{ /checkout:form }}  {{ /checkout }}</main>

Custom checkout layouts are more sensitive because payment gateways and WooCommerce extensions may expect normal checkout structure. If a plugin-provided field disappears, try {{ field }} instead of {{ input }}, or return to plain {{ checkout }}.

{{ field }} and {{ input }} are value tags inside checkout field loops. They print markup and do not have closing tags.

Checkout Field Groups#

These tags loop over WooCommerce checkout fields:

TagField group
{{ checkout:billing }}Billing address fields.
{{ checkout:shipping }}Shipping address fields.
{{ checkout:account }}Account creation fields.
{{ checkout:order_fields }}Order notes fields.
{{ checkout:fields group="billing" }}Explicit group name.
{{ checkout:fields group="order" }}Explicit order notes group.

Each field loop exposes:

ValuePrints
keyField key, such as billing_email.
idField ID.
nameInput name.
typeField type.
labelLabel text.
placeholderPlaceholder text.
descriptionDescription text.
requiredWhether the field is required.
valueCurrent submitted/customer value.
priorityWooCommerce field priority.
classWrapper classes from WooCommerce.
input_classInput classes from WooCommerce.
label_classLabel classes from WooCommerce.
autocompleteBrowser autocomplete value.
optionsSelect options collection.
inputInput-only markup.
fieldWooCommerce's full field markup.

Input Versus Field#

Use {{ field }} when you want WooCommerce's complete field wrapper:

php
{{ checkout:billing }}  {{ field }}{{ /checkout:billing }}

Use {{ input }} when you want to write your own label and wrapper:

php
{{ checkout:billing }}  <div class="field">    <label for="{{ id }}">{{ label }}</label>    {{ input }}  </div>{{ /checkout:billing }}

Both {{ field }} and {{ input }} are value tags. Do not write {{ /field }} or {{ /input }}.

Order Review, Payment, And Submit#

A custom checkout form should include:

php
{{ checkout:order }}{{ checkout:payment }}{{ checkout:submit }}Place order{{ /checkout:submit }}

{{ checkout:order }} prints WooCommerce's order review. {{ checkout:payment }} prints payment methods and gateway fields. {{ checkout:submit }} wraps the final place-order button.

If payment methods, terms, hidden fields, or the place-order button are missing, return to plain {{ checkout }} or make sure the custom layout includes {{ checkout:payment }} and {{ checkout:submit }}.

Coupons Near Checkout#

WooCommerce's native checkout may include its own coupon behavior. If you add TemplateX's generic coupon form, keep it outside the checkout form:

php
<main class="checkout-page">  {{ notices }}  {{ coupon }}    <input name="coupon_code" placeholder="Coupon code">    <button type="submit">Apply coupon</button>  {{ /coupon }}  {{ checkout }}</main>

Do not place {{ coupon }} inside {{ checkout:form }}.

Contextual Shortcuts#

Inside paired {{ checkout }}, you may omit the checkout: prefix for checkout parts:

php
{{ checkout }}  {{ form }}    {{ billing }}      {{ field }}    {{ /billing }}    {{ order }}    {{ payment }}    {{ submit }}Place order{{ /submit }}  {{ /form }}{{ /checkout }}

The full names are clearer for new readers, so the docs use {{ checkout:billing }} and related names first.