HG Hulo Global

Business Credit — User Manual

Overview

Business Credit adds trade-credit accounts to Vendure. A business customer applies for terms from your storefront, you approve them with a credit limit and net terms, and from then on they can choose Pay on Account at checkout: the order is placed immediately and an invoice with a due date is raised against their account. Money comes back by bank transfer, card (a Stripe pay link), direct debit, cheque, cash, credit note or write-off, and every settlement is allocated oldest-first across their open invoices. A daily run marks invoices overdue, sends reminders, applies late fees if you use them, suspends accounts that go too far past due, and emails monthly statements.

  • Available credit = effective limit (a temporary increase while it lasts, else the permanent limit) − open invoice balances (including late fees) + any credit balance held from overpayments.
  • Account statuses: pending → active ⇄ suspended → closed (closing needs zero exposure).
  • Invoice statuses: open → part_paid → paid; overdue once past due date plus grace; written_off; void.
  • Audit: every limit change stores old value, new value, kind (permanent / temporary / expired), reason and administrator; every state change writes an event.

Install & configure

Install and register the plugin:

yarn add @huloglobal/vendure-plugin-business-credit
import { BusinessCreditPlugin } from '@huloglobal/vendure-plugin-business-credit';

plugins: [
  BusinessCreditPlugin.init({
    publicBaseUrl: 'https://shop.example.com',        // licence domain matching
    storefrontBaseUrl: 'https://shop.example.com',    // links in customer emails
    licenceKey: process.env.HULO_LICENCE_KEY_BUSINESS_CREDIT,  // optional — or activate in the admin
    stripeWebhookSecret: process.env.BUSINESS_CREDIT_STRIPE_WEBHOOK_SECRET, // card pay links
    smtp: { host, port, user, pass, from },           // or SMTP_SERVER / SMTP_USER / SMTP_PASSWORD env
  }),
]

Add the admin UI in your compileUiExtensions call with BusinessCreditPlugin.uiExtensions, then create a payment method in Settings → Payment methods: handler Pay on Account (business credit), eligibility checker business-credit-eligibility. The method only appears at checkout for customers with an active account, enough available credit and no overdue hold. Tables are created on first boot; no migration is needed.

Setting (per channel)What it does
Default terms / limit / graceApplied to approvals; grace days delay the overdue mark.
Invoice prefix + sequenceInvoice numbers such as INV-000042.
Reminder scheduleDays relative to the due date, e.g. -3, 0, 7, 14, 30.
Late fee % per month + gracePro-rata monthly fee on the overdue balance; off when empty.
Auto-suspend after N daysSuspends the account when any invoice is that far overdue.
Statement day + statement emailsEmails last month's statement with aging on that day.
Require purchase orderPay on Account is refused without a PO number.
Remittance textYour bank details, shown on invoices, emails and the confirmation page.

Quote requests from your storefront

Customers can ask for a quote from a basket, a product page, a calculator or a plain form: post JSON to POST /quotations/request with the channel's vendure-token header (name, email, company, phone, message, source and optional lines by variant id or SKU). The request lands under Sales → Quotations as requested with catalogue lines pre-priced at list, the notify address hears about it, and the customer receives an acknowledgement carrying the reference. Price any free-text lines, then Send to customer. Turn requests off per channel in Settings; the endpoint is throttled and honeypot-protected.

Admin UI

Sales → Business credit.

  • Overview — total exposure, overdue, credit held, due in the next seven days, pending applications, aging buckets and the ten largest exposures.
  • Accounts — search and filter; open an account for its availability gauge, company details, terms, status actions (suspend / reactivate / close), limit adjustments with history, invoices, ledger, settlement recording, statements and events. New account creates one for an existing customer without an application.
  • Applications — the storefront queue: approve with a limit, terms and a note, or reject with a note; the customer is emailed either way.
  • Invoices and Settlements — all invoices and payments across accounts with write-off, void, fee, pay-link and refund actions, plus CSV export.
  • Settings — the per-channel configuration above, email previews and a test send, and Run dunning now with a report.

Company accounts, invitations, auto-approval, reviews

Members. An account belongs to one customer login (the owner) but a company usually has several buyers. The owner adds colleagues from the storefront (Credit account → Team) as buyer (can place orders on account) or viewer (can see invoices and statements only); admins can do the same from the account's Team pane. Members share the limit, funds and invoices of the company account.

Invitations. Sales → Business credit → Invitations → Invite a business: email, company, limit, terms and a message. The invitee gets a link valid for the configured number of days; when they accept while signed in with that email, an active account is created at the invited limit — no application needed.

Auto-approval. In Settings, switch on auto-approval and set the maximum limit, minimum settled orders, minimum spend and whether a company number is required. Storefront applications that meet every rule are approved immediately (tagged Auto-approved in the queue); the rest wait for you.

