Free Shopify Net-30 PO Snippet & AP Dunning Generator
Capture Purchase Order numbers & Accounts Payable emails on any Shopify theme without installing bloated apps—plus generate your Net-30 overdue dunning sequence.
Only renders for logged-in buyers tagged wholesale-net30. Saves PO Number & AP Email directly to the Shopify order attributes.
{% comment %}
Free Zero-App Shopify Wholesale PO Number & AP Email Capture (Dawn / OS 2.0 Tested)
Where to paste:
• Cart Page: Inside <form action="{{ routes.cart_url }}" ...> in sections/main-cart-items.liquid
• Cart Drawer: Inside <form id="CartDrawer-Form" ...> in snippets/cart-drawer.liquid
{% endcomment %}
{% if customer and customer.tags contains 'wholesale-net30' %}
<div class="net30-po-box" style="margin: 16px 0; padding: 16px; border: 1px solid #e2e8f0; border-radius: 8px; background: #f8fafc; text-align: left;">
<h4 style="margin: 0 0 8px 0; font-size: 14px; font-weight: 600; color: #0f172a;">
Wholesale Net-30 Checkout Approved
</h4>
<div style="margin-bottom: 10px;">
<label for="CartPONumber" style="display:block; font-size: 12px; margin-bottom: 4px; color: #334155;">
Purchase Order (PO) Number *
</label>
<input
required
id="CartPONumber"
type="text"
name="attributes[Purchase Order Number]"
value="{{ cart.attributes['Purchase Order Number'] }}"
placeholder="e.g. PO-2026-0841"
onchange="fetch((window.Shopify && window.Shopify.routes && window.Shopify.routes.root || '/') + 'cart/update.js', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ attributes: { 'Purchase Order Number': this.value } }) })"
style="width: 100%; padding: 8px; border: 1px solid #cbd5e1; border-radius: 6px; color: #0f172a; background: #fff;"
/>
</div>
<div>
<label for="CartAPEmail" style="display:block; font-size: 12px; margin-bottom: 4px; color: #334155;">
Accounts Payable (AP) Invoice Email *
</label>
<input
required
id="CartAPEmail"
type="email"
name="attributes[Accounts Payable Email]"
value="{{ cart.attributes['Accounts Payable Email'] }}"
placeholder="ap@buyercompany.com"
onchange="fetch((window.Shopify && window.Shopify.routes && window.Shopify.routes.root || '/') + 'cart/update.js', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ attributes: { 'Accounts Payable Email': this.value } }) })"
style="width: 100%; padding: 8px; border: 1px solid #cbd5e1; border-radius: 6px; color: #0f172a; background: #fff;"
/>
</div>
</div>
{% endif %}Includes W-9 attachment note, $5,000 credit-limit hold warning, and 1.5%/mo ($36.75) late fee calculation.
{% comment %}
Paste into Shopify Admin -> Settings -> Notifications -> Payment Reminder
(Or copy the plain text for manual / Shopify Flow email reminders)
{% endcomment %}
SUBJECT: [Reminder] Apex Coffee Roasters Invoice {{ name }} {% if attributes['Purchase Order Number'] != blank %}(PO #{{ attributes['Purchase Order Number'] }}){% endif %} — Net-30 Due Soon
Hi Accounts Payable Team,
Friendly reminder that Apex Coffee Roasters Invoice {{ name }} {% if attributes['Purchase Order Number'] != blank %}for Purchase Order #{{ attributes['Purchase Order Number'] }}{% endif %} ({{ total_outstanding | money }}) on Net-30 terms is due on {{ payment_terms.next_payment.due_at | date: "%b %d, %Y" }}.
• Amount Due: {{ total_outstanding | money }} (Sample: $2,450)
• Instant ACH / Card Payment Link: {{ checkout_payment_collection_url }}
---
SUBJECT: [OVERDUE +7 Days] Action Required: Apex Coffee Roasters Invoice {{ name }} ({{ total_outstanding | money }})
Hi Accounts Payable Team,
Invoice {{ name }} ({{ total_outstanding | money }}) is now past its Net-30 due date. Per our wholesale terms, accounts with overdue balances or exceeding their $5,000 credit limit are automatically placed on temporary checkout hold, and a 1.5%/mo ($36.75 on $2,450) late fee applies to balances 15+ days past due.
Please remit payment via ACH or card using your secure Shopify invoice link below so your buyer account remains active for upcoming shipments:
{{ checkout_payment_collection_url }}Stop Chasing Overdue Net-30 Shopify Invoices by Hand
Native Shopify payment terms still don't enforce automatic credit-limit holds when an account is overdue, attach your W-9 PDF pack to AP emails, or run multi-step dunning. Net30Pulse automates all three for a flat $29/mo.
Shopify Net-30 & Cart Attribute Implementation FAQ
Where do cart.attributes show up in my Shopify Admin?
Any input named attributes[Purchase Order Number] inside your cart form is automatically saved by Shopify and appears on the right-hand sidebar of the Order Details page under Additional Details—and can be referenced in Order Confirmation emails via {{ attributes['Purchase Order Number'] }}.
What is the difference between this free snippet and Net30Pulse?
The free Liquid snippet captures the PO number and AP email on the cart page. Net30Pulse ($29/mo) automates everything that happens after checkout: generating the PDF invoice + W-9 pack, emailing the buyer's AP department, running automated T-3 / Due Date / +7d overdue reminders with 1-click ACH payment links, and automatically pausing Net-30 checkout if a buyer exceeds their credit limit or goes past due.
Does this work with Shopify Dawn and Online Store 2.0 slide-out cart drawers?
Yes. Paste the snippet inside the <form action="{{ routes.cart_url }}"> element in sections/main-cart-items.liquid or snippets/cart-drawer.liquid. Because it uses native HTML form attributes, it adds zero JavaScript overhead.
Why does Shopify's native Companies feature still leave overdue invoices unpaid?
While Shopify added basic Net-30 due dates to non-Plus plans, it does not enforce credit limits, does not block a chronically late buyer from placing new Net-30 orders, and does not send multi-step dunning sequences to a separate Accounts Payable contact with your W-9 attached.