{"id":351260,"date":"2026-08-14T15:04:18","date_gmt":"2026-08-14T15:04:18","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/print-app-product-options-for-woocommerce\/"},"modified":"2026-10-26T15:49:26","modified_gmt":"2026-10-26T15:49:26","slug":"print-app-product-options-for-woocommerce","status":"publish","type":"plugin","link":"https:\/\/ko.wordpress.org\/plugins\/print-app-product-options-for-woocommerce\/","author":20912014,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.4.17","stable_tag":"0.4.17","tested":"7.0.7","requires":"6.2","requires_php":"7.4","requires_plugins":null,"header_name":"Print.App Product Options for WooCommerce","header_author":"Print.App","header_description":"Print product configurator for WooCommerce \u2014 options, live pricing, artwork upload. Prices are always re-verified server-side.","assets_banners_color":"ddfbfe","last_updated":"2026-10-26 15:49:26","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/options.print.app","header_author_uri":"","rating":0,"author_block_rating":0,"active_installs":0,"downloads":863,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.4.0":{"tag":"0.4.0","author":"printapp","date":"2026-08-14 15:03:43","revision":3647598},"0.4.1":{"tag":"0.4.1","author":"printapp","date":"2026-08-14 17:50:11","revision":3647785},"0.4.10":{"tag":"0.4.10","author":"printapp","date":"2026-10-07 13:58:31","revision":3732720},"0.4.11":{"tag":"0.4.11","author":"printapp","date":"2026-10-08 06:07:50","revision":3733757},"0.4.12":{"tag":"0.4.12","author":"printapp","date":"2026-10-14 12:25:52","revision":3746314},"0.4.13":{"tag":"0.4.13","author":"printapp","date":"2026-10-14 13:39:33","revision":3746501},"0.4.14":{"tag":"0.4.14","author":"printapp","date":"2026-10-17 14:08:43","revision":3751995},"0.4.15":{"tag":"0.4.15","author":"printapp","date":"2026-10-18 10:28:35","revision":3752885},"0.4.16":{"tag":"0.4.16","author":"printapp","date":"2026-10-26 14:21:08","revision":3766653},"0.4.17":{"tag":"0.4.17","author":"printapp","date":"2026-10-26 15:49:26","revision":3766845},"0.4.2":{"tag":"0.4.2","author":"printapp","date":"2026-09-10 11:43:26","revision":3689825},"0.4.3":{"tag":"0.4.3","author":"printapp","date":"2026-09-21 10:52:23","revision":3705432},"0.4.4":{"tag":"0.4.4","author":"printapp","date":"2026-09-21 11:44:59","revision":3705516},"0.4.5":{"tag":"0.4.5","author":"printapp","date":"2026-09-23 11:23:02","revision":3709180},"0.4.6":{"tag":"0.4.6","author":"printapp","date":"2026-10-01 17:00:42","revision":3723524},"0.4.7":{"tag":"0.4.7","author":"printapp","date":"2026-10-01 17:26:25","revision":3723601},"0.4.8":{"tag":"0.4.8","author":"printapp","date":"2026-10-06 15:47:00","revision":3731164},"0.4.9":{"tag":"0.4.9","author":"printapp","date":"2026-10-06 17:01:58","revision":3731272}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3647598,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3647598,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3647598,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3647598,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["0.4.0","0.4.1","0.4.10","0.4.11","0.4.12","0.4.13","0.4.14","0.4.15","0.4.16","0.4.17","0.4.2","0.4.3","0.4.4","0.4.5","0.4.6","0.4.7","0.4.8","0.4.9"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3647598,"resolution":"1","location":"assets","locale":"","width":1600,"height":900},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3647598,"resolution":"2","location":"assets","locale":"","width":1600,"height":900},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3647598,"resolution":"3","location":"assets","locale":"","width":1600,"height":900},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3647598,"resolution":"4","location":"assets","locale":"","width":1600,"height":900}},"screenshots":{"1":"The configurator on a product page: options, live pricing, and the verified total.","2":"The visual builder \u2014 outline, editor and a live preview of the storefront widget.","3":"Ready-made print templates: business cards, flyers, stickers, thesis binding and more.","4":"Every price is recomputed and signed on the server before it can reach the cart."}},"plugin_section":[],"plugin_tags":[15432,890,155785,24228,286],"plugin_category":[45],"plugin_contributors":[271287],"plugin_business_model":[],"class_list":["post-351260","plugin","type-plugin","status-publish","hentry","plugin_tags-price-calculator","plugin_tags-printing","plugin_tags-product-options","plugin_tags-web-to-print","plugin_tags-woocommerce","plugin_category-ecommerce","plugin_contributors-printapp","plugin_committers-printapp"],"banners":{"banner":"https:\/\/ps.w.org\/print-app-product-options-for-woocommerce\/assets\/banner-772x250.png?rev=3647598","banner_2x":"https:\/\/ps.w.org\/print-app-product-options-for-woocommerce\/assets\/banner-1544x500.png?rev=3647598","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/print-app-product-options-for-woocommerce\/assets\/icon-128x128.png?rev=3647598","icon_2x":"https:\/\/ps.w.org\/print-app-product-options-for-woocommerce\/assets\/icon-256x256.png?rev=3647598","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/print-app-product-options-for-woocommerce\/assets\/screenshot-1.png?rev=3647598","caption":"The configurator on a product page: options, live pricing, and the verified total."},{"src":"https:\/\/ps.w.org\/print-app-product-options-for-woocommerce\/assets\/screenshot-2.png?rev=3647598","caption":"The visual builder \u2014 outline, editor and a live preview of the storefront widget."},{"src":"https:\/\/ps.w.org\/print-app-product-options-for-woocommerce\/assets\/screenshot-3.png?rev=3647598","caption":"Ready-made print templates: business cards, flyers, stickers, thesis binding and more."},{"src":"https:\/\/ps.w.org\/print-app-product-options-for-woocommerce\/assets\/screenshot-4.png?rev=3647598","caption":"Every price is recomputed and signed on the server before it can reach the cart."}],"raw_content":"<!--section=description-->\n<p>Print Options renders a fast, accessible configurator on your product pages:<\/p>\n\n<ul>\n<li>Visual builder with print-ready templates (business cards, stickers with\narea pricing, t-shirt size \u00d7 color matrices, posters, \u2026) \u2014 right inside\nyour WordPress admin, no JSON anywhere<\/li>\n<li>Live price preview: per-unit, per-page, per-area, quantity breaks\n(flat or graduated), setup fees, minimum orders<\/li>\n<li>Conditional options, multi-select finishes, and artwork upload<\/li>\n<li>Prices are ALWAYS re-verified server-side before an item enters the cart \u2014\nthe browser price is never trusted.<\/li>\n<\/ul>\n\n<p>Create your option sets on the Print Options page, then open any product and\npick a set from its Print Options tab \u2014 next to Attributes and Variations.\nEditing a set later updates every product that uses it.<\/p>\n\n<p>Requires WooCommerce.<\/p>\n\n<h3>External Services<\/h3>\n\n<p>This plugin connects to the Print.App options service to do its job. No\ncustomer account is required and no personal data is sold or shared.<\/p>\n\n<p><strong>api.print.app<\/strong> (Print.App API)<\/p>\n\n<ul>\n<li><em>Price verification<\/em> \u2014 when a customer adds a configured product to the\ncart, the selected options and the product's option set are sent\nserver-to-server so the price can be recomputed independently of the\nbrowser. No customer names, emails or addresses are transmitted.<\/li>\n<li><em>Artwork upload<\/em> \u2014 when a customer uploads a file, the browser requests a\none-time upload authorization. The file itself goes directly to storage\nand is automatically deleted after 30 days.<\/li>\n<li><em>Option set management<\/em> \u2014 when a shop manager saves or assigns option\nsets, the set definition is stored under an anonymous store identifier\n(a random ID generated at activation; your site URL host is recorded as\nmetadata only).<\/li>\n<\/ul>\n\n<p><strong>options.print.app<\/strong> (Print.App CDN)<\/p>\n\n<ul>\n<li>Published option sets are served from this domain to your product pages\nvia your server (cached locally for 60 seconds). The visual builder itself\nis not loaded from here \u2014 it ships with the plugin and runs on your site.<\/li>\n<\/ul>\n\n<p>These services are operated by Print.App ApS: https:\/\/print.app\/\nPrivacy policy: https:\/\/print.app\/company\/privacy\nTerms of service: https:\/\/print.app\/company\/terms<\/p>\n\n<p><strong>cdn.filecheck.io<\/strong> (Filecheck artwork preflight \u2014 optional)<\/p>\n\n<p>Only used if you enter a Filecheck publishable key in the plugin settings.\nLeave that field empty and this service is never contacted.<\/p>\n\n<ul>\n<li><em>When it loads<\/em> \u2014 with a key configured, the product page loads the\nFilecheck upload element from this domain for any option set that has an\nartwork-check step.<\/li>\n<li><em>What is sent<\/em> \u2014 the artwork file the customer chooses, and the check\nsettings for that option set (such as the required size, bleed and page\ncount). The check result \u2014 page count, artwork dimensions and any\nwarnings \u2014 comes back to the page and is stored with the order line so\nyou can see what was checked. No customer names, emails or addresses are\ntransmitted.<\/li>\n<\/ul>\n\n<p>This service is operated by Filecheck (Print.App ApS): https:\/\/filecheck.io\/\nPrivacy policy: https:\/\/filecheck.io\/company\/privacy\nTerms of service: https:\/\/filecheck.io\/company\/terms<\/p>\n\n<h3>Source Code<\/h3>\n\n<p>Two files in assets\/ are compiled from TypeScript and Vue sources:<\/p>\n\n<ul>\n<li>assets\/print-configurator.js \u2014 the storefront configurator<\/li>\n<li>assets\/builder.js and assets\/builder.css \u2014 the option-set builder used on\nthe plugin's own admin page<\/li>\n<\/ul>\n\n<p>The full, human-readable source and the build tooling are available at:<\/p>\n\n<p>https:\/\/github.com\/PrintApp\/print-options-wordpress<\/p>\n\n<p>Run <code>npm install<\/code>, then <code>npm run build<\/code> in the core-ui package for the\nconfigurator and in the admin package for the builder; the outputs are the\nfiles bundled here unchanged.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload and activate the plugin.<\/li>\n<li>Open Print Options \u2192 Option Sets in your admin sidebar and create an option\nset from a template.<\/li>\n<li>Edit a product, open its Print Options tab, and pick the set from the\ndropdown. Done \u2014 the product page now shows the configurator.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"where%20do%20i%20build%20the%20options%3F\"><h3>Where do I build the options?<\/h3><\/dt>\n<dd><p>Print Options \u2192 Option Sets, inside your own admin. Start from a template and\nadjust the choices and prices to match what you sell.<\/p><\/dd>\n<dt id=\"can%20several%20products%20share%20the%20same%20options%3F\"><h3>Can several products share the same options?<\/h3><\/dt>\n<dd><p>Yes \u2014 assign the same set on each product's Print Options tab. Saving the set\nonce updates all of them.<\/p><\/dd>\n<dt id=\"do%20i%20need%20an%20account%20or%20api%20keys%3F\"><h3>Do I need an account or API keys?<\/h3><\/dt>\n<dd><p>No. The plugin creates its own anonymous identity when you activate it, and\ntalks to the service on your server's behalf.<\/p><\/dd>\n<dt id=\"what%20happens%20if%20the%20verification%20endpoint%20is%20down%3F\"><h3>What happens if the verification endpoint is down?<\/h3><\/dt>\n<dd><p>Adding to cart is refused with a friendly error. The plugin never falls back\nto a browser-computed price.<\/p><\/dd>\n<dt id=\"is%20it%20really%20free%3F\"><h3>Is it really free?<\/h3><\/dt>\n<dd><p>Yes, with no product or option limits.<\/p><\/dd>\n<dt id=\"can%20the%20configurator%20be%20translated%3F\"><h3>Can the configurator be translated?<\/h3><\/dt>\n<dd><p>Yes. Danish, German, French, Spanish, Italian, Dutch and Romanian ship with\nthe plugin and follow the site language automatically. Every label the\nconfigurator renders itself (\"Summary\", \"Add to cart\", \"Drop your file\nhere\u2026\", validation messages) goes through WordPress translation, so for any\nother language a language pack from translate.wordpress.org, Loco Translate\nor a .po file in wp-content\/languages\/plugins applies. Option names, choices\nand help text come from your option set and are written in whatever language\nyou type them in. To change individual labels from code, use the\n    papo_widget_strings filter. Prices follow your WooCommerce currency\nsettings (symbol, position, decimal and thousand separators).<\/p><\/dd>\n<dt id=\"can%20i%20show%20a%20tax%20note%20next%20to%20the%20price%3F\"><h3>Can I show a tax note next to the price?<\/h3><\/dt>\n<dd><p>The configurator shows the WooCommerce price display suffix (WooCommerce \u2192\nSettings \u2192 Tax \u2192 Price display suffix) under the total. To use different\nwording, or to hide it, return your text from the <code>papo_price_note<\/code> filter.<\/p><\/dd>\n<dt id=\"does%20the%20summary%20show%20the%20tax%3F\"><h3>Does the summary show the tax?<\/h3><\/dt>\n<dd><p>Yes, automatically, when WooCommerce taxes are on and prices are displayed\nincluding tax (WooCommerce \u2192 Settings \u2192 Tax \u2192 \"Display prices in the shop\").\nIf you enter prices without tax, the summary lists the total excluding tax,\nthe tax, and the total including tax. If you enter prices with tax, it shows\nthe tax included under the total. The rate is the one that applies to the\nshopper's location. Shops that display prices without tax see no breakdown.\nIt is for display only: the cart and checkout calculate tax as before. To\nchange or hide it, use the <code>papo_tax_display<\/code> filter (return an empty array\nfor none).<\/p><\/dd>\n<dt id=\"can%20the%20cart%20show%20the%20real%20quantity%20instead%20of%201%3F\"><h3>Can the cart show the real quantity instead of 1?<\/h3><\/dt>\n<dd><p>Yes. Open the option set, and on the Product panel set \"Line quantity\" to\n\"Real quantity\". The cart and order line then show the configured quantity at\na per-copy price, and stock and shipping weight follow it. This is applied\nonly when the total divides exactly by the quantity (a 10.00 job of 3 copies\ncannot be 3.33 each), so some jobs will still appear as one line of quantity\n1 at the same total. The quantity of a real-quantity line cannot be edited in\nthe cart; the customer changes it on the product page so the price is\nverified again. If you track stock on the product, make sure it covers your\nlargest jobs before turning this on.<\/p><\/dd>\n<dt id=\"how%20is%20shipping%20weight%20calculated%3F\"><h3>How is shipping weight calculated?<\/h3><\/dt>\n<dd><p>Enter the weight of ONE copy on the WooCommerce product. A configured job is a\nsingle cart line, and the plugin gives that line the product weight multiplied\nby the configured quantity, so weight-based shipping rates are right. Use the\n    papo_cart_item_weight filter if the weight depends on the chosen options.<\/p><\/dd>\n<dt id=\"can%20i%20edit%20an%20option%20set%20as%20json%2C%20or%20set%20it%20up%20with%20an%20ai%20assistant%3F\"><h3>Can I edit an option set as JSON, or set it up with an AI assistant?<\/h3><\/dt>\n<dd><p>Yes. In the option set editor, click More (the ... button at the top right).\nExport JSON shows the whole set as text to copy or download; Import JSON\nreplaces the set you are editing with pasted JSON, after checking it, and can\nbe undone. Nothing changes on your store until you click Save. The format is\ndescribed at https:\/\/print.app\/docs\/print-options\/developers\/option-set-json.<\/p><\/dd>\n<dt id=\"why%20does%20the%20product%27s%20own%20price%20not%20match%20the%20option%20set%3F\"><h3>Why does the product's own price not match the option set?<\/h3><\/dt>\n<dd><p>It is not used. A product with an option set is priced entirely by the set's\nbase price and modifiers, re-verified on the server at add-to-cart, and the\nproduct's regular price is hidden on the storefront. Leave the regular price\nat 0 (or any placeholder) and treat the option set as the single source of\ntruth.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.4.17<\/h4>\n\n<ul>\n<li>New: import and export option sets as JSON. In the option set editor,\nMore (the ... button) &gt; Export JSON shows the whole set as text to copy\nor download, and Import JSON replaces the set you are editing with pasted\nJSON, after checking it. The import can be undone, and nothing changes on\nyour store until you click Save. Useful for setting up options with an AI\nassistant, copying a set to another store, or keeping a backup.<\/li>\n<\/ul>\n\n<h4>0.4.16<\/h4>\n\n<ul>\n<li>New: pricing by formula. A Formula price rule works the price out from the\nquantity, the size (width, height, area) and the page count, in named\nsteps, for prices that follow a curve rather than tiers, such as\ncustom-size signs. The builder checks the formula as you type and shows\nthe prices it gives for a sample size and a few quantities.<\/li>\n<li>New: quantity per option. A \"Quantity per option\" field takes a count\nfor each option, such as the sizes of a T-shirt run. The total sets the\nquantity for price breaks, and the cart line lists each option's count.<\/li>\n<li>Fix: on cart lines, a field without a label is named by its section\ntitle instead of its internal id.<\/li>\n<\/ul>\n\n<h4>0.4.15<\/h4>\n\n<ul>\n<li>Fix: on a narrow product page column, on phones and in the option set\npreview, the summary no longer stays stuck to the bottom of the screen\nover the options. It now follows the options and scrolls with the page.<\/li>\n<\/ul>\n\n<h4>0.4.14<\/h4>\n\n<ul>\n<li>New: the summary can show the tax. With WooCommerce taxes on and prices\ndisplayed including tax, it lists the total excluding tax, the tax and the\ntotal including tax (or, for prices entered with tax, the tax included),\nat the rate for the shopper's location. Display only; checkout calculates\ntax as before. See the FAQ.<\/li>\n<li>Improved: large price matrices. Option sets are stored in a compact form\n(about 30 times smaller), and an option set can now be up to 1 MB, so a\nprice list across six or seven options with a few thousand combinations\nfits.<\/li>\n<\/ul>\n\n<h4>0.4.13<\/h4>\n\n<ul>\n<li>Improved: the price matrix lists the fields that cannot be one of its\noptions (only single-choice fields can), and turns a multiple-choice field\ninto a single choice in one click.<\/li>\n<li>Fix: deleting a field used by the price matrix, or changing its type, no\nlonger leaves the option set invalid; deleting a choice also removes the\nmatrix prices set for it.<\/li>\n<\/ul>\n\n<h4>0.4.12<\/h4>\n\n<ul>\n<li>New: the price matrix (Product panel, \"Price matrix\") now takes any number\nof options, so a supplier price list (quantity x paper x sides x turnaround\nx finishing, say) can price every combination exactly. One or two options\nshow as a grid; any number as a filterable list with price, availability\nand SKU per combination.<\/li>\n<li>New: import and export the matrix as CSV. The export lists every\ncombination, ready to fill in a spreadsheet; the import reads comma,\nsemicolon or tab files, decimal commas, and matches options and choices by\nname, reporting any row it could not use.<\/li>\n<\/ul>\n\n<h4>0.4.11<\/h4>\n\n<ul>\n<li>New: a \"Download file\" button under each order line with an uploaded file,\non the order screen in the admin. It works for existing orders too, as long\nas the file is still stored (uploads are kept for 30 days).<\/li>\n<li>Downloads keep the customer's original file name.<\/li>\n<\/ul>\n\n<h4>0.4.10<\/h4>\n\n<ul>\n<li>Fix: a product priced entirely by its options (for example a price per\nsize, with the base price left at 0) no longer shows a \"Base price 0,00\"\nline in the summary. A base price with an amount is still listed.<\/li>\n<\/ul>\n\n<h4>0.4.9<\/h4>\n\n<ul>\n<li>Fix: the quantity shown on the product page, the cart line and the order\nis always the quantity that is charged. On an option sold in steps (25,\n50, 75\u2026), a typed or script-set number such as 333 was priced as 325 but\nstill listed as 333; it now snaps to 325 when the customer leaves the\nfield, and every line says 325.<\/li>\n<\/ul>\n\n<h4>0.4.8<\/h4>\n\n<ul>\n<li>New: real quantities, an opt-in setting on each option set (Product panel,\n\"Line quantity\"). The cart and order line carry the real copy count at a\nper-copy price, so WooCommerce's quantity, stock and shipping weight all\nuse the true number. Applied only when the verified total splits exactly\nacross the copies; any other job stays one line at the same total. The\nquantity of such a line is fixed in the cart, because the price was\nverified for that count: customers change it on the product page.<\/li>\n<\/ul>\n\n<h4>0.4.7<\/h4>\n\n<ul>\n<li>New: a quantity option can carry a unit word (\"banners\", \"cards\"), shown\nafter the number on the cart line and the order: \"5 banners\"<\/li>\n<li>Fix: a quantity option without a label is listed as \"Quantity\" on the cart\nline and order instead of its internal id<\/li>\n<\/ul>\n\n<h4>0.4.6<\/h4>\n\n<ul>\n<li>Fix: shipping weight. A configured job is one cart line, so weight-based\nshipping saw the weight of a single copy. The line now weighs the product's\nweight multiplied by the configured quantity. The <code>papo_cart_item_weight<\/code>\nfilter adjusts it, and the order line records the total as <code>_papo_weight<\/code>.<\/li>\n<li>Builder: quantity breaks on the base price can now be seen and edited on the\nProduct panel. Templates such as Business Cards price their base this way,\nand the plain Amount field had no effect while the breaks were hidden.<\/li>\n<\/ul>\n\n<h4>0.4.5<\/h4>\n\n<ul>\n<li>New: the configurator ships translated into Danish, German, French,\nSpanish, Italian, Dutch and Romanian \u2014 the site language is picked up\nautomatically. Community translations on translate.wordpress.org take\nprecedence once available.<\/li>\n<li>Fix: a design made in a connected designer (for example Print.App) is now\nlabelled in the site language instead of \"Your design\"<\/li>\n<li>Change: the design summary shows the page count only on products that are\npriced by page; per-unit products no longer show \"1 page\"<\/li>\n<\/ul>\n\n<h4>0.4.4<\/h4>\n\n<ul>\n<li>New: quantity fields can take turns. Add one quantity field per group of\nchoices, each with a visibility rule (for example a paper that only comes\nin three of your set quantities), and the visible one is the quantity that\nis priced. Only one quantity field may be unconditional.<\/li>\n<li>Builder: a quantity field can no longer be shown or hidden by the quantity\nitself (circular)<\/li>\n<\/ul>\n\n<h4>0.4.3<\/h4>\n\n<ul>\n<li>Fix: prices in the configurator ignored the site language \u2014 WordPress\nlocales such as ro_RO were rejected by the browser's number formatter and\nthe summary fell back to \"RON 10.00\"<\/li>\n<li>New: the summary uses your WooCommerce currency format (symbol, position,\nseparators), so it prints \"10,00 lei\" exactly as the cart will<\/li>\n<li>New: every configurator label is translatable through WordPress i18n, with\na <code>papo_widget_strings<\/code> filter for per-site wording<\/li>\n<li>New: the WooCommerce price display suffix (for example \"incl. VAT\") shows\nunder the total; <code>papo_price_note<\/code> sets custom wording<\/li>\n<li>Theming: <code>::part()<\/code> hooks for the unit-price line (summary-unit), the\nprice note (summary-note), summary line labels\/values and the choices\nrecap rows<\/li>\n<\/ul>\n\n<h4>0.4.2<\/h4>\n\n<ul>\n<li>New: file upload fields can be set to \"Designer only (no direct upload)\" -\nonly connected design tools (for example the Print.App designer) are\noffered, without a dropzone<\/li>\n<li>Fix: the configurator sized its text from the page root, so themes that\nset the root font size to 62.5% rendered it at roughly 60% of the theme's\ntext size - it now follows the surrounding text<\/li>\n<li>Fix: the widget's numeric inputs no longer shrink on those themes<\/li>\n<li>Builder: per-length price rules (roll and linear pricing) with length-based\nvolume breaks<\/li>\n<\/ul>\n\n<h4>0.4.1<\/h4>\n\n<ul>\n<li>Fix: option sets with quantity tiers on individual choices (for example\nsize-dependent price breaks) could not be saved \u2014 the values were being\ntruncated before they reached the server and the save was refused<\/li>\n<\/ul>\n\n<h4>0.4.0<\/h4>\n\n<ul>\n<li>The visual builder now ships with the plugin and runs on its own admin page\ninstead of being embedded from options.print.app<\/li>\n<li>All classes, constants, options, transients, post meta and hooks carry a\nPAPO_\/papo_ prefix; existing store identity and product assignments are\nmigrated automatically on update<\/li>\n<li>Configuration submitted with add-to-cart is sanitized value by value<\/li>\n<li>Filecheck artwork preflight documented under External Services<\/li>\n<\/ul>\n\n<h4>0.3.0<\/h4>\n\n<ul>\n<li>Print Options tab on the product edit page \u2014 assign a named option set from\na dropdown, no JSON pasting<\/li>\n<li>Embedded visual builder (Print Options \u2192 Option Sets) to create and manage\noption sets<\/li>\n<li>Option sets are served from the CDN and shared across products; editing a\nset updates every product that uses it<\/li>\n<li>Anonymous store identity; all management calls are HMAC-signed server-side<\/li>\n<\/ul>\n\n<h4>0.2.0<\/h4>\n\n<ul>\n<li>Full add-to-cart bridge with server-side price verification<\/li>\n<li>Settings page, per-product options metabox, order line persistence<\/li>\n<\/ul>\n\n<h4>0.1.0<\/h4>\n\n<ul>\n<li>Initial stub<\/li>\n<\/ul>","raw_excerpt":"Print product options with live pricing and artwork upload for WooCommerce \u2014 built for print shops.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/ko.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/351260","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ko.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/ko.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/ko.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=351260"}],"author":[{"embeddable":true,"href":"https:\/\/ko.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/printapp"}],"wp:attachment":[{"href":"https:\/\/ko.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=351260"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/ko.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=351260"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/ko.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=351260"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/ko.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=351260"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/ko.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=351260"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/ko.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=351260"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}