Hooks reference

Updated

Filters and actions for customizing the plugin, plus the WordPress and WooCommerce hooks it relies on.

Filters

FilterArgsPurpose
wpinterface_paddle_woo_billing_transaction$body, $order, $subscriptionChange the Billing POST /transactions body
wpinterface_paddle_woo_classic_pay_link$fields, $order, $subscriptionChange the Classic generate_pay_link fields
wpinterface_paddle_woo_checkout_mode$modeinline or overlay; anything else falls back to inline
wpinterface_paddle_woo_checkout_config$configSettings passed to the browser as wpinterfacePaddleWooConfig
wpinterface_paddle_woo_webhook_base_url$url ('')Base URL Paddle should call (tunnels, proxies)
wpinterface_paddle_woo_settings_fields$fieldsGateway form fields
wpinterface_paddle_woo_handle_billing_event$handled (false), $event, $sandboxReturn true to handle a verified Billing event instead of the plugin
wpinterface_paddle_woo_handle_classic_alert$handled (false), $fields, $sandboxSame for Classic
wpinterface_paddle_woo_billing_webhook_events$eventsEvents Set up webhook subscribes to
wpinterface_paddle_woo_license_store_url$urlStore used for license calls and updates

$subscription is the array from Subscriptions::checkout_subscription() or null. The plugin also applies WooCommerce’s woocommerce_gateway_icon.

functions.php

add_filter( 'wpinterface_paddle_woo_billing_transaction', function ( $body, $order, $subscription ) {
	// Use a SaaS tax category for subscription orders only.
	if ( $subscription ) {
		foreach ( $body['items'] as &$item ) {
			$item['price']['product']['tax_category'] = 'saas';
		}
		unset( $item );
	}
	return $body;
}, 10, 3 );

Keep the order references

Keep custom_data.wc_order_id and custom_data.wc_site; the webhook relies on them. For Classic keep passthrough, and don’t set discountable or quantity_variable to 1 (the amount check would refuse a lower payment).

functions.php

// Overlay on phones, the configured style elsewhere.
add_filter( 'wpinterface_paddle_woo_checkout_mode', function ( $mode ) {
	return wp_is_mobile() ? 'overlay' : $mode;
} );

Handling an extra Billing event: add it to the subscribed events, click Set up webhook again, and claim it.

functions.php

add_filter( 'wpinterface_paddle_woo_billing_webhook_events', function ( $events ) {
	$events[] = 'customer.updated';
	return $events;
} );

add_filter( 'wpinterface_paddle_woo_handle_billing_event', function ( $handled, $event, $sandbox ) {
	if ( 'customer.updated' === $event['event_type'] ) {
		my_crm_update_customer( $event['data'], $sandbox ); // Your own function.
		return true;
	}
	return $handled;
}, 10, 3 );

An exception thrown from your handler makes the endpoint answer 500, so Paddle retries.

Actions

ActionArgsFires
wpinterface_paddle_woo_loadednoneEnd of Plugin::__construct
wpinterface_paddle_woo_billing_webhookarray $event, bool $sandboxAfter a verified Billing event was handled without an exception
wpinterface_paddle_woo_classic_webhookarray $fields, bool $sandboxAfter a verified Classic webhook was handled without an exception
wpinterface_paddle_woo_order_panelWC_Order $orderEnd of the Paddle meta box on Paddle orders
wpinterface_paddle_woo_after_status_panelnoneEnd of the Status row on the settings screen
wpinterface_paddle_woo_field_{key}array $dataContent of a settings field of type wpinterface_paddle_hook
wpinterface_paddle_woo_link_subscriptionint $order_id, int $attemptAction Scheduler hook the plugin schedules and handles

functions.php

add_action( 'wpinterface_paddle_woo_billing_webhook', function ( $event, $sandbox ) {
	if ( 'subscription.updated' === $event['event_type'] ) {
		// Sync seats, CRM, analytics…
	}
}, 10, 2 );

A custom settings row (it stores nothing):

functions.php

add_filter( 'wpinterface_paddle_woo_settings_fields', function ( $fields ) {
	$fields['my_note'] = array(
		'title' => __( 'Notes', 'my-plugin' ),
		'type'  => 'wpinterface_paddle_hook',
	);
	return $fields;
} );

add_action( 'wpinterface_paddle_woo_field_my_note', function ( $data ) {
	echo '<p>' . esc_html__( 'Managed by My Plugin.', 'my-plugin' ) . '</p>';
} );

Hooks the plugin uses

  • WordPress: plugins_loaded (20), init, rest_api_init, wp_enqueue_scripts, template_redirect, admin_init, admin_menu (60), admin_notices, admin_enqueue_scripts, add_meta_boxes (30), plugin_action_links_{basename}, wp_ajax_*, wp_ajax_nopriv_wpinterface_paddle_woo_order_status, admin_post_wpinterface_paddle_woo_license, admin_post_wpinterface_paddle_woo_dismiss_welcome.
  • WooCommerce: before_woocommerce_init, woocommerce_payment_gateways, woocommerce_blocks_loaded, woocommerce_blocks_payment_method_type_registration, woocommerce_update_options_payment_gateways_wpinterface_paddle, woocommerce_receipt_wpinterface_paddle, woocommerce_before_thankyou (5), woocommerce_thankyou_wpinterface_paddle (5), woocommerce_order_refunded (10, 2), woocommerce_get_order_item_totals (20, 2), woocommerce_email_after_order_table (20, 4).
  • WooCommerce Subscriptions: woocommerce_subscription_status_updated (10, 3), wcs_view_subscription_actions (10, 2), woocommerce_subscriptions_can_item_be_switched (10, 3).

Was this page helpful?