LearnDash WooCommerce access
SkillAI & modelsBuild or audit the LearnDash WooCommerce integration that grants/revokes LearnDash course and group access from WooCommerce products, orders, refunds, subscriptions, switches, and order-item changes. Use when code mentions learndash-woocommerce, _related_course, _related_group, LearnDash\WooCommerce\Settings\Status_Access, learndash_woocommerce_enrollment_status_settings, _learndash_woocommerce_enrolled_courses_access_counter, add_course_access, remove_course_access, add_subscription_course_access, HPOS compatibility, silent enrollment queue, or variable product/variation course links.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the LearnDash WooCommerce access skill
What this skill tells your AI
The instructions your AI receives, as published by lonsdale201/wp-agent-skills in learndash/learndash-woocommerce-access/SKILL.md and read by ahel’s review.
Use this when WooCommerce products, orders, subscriptions, refunds, or product variations must grant or revoke LearnDash course/group access.
The LearnDash WooCommerce bridge is not just "on completed order call
ld_update_course_access()". It tracks product relations, variable product
relations, configurable order/subscription statuses, partial refunds,
subscription switches, order item mutations, access expiration, silent queued
enrollment, and a per-user counter so one access source does not remove another.
When to use this skill
Trigger when ANY of these appears:
- Plugin path/name
learndash-woocommerce. - Product meta
_related_courseor_related_group. - User meta
_learndash_woocommerce_enrolled_courses_access_counter. LearnDash\WooCommerce\Settings\Status_Access.- Options
learndash_woocommerce_enrollment_status_settings,learndash_woocommerce_silent_course_enrollment_queue, orlearndash_woocommerce_disable_access_removal_on_expiration. - Woo hooks around order status, refund, subscription status, subscription switch, order item added/deleted, customer change, or HPOS.
Product relation model
LearnDash WooCommerce stores related LearnDash objects on the Woo product or variation:
_related_courseis an array of LearnDash course IDs._related_groupis an array of LearnDash group IDs.- Simple products store relations on the product ID.
- Variable and variable-subscription parents clear parent-level relations and store relations on each variation.
- Runtime order processing checks the variation ID first; if no variation ID is present, it checks the product ID.
When building a compatible importer/sync, preserve that shape:
update_post_meta( $product_or_variation_id, '_related_course', array_map( 'absint', $course_ids ) );
update_post_meta( $product_or_variation_id, '_related_group', array_map( 'absint', $group_ids ) );
Do not store a scalar ID and do not attach courses only to a variable parent if the product is sold through variations.
Enrollment status settings
The bridge decides which Woo statuses grant or revoke access through
LearnDash\WooCommerce\Settings\Status_Access. That class reads the LearnDash
Woo settings option learndash_woocommerce_enrollment_status_settings.
Default grant statuses in 2.0.2:
- Orders:
wc-processing,wc-completed. - Subscriptions:
wc-active,wc-pending-cancel,wc-on-hold.
The plugin hooks dynamically:
- Granted order statuses call course/group enrollment.
- Denied order statuses remove course/group access.
refundedis handled throughwoocommerce_order_refundedso partial refunds can remove access only for refunded items.- Granted subscription statuses add subscription course/group access.
- Denied subscription statuses remove it, except expired subscriptions can be
skipped when
learndash_woocommerce_disable_access_removal_on_expirationisyes.
Do not hard-code completed as the only access status in a compatibility
plugin. Read the status settings or hook after the bridge's own status actions.
Order lifecycle behavior
The bridge grants/removes access from several surfaces:
- Order status changes.
- Partial and full refunds.
- Order deletion.
- Customer changes on processing/completed orders.
- New/deleted order items.
- Subscription status changes.
- Subscription renewal billing-cycle completion.
- Subscription switches.
It declares WooCommerce HPOS compatibility during before_woocommerce_init, so
compatible plugins should use Woo order CRUD (wc_get_order(),
WC_Order::get_items(), order item methods) rather than direct postmeta SQL.
Access counter behavior
The user meta _learndash_woocommerce_enrolled_courses_access_counter prevents
one purchase/refund from revoking access that is still granted by another order
or subscription.
For courses:
update_add_course_access()increments the counter.- It calls
ld_update_course_access()only if the user is not already enrolled, or if the existing access has expired and must be reset. update_remove_course_access()decrements the counter and revokes direct course access only when no counter entry remains for that course.
For groups:
update_add_group_access()increments the counter and callsld_update_group_access()only when the user is not already in the group.update_remove_group_access()decrements and removes group access only when no counter entry remains for that group.
If a custom plugin bypasses the bridge and calls ld_update_course_access() on
every order/refund, it can remove access while another valid order still exists.
Use LearnDash Woo's relationship/status model when the access source is Woo.
Expiration and paid date
When granting from an order, the bridge checks whether the LearnDash course or group product access already expired relative to the Woo order paid date. It can remove instead of add access if the product's access window has elapsed.
When a course has no product start date, the bridge can set direct course
access_from from the order paid date through LearnDash's access-date API.
This matters for historical imports and delayed processing.
Silent enrollment queue
When an order contains many related courses/groups, the bridge can enqueue work
in learndash_woocommerce_silent_course_enrollment_queue and process it from
its cron hook. The queue is intentionally non-autoloaded by the upgrade routine.
Do not assume access is synchronous for very large orders. If a custom workflow
needs immediate post-order access, inspect the queue and the bridge threshold
filter learndash_woocommerce_process_silent_course_enrollment_queue_count.
Integration patterns
For a plugin that sells LearnDash access through normal Woo products:
- Store
_related_courseand/or_related_groupon the exact product or variation that is sold. - Let Woo order/subscription status transitions trigger LearnDash Woo.
- Use Woo CRUD and HPOS-safe order APIs.
- Avoid direct LearnDash grant/revoke calls unless the access source is not a Woo order/subscription handled by the bridge.
- If you must reconcile access, honor the bridge counter before revoking.
For an admin/import tool:
- Resolve whether the SKU maps to a product or variation.
- Save arrays of integer LearnDash IDs in the expected meta keys.
- Trigger normal Woo order status transitions or run a deliberate reconciliation command.
- Log skipped guest orders, invalid users, missing courses/groups, and queued enrollments.
Common mistakes to reject
- Hooking only
woocommerce_order_status_completedand ignoring processing, refunds, subscription statuses, item changes, and settings. - Reading relations only from the parent variable product.
- Storing scalar
_related_courseor_related_groupvalues. - Calling
ld_update_course_access()directly on refund without checking the LearnDash Woo access counter. - Assuming group access and course access use the same LearnDash helper.
- Using direct SQL against order posts/postmeta when HPOS is enabled.
- Allowing guest checkout for products that grant LearnDash access without a clear account-linking flow.
Cross-references
- Use
learndash-course-accessfor final course access checks and direct course grant/revoke behavior. - Use
learndash-group-accessfor group membership and group-course relation behavior. - Use
learndash-course-progresswhen order-driven access must be distinguished from preserving, resetting, or completing learner progress. - Use WooCommerce skills for generic HPOS, order lifecycle, subscriptions, and payment gateway behavior.
References
Validated against LearnDash WooCommerce 2.0.2 and LearnDash LMS 5.1.9 local source:
learndash-woocommerce/learndash_woocommerce.phplearndash-woocommerce/includes/class-learndash-woocommerce.phplearndash-woocommerce/src/App/Settings/Status_Access.phplearndash-woocommerce/src/App/Admin/Pages/Sections/Settings_Enrollment_Status.phplearndash-woocommerce/includes/class-cron.phplearndash-woocommerce/includes/class-upgrade.phpsfwd-lms/includes/course/ld-course-user-functions.phpsfwd-lms/includes/ld-groups.php- Official documentation: https://developers.learndash.com/
- Verified source paths:
wp-content/plugins/learndash-woocommerce/src/App/Modules/Retroactive_Access_Tool/Handler.php
Signals
- GitHub stars
- 22
- Forks
- 2
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
learndash-woocommerce-access- Source
- github.com/lonsdale201/wp-agent-skills