OptionKit Add-ons — Documentation

Guide to installing and using OptionKit Add-ons (version 0.5.4). The plugin is standalone, so this page covers all of it. Product page: OptionKit Add-ons.

1. Installation

  1. Install and activate WooCommerce 8.0 or newer.
  2. In WordPress, go to Plugins → Add New → Upload Plugin and upload the OptionKit Add-ons zip file you downloaded from WPBay. Updates are delivered through WPBay.
  3. Activate OptionKit Add-ons on the Plugins screen. Everything works straight away; there is no key or account to enter.
  4. Open WooCommerce → OptionKit Add-ons.

Coming from the free OptionKit plugin? You do not need to deactivate it first: while OptionKit Add-ons is active, the free plugin pauses itself and shows a notice. Both use the same option groups, so your groups, fields and assignments are there immediately. You can then deactivate the free plugin.

If WooCommerce is missing, inactive or older than 8.0, the plugin shows a notice and does nothing else until WooCommerce is ready.

2. Requirements and compatibility

ItemRequirement
WordPress6.3 or later (tested up to 7.1)
PHP7.4 or later (tested on 7.4 and 8.4)
WooCommerce8.0 or later, required (tested up to 11.1)
Order storageHigh-Performance Order Storage (HPOS) and legacy posts storage; compatibility with HPOS is declared
Cart and Checkout blocksSupported through the Store API, including the cart's "Edit options" link
Who can manageUsers with the manage_woocommerce capability (store managers and administrators)
Web serverApache and IIS protect customer uploads automatically; nginx needs one rule (see Upload folder protection)

3. Where to find things

All screens are under the WooCommerce menu:

Menu itemWhat it is for
OptionKit Add-onsOption groups: list, add, edit, export and import; a Status box (WooCommerce version, order storage, database tables)
Lookup tablesCSV price tables used by the "Lookup table" price
Starter templatesReady-made groups installed as drafts
Option analyticsReports on option use and revenue
Import add-onsImporters for other add-on plugins' data, with dry run
OptionKit Add-ons settingsDelete data on uninstall, Option statistics, Keep statistics for, Upload limits, Customer uploads (storage usage), Upload folder protection

On each product's edit screen, the Product data → OptionKit tab holds Local option groups for that product.

4. Creating an option group

  1. Open WooCommerce → OptionKit Add-ons and click Add group, or install a starter template.
  2. Enter a Name (and optionally a Slug).
  3. Choose a Status: Draft groups are never shown to customers; Active groups are.
  4. Set a Priority: when several groups apply to one product, lower numbers are shown first.
  5. Pick a Layout (see Group layouts) and an optional Shipping hint.
  6. Choose the products under Assignment and click Create group.
  7. Click Add field for each field.

There is no limit on the number of active groups or fields per group.

5. Field types and settings

OptionKit Add-ons has 13 field types:

TypeUse
TextOne line of text (up to 500 characters unless you set a lower max length).
Text areaSeveral lines; line breaks are kept (up to 5,000 characters unless you set a lower max length).
NumberA number with optional min, max and step.
Dropdown, Radio buttons, CheckboxesChoices with their own prices; can be shown as swatches.
Range sliderA slider with min, max, step and a unit (see Date and range fields).
DateA date picker with earliest and latest day and an optional "No weekends".
File uploadA private customer upload (see File uploads).
Calculated feeA fee worked out by a formula or lookup table; the customer enters nothing.
SignatureA signature pad; the drawing is stored as a PNG with the upload system.
Shortcode / HTMLDisplay-only content on the product page.
Repeater (multiple entries)1 to 20 entries of the same small set of sub-fields (see Repeater fields).

Settings every field has

6. Pricing types

Prices are previewed live on the product page and always recalculated on the server when the product is added to the cart or the cart is updated.

