{"id":386833,"date":"2026-10-13T07:46:19","date_gmt":"2026-10-13T07:46:19","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/hdwebmobile-booking-appointments\/"},"modified":"2026-10-14T08:42:22","modified_gmt":"2026-10-14T08:42:22","slug":"hdwebmobile-booking-appointments","status":"publish","type":"plugin","link":"https:\/\/me.wordpress.org\/plugins\/hdwebmobile-booking-appointments\/","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 Booking & Appointments","header_author":"htrxuan - Han Tran","header_description":"Sell bookable services and appointments through WooCommerce. A booking's owner is set exactly once, server-side, at purchase and never accepted from any later request -- and this plugin never touches a WordPress password.","assets_banners_color":"508478","last_updated":"2026-10-14 08:42:22","external_support_url":"","external_repository_url":"","donate_link":"https:\/\/paypal.me\/htrxuan\/20","header_plugin_uri":"https:\/\/hdwebmobile.com\/plugins\/hdwebmobile-booking-appointments\/","header_author_uri":"https:\/\/hdwebmobile.com\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":76,"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:22","revision":3745741}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3743194,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3743194,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3743194,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3743194,"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":3743194,"resolution":"1","location":"assets","locale":"","width":1600,"height":1000},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3743194,"resolution":"2","location":"assets","locale":"","width":1600,"height":1000},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3743194,"resolution":"3","location":"assets","locale":"","width":1600,"height":1000}},"screenshots":{"1":"The \"Booking\" tab on a product, with availability and capacity settings.","2":"The date\/time picker on a product page.","3":"The Bookings list under WooCommerce &gt; HDWebmobile."}},"plugin_section":[],"plugin_tags":[8132,269,1475,268,286],"plugin_category":[40,45],"plugin_contributors":[254181],"plugin_business_model":[],"class_list":["post-386833","plugin","type-plugin","status-publish","hentry","plugin_tags-appointments","plugin_tags-booking","plugin_tags-reservations","plugin_tags-scheduling","plugin_tags-woocommerce","plugin_category-calendar-and-events","plugin_category-ecommerce","plugin_contributors-htrxuan","plugin_committers-htrxuan"],"banners":{"banner":"https:\/\/ps.w.org\/hdwebmobile-booking-appointments\/assets\/banner-772x250.png?rev=3743194","banner_2x":"https:\/\/ps.w.org\/hdwebmobile-booking-appointments\/assets\/banner-1544x500.png?rev=3743194","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/hdwebmobile-booking-appointments\/assets\/icon-128x128.png?rev=3743194","icon_2x":"https:\/\/ps.w.org\/hdwebmobile-booking-appointments\/assets\/icon-256x256.png?rev=3743194","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/hdwebmobile-booking-appointments\/assets\/screenshot-1.png?rev=3743194","caption":"The \"Booking\" tab on a product, with availability and capacity settings."},{"src":"https:\/\/ps.w.org\/hdwebmobile-booking-appointments\/assets\/screenshot-2.png?rev=3743194","caption":"The date\/time picker on a product page."},{"src":"https:\/\/ps.w.org\/hdwebmobile-booking-appointments\/assets\/screenshot-3.png?rev=3743194","caption":"The Bookings list under WooCommerce &gt; HDWebmobile."}],"raw_content":"<!--section=description-->\n<p>HDWebmobile Booking &amp; Appointments turns any simple WooCommerce product into a bookable service. Customers pick an available date and time slot on the product page; the booking is confirmed the moment their order completes, and they can view or cancel it later under My Account.<\/p>\n\n<h4>Security by design<\/h4>\n\n<p>A serious class of bug in booking tools is an \"update my booking profile\" endpoint that accepts a client-supplied field linking the booking record to a WordPress user id, with no check that it still points at the requester's own account (an IDOR \/ mass-assignment flaw) -- which can let a low-privileged customer reset the password of <em>any<\/em> WordPress user, including an administrator. This plugin closes that vulnerability class by construction:<\/p>\n\n<ul>\n<li>A booking's owner is written in exactly one place -- at order completion, from the order's own customer id -- and never again. There is no \"update booking\" code path anywhere in this plugin that accepts a customer id, user id, or any similar field from a request.<\/li>\n<li>This plugin never touches a WordPress password. There is no code path here that calls <code>wp_set_password()<\/code> or anything like it, at all -- a customer's password remains entirely WordPress core's own Account Details screen.<\/li>\n<li>A customer can only ever see or cancel their own bookings, scoped by their logged-in account at the database query itself -- never by an id taken from the request.<\/li>\n<li>Per-slot capacity is enforced with an atomic, race-condition-safe claim (a database uniqueness constraint), so two customers can never both be confirmed into the same slot beyond its configured capacity.<\/li>\n<\/ul>\n\n<h4>Key Features<\/h4>\n\n<ul>\n<li>Turn any simple product into a bookable service from its own Product Data &gt; Booking tab<\/li>\n<li>Configurable available days, time slots, lead time, and how many days ahead to offer<\/li>\n<li>Per-slot capacity -- a slot stops being offered once it's full<\/li>\n<li>Booking is confirmed automatically when the order is marked Completed<\/li>\n<li>A \"Bookings\" tab under My Account to view and cancel upcoming bookings<\/li>\n<li>If a slot fills up between add-to-cart and checkout, the order still completes normally and the admin is emailed to help reschedule -- no booking is ever double-booked<\/li>\n<\/ul>\n\n<h4>Limitations (please read before installing)<\/h4>\n\n<ul>\n<li>Simple products only in this version -- no variable-product support<\/li>\n<li>No staff\/resource assignment -- a slot's capacity is a single shared number, not per-staff-member<\/li>\n<li>No calendar sync (Google Calendar, iCal, etc.) in this version<\/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-booking-appointments\/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-booking-appointments\/\">open a support topic<\/a> first so it can be fixed.<\/p>\n\n<h3>How to Use<\/h3>\n\n<h4>1. Configure a bookable product<\/h4>\n\n<p>On a simple product's \"Booking\" tab, check \"Bookable service\", set available days, time slots (one per line), lead time, and capacity per slot.<\/p>\n\n<h4>2. Customer books<\/h4>\n\n<p>On the product page, the customer picks a date and time slot before adding to cart -- exactly like any other WooCommerce purchase.<\/p>\n\n<h4>3. Booking confirmed<\/h4>\n\n<p>Once the order is marked Completed, the booking is confirmed and appears under the customer's My Account &gt; Bookings, where they can cancel it if needed.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin files to the <code>\/wp-content\/plugins\/hdwebmobile-booking-appointments<\/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>Edit a simple product, open its new \"Booking\" tab under Product Data, and configure availability.<\/li>\n<\/ol>\n\n<!--section=changelog-->\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release: per-product availability and capacity, atomic slot claiming on order completion, \"Bookings\" My Account tab with cancellation, shortage handling with admin notification.<\/li>\n<\/ul>","raw_excerpt":"Sell bookable services and appointments through WooCommerce, with a per-slot capacity that can never be oversold.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/me.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/386833","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/me.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/me.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/me.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=386833"}],"author":[{"embeddable":true,"href":"https:\/\/me.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/htrxuan"}],"wp:attachment":[{"href":"https:\/\/me.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=386833"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/me.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=386833"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/me.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=386833"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/me.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=386833"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/me.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=386833"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/me.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=386833"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}