Developer reference
Code lives under the CheckoutShield\ namespace in includes/. The prefix for options, tables, hooks and the cookie is cksh_.
Filters
cksh_client_ip
Change the client IP CardFence uses (after the configured IP source has been applied).
add_filter( 'cksh_client_ip', function ( $ip, $remote_addr ) {
// e.g. a custom header set by your own trusted edge.
return $_SERVER['HTTP_X_MY_EDGE_IP'] ?? $ip;
}, 10, 2 );
Must return a valid IP. Invalid values fall back to 0.0.0.0.
cksh_rule_verdict
Add your own blocking rules. Return a reason slug to block, or the incoming value to continue. Runs after the allow and block lists and the store-manager check. It also respects Monitor mode.
add_filter( 'cksh_rule_verdict', function ( $reason, $context, $ip, $email ) {
if ( '' !== $reason ) {
return $reason; // another rule already decided.
}
if ( str_ends_with( $email, '@competitor.example' ) ) {
return 'competitor';
}
return '';
}, 10, 4 );
$context is one of store_checkout, store_order_pay, classic_checkout, order_pay, add_payment_method, or wc_ajax:{action}. The reason appears in the activity log.
cksh_denied_message
Change the message a refused buyer sees.
add_filter( 'cksh_denied_message', function ( $message, $kind, $reason ) {
// $kind: blocked | rate_limited | session | challenge
return 'blocked' === $kind ? 'Please call us on 555-0100 to complete your order.' : $message;
}, 10, 3 );
cksh_count_async_failure
Decide whether a payment failure reported outside a checkout request (a gateway webhook or cron) counts towards blocks and attack mode. By default, only orders created via checkout or store-api in the last 24 hours count.
add_filter( 'cksh_count_async_failure', function ( $counts, $order ) {
return $counts || 'my-headless-app' === $order->get_created_via();
}, 10, 2 );
cksh_is_payment_page
Mark extra pages (for example a custom one-page checkout) as payment pages, so they get the browser-token cookie.
add_filter( 'cksh_is_payment_page', function ( $is ) {
return $is || is_page( 'express-checkout' );
} );
cksh_disposable_domains (Pro)
Change the disposable-email domain list.
add_filter( 'cksh_disposable_domains', function ( $domains ) {
$domains[] = 'throwaway.example';
return array_diff( $domains, array( 'trashmail.com' ) );
} );
cksh_ip_country (Pro)
Supply or override the two-letter country used by the country rule, for example from your own geolocation.
add_filter( 'cksh_ip_country', function ( $country, $ip ) {
return $country ?: my_geo_lookup( $ip ); // '' = unknown (allowed).
}, 10, 2 );
Actions
| Action | Arguments | Fires when |
|---|---|---|
cksh_attack_started |
$source (auto or manual), $minutes |
Attack mode switches on (not when it is extended). |
cksh_auto_blocked |
$kind (ip or email), $value, $reason (rate_limit or failures), $minutes |
An IP or email is blocked automatically. |
cksh_fs_loaded |
none | The Freemius SDK (or the stub) is ready. |
add_action( 'cksh_attack_started', function ( $source, $minutes ) {
my_pager_alert( "Card-testing attack: attack mode on for {$minutes} min ({$source})" );
}, 10, 2 );
Block checkout extension data
The checkout block sends the browser token and Turnstile response as Store API extension data under the cardfence-for-woocommerce namespace:
{ "extensions": { "cardfence-for-woocommerce": { "token": "1760000000.ab12…", "turnstile": "0.xyz…" } } }
A headless storefront that wants to pass the browser check must load a payment page to get the cksh_sid cookie and a token. Simpler options: keep Browser check on Log only or During attacks, or allow-list your storefront's servers.
Crash protection
Every hook CardFence registers goes through CheckoutShield\Core\Safe:
| Hook type | When it throws |
|---|---|
| Action | Does nothing. |
| Filter | Returns its input unchanged. |
| Checkout checks | Allow the checkout (fail open). |
Caught errors are logged (CardFence caught an error … and let the request continue) and the latest one is stored in the cksh_last_error option for a wp-admin notice. Your own callbacks on cksh_* filters run inside that guard, so an exception in them can't take the checkout down either.
Because the hooks are registered through closures, remove_action() / remove_filter() can't target them by callback. To switch a behavior off, use the plugin's settings or filters instead.
Constants
| Constant | Where | Effect |
|---|---|---|
CARDFENCE_FS_PLUGIN_ID, CARDFENCE_FS_PUBLIC_KEY |
wp-config.php |
Override the Freemius product credentials (for staging or development). |
CARDFENCE_FS_OFF |
wp-config.php |
true keeps the Freemius SDK off and uses the built-in stub. For development and the test suites only. |
CKSH_DEV_UNLOCK |
wp-config.php |
Unlocks Pro for local development, only when WP_DEBUG is also true and the Pro code is present. It has no effect in the free build. |
Data the plugin stores
| What | Name |
|---|---|
| Settings | option cksh_settings |
| Attack-mode state | option cksh_attack (autoloaded) |
| Versions | options cksh_version, cksh_db_version |
| Last weekly report (Pro) | option cksh_last_report |
| Event log | table {prefix}cksh_events: id, created_at (UTC), type, context, ip, email, order_id, reason, detail, hits |
| Temporary blocks | table {prefix}cksh_blocks: id, kind, value, reason, source, created_at, expires_at |
| Attack-order flag | order meta _cksh_suspect (HPOS and legacy) |
| Browser-token session | cookie cksh_sid (session, HttpOnly, SameSite=Lax) |
| Scheduled tasks | cksh_daily (clean-up), cksh_weekly_report and cksh_cleanup (Pro) |
IPv6 addresses are stored per /64 network (2001:db8:1:2::/64).
Code map
| Folder | Contents |
|---|---|
includes/Engine/ |
Guard (the decision engine), Failures, AttackMode, Suspects |
includes/Integration/ |
StoreApi (block checkout), Classic (classic forms and wc-ajax), CheckoutBlocks (front-end script data) |
includes/Detect/ |
Ip, Token, Turnstile |
includes/Store/ |
Events, Blocks (custom tables) |
includes/Admin/ |
Admin (screens), Actions (form handlers), Labels |
includes/Freemius/ |
Gate (plan checks), Stub |
includes/Pro/ |
Premium-only modules. Freemius strips this folder from the free build. |
views/ |
Admin screen templates |