
Accounts Receivable Automation
- 67 installs
- 41 repo stars
- Updated March 13, 2026
- finsilabs/awesome-ecommerce-skills
Automate B2B accounts receivable with invoice generation, payment tracking, dunning sequences for past-due invoices, and aging analysis to reduce days sales outstanding.
About
A skill for automating B2B accounts-receivable workflows: invoicing, payment tracking, dunning, and aging reports for net-terms customers. A developer uses it when B2B customers pay on credit terms and manual follow-up is breaking down.
- Per-platform AR tooling (Invoiced, Apruve, Shopify B2B)
- Targets DSO reduction and audit-ready AR records
Accounts Receivable Automation by the numbers
- 67 all-time installs (skills.sh)
- Ranked #559 of 1,106 Finance & Trading skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/finsilabs/awesome-ecommerce-skills --skill accounts-receivable-automationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 67 |
|---|---|
| repo stars | ★ 41 |
| Last updated | March 13, 2026 |
| Repository | finsilabs/awesome-ecommerce-skills ↗ |
What it does
Automate B2B accounts receivable with invoice generation, payment tracking, dunning sequences for past-due invoices, and aging analysis to reduce days sales outstanding.
Files
Accounts Receivable Automation
Overview
Accounts receivable (AR) automation converts manual invoice follow-up — sending reminders, tracking payment status, escalating overdue accounts — into a system-driven workflow. In B2B ecommerce, where customers pay on net-30, net-60, or net-90 terms rather than at checkout, AR management directly impacts cash flow and days sales outstanding (DSO).
A well-configured AR system reduces DSO by 5–15 days by ensuring follow-up is timely and persistent, eliminates invoices falling through the cracks, and gives the finance team real-time visibility into what is owed and how overdue each invoice is.
When to Use This Skill
- When your B2B customers pay on credit terms (net-30, net-60, net-90) rather than at checkout
- When your finance team spends more than a few hours per week chasing past-due invoices
- When you have more than 50 active B2B accounts and manual tracking is breaking down
- When you need to enforce credit limits and flag accounts that have exceeded them
- When DSO is higher than industry benchmarks and you need to identify the root cause
- When building a wholesale or distribution ecommerce platform with trade accounts
- When you need audit-ready AR records for lenders or investors
Core Instructions
Step 1: Determine your platform and choose the right AR tool
| Platform | Recommended Tool | Why |
|---|---|---|
| Shopify | Invoiced.com or Apruve (B2B app) + QuickBooks Online | Shopify handles orders; a dedicated AR tool handles net-terms invoicing, dunning, and aging outside Shopify's standard checkout flow |
| Shopify Plus | Shopify B2B (built-in) + Invoiced or NetSuite | Shopify Plus has native B2B payment terms, company accounts, and order approval workflows; pair with Invoiced for advanced dunning |
| WooCommerce | WooCommerce B2B plugin + WooCommerce PDF Invoices | WooCommerce B2B enables net terms; WooCommerce Payments or Stripe handles payments; FreshBooks/QuickBooks sync handles AR aging |
| BigCommerce | BigCommerce B2B Edition + Apruve or NetSuite | BigCommerce B2B Edition supports company accounts, payment terms, and quotes natively |
| Custom / Headless | Stripe Invoicing API or build with Stripe + accounting system webhook | Stripe Invoicing handles invoice creation, dunning, and payment links; pair with QuickBooks or Xero for AR aging |
Step 2: Configure net-terms payment options
Shopify (Standard)
1. For basic net-terms invoicing, install Invoiced from the Shopify App Store 2. In Invoiced: go to Settings → Payment Terms and configure net-30, net-60, net-90 options 3. Assign payment terms per customer in Invoiced → Customers → [Customer] → Payment Terms 4. Connect Invoiced to Shopify: go to Invoiced → Integrations → Shopify and authorize your store 5. When a B2B order is placed, Invoiced automatically creates a corresponding invoice with the correct due date
Shopify Plus (B2B native)
1. Go to Shopify Admin → Customers → Companies and create company profiles for B2B accounts 2. For each company, set Payment Terms (net 7, net 15, net 30, net 60, net 90, or custom) 3. Set a Credit Limit on the company profile to prevent orders beyond the approved amount 4. Orders placed by company buyers automatically generate invoices with the configured payment terms 5. For dunning, install Klaviyo or Invoiced to automate past-due email sequences beyond Shopify's basic reminders
WooCommerce
1. Install the WooCommerce B2B plugin and configure payment terms per customer group 2. Install WooCommerce PDF Invoices & Packing Slips for branded invoice PDFs 3. For dunning automation, install AutomateWoo and configure a workflow:
- Trigger: Order status changed to On Hold (representing unpaid invoices)
- Add timing rules for 1 day, 7 days, 14 days past the due date
- Actions: Send reminder email with payment link
4. Connect to QuickBooks Online via the WooCommerce QuickBooks plugin for AR aging reports
BigCommerce
1. In BigCommerce B2B Edition: go to Company Management → Payment Methods and enable net-terms 2. Set credit limits and payment terms per company in B2B Edition → Companies → [Company] 3. Install Invoiced or NetSuite from the BigCommerce App Marketplace for advanced AR automation 4. Configure automated dunning sequences in your AR tool for 1 day, 7 days, 14 days, and 30 days past due
Custom / Headless
Use Stripe Invoicing to handle the full AR lifecycle without building from scratch:
// Create an invoice for a B2B order using Stripe Invoicing
const invoice = await stripe.invoices.create({
customer: stripeCustomerId,
collection_method: 'send_invoice',
days_until_due: 30, // Net-30 terms
metadata: { order_id: orderId, po_number: poNumber },
description: `Invoice for Order ${orderNumber}`,
});
// Add line items
await stripe.invoiceItems.create({
customer: stripeCustomerId,
invoice: invoice.id,
amount: lineTotal, // in cents
currency: 'usd',
description: productDescription,
});
// Finalize and send
await stripe.invoices.finalizeInvoice(invoice.id);
await stripe.invoices.sendInvoice(invoice.id);Stripe automatically handles:
- PDF generation with your branding
- Payment link in the email so customers pay online
- Dunning retries (configure in Stripe Dashboard → Billing → Settings → Invoice reminders)
- Marking invoices as paid when payment arrives
Step 3: Configure dunning sequences
Set up automated reminder emails for overdue invoices. The standard escalation sequence:
Day 0 (due date): Invoice due reminder — "Your invoice is due today" Day 1 overdue: Friendly reminder — "Your payment is a day past due" Day 7 overdue: Second notice — "Invoice still outstanding — please arrange payment" Day 14 overdue: Final notice — "Account review required — please contact us immediately" Day 30 overdue: Credit hold — stop new orders; escalate to account manager or collections
In Invoiced: Configure this under Settings → Chasing → Chasing Schedules. Set a default schedule and assign it to all customers, with a separate more aggressive schedule for high-risk accounts.
In Stripe Invoicing: Configure under Stripe Dashboard → Billing → Settings → Invoice reminders. Enable reminders at due date, 3 days after, 7 days after, and 14 days after.
Step 4: Set up aging reports
Aging reports show outstanding invoices grouped into buckets: current, 1–30 days, 31–60 days, 61–90 days, and 90+ days.
- Invoiced: Built-in aging report under Reports → Accounts Receivable Aging
- QuickBooks Online: Reports → Accounts Receivable Aging Summary or Detail
- Xero: Reports → Aged Receivables
- Stripe: Use Stripe's invoice reporting under Dashboard → Billing → Revenue Recognition or export via the API
Review the aging report weekly. Any account in the 61–90 day bucket should get a phone call, not just an email. Any account in the 90+ day bucket should be on credit hold.
Step 5: Enforce credit limits
Before accepting new orders from a B2B customer on net terms, check that their current AR balance does not exceed their credit limit.
- Shopify Plus B2B: Credit limits are enforced natively — orders over the credit limit are blocked or sent for approval
- Invoiced: Set credit limits per customer under Customer → Credit Limit; Invoiced blocks invoice creation when the limit is exceeded
- WooCommerce B2B: Configure credit limits in the plugin's customer settings; orders over the limit go to pending/on-hold status for review
Best Practices
- Send invoices immediately — do not batch invoices for weekly or monthly sends; each day of delay is a day added to your DSO
- Include a payment link in every invoice — make it a single click for the customer to pay online; friction in the payment process is the enemy of on-time payment
- Separate dunning sequences by customer tier — your treatment of a $500K annual account should be very different from a $5K account; set up separate sequences
- Offer early payment discounts for strategic customers — "2/10 net-30" (2% discount if paid in 10 days) can dramatically reduce DSO
- Set credit holds at 45–60 days overdue, not 90+ — by 90 days, the relationship is already damaged and you have been extending unsecured credit to an uncreditworthy customer
- Reconcile AR daily against payment processor deposits to ensure partial payments are recorded promptly
Common Pitfalls
| Problem | Solution |
|---|---|
| Dunning emails marked as spam | Use a dedicated sending domain for billing emails (billing@yourdomain.com); authenticate with SPF, DKIM, DMARC; never send dunning from your marketing domain |
| Customer paid but invoice still shows overdue | Connect your payment processor to your AR tool so payments are matched automatically; Invoiced and Stripe Invoicing both do this automatically |
| Credit limit not enforced at checkout | Use platform-native credit limits (Shopify Plus B2B, BigCommerce B2B Edition) or your AR tool's credit limit feature; check limits before order confirmation |
| Month-end AR balance does not reconcile with accounting | Use a single integration between your ecommerce platform and accounting system (QuickBooks or Xero); avoid manual data entry that creates discrepancies |
| Customer disputes invoice amount after 60 days | Require PO number at order creation for B2B; send invoice immediately at shipment; document customer email acknowledgment |
Related Skills
- @invoice-generation-automation
- @payment-terms-optimization
- @payment-reconciliation-automation
- @stripe-integration
- @tax-compliance-automation
{
"context": "Tests whether the agent designs the AR database schema with computed columns, correct status/payment-term enumerations, proper JSONB usage for dunning steps, and the required indexes on the invoices table.",
"type": "weighted_checklist",
"checklist": [
{
"name": "amount_due computed column",
"max_score": 10,
"description": "invoices table includes amount_due as a GENERATED ALWAYS AS (total_amount - amount_paid) STORED computed column, not a regular column"
},
{
"name": "available_credit computed column",
"max_score": 10,
"description": "customer_credit table includes available_credit as a GENERATED ALWAYS AS (credit_limit - current_balance) STORED computed column"
},
{
"name": "Invoice status values",
"max_score": 8,
"description": "Schema or comments define invoice status values that include all of: 'draft', 'sent', 'viewed', 'partially_paid', 'paid', 'overdue', 'written_off', 'void'"
},
{
"name": "Payment terms values",
"max_score": 8,
"description": "Schema or comments define payment_terms values that include 'net_30', 'net_60', 'net_90', 'due_on_receipt', and '2/10_net_30'"
},
{
"name": "Dunning steps as JSONB",
"max_score": 8,
"description": "dunning_sequences table stores steps as a JSONB column (not a separate steps table or plain text)"
},
{
"name": "Index on (customer_id, status)",
"max_score": 7,
"description": "An index on invoices(customer_id, status) is present"
},
{
"name": "Index on (due_date, status)",
"max_score": 7,
"description": "An index on invoices(due_date, status) is present"
},
{
"name": "Index on invoice_number",
"max_score": 7,
"description": "An index on invoices(invoice_number) is present"
},
{
"name": "Default dunning sequence steps",
"max_score": 10,
"description": "Seed data or example JSON for the default dunning sequence includes 5 steps: step at 1 day (gentle reminder email), 7 days (second notice email), 14 days (final notice email), 30 days (hold_account action), 60 days (collections warning email)"
},
{
"name": "Credit hold fields",
"max_score": 7,
"description": "customer_credit table includes both credit_hold (boolean) and credit_hold_reason (text) columns"
},
{
"name": "dunning_log table",
"max_score": 8,
"description": "A dunning_log table exists that references invoices and records step_number, action, template_name, and opened_at/clicked_at timestamps"
},
{
"name": "invoice_payments table",
"max_score": 10,
"description": "A separate invoice_payments table exists with payment_method, reference, and payment_date columns (payments stored separately, not aggregated into invoices)"
}
]
}
B2B Wholesale Platform: AR Database Schema
Problem/Feature Description
A wholesale distribution company is building a new B2B ecommerce platform that will serve roughly 300 trade accounts, each with custom payment terms ranging from payment on receipt to 90-day net terms. The finance team currently uses spreadsheets to track who owes what and has been losing invoices and missing follow-ups. The CFO has mandated a proper accounts receivable system before the platform goes live.
You are joining as the backend engineer responsible for designing the database layer. The platform runs PostgreSQL. The finance team needs the system to track invoices through their entire lifecycle, store payment records, manage customer credit limits with automatic enforcement, and support escalation workflows for past-due accounts. The aging report is a critical output — the finance team needs to see outstanding balances bucketed by how many days past-due each customer is.
Output Specification
Produce a single SQL migration file named ar_schema.sql that creates all the tables, computed columns, and indexes needed for the AR system. The file should be runnable on a clean PostgreSQL database. Include any seed data needed to configure a default escalation workflow.
Also produce a short schema_notes.md explaining the key design decisions you made — in particular around how computed values are handled and why.
{
"context": "Tests whether the agent implements the dunning engine with correct daily-cron design, invoice status filtering, step selection logic, hold_account behavior, email urgency levels, billing_email preference, and the correct default sequence configuration.",
"type": "weighted_checklist",
"checklist": [
{
"name": "Daily cron design",
"max_score": 7,
"description": "The dunning processor is described or annotated as running daily (e.g. via cron), not triggered per-invoice or per-event"
},
{
"name": "Invoice status filter",
"max_score": 10,
"description": "The query filtering overdue invoices includes exactly these status values: 'sent', 'viewed', 'partially_paid', 'overdue' (not just 'overdue', and not including 'draft' or 'paid')"
},
{
"name": "void_at filter",
"max_score": 7,
"description": "The overdue invoice query also excludes invoices where void_at is not null"
},
{
"name": "Step selection logic",
"max_score": 10,
"description": "Step selection finds the first step where step.days_overdue <= daysOverdue AND step.step_number > lastStepSent (not just the step whose days_overdue matches exactly)"
},
{
"name": "hold_account sets credit_hold_reason",
"max_score": 8,
"description": "The hold_account action sets credit_hold=true AND sets credit_hold_reason that references the invoice number and number of days overdue"
},
{
"name": "Email urgency levels",
"max_score": 8,
"description": "Dunning email data includes an urgency field with three tiers: 'medium' (up to 30 days), 'high' (31-60 days), 'critical' (over 60 days)"
},
{
"name": "billing_email preference",
"max_score": 8,
"description": "Dunning emails are sent to billing_email when available, falling back to the general email address"
},
{
"name": "Payment link included",
"max_score": 7,
"description": "Dunning emails include a payment_link or payment URL so the customer can pay in a single click"
},
{
"name": "Default sequence step count",
"max_score": 7,
"description": "The default dunning_config.json contains exactly 5 steps"
},
{
"name": "Default sequence timing",
"max_score": 8,
"description": "The 5 default steps trigger at: 1 day, 7 days, 14 days, 30 days, and 60 days overdue"
},
{
"name": "hold_account at 30 days",
"max_score": 10,
"description": "The hold_account action is at step 4 / 30 days overdue (not at 90+ days)"
},
{
"name": "Tiered customer handling",
"max_score": 10,
"description": "The notes or code describe treating high-value accounts differently — account manager outreach rather than just automated emails"
}
]
}
Automated Invoice Follow-Up System
Problem/Feature Description
A B2B software company bills its clients on net-30 and net-60 terms. Historically, a billing admin would manually check a spreadsheet each morning and send follow-up emails to overdue accounts. As the client base has grown to 200 accounts, this process is no longer scalable — invoices are falling through the cracks and the company's average collection time has crept up significantly.
The engineering team needs to automate the follow-up process entirely. The system already has an invoices table and a dunning_sequences table (with a steps JSONB column holding an array of {step_number, days_overdue, action, template_id} objects). The automation should process overdue invoices once per day, advance each invoice through the appropriate escalation step, and when accounts become seriously delinquent, put them on credit hold automatically.
The company also caters to a small number of enterprise clients worth $500K+ annually — the team wants those accounts handled differently from small clients.
Output Specification
Produce a JavaScript module dunning.js that implements the daily dunning processor. The file should be self-contained and use JSDoc comments to document the key functions.
Also produce a dunning_config.json file containing the default dunning sequence configuration that should be seeded into the database.
Include a dunning_notes.md that explains:
- How the system decides which step to execute for a given overdue invoice
- How credit hold escalation is triggered and what it sets on the customer record
- How the system handles high-value vs. standard accounts differently
{
"context": "Tests whether the agent implements payment recording with atomic transactions, correct full-payment detection (floating point tolerance), credit hold lifting on full payment, validation of voided invoices, and credit limit enforcement at B2B checkout.",
"type": "weighted_checklist",
"checklist": [
{
"name": "Atomic transaction",
"max_score": 10,
"description": "Payment recording uses a single database transaction that atomically creates the payment record, updates invoice status, and adjusts customer AR balance in one operation"
},
{
"name": "Floating point tolerance",
"max_score": 10,
"description": "The full-payment check uses a tolerance of 0.005 (e.g. newAmountPaid >= total_amount - 0.005) rather than strict equality"
},
{
"name": "Partial payment status",
"max_score": 8,
"description": "Invoice is set to 'partially_paid' status when the amount paid is less than the total (not 'overdue' or some other status)"
},
{
"name": "last_payment_date update",
"max_score": 7,
"description": "customer_credit.last_payment_date is updated when a payment is recorded"
},
{
"name": "Decrement AR balance",
"max_score": 8,
"description": "customer_credit.current_balance is decremented by the payment amount (not set to a recalculated value or left unchanged)"
},
{
"name": "Credit hold lifted on full payment",
"max_score": 10,
"description": "When an invoice is fully paid, the system checks and conditionally lifts the customer's credit hold (only if no other overdue invoices remain)"
},
{
"name": "Void invoice guard",
"max_score": 8,
"description": "Attempting to record a payment against a voided invoice throws an error or returns an error response"
},
{
"name": "Do not modify total_amount",
"max_score": 8,
"description": "Payment recording updates amount_paid (and status) but does NOT modify the total_amount field to reflect the payment"
},
{
"name": "credit-check uses available_credit",
"max_score": 8,
"description": "The credit check module reads available_credit (or computes credit_limit - current_balance) to determine if an order can proceed"
},
{
"name": "Order blocked at credit limit",
"max_score": 8,
"description": "The credit check blocks or flags orders where the order amount would cause the customer to exceed their credit limit"
},
{
"name": "Immediate status update",
"max_score": 7,
"description": "The notes or code make clear that invoice status is updated immediately when a payment is recorded, not deferred to a nightly job"
},
{
"name": "paid_at timestamp on full payment",
"max_score": 8,
"description": "When an invoice becomes fully paid, the paid_at timestamp is set on the invoice record"
}
]
}
B2B Payment Processing and Credit Management Service
Problem/Feature Description
A wholesale supplier's finance team records incoming payments manually today — each morning they open bank statements and mark invoices as paid in the system. This causes problems: partially paid invoices sit unrecorded for days, customers on credit hold are unblocked late, and occasionally a payment is applied to an already-voided invoice causing data integrity issues.
The engineering team needs a payment recording service that handles the full lifecycle: recording each incoming payment against an invoice, updating the invoice status correctly (distinguishing partial from full payment), keeping the customer's outstanding AR balance accurate, and automatically releasing credit holds when a customer's overdue invoices are cleared. The service will be called both from the finance team's internal admin panel and by an automated bank reconciliation feed.
Separately, the team also needs the B2B checkout flow to enforce credit limits — orders placed by trade accounts should be blocked if the customer would exceed their approved credit limit.
Output Specification
Produce two JavaScript files:
payment-recorder.js— the payment recording servicecredit-check.js— a module that checks a customer's credit availability before an order is placed
Also produce a payment_notes.md explaining:
- How the system determines whether an invoice is fully paid vs. partially paid
- How the customer's AR balance is kept consistent with payment activity
- What happens to a customer's credit hold status when their overdue invoice is paid
- What checks are in place to prevent data integrity problems with payment recording
{
"name": "finsi/accounts-receivable-automation",
"version": "0.1.0",
"summary": "Automate B2B accounts receivable with invoice generation, payment tracking, dunning sequences for past-due invoices, and aging analysis dashboards",
"skills": {
"accounts-receivable-automation": {
"path": "SKILL.md"
}
}
}