Kayce Discount Rules is built to be extended. Pro itself uses only the hooks on this page.
Actions
| Hook | When |
|---|---|
kayce_dr_loaded | The plugin has booted (on plugins_loaded). Add-ons start here. |
kayce_dr_register | Register custom rule types and conditions (on init). |
kayce_dr_rules_saved | After rules are saved. Receives the saved rules. |
kayce_dr_after_calculate | After rules are applied to the cart. Receives the cart and engine. |
Filters
| Filter | Use |
|---|---|
kayce_dr_rule_matches_product | Change whether a rule applies to a product. |
kayce_dr_skip_cart_item | Leave a cart line untouched (bundles, gifts). |
kayce_dr_resolve_price | Resolve competing rules with your own strategy. |
kayce_dr_strategies | Add options to “If several rules match one item”. |
kayce_dr_catalog_price | Change the price shown in the shop. |
kayce_dr_display_product_type | Show discounted prices for other product types. |
kayce_dr_cart_savings | Change the “You save” amount. |
A custom rule type
Extend Kayce\DiscountRules\Rule_Type and register it:
use Kayce\DiscountRules\Rule_Type;
use Kayce\DiscountRules\Rule_Types;
class My_Members_Price extends Rule_Type {
public function id() { return 'members'; }
public function label() { return 'Members price'; }
// Unit price for a cart line, or null to leave it alone.
public function item_price( $price, array $rule, array $context ) {
return is_user_logged_in() ? $price * 0.9 : null;
}
}
add_action( 'kayce_dr_register', function () {
Rule_Types::register( new My_Members_Price() );
} );
Types that work on the whole cart implement apply_to_cart( $rule, $cart, $matching_keys ) and set line prices with kayce_dr_engine()->set_line_price( $cart, $key, $price, $rule ), so repeated calculations never discount twice.
A custom condition
use Kayce\DiscountRules\Condition;
use Kayce\DiscountRules\Conditions;
class Customer_In_Nepal extends Condition {
public function id() { return 'country_np'; }
public function label() { return 'Customer in Nepal'; }
public function matches( array $config, array $context ) {
return WC()->customer && 'NP' === WC()->customer->get_billing_country();
}
}
add_action( 'kayce_dr_register', function () {
Conditions::register( new Customer_In_Nepal() );
} );
Fail-safe: A rule whose type or condition isn’t registered is kept when saving but never applied.
Admin extension points
The admin app is React. Add-ons enqueue a script that depends on kayce-dr-admin and use wp.hooks:
| JavaScript filter | Use |
|---|---|
kayceDR.typeEditors | Editor component per rule type ({ config, onChange, rule }). |
kayceDR.conditionsPanel | Component for step 3. |
kayceDR.blankRule | Default settings for a new rule of a type. |
kayceDR.ruleChips | Summary chips on rule cards. |
kayceDR.validateRule | Add errors and warnings. |
kayceDR.templates | Add templates to the New rule window. |
kayceDR.preview | Replace the live preview for a rule type. |
Shared components (number fields, segmented controls, option cards, product pickers) are available on window.kayceDRAdmin.
REST API
All routes need the manage_woocommerce capability.
| Route | Methods |
|---|---|
/wp-json/kayce-dr/v1/rules | GET, PUT (whole ordered list) |
/wp-json/kayce-dr/v1/settings | GET, PUT |
/wp-json/kayce-dr/v1/stats | GET (30-day stats) |
/wp-json/kayce-dr/v1/search | GET (products or categories) |
Data storage
- Rules: option
kayce_dr_rules(ordered list). Settings:kayce_dr_settings. No custom tables. - Order line meta:
_kayce_dr_rule_id,_kayce_dr_original_price,_kayce_dr_price; Pro gifts add_kayce_dr_gift.