Price typeHow it is charged
NoneNo charge.
FlatThe amount is added to each item, so it is multiplied by the quantity.
% of baseA percentage of the product price (the variation's price for variable products), added to each item.
Per qtyThe amount per item, multiplied by the quantity (same calculation as Flat).
One-timeAdded once per cart line, whatever the quantity.
FormulaThe result of a formula, either per item (× quantity) or once per cart line (see Formulas).
Lookup tableA value looked up in a CSV table, per item or once per cart line (see Lookup tables).
Per entry (repeater)For repeater fields: the amount for each entry after the free entries, per item (× quantity).

7. Assigning groups to products

8. Showing and hiding fields

In the field editor under Conditions:

  1. Choose Show this field or Hide this field.
  2. Choose when all conditions match (AND) or when any condition matches (OR).
  3. In each condition row choose a field from the same group, a comparison (equals, does not equal, contains, is empty, is not empty, is checked, is not checked) and a value. For choice fields, compare with the choice's value; the value box suggests the chosen field's choice values.
  4. Click Add condition for another row, or Remove to delete one. Rows without a field are ignored, and a field with no conditions is always shown.

Example: show Engraving when Size equals l and Material equals metal; show Card message when Size equals s or Gift is checked wrap.

Conditions are saved in the same format as a group's JSON export, so they survive export and import and reopen in the editor exactly as saved. A condition must point at another field of the same group; conditions on a deleted field are removed when you save. Nested condition groups brought in through JSON (see JSON export and import) are kept when you save the field; the editor notes them, and each counts as one more condition in the AND/OR match.

The rows are keyboard accessible: every control has a numbered label for screen readers (for example "Condition 2: field"), Add condition moves focus to the new row, Remove moves focus to the next row, and additions and removals are announced.

Hidden fields are not charged and not required. The server applies the same rules and drops values sent for hidden fields.

9. Formulas and calculated fees

Choose the Formula price on a field, or add a Calculated fee field (always priced by its formula, never asks the customer for input). Enter the formula under Price formula and choose per item (× quantity) or once per cart line.

PartAvailable
Variablesbase (product price), qty (quantity), value (this field or chosen choice as a number), len (characters without spaces), count (choices picked), and any other field by its Key. A checkbox field's key gives the number of ticked choices; an upload field gives 1 when a file is attached.
Functionsmin(a, b, …), max(a, b, …), round(x) or round(x, digits) (0–6), ceil(x), floor(x), abs(x), clamp(x, low, high), if(condition, then, else)
Operators+ - * / % ^ < <= > >= == != && || !
max(5, width * height * 0.02)      area fee with a 5.00 minimum
if(len > 10, len * 0.5, 5)          engraving: 5.00 up to 10 characters, otherwise 0.50 per character
clamp(value * 0.1, 1, 20)          10% of a number field, between 1 and 20

10. Swatches

For dropdown, radio and checkbox fields, set Choice style to Text buttons, Color swatches or Image swatches (or keep Default). On each choice row, enter a color (#hex) or pick an image from the media library with the Image button. Swatches are real radio buttons and checkboxes underneath, so they work with the keyboard and screen readers; the visible label names each swatch.

11. Date and range fields

12. File uploads

What is checked for each file type

The file name and the browser's stated type are never trusted on their own. A file is accepted only when its content passes the check for its type:

TypeContent check
JPEG, PNG, GIF, WebPThe file signature (first bytes) must match the extension; PHP's fileinfo must detect the same image type; the image must decode as that type (getimagesize) and be at most 12,000 pixels wide or high; files containing <?php or script tags (image/PHP polyglots) are refused.
PDFMust start with %PDF- and contain %%EOF in the last 2 KB; fileinfo must detect application/pdf. PDFs that declare JavaScript (/JS, /JavaScript), launch actions (/Launch), embedded files, /RichMedia or XFA forms are refused, including hex-escaped names and compressed streams. This is a structural safety check, not a full PDF parser or virus scan.
Plain text (.txt)UTF-8 or ASCII, no NUL bytes, no HTML, PHP or script tags, at most 2 MB; fileinfo must detect a text type that is not HTML, PHP, script or XML.

If the server's PHP has no fileinfo extension, the signature and structure checks still run. No other formats can be enabled: the optionkit_pro_upload_types filter can only remove types.

Upload limits

Set under WooCommerce → OptionKit Add-ons settings → Upload limits (0 = no limit). Every upload must fit all of them, so starting a new session or clearing cookies does not reset the IP address or store limits:

LimitDefault
Per guest IP address (IPv6 grouped by /64), per hour30 files, 100 MB
Per guest session, per hour30 files
Per customer account (logged in), per hour60 files, 250 MB
Whole store, per hour500 MB
Whole store, uploads waiting to be ordered2,000 files, 1 GB

Counters are atomic database updates, so parallel requests cannot go over a limit. Over a limit the visitor sees a short message and the response is HTTP 429 with a Retry-After header. The settings screen shows pending upload storage and this hour's total. Only a one-way keyed hash of the IP address is stored, never the address, and the hourly counters are deleted about two hours after the hour ends. The IP address comes from REMOTE_ADDR; behind a trusted reverse proxy, return the real client IP with the optionkit_pro_upload_client_ip filter. Developers can also adjust the limits with the optionkit_pro_upload_limits filter.

13. Upload folder protection (nginx)

WooCommerce → OptionKit Add-ons settings → Upload folder protection shows the folder, the web server and the last result. Check now writes a random test file into the folder, requests it once from your own site, then deletes it. No other site is contacted. The result is one of:

Apache and IIS read the generated .htaccess / web.config. nginx ignores them, so add this inside your site's server block, reload nginx (nginx -t then systemctl reload nginx, or your host's equivalent), and click Check now:

location ^~ /wp-content/uploads/optionkit-secure/ {
    deny all;
    return 404;
}

The settings screen prints this rule with your site's actual path; use that path if your uploads folder is elsewhere. Alternatively, move the folder outside the web root by adding this line to wp-config.php:

define( 'OPTIONKIT_PRO_UPLOAD_DIR', '/path/outside/webroot/optionkit-secure' );

14. Signature, shortcode/HTML, first choices free, weight and role prices

15. Repeater fields

A repeater lets the customer add several entries of the same sub-fields, for example a name, number and size per team shirt.

  1. Add a field of type Repeater (multiple entries).
  2. Under Repeater entries, enter one sub-field per line as key | Label | type | options. Types: text (options = max length), number (options = min-max), select (options = comma-separated choices). End a label with * to make it required. Up to 6 sub-fields.
  3. Set Min entries, Max entries (up to 20), Free entries and the "Add" button text.
  4. For a price per entry, choose the Per entry (repeater) price: the amount is charged for each entry after the free ones, per item (× quantity). A Flat price charges its amount once per item, however many entries there are.
name | Name* | text | 20
number | Shirt number | number | 0-99
size | Size* | select | S, M, L, XL

Entries are checked on the server, saved with the cart line and order, and can be changed from the cart. Adding and removing entries is announced to screen readers.

16. Lookup tables (CSV)

Lookup tables give a price from one or two values, for example width × height or size × material.

  1. Go to WooCommerce → Lookup tables → Add lookup table. Enter a name, choose 1 or 2 axes, optional axis labels, and paste the CSV.
  2. In a field (often a Calculated fee field), choose the Lookup table price, pick the table, enter the axis fields (other fields' Keys, or value, base, qty) and choose per item or once per cart line.

CSV format, one axis: each line is label,price. Two axes: the header row is ,col1,col2,…, then each row is rowlabel,price,price,….

S,5
M,7.5
L,10
,oak,walnut
60,120,150
80,140,175
100,160,199

17. Starter templates

WooCommerce → Starter templates: click Install as draft group on a card. Each install creates a new draft group (existing groups are never overwritten); assign it and set it to Active.

TemplateContents
EngravingOptional engraving text, 40 characters, flat fee 5.00
Gift wrapRequired radio "No thanks" / "Yes, wrap it" (3.50) and an optional gift message (200 characters)
Pizza toppingsFive checkbox toppings (1.00–2.50) with the first two free
MeasurementWidth and height in cm (1–500, step 0.1) and an "Area fee" calculated fee: max(5, width * height * 0.02)

Amounts are in your store currency; change them after installing.

18. Importing from other add-on plugins

WooCommerce → Import add-ons reads data that the other plugin already stored in your WordPress database (product meta and its own post types). It never downloads or includes the other plugin's code, and it never changes the other plugin's data.

  1. Choose the source: WooCommerce Product Add-Ons, PPOM (Themeisle) or ThemeComplete Extra Product Options.
  2. Click Dry-run (no writes). The report lists what is Mapped, what Would create, what Needs manual follow-up, what was Skipped and any Errors.
  3. When the report looks right, click Import. Groups are created as Draft; review them, then set them to Active.
SourceWhat is imported
WooCommerce Product Add-OnsPer-product add-ons (up to 200 products per run): text, textarea, number, checkbox, multiple choice, select and file upload fields with their choices and choice prices. Each product's group is assigned to that product.
PPOMPPOM field groups: text, textarea, number, select, radio, checkbox, date, file, image and color fields, with choices and choice prices. Groups are created without assignments.
ThemeComplete EPOGlobal forms (up to 100): field types and labels for text, textarea, date, range, color, select, radio, checkbox and upload elements. Choices and prices are not imported. Product-level EPO data and nested builder data are listed for manual follow-up.

Conditional rules, field-level prices and field types without an equivalent are not imported; they are listed in the report so you can recreate them.

19. Group layouts

Choose the Layout on the group's edit screen:

If a required field is inside a closed tab, step, accordion or popup, it is revealed and focused before the error message appears.

20. Editing options from the cart

Each cart line with options gets an Edit options link in the classic cart and the Cart block. It opens the product's fields in a dialog; Update cart item saves the changes after the same server checks as add-to-cart, with recalculated prices.

21. Option analytics and retention

WooCommerce → Option analytics shows, for the last 7, 30, 90 or 365 days or custom dates (site time zone):

How it is counted. At checkout each order line gets a small hidden summary of its option amounts (product, quantity, amount per field and per chosen choice; typed-in text is never included). When the order becomes paid, the summary is added to daily totals and the order is stamped with the day it was counted. If the order is later cancelled, refunded or failed, its amounts are subtracted again. Attachment rate is the share of cart lines with at least one option among lines for products that offer options. Option revenue is the option amounts charged at checkout, before coupons.

Settings (WooCommerce → OptionKit Add-ons settings):

Rebuild from orders recounts paid orders inside the retention period (up to 5,000 per run, oldest first). Orders placed before version 0.5.0 count option use but not option revenue. Delete all statistics empties the table.

22. JSON export and import

On the option groups screen, Export JSON downloads a group with its fields, choices, prices, conditions, layout and assignments. Import group (JSON) creates a new Draft group from such a file. Assignments refer to product, category and tag IDs, which can differ between sites, so check them after importing elsewhere. A rule's top-level conditions can list several fields with "match": "all" (AND) or "match": "any" (OR).

23. Accessibility

Please report any barrier to admin@007aj.com.

24. Performance

25. Privacy and personal data

What is stored

Export and erasure

Option values are included in Tools → Export Personal Data. On Tools → Erase Personal Data, when WooCommerce is set to remove personal data from orders on erasure requests (WooCommerce → Settings → Accounts & Privacy):

RemovedKept
Option values on that customer's orders (anonymised); files uploaded with those orders (deleted); the hidden analytics summary on each line and the order's counted-on dayOption prices as part of the order totals; anonymous daily analytics totals (they contain no personal data)

When WooCommerce is set to keep order data, option values and files are kept with the order and the eraser reports that they were retained.

Suggested privacy policy text (including paragraphs on uploads and statistics) is added under Settings → Privacy. The plugin sends nothing to 007AJ or anyone else; its only HTTP request is the upload folder loopback check described above. Privacy policy of the plugin author: https://007aj.com/privacy.

26. Deactivating, uninstalling and deleting data

Deactivating stops the plugin and its daily clean-up events but keeps your data. Deleting the plugin keeps settings, option groups and statistics unless you first tick Delete data on uninstall in the settings; then the settings, statistics table, cache and option group tables are removed. If the free OptionKit plugin is still installed, the shared option group tables are kept for it (the statistics table is always removed). Options already saved on orders are never removed.

27. Known limits

28. Questions

Do I need the free OptionKit plugin too?

No. OptionKit Add-ons is standalone. If the free plugin is active it pauses itself.

Do I need a key or account?

No. Nothing is locked and nothing is checked remotely. Updates are delivered through WPBay.

Why does a lookup table price show 0?

The value did not match a label exactly, or an axis Key is wrong. Check that the axis fields' Keys are entered in the field's Lookup table settings and that the values match the CSV labels.

Why does my formula give 0?

The field editor shows a "Formula error" message if the formula cannot be read. Unknown keys count as 0, so check spelling against the other fields' Keys.

My server is nginx. Are customer uploads safe?

Not until you add the rule in Upload folder protection (or move the folder outside the web root). The plugin warns you until the check passes.

Can customers change options after adding to the cart?

Yes, with the "Edit options" link on each cart line.

Where do I get help?

Email admin@007aj.com.

29. Changelog

0.5.4

0.5.3

0.5.2

0.5.1

0.5.0

0.4.0

0.3.0

0.2.1

0.2.0

0.1.0 – 0.1.1

Support: admin@007aj.com · Privacy · Terms · 007aj.com