{"id":386093,"date":"2026-10-13T04:18:48","date_gmt":"2026-10-13T04:18:48","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/hdwebmobile-loyalty-points-store-credit\/"},"modified":"2026-10-14T08:42:12","modified_gmt":"2026-10-14T08:42:12","slug":"hdwebmobile-loyalty-points-store-credit","status":"publish","type":"plugin","link":"https:\/\/lmo.wordpress.org\/plugins\/hdwebmobile-loyalty-points-store-credit\/","author":9757813,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.0","stable_tag":"1.0.0","tested":"7.1.3","requires":"6.9","requires_php":"7.4","requires_plugins":null,"header_name":"HDWebmobile Loyalty Points & Store Credit","header_author":"htrxuan - Han Tran","header_description":"Customers earn points on completed orders and redeem them for a discount at checkout. Balance is always computed from an append-only ledger, never a value the browser can hand back to the server.","assets_banners_color":"cbdcd8","last_updated":"2026-10-14 08:42:12","external_support_url":"","external_repository_url":"","donate_link":"https:\/\/paypal.me\/htrxuan\/20","header_plugin_uri":"https:\/\/hdwebmobile.com\/plugins\/hdwebmobile-loyalty-points-store-credit\/","header_author_uri":"https:\/\/hdwebmobile.com\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":69,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"htrxuan","date":"2026-10-14 08:42:12","revision":3745740}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3742883,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3742883,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3742883,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3742883,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3742883,"resolution":"1","location":"assets","locale":"","width":1600,"height":1000},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3742883,"resolution":"2","location":"assets","locale":"","width":1600,"height":1000},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3742883,"resolution":"3","location":"assets","locale":"","width":1600,"height":1715}},"screenshots":{"1":"The points redemption box on the cart page.","2":"The \"Loyalty Points\" tab in My Account, showing balance and history.","3":"The admin settings, manual adjustment, and recent-activity ledger under WooCommerce &gt; HDWebmobile."}},"plugin_section":[],"plugin_tags":[331,74756,294,5495,286],"plugin_category":[45],"plugin_contributors":[254181],"plugin_business_model":[],"class_list":["post-386093","plugin","type-plugin","status-publish","hentry","plugin_tags-discount","plugin_tags-loyalty-points","plugin_tags-rewards","plugin_tags-store-credit","plugin_tags-woocommerce","plugin_category-ecommerce","plugin_contributors-htrxuan","plugin_committers-htrxuan"],"banners":{"banner":"https:\/\/ps.w.org\/hdwebmobile-loyalty-points-store-credit\/assets\/banner-772x250.png?rev=3742883","banner_2x":"https:\/\/ps.w.org\/hdwebmobile-loyalty-points-store-credit\/assets\/banner-1544x500.png?rev=3742883","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/hdwebmobile-loyalty-points-store-credit\/assets\/icon-128x128.png?rev=3742883","icon_2x":"https:\/\/ps.w.org\/hdwebmobile-loyalty-points-store-credit\/assets\/icon-256x256.png?rev=3742883","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/hdwebmobile-loyalty-points-store-credit\/assets\/screenshot-1.png?rev=3742883","caption":"The points redemption box on the cart page."},{"src":"https:\/\/ps.w.org\/hdwebmobile-loyalty-points-store-credit\/assets\/screenshot-2.png?rev=3742883","caption":"The \"Loyalty Points\" tab in My Account, showing balance and history."},{"src":"https:\/\/ps.w.org\/hdwebmobile-loyalty-points-store-credit\/assets\/screenshot-3.png?rev=3742883","caption":"The admin settings, manual adjustment, and recent-activity ledger under WooCommerce &gt; HDWebmobile."}],"raw_content":"<!--section=description-->\n<p>HDWebmobile Loyalty Points &amp; Store Credit rewards customers with points for every completed order, which they can redeem for a discount on a future purchase. Customers see their balance and full history on a new \"Loyalty Points\" tab in their account.<\/p>\n\n<h4>Security by design<\/h4>\n\n<p>Store credit and coupon tools hold real monetary value, so broken access control in them (CWE-284) can let attackers generate high-value credit through insufficient authorization checks -- forging value that was never actually earned. A points balance is exactly the same kind of value, and needs the same discipline. This plugin closes that vulnerability class by construction:<\/p>\n\n<ul>\n<li>There is no \"balance\" field anywhere that gets directly written. Every award, redemption, and admin adjustment is a signed row in an append-only ledger table, and a customer's balance is always the live sum of their own rows -- never a cached number that could drift or be overwritten by a bad request.<\/li>\n<li>Every redemption re-checks the customer's <em>current<\/em> live balance at the exact moment of redemption, both when the discount is shown in the cart and again when the order is actually created -- never a points figure the checkout form sent back to the server.<\/li>\n<li>Every earn and redemption is tied to a specific order and only ever happens once for that order, so a page refresh, retried request, or duplicate status-change event can never double-award or double-redeem.<\/li>\n<li>If an order is later cancelled, refunded, or fails, any points it awarded or redeemed are automatically reversed -- so a cancelled order can never leave a customer with free points, or a lost balance, on the books.<\/li>\n<li>Manual adjustments (for customer service) always record which admin made the change.<\/li>\n<\/ul>\n\n<h4>Key Features<\/h4>\n\n<ul>\n<li>Configurable points-earning rate (points per currency unit spent) and the order status that triggers earning<\/li>\n<li>Configurable redemption rate (points required per currency unit of discount), a minimum-points-to-redeem threshold, and a maximum percentage of any single order that can be paid with points<\/li>\n<li>A simple redemption box on the cart page showing the customer's live balance, with an amount they can apply as a discount<\/li>\n<li>\"Loyalty Points\" tab in My Account showing current balance and full transaction history<\/li>\n<li>Automatic point reversal on cancelled, refunded, or failed orders<\/li>\n<li>Admin manual adjustment tool (grant or deduct points for a specific customer by email) plus a recent-activity ledger view, both under WooCommerce &gt; HDWebmobile<\/li>\n<\/ul>\n\n<h4>Limitations (please read before installing)<\/h4>\n\n<ul>\n<li>Points can only be earned by logged-in customers with an account -- guest checkouts don't accrue points, since there's no account to credit them to<\/li>\n<li>No expiry date on points in this version<\/li>\n<li>The cart redemption box uses a plain form submission (not AJAX) -- applying or removing a redemption reloads the cart page<\/li>\n<\/ul>\n\n<h4>Enjoying this plugin?<\/h4>\n\n<p>If it helps your site, please consider <a href=\"https:\/\/wordpress.org\/support\/plugin\/hdwebmobile-loyalty-points-store-credit\/reviews\/#new-post\">leaving an honest review on WordPress.org<\/a> -- it helps other WordPress users find it. Found a problem or have an idea? Please <a href=\"https:\/\/wordpress.org\/support\/plugin\/hdwebmobile-loyalty-points-store-credit\/\">open a support topic<\/a> first so it can be fixed.<\/p>\n\n<h3>How to Use<\/h3>\n\n<h4>1. Customers earn points automatically<\/h4>\n\n<p>As soon as an order reaches the configured \"earning\" status (Completed, by default), the customer's account is credited with points based on the order total. Nothing else to configure.<\/p>\n\n<h4>2. Customers redeem points on the cart page<\/h4>\n\n<p>Once a customer has enough points (the configured minimum), a box appears on the cart page showing their balance and an amount to redeem. Applying it adds a discount, capped at the configured maximum percentage of the order.<\/p>\n\n<h4>3. Customers track their balance<\/h4>\n\n<p>\"Loyalty Points\" appears in the My Account menu, showing the current balance and a full history of every point earned, redeemed, or adjusted.<\/p>\n\n<h4>4. Customer service adjustments<\/h4>\n\n<p>Under WooCommerce &gt; HDWebmobile &gt; Loyalty Points, an admin can grant or deduct points for any customer by email, with a note -- useful for compensating a delayed order or correcting an issue.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin files to the <code>\/wp-content\/plugins\/hdwebmobile-loyalty-points-store-credit<\/code> directory, or install the plugin through the WordPress plugins screen directly.<\/li>\n<li>Activate the plugin through the 'Plugins' screen in WordPress. WooCommerce must already be installed and active.<\/li>\n<li>Adjust the earning\/redemption rates under WooCommerce &gt; HDWebmobile &gt; Loyalty Points if the defaults don't suit your store.<\/li>\n<\/ol>\n\n<!--section=changelog-->\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release: append-only points ledger, automatic earning on order completion, cart-page redemption with live balance re-verification, automatic reversal on cancelled\/refunded\/failed orders, My Account balance and history, admin manual adjustment and ledger view.<\/li>\n<\/ul>","raw_excerpt":"Customers earn points on completed orders and redeem them for a discount at checkout -- balance always computed from an audit-logged ledger.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/386093","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=386093"}],"author":[{"embeddable":true,"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/htrxuan"}],"wp:attachment":[{"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=386093"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=386093"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=386093"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=386093"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=386093"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=386093"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}