Skip to content

customer

The customer object is the authenticated buyer for the current storefront. It contains buyer-visible identity, address, order, loyalty, referral, review reward, store-credit, tag, and metafield data.

Availability and context

customer is available globally and is normally nil for a guest. Always guard customer properties with {% if customer %}. Live customer data comes only from the authenticated storefront customer session; a customer identifier in a URL or theme setting cannot load another buyer. On verified visual-editor account pages, Sellerlane instead injects a fixed, non-persisted sample customer so the account UI can be previewed without exposing live buyer data.

Examples

Render signed-in and guest states

{% if customer %}
<p>Hi {{ customer.first_name | default: customer.name | escape }}!</p>
<a href="{{ routes.account_url }}">View your account</a>
{% else %}
<p>Welcome!</p>
<a href="{{ routes.account_login_url }}">Sign in</a>
{% endif %}

Example output for a signed-in buyer:

<p>Hi Asha!</p>
<a href="/account">View your account</a>

For a guest, the same template renders:

<p>Welcome!</p>
<a href="/account/login">Sign in</a>

Paginate the buyer’s orders

{% if customer %}
{% paginate customer.orders by 10 %}
<ul>
{% for order in customer.orders %}
<li>
<a href="{{ routes.account_url }}/orders/{{ order.id }}">{{ order.name | escape }}</a>
{{ order.created_at | date: '%d %b %Y' }}
{{ order.total_price | money }}
</li>
{% else %}
<li>You have not placed an order yet.</li>
{% endfor %}
</ul>
{{ paginate | default_pagination }}
{% endpaginate %}
{% endif %}

Example output:

<ul>
<li><a href="/account/orders/ord_01J8">#1042</a> — 12 Jul 2026 — ₹2,498.00</li>
</ul>

Orders are returned newest first. last_order is the newest non-test order and is nil when the customer has no eligible order.

Paginate saved addresses

{% if customer %}
{% paginate customer.addresses by 10 %}
{% for address in customer.addresses %}
<address>
{{ address.name | escape }}<br>
{{ address.address1 | escape }}<br>
{{ address.city | escape }}, {{ address.province_code | escape }}
</address>
{% else %}
<p>No saved addresses.</p>
{% endfor %}
{{ paginate | default_pagination }}
{% endpaginate %}
{% endif %}

Example output:

<address>
Asha Rao<br>
12 Residency Road<br>
Bengaluru, KA
</address>

Show buyer-owned rewards safely

{% if customer %}
<p>Lifetime spend: {{ customer.total_spent | money }}</p>
{% if customer.referral_url != blank %}
<a href="{{ customer.referral_url }}">Share your referral link</a>
{% endif %}
{% if customer.store_credit_account.balance > 0 %}
<p>Store credit: {{ customer.store_credit_account.balance | money }}</p>
{% endif %}
{% endif %}

Example output:

<p>Lifetime spend: ₹24,880.00</p>
<a href="/?ref=ASHA24">Share your referral link</a>
<p>Store credit: ₹500.00</p>

Nil values, ordering, and limits

  • customer.orders is newest first. Direct iteration exposes at most 20 orders; pagination supports a page size of up to 20.
  • Direct customer.addresses iteration exposes at most 20 addresses, and its maximum pagination page size is also 20.
  • Direct customer.review_rewards iteration exposes at most 20 records; pagination supports a page size of up to 250.
  • orders_count and addresses_count use 25001 to mean “more than 25,000.”
  • default_address and last_order can be nil. Missing email, phone, first name, last name, combined name, birthday, and referral string properties are empty strings.
  • has_account is true only when the identity state is enabled for passwordless access. has_avatar? currently always returns false.
  • store_credit_account is always an object for a customer; its balance defaults to zero when no credit account exists. total_spent and that balance are currency minor units and should be formatted with money.

