Skip to content

Developer notes

← Overview

app/addons/kv_returns_portal/
addon.xml settings, 3 tables, 2 privileges, 2 e-mail templates
init.php / func.php hooks, signed order links, settings info, licence helpers
controllers/frontend/kv_returns_portal.php withdraw (look-up / statement), lookup, review (step 2), confirm,
done, document, model_form
controllers/frontend/orders.post.php order page button and order list column
controllers/backend/kv_returns_portal.php register: manage, details, update, m_update_status, resend, export, document
controllers/backend/orders.post.php notice on the admin/vendor order page
controllers/backend/kv_returns_portal_license.php "Check now" and licence cron
schemas/menu/*.post.php Orders → Withdrawals (admin and vendor panel)
schemas/permissions/*.post.php privileges, vendor modes
schemas/settings/variants.functions.post.php order status and RMA action variants
Tygh/Addons/KvReturnsPortal/
Config.php settings access, licence state
Orders.php contracts (orders / vendor sub-orders), withdrawal period, lines, exclusions, delivery dates
Statement.php access, guest look-up, validation (step 1), submission (step 2)
Signer.php HMAC tokens: order links, statement payload, document links; references
Repository.php register storage, search, CSV, retention, rate limits
Automation.php order cancellation and RMA return requests
Notifier.php acknowledgement and notices, attachment
Document.php the confirmation document
Labels.php labels and date formatting
License/, Upgrade/ licence client, self-healing upgrades
design/backend/templates/addons/kv_returns_portal/ register views, licence UI
var/themes_repository/responsive/templates/addons/kv_returns_portal/
views/kv_returns_portal/*.tpl storefront pages (components/page.tpl, contract_lines.tpl, model_form.tpl)
hooks/index/footer.post.tpl footer strip
hooks/orders/details_tools.post.tpl order page button
hooks/orders/manage_header.post.tpl, manage_data.post.tpl order list column
hooks/profiles/my_account_menu.post.tpl account menu link
blocks/static_templates/withdrawal_button.tpl Block Manager template "Withdrawal button"
var/themes_repository/responsive/css/addons/kv_returns_portal/styles.less
js/addons/kv_returns_portal/func.js
var/langs/en/addons/kv_returns_portal.po

The storefront keeps no state in the session:

  1. kv_returns_portal.withdraw (GET) shows the look-up or, with access, the statement form. Access: the order belongs to the signed-in customer (fn_is_order_allowed), or the request carries t = HMAC(order ID | order e-mail).
  2. kv_returns_portal.lookup (POST) checks the image verification (scenario kv_withdrawal) and the rate limit, compares the order e-mail (case-insensitive) and redirects to the signed statement form.
  3. kv_returns_portal.review (POST) validates the statement and renders step 2 with a signed payload (payload + signature, HMAC-SHA256, one hour, with a random nonce).
  4. kv_returns_portal.confirm (POST) verifies the payload, re-checks the order and creates the records. The nonce is the batch key (UNIQUE(batch, order_id)), so repeated posts return the same statement. Then the follow-up actions run, the acknowledgement and the notices are sent, and the customer is redirected to kv_returns_portal.done?ref=…&t=….

The HMAC key is derived from $config['crypt_key']. All links on the storefront are static (no session data is printed into cached pages); the withdrawal pages are not on the full page cache’s cacheable list.

Table Contents
?:kv_wdr_withdrawals One row per order (vendor sub-order on Multi-Vendor) and statement: reference, batch, order, parent order, company, user, name, e-mail, order e-mail, scope (F/P), items JSON, excluded items JSON, reason, comment, submission time, period end, in period (Y/N), refund due, status (N/P/R/C/D), automatic action (N/C/R), RMA return ID, previous order status, acknowledgement time or error, IP, language, notes
?:kv_wdr_order_dates order_id, delivered_at: when an order entered a “delivered” status
?:kv_wdr_attempts Hashed IP, kind (failed look-up / statement), time: the rate limit (kept 24 hours)

All are InnoDB. Uninstall drops them.

change_order_status (delivery time), delete_order (removes the delivery time; the register keeps its records), mailer_send_pre (box in customer order_notification.* e-mails), settings_variants_image_verification_use_for (antibot scenario). All exist with the same arguments in 4.17.2 and 4.21.2. Template hooks: index:footer, orders:details_tools, orders:manage_header, orders:manage_data, profiles:my_account_menu.

When the RMA add-on is active, Automation::createReturn() writes the same rows as the RMA add-on’s own Return registration: ?:rma_returns (status R), ?:rma_return_products and the returns entry in ?:order_details.extra. No RMA e-mail is sent by the add-on; the store notice covers it.

Storefront pages: kv_wdr_step (lookup, statement, review, done, expired), kv_wdr_order, kv_wdr_contracts, kv_wdr_summary, kv_wdr_doc. Order pages: kv_wdr_order_link, kv_wdr_order_links. CSS classes start with kv-wdr- under the root class .kv-returns-portal.

Config::isLicensed() (License\Client::isActive()) gates the extras: item selection, reasons and comments, automatic cancellation and RMA requests, the PDF attachment, the box in order e-mails, the register filters and the CSV export. The withdrawal button, the whole-order statement, the acknowledgement, the notices and the register never depend on it. The check runs only in the admin panel or from cron (php admin.php --dispatch=kv_returns_portal_license.check).