=== BulCommerce ===
Contributors: wpsupporting
Tags: woocommerce, invoice, shipping, cash-on-delivery, bulgaria
Requires at least: 6.0
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.4.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

NRA Ordinance H-18 fiscal documents, Econt and Speedy waybills and a compact checkout for Bulgarian WooCommerce stores.

== Description ==

BulCommerce extends WooCommerce with what a Bulgarian store needs to work under the local rules — from fiscal reporting to courier delivery and customer risk checks.

**Documents and compliance**

*   Audit XML file per NRA Ordinance H-18, ready to submit to the revenue agency.
*   Order document, invoice and credit note on refund — generated automatically when the order is placed.
*   Export of invoices and credit notes in Microinvest Delta format.
*   Company billing fields (company name, UIC/EIK, MOL, VAT number) on the checkout.
*   VAT number validation against the European VIES system.
*   Automatic company-details lookup by UIC/EIK.

**Courier delivery**

Separate methods for address and for office/locker delivery, with real-time search against each carrier's official API:

*   [Econt](https://www.econt.com/)
*   [Speedy](https://speedy.bg/)

**Checkout and pricing**

*   A more compact checkout: the country, region, postcode and address fields are hidden and replaced by a single locality search field that loads cities directly from the courier API. The country field can be restored if you also sell abroad.
*   Classic and Modern layouts for the shipping method selector.
*   Automatic order status updates based on the waybill status.
*   Show prices in both BGN and EUR at the same time.

**Customer risk checks**

*   Check the customer against the nepostop.com database (with your own API key) and optionally block cash on delivery for a flagged phone number, with a notice or a popup, plus a customer-status column in the orders list.

**Cash on delivery**

*   A cash-on-delivery module and a dashboard summary of orders and amounts.

== Installation ==

1.  Upload the `bulcommerce` folder to `wp-content/plugins/`, or install the ZIP via **Plugins > Add New > Upload**.
2.  Activate BulCommerce from the **Plugins** menu.
3.  Open the plugin settings and fill in the company details and document numbering.
4.  Enable Econt and/or Speedy from the main settings. After saving and reloading, each enabled courier gets its own settings tab.
5.  Add the shipping methods with the built-in Setup Wizard, or from the **Shipping Methods** tab's "Manage zones" button — both create the Bulgaria shipping zone and add the courier methods for you, no manual digging in WooCommerce's own shipping-zone screens required.
6.  For customer checks, enable the option in the main settings and enter your own nepostop.com API key in the tab that appears.

If you are unsure about an accounting field, consult your accountant.

== Frequently Asked Questions ==

= Do I need a contract with the couriers? =

Yes. Waybills are created through the official Econt and Speedy APIs, so you need an active client account / API access with the carrier, which you enter in its settings tab.

= Does it work with High-Performance Order Storage (HPOS)? =

Yes. The admin screens and order columns support both the classic storage and HPOS.

= What language are the strings in and can I translate them? =

The source strings are in English and follow the standard WordPress translation mechanism, so the plugin can be localized. A Bulgarian translation is bundled.

= When are the documents generated? =

The order document and the invoice are created when the order is placed; the credit note is created on a return/refund.

= Is there a paid version? =

Yes. The paid version adds more couriers (BOX NOW, Sameday, Pigeon, euShipments), a shared customer-risk network, extra checkout templates and more modules. The free version is a fully functional standalone plugin without it.

== Screenshots ==

1. Shipping Methods — enable Econt and/or Speedy, each with its own WooCommerce shipping zones and instance count at a glance.
2. Shipping Methods — a courier fully configured and active, ready to take orders.
3. Checkout design — customize the courier logo buttons (colors, borders, sizes) with a live preview.
4. Addons — turn on invoices & H-18 documents, dual BGN/EUR pricing, the nepostop.com risk check and other optional modules.
5. Checkout — the customer picks an Econt office with a live city/office search, right at checkout.

== External services ==

To automate delivery and order checks, BulCommerce connects to external services. The list below shows each service, the endpoints it contacts, and what data is sent.

Courier services — creating and managing waybills, loading offices/lockers and tracking links. A connection happens only when you enable the courier and enter its credentials:

*   Econt ( [terms](https://www.econt.com/econt-express/terms-of-use) ) — https://www.econt.com/, http://ee.econt.com/, http://demo.econt.com/, https://delivery.econt.com/
*   Speedy ( [terms](https://api.speedy.bg/api/docs/#href-terms) ) — https://www.speedy.bg/, https://api.speedy.bg/

Customer risk checks (optional, only with your own API key):

*   nepostop.com ( [terms](https://nepostop.com/terms), [privacy policy](https://nepostop.com/gdpr) ) — https://nepostop.com/api/v1/phone-check, https://nepostop.com/api/v1/shipments

Company details and VAT numbers (optional):

*   European VIES system — https://ec.europa.eu/taxation_customs/vies/

VIES is contacted in two cases, and in both only the number typed is sent: when a buyer asks for a company invoice and types a UIC/EIK or VAT number, so the company name, town and address can be filled in for them (this can be switched off under Invoices), and when the VIES check for VAT numbers is enabled.

Anonymous usage statistics (optional, off until you switch it on):

*   BulCommerce — https://wpsupporting.com/api/wp/activity

This one is off by default and sends nothing at all until you enable "Share anonymous usage data" under BulCommerce → Settings → General. Once a week it then sends: the versions of WordPress, WooCommerce and PHP, your site language, whether the site is a multisite, and which couriers and features are switched on — plus a one-way fingerprint (SHA-256) of your site address, used only so the same installation is not counted twice. Your site address itself is never sent, and neither are your customers, your orders, your order totals or your API keys. Switching the setting back off stops it completely.

The couriers and nepostop.com may receive the data needed for delivery and checks: recipient name and address, phone, email, order value and cash-on-delivery amount. Data leaves the store only to process and deliver the order, or to assess the risk of abuse. The plugin sends no telemetry.

== Credits ==

Bundled third-party libraries:

*   nra-audit-generator (modified) — https://github.com/escapeboy/nra-audit-generator
*   php-qrcode — https://github.com/chillerlan/php-qrcode
*   vatin — https://github.com/ddeboer/vatin

== Changelog ==

= 1.4.1 =
Fix: the hourly limit on courier office/locker lookups counted the proxy instead of the shopper. Behind Cloudflare or any reverse proxy that is one address for every visitor, so thirty lookups an hour was a budget for the whole shop: after the thirtieth, every further customer was told there had been too many lookups from their address and office selection stopped working for them. The shopper's own address is now used, as WooCommerce already resolves it for the order.
Fix: a product name longer than 200 characters made the whole month's H-18 audit file invalid, so the shop could not file until someone renamed a product. The audit file caps that field at 200 characters; the name is now written trimmed to fit, with the full value recorded in the log. The same cap is applied to the order number and the payment reference fields.
Fix: "There are no orders in this month" now says why. Cash on delivery takes no money at checkout, so WooCommerce records no payment date while the order sits at Processing, and the audit file — which reports the month of delivery — correctly leaves such orders out. It now says so, names the orders, and explains that completing them files them in the month the delivery happened, instead of reading as if the orders had vanished.
Fix: the H-18 readiness check reported "no payment type is set" for every enabled payment method, including ones the export was mapping correctly, because it read the setting from the wrong place.
Changed: a "Need support" button on every settings screen, and a section on the Help and About tabs explaining the two routes — the Facebook group for general questions, a ticket for anything specific to one shop.
Internal: the bundled H-18 schema was compared declaration by declaration with the one NRA publishes and aligned with it; two elements were required here that NRA leaves optional.

= 1.4.0 =
New: company details fill themselves in at checkout. A buyer who asks for a company invoice types the EIK and the company name, town, address and VAT number arrive from the European VIES register. MOL is still typed by hand — no public register publishes it. Every field stays editable, and a second tab is there for a foreign company or one that is not VAT-registered. With JavaScript off the checkout behaves exactly as before.
New: an Ordinance H-18 readiness check on the Invoices & H-18 screen. It reports what would make the audit file invalid before you produce one: a missing NRA reference number or shop domain (both required by the file format), an EIK that is not 9-13 digits, and — the one that loses data silently — a payment method with no H-18 payment type set, whose orders are left out of the file without any warning.
New: a fiscal numbering register showing what each series has actually issued, with any missing or repeated numbers highlighted. Ordinance H-18 requires an unbroken sequence, and until now nothing read the issued numbers back.
New: the "next document number" fields are now checked when you save. A number that is not digits, or that is at or below a number already printed on an issued document, is refused and the previous value kept — re-issuing a fiscal number cannot be undone once a customer has the document.
New: "Kind of shop" under Company info — own domain or online sales platform. The audit file always declared "own domain" before, with no way to correct it.
New: optional anonymous usage statistics, off unless you switch them on under Settings > General. See "External services" for exactly what is sent; your site address, customers, orders and API keys are never among it.
Fix: shipping was missing from the H-18 audit file, and a single order with no lines at all made the whole month's file invalid.
Fix: schema errors from the audit file are explained in plain language naming the setting to correct, instead of the raw English validator output.
Changed: several labels on the invoices and H-18 documents were reworded, and two documents that named the same field differently now agree. The statutory requisites are unchanged.

= 1.3.10 =
Fix: after updating to 1.3.8 or 1.3.9, Econt and Speedy reported "this username and password were rejected" and their settings screens came up empty. Nothing was lost — an internal rename left the "profile is valid" flag stored under its old name, and the panels hide their fields until that flag reads true. The value is moved to its current name automatically on update; no re-entering of credentials is needed.
Fix: cancelling a courier waybill reported success even when the courier had refused it. Econt answers per shipment rather than per request, so a refusal was read as a success: the waybill data was cleared from the order and the merchant was told the shipment was cancelled while it was still live at the courier. Both Econt and Speedy now refuse with the courier's own message and leave the order untouched.

= 1.3.9 =
Fix: saving settings failed with a critical error on every settings screen in 1.3.8 — the save handler called methods an internal rename had removed. If you are on 1.3.8, update now.
Fix: the documents export left out the Ordinance H-18 documents themselves. On a shop selling to private buyers those are most of what exists, so a month of nothing but H-18 orders produced an empty archive. Both the sale and refund H-18 documents are now included.
Fix: the multi-month export read its own generated NRA and Microinvest files over HTTP instead of from disk; on hosts that block or time out that loopback request the month's file arrived empty or not at all. A month with no NRA file is now listed with the reason rather than quietly missing.
Fix: credit notes in the document archive were named after the parent order id, which is always 0 — "0-refund-60.pdf" instead of "60-refund.pdf".
Fix: the Econt order panel could log "Attempt to read property ID on null" when WooCommerce's High-Performance Order Storage is enabled, and print it into the admin page with debugging on.
Changed: showing lev and euro prices side by side is now a Pro-only feature and is no longer part of this edition.
Note: several of the plugin's own CSS class names changed. Custom CSS that targets them needs updating.

= 1.3.8 =
Fix: delivery the shop charged for was left out of the Ordinance H-18 audit file on cash-on-delivery orders shipped by a courier, so the reported order total was lower than the real one. A fully refunded order was then reported as a refund larger than the sale, which the NRA validates against. The setting that hides delivery on a printed invoice is a layout preference and no longer touches the audit file.
Fix: a single order with no products, shipping or fees made the entire monthly audit file invalid and the NRA rejected the submission. Such orders are now excluded and listed by number, so the file goes through and the problem order can be corrected.
Fix: a fiscal document number was used up even when the document itself failed to generate, leaving a permanent gap in the H-18 sequence with nothing behind it. The number is now returned to the sequence when that is safe, and written to the log with its number when it is not, so the gap can be accounted for.
Fix: the Shipping methods settings screen filled the error log on PHP 8.1 and newer — one notice per courier on every page view — for shops using the default courier logos.

= 1.3.7 =
Fix: the Econt waybill preview could show a raw "FPDF error: Missing or incorrect image file" instead of the label. Econt's print service fails intermittently; the plugin now retries it before giving up, and shows a clear message rather than the courier's error page if the waybill still cannot be fetched.
Fix: the waybill preview ignored the print size chosen in the Econt settings and always used 10x9.
Fix: the "Print waybill" link could stop working and answer "-1" when the order screen had been left open for a long time.

= 1.3.6 =
Improved: the QR code on invoices and NRA documents is noticeably larger, so it scans reliably. The fiscal (Ordinance H-18) QR in particular was being printed far too small.
Improved: the city dropdown at checkout now lists each city on two lines (name, then region and post code), matching the office pickers.
Fix: on the Orders screen, a courier logo with wide proportions could overflow the "Carrier" column and run into the next one.

= 1.3.5 =
Fix: Speedy shipping rates could fail with a critical error when tax calculation was enabled (a missing class reference now resolves correctly).
Fix: the Cash on Delivery panel's live total/status update (after "mark received") now respects the store's configured decimal separator instead of always showing a period.
Fix: a rare timing issue could let a GDPR erase (or un-flagging a phone number) silently drop a risk report added moments earlier.
Fix: buyer risk-check (NepoStop) connection failures are now logged, so a merchant can tell risk-checking silently stopped working during an outage instead of finding out with no trace afterward.

= 1.3.4 =
Fix: the Dashboard's "Orders by courier" panel showed a critical error on every site — a helper function used to render each courier's icon was missing from the 1.3.3 package. Update as soon as possible if you're on 1.3.3.

= 1.3.3 =
Fix: NRA credit-note/refund documents and the Microinvest Delta invoice-date column could print the wrong day near local midnight (timezone offset applied twice).
Fix: the Dashboard's daily revenue chart could mislabel days near local midnight for the same reason.
Fix: Dashboard "best-selling products" undercounted decimal-quantity sales; the Dashboard/COD money display now respects the store's configured decimal separator instead of a hardcoded period.
Fix: the Speedy COD label panel now nets out already-refunded amounts instead of pre-filling the pre-refund total.

= 1.3.2 =
Fix: several Bulgarian translation strings that were missing on the "Own delivery / Pickup" settings and the Accountant addon's digest-day field.
Improved: the Installation instructions now describe the automated Setup Wizard / "Manage zones" shipping setup instead of the older manual steps.

= 1.3.1 =
Fix: checkout could fail with a fatal error when "Hide delivery line from documents" (NRA / Fiscal settings) was enabled — a leftover call from the 1.3 refund-shipping fix was missing an argument. If you use that setting, update as soon as possible.

= 1.3 =
New: an explicit "who pays the courier?" setting for Speedy, decoupled from whether pricing is fixed or live.
New: option to show the order number instead of the product list in the Speedy waybill content field.
Fix: Speedy orders now correctly fold the shipping cost into cash-on-delivery in every pricing mode, not just fixed-price.
Fix: cash-on-delivery on Speedy orders is now taken from the order's real payment method instead of a checkout-time cookie, so it can no longer go out uncollected (or stay demanded) if the customer changes payment method after choosing a shipping option.
Fix: a credit note / refund document no longer loses its shipping line item when generated for a fully refunded, cash-on-delivery courier order.
Fix: the Setup Wizard's "buyer risk check" step now links directly to a free nepostop.com signup and explains that a nepostop.com API key still needs to be entered under Risk checks to activate it.
Fix: several Setup Wizard screens that were showing English text even when the site language was set to Bulgarian.

= 1.2 =
First release on WordPress.org.

Fiscal documents: audit XML per NRA Ordinance H-18, order document, invoice and credit note generated from the order, and a Microinvest Delta export. Company billing fields (name, UIC/EIK, MOL, VAT number) with VIES validation and automatic company lookup by UIC/EIK.

Courier delivery: Econt and Speedy, to address and to office/locker, with live rates from each carrier's API, office and street search, waybill creation and printing, and automatic order status updates from the waybill.

Checkout: a compact layout that replaces country/region/postcode/address with a single locality search fed by the courier's own city database, Classic and Modern shipping-method layouts, and prices shown in both BGN and EUR.

Own delivery / Pickup: run deliveries yourself with no courier account — home delivery and/or pickup from one of your own locations, with a flat price per mode and an optional free-shipping threshold.

Customer risk checks (optional): check the buyer's phone against nepostop.com with your own API key, with an orders-list column and the option to withhold cash on delivery from a flagged number.

Cash on delivery: a dedicated module with a dashboard summary of orders and amounts.