Reviews. Every approval sets a review date (Settings → review every N months). The daily run emails you when an account is due and the account shows a Review due pill until you click Mark reviewed.

Payment plans

An outstanding invoice can be split into instalments: Invoices → Create payment plan (number of instalments, first date, interval, note) or accept a customer's request from their account page. While a plan is active, reminders and overdue marking follow the instalment dates, late fees pause, and each settlement fills the instalments in order; the plan completes when the invoice is paid and can be cancelled at any time (the invoice then falls back to its original due date).

Reward points

Sales → Business credit → Loyalty. Switch the programme on per channel and set: points per £1 spent, the value of a point when redeemed, the minimum points to redeem, the maximum share of an order that points may cover, expiry in months, a signup bonus, whether on-account orders earn, and tiers (name, lifetime-points threshold, earn multiplier). Points are earned when an order's payment settles and reversed if it is cancelled. At checkout a signed-in customer applies points as a discount (a negative surcharge on the order); the storefront shows "Earn ~N points" on product pages and the balance, tier progress and history under Account → Reward points. Adjust balances, view any customer's history, see programme statistics and export CSV from the Loyalty tab.

Settlements & Stripe

Record a settlement with a method, amount, reference and date. Allocation is oldest-first across open invoices unless you allocate per invoice; anything left over is held as account credit and applied to the next invoices automatically. Overpayments, credit notes from refunds and write-offs all flow through the same ledger, so the account balance is always the sum of its ledger rows.

Prepaid funds. Money can also be paid in before any invoice exists: customers top up by card from their account page, or you record a deposit (account → Funds). Held funds settle open invoices at once and pay for new on-account orders the moment they are placed, so an account with a zero limit and £500 of funds can order up to £500. Withdraw unused funds from the same pane.

Card pay links create a Stripe Checkout Session for one or more invoices using the Stripe key on the channel's Stripe payment method. Point a Stripe webhook at https://your-vendure-host/business-credit/stripe-webhook with the events checkout.session.completed and checkout.session.async_payment_succeeded, and set the signing secret as BUSINESS_CREDIT_STRIPE_WEBHOOK_SECRET_<CHANNELCODE> or the plugin's stripeWebhookSecret. Replays are ignored: one settlement per payment intent.

REST endpoints

MethodPathPurpose
GET/business-credit/my/accountShop: limit, available credit, terms, status
POST/business-credit/my/applyShop: apply for an account (licensed)
GET/business-credit/my/invoicesShop: my invoices
POST/business-credit/my/invoices/pay-linkShop: pay selected invoices by card (licensed)
GET/business-credit/my/statementShop: statement for a period (JSON or HTML)
GET/business-credit/dashboardAdmin: exposure, overdue, aging
GET/POST/business-credit/accountsAdmin: list / create
POST/business-credit/accounts/:id/limitAdmin: permanent or temporary limit change
POST/business-credit/accounts/:id/statusAdmin: suspend / reactivate / close
POST/business-credit/applications/:id/approveAdmin: approve with limit + terms
POST/business-credit/settlementsAdmin: record a settlement
POST/business-credit/invoices/:id/pay-linkAdmin: Stripe pay link for an invoice
POST/business-credit/stripe-webhookStripe: signed webhook for card settlements
POST/business-credit/dunning/runAdmin: run reminders / fees / suspensions now
GET/business-credit/export/:kind.csvAdmin: invoices / settlements / ledger CSV (licensed)

Storefront tip: send the customer's PO number as metadata.purchaseOrder in addPaymentToOrder, and read payment.metadata.public (invoice number, due date, remittance text) on your confirmation page.

Licensing & tiers

Unlicensed installs run in the free tier: accounts, limits with the audit trail, Pay on Account, invoices, manual settlements, the ledger and statements in the admin all stay on. Card pay links, reminders and dunning emails, late fees, auto-suspend, statement emails, CSV exports and storefront applications require a licence. Start the 14-day free trial from the admin banner, click Buy licence and the key installs itself within a minute of checkout, or paste a key into the admin or set HULO_LICENCE_KEY_BUSINESS_CREDIT. Buy at huloglobal.com/vendure-plugins/business-credit — monthly, annual, or lifetime.

Troubleshooting

  • Pay on Account is not offered at checkout: the customer needs an active account in this channel, available credit at least the order total, no overdue hold, and the payment method must be enabled with the business-credit-eligibility checker.
  • Declined with "purchase order required": the channel or account requires a PO; send it as metadata.purchaseOrder.
  • No reminder emails: reminders need a licence, SMTP configured, and the daily run happens on the worker at 07:00 — use Run dunning now in Settings to test.
  • Card payment did not settle the invoice: check the webhook secret env name matches the channel code, and that Stripe shows the event delivered with a 200.
  • Cannot close an account: closing needs zero exposure — settle or write off open invoices first.