Customer data is private to the authenticated buyer. Customer metafields are resolved only for that buyer, and customer-typed references are redacted from general storefront metafield traversal. Never cache customer-rendered HTML in a shared public cache.

Properties

PropertyDescription
customer.accepts_marketingtrue when opted in to marketing.
customer.addressesSaved addresses, limited to the first 20 without pagination; maximum pagination page size 20.
customer.addresses_countTotal saved-address count, capped by the storefront count sentinel.
customer.b2b?true when the current session is an authenticated company (wholesale) contact.
customer.birthdayDate-only birthday in YYYY-MM-DD, or an empty string.
customer.birthday_locked_untilISO instant until birthday self-service can be changed again, or an empty string.
customer.company_available_locations_countNumber of company locations the contact can order for; 0 for D2C sessions. Fetch the list itself from the paginated locations endpoint.
customer.company_purchasing_only?true when the store’s “Company purchasing only” setting applies to this wholesale contact, so the theme must not offer the “Purchasing personally” option. Always false for D2C shoppers and guests. Display gating only — the seller re-enforces it at the session and checkout seams.
customer.current_companyCurrent wholesale session’s company as { id, name }, or nil for D2C sessions.
customer.current_locationActive ordering location as { id, name }, or nil until the contact selects one.
customer.default_addressDefault address, or nil.
customer.emailEmail address, or an empty string.
customer.first_nameFirst name, or an empty string.
customer.has_accounttrue when the customer identity is enabled for passwordless account access.
customer.has_avatar?false until a storefront customer-avatar source is configured.
customer.idUnique identifier.
customer.last_nameLast name, or an empty string.
customer.last_orderMost recent non-test order, or nil.
customer.loyaltyAuthenticated customer loyalty summary and balances; an inactive zero-balance summary is returned when no account exists.
customer.metafieldsMetafields on this resource.
customer.nameCombined first and last name, or an empty string.
customer.ordersNewest-first orders, limited to the first 20 without pagination and to 20 per page. Build account links from routes.account_url and the order ID; list results do not populate order.customer_url.
customer.orders_countOrder count, using 25001 as the “more than 25,000” sentinel.
customer.phonePhone number, or an empty string.
customer.referral_codeAuthenticated customer referral code, or an empty string.
customer.referral_summaryAuthenticated customer referral-program summary; an inactive zero-value summary is returned when none exists.
customer.referral_urlRoot-relative same-store referral path, or an empty string.
customer.referrals_countNumber of referrals attributed to the customer.
customer.purchasing_personally?true only when a wholesale buyer explicitly chose the Purchasing personally identity; false when no purchase identity was selected.
customer.review_rewardsReview reward records visible to the authenticated customer: first 20 without pagination, with a maximum page size of 250.
customer.review_rewards_countNumber of visible review reward records.
customer.store_credit_accountAlways-present object whose balance is the authenticated customer’s store credit in currency minor units, defaulting to zero.
customer.tagsTags as an array of strings.
customer.tax_exempttrue when the customer is tax exempt.
customer.total_spentLifetime order spend in currency minor units; format with money.

Property names are generated from the storefront engine (CustomerDrop), so the list matches what themes can access. {{ customer | json }} is a curated identity and aggregate subset; it does not serialize addresses, orders, rewards, loyalty, referrals, store credit, metafields, or last_order. Inspect those properties directly.

Sellerlane differences from Shopify

  • Storefront accounts use Sellerlane’s OTP/passwordless identity flow. has_account therefore means an enabled passwordless identity, not that the customer created a Shopify-style password.
  • loyalty, referral properties, review rewards, birthday properties, and store_credit_account are Sellerlane extensions scoped to the authenticated customer, or to the fixed non-persisted sample on a verified editor account preview.
  • Shopify B2B company, company-location, and Markets-specific customer fields are not present. Themes must not depend on those fields.
  • Sellerlane excludes test orders from last_order so account summaries do not present test activity as a buyer purchase.