v1.21.0
StableA stable release, offered to every installation. The headline is that account credit is a payment, not a discount: an invoice paid from the balance used to have its total written down to zero, so the document printed a gross of zero and the shop's figures lost the sale. Around it: Add Funds now follows the proforma scheme end to end, the admin domain screen gained the four things it was missing, two registrars can set WHOIS privacy, a missing registration date is filled from the registrar or RDAP, and PNLCS speaks Italian.
Thank you @hedon77 (#398, #399, #400, #401, #402, #405), @vvezzola (#403), @ertugrulkeyvan (#406, #407, #408) and @5eBeKs (#409).
One thing to know after upgrading. Every invoice that had credit spent on it gets its total put back to the gross value, and the credit is taken off when the balance is worked out instead. Nothing is re-charged and nothing is owed differently: what the customer still has to pay is identical before and after. What changes is what the document and the reports show — an invoice paid from a 120 balance reads 120 with 120 credited, not 0. Issued invoices keep their numbers.
Добавлено7
- WHOIS privacy for HRD and OVH. Both registrars can now switch a domain's WHOIS privacy from the panel (client area and admin), and the daily sync reads the state back into
id_protection: HRD viadomain/privacySet, OVH via its WHOIS opt-in (OWO). - A registrar can say it has no transfer lock. A module implementing the new
App\Contracts\CannotManageTransferLockmarker (HRD, Manual) no longer shows a Lock/Unlock control that could only pretend to work. - The admin domain screen does the whole job. A domain can be deleted, its billing edited, the add-domain form validates what it is given, and prices are shown in the currency the shop sells in.
- A missing registration date is filled in. The daily sync and the admin sync button ask the registrar first and fall back to RDAP, so domains imported without that date stop showing a blank. The RDAP pass is capped per run (
DomainSyncRdapMaxPerRun) so a large import does not turn into a flood of lookups. - Pay a covered order from the balance. Checkout shows the account balance and, when it covers the order, lets the customer pay with it instead of going out to a gateway.
- Staff can email a customer the link to add a card, with its own template an operator can reword like every other customer email.
- Italian. A complete translation (#403), joining the languages already shipped.
Изменено3
- The domain screen — staff and client — hides the transfer-lock control for a registrar whose API has none (HRD, Manual), instead of reporting a change it did not make.
- A customer reading a ticket sees the staff member's first name, not the name they sign in with.
- Cancel on the server edit dialog closes the dialog, not the form inside it.
Исправлено6
- Account credit is a payment, not a discount. Spending credit used to lower
invoices.total, so a balance-paid invoice printed a gross of zero, the revenue reports lost the sale, and a partly-credited invoice showed a total that matched no line on it. The gross stays the gross, the credit is recorded and taken off when what is due is worked out, and checkout decides an order is covered from what is actually due. - A partial refund leaves a paid invoice paid. Refunding part of a payment moved the invoice back to partially paid, which then chased the customer for money they had already handed over. Only a refund that clears the whole lot reopens it.
- Add Funds invoices follow the proforma scheme. A top-up is a payment on account, not a supply. It is now numbered and typed the same way — a PRO- proforma when that scheme is on, instead of a PRO- number carrying the
vattype default that made the document print as an ordinary invoice. A top-up stays untaxed, and paying one issues no VAT invoice: the money becomes credit, and VAT is charged on the services that credit later pays. - A paid Add Funds proforma stays visible. "Hide paid proformas" hid every paid proforma, assuming a VAT invoice replaced it. A top-up has no VAT invoice, so hiding it made the payment disappear from every list. Only a proforma whose VAT invoice exists is hidden now.
- An affiliate commission on tax-inclusive prices leaves the tax out, so the shop does not pay commission on money it collects for the tax office.
- The OVH sync no longer takes a transfer date for a registration date. OVH reports when a domain entered that account; for a domain transferred in, that is the transfer, and writing it over a correct date from RDAP made the domain look younger than it is.
Database changes2
2026_11_07_000001_credit_as_payment_restore_gross_totals—invoices.totalis set back to the gross value withROUND(total + credit, 2). It adds back exactly what the old code took off;down()subtracts it again. Invoices with no credit are untouched.2026_11_07_000001_seed_card_setup_request_template— adds the Card Setup Request email template on installations that already exist (fresh installs get it from the seeder), created through the model so every language gets its copy. It does nothing if a template with that name is already there, so an operator's own wording is never overwritten.
For theme and module authors4
- New optional marker
App\Contracts\CannotManageTransferLock: implement it in a registrar module that cannot change the registry lock; the panel then hides the Lock/Unlock control for its domains. Modules that do not implement it keep the control, so nothing changes for them. App\Contracts\SyncsDomainData::syncDomain()may now also returnregistration_date. It is optional: a module that does not return it behaves exactly as before.- Anything reading
invoices.totalas "what is left to pay" must change to read it as the gross and useInvoice::amountDue(). A module that charged the total was charging zero on a balance-paid invoice before this release. dist/is now ignored and export-ignored. If you build packages from a checkout, the output directory is no longer picked up by a straygit addand can never end up inside a package.
Изменённые шаблоны, которые тема может переопределять3
admin/clients/show.blade.php,admin/config/servers.blade.php,admin/domains/index.blade.php,admin/domains/show.blade.php,admin/invoices/show.blade.php,admin/settings/general.blade.phpclient/cart/checkout.blade.php,client/invoices/show.blade.php,client/invoices/partials/payment-notification-form.blade.php,client/tickets/show.blade.phpemails/card-setup-request.blade.php(new),emails/invoice-overdue.blade.php,emails/payment-reminder.blade.php,pdf/invoice.blade.php