Add these hooks in a small custom plugin, a code snippets plugin, or your child theme's functions.php. Hooks that change the front end must be added before WordPress runs template_redirect.
| Hook | Type | Use it to |
|---|---|---|
payment_page_payment_received |
Action | Run code after a payment is recorded as paid |
payment_page_subscription_created |
Action | Run code when a subscription's first invoice is paid |
payment_page_subscription_payment_received |
Action | Run code when a renewal invoice is paid |
payment_page_subscription_status_changed |
Action | React to a subscription being created, updated or canceled |
payment_page_subscription_payment_method_event |
Action | React to the result of saving a subscription's payment method |
payment_page_cart_recovery_email |
Filter | Change an abandoned-cart reminder email |
payment_page_cart_recovery_capture_cap |
Filter | Change the hourly limit on new abandoned-cart addresses |
payment_page_force_universal_interface |
Filter | Load the form scripts on pages where a form is not detected |
payment_page_stripe_advanced_fraud_signals |
Filter | Turn on Stripe.js advanced fraud signals |
payment_page_stripe_payment_methods_administration |
Filter | Change the Stripe methods listed in the admin |
payment_page_stripe_payment_methods_frontend |
Filter | Change the Stripe methods offered on a form |
payment_page_paypal_payment_methods_administration |
Filter | Change the PayPal methods listed in the admin |
payment_page_paypal_payment_methods_frontend |
Filter | Change the PayPal methods offered on a form |
payment_page_register_post_type_payment_form_args |
Filter | Change how the payment form post type is registered |
payment_page_administration_form_field_map |
Filter | Change the form builder's field groups |
payment_page_administration_dashboard |
Filter | Change the gateway data shown on the dashboard |
payment_page_form_templates |
Filter | Change the form template gallery |
payment_page_update_settings |
Filter | Change settings before they are saved |
payment_page_template_path |
Filter | Change the theme folder for template overrides |
payment_page_locate_template |
Filter | Change which template file is found |
payment_page_get_template |
Filter | Change the template file just before it loads |
payment_page_before_template_part |
Action | Output before a template |
payment_page_after_template_part |
Action | Output after a template |
payment_page_fs_loaded |
Action | Run code once the Freemius SDK is ready |
Payment and subscription events#
These actions run while Payment Page processes a Stripe webhook, a PayPal capture or a PayPal webhook.
payment_page_payment_received#
Runs after a payment is recorded as paid: a one-time Stripe payment, the first invoice of a Stripe subscription, or a PayPal capture. Renewals use payment_page_subscription_payment_received instead. An accepted upsell is its own payment and runs this action again.
Arguments: array $data, array $gateway_args
$data holds:
| Key | Value |
|---|---|
gateway, method, mode |
Gateway (stripe or paypal), payment method (for example ccard) and live or test |
name, email |
The buyer's name and email |
amount, amount_received, currency |
Amounts in the smallest currency unit (cents for USD) and the currency code |
frequency |
one-time, or the subscription interval code: d_1, w_1, m_1, m_3, m_6, y_1 or y_3 |
items |
What the buyer added (order bumps, products or the upsell offer). Present only when the buyer added something. |
payment_page_payment_id, payment_page_id, payment_page_url, domain_name |
The payment record ID, the form ID, the form URL and the site domain |
provider_event_id, provider_object_id |
The Stripe event ID and PaymentIntent or Invoice ID, or paypal- plus the capture ID and the PayPal order ID |
| Custom field keys | One key per custom field on the form |
$gateway_args has one key: stripe (the Stripe event's data object; ->object is the PaymentIntent or Invoice) or paypal (the PayPal order result).
add_action( 'payment_page_payment_received', function ( $data, $gateway_args ) {
if ( 'live' !== $data['mode'] ) {
return; // Ignore test payments.
}
wp_remote_post( 'https://example.com/crm/payments', array(
'timeout' => 5,
'body' => array(
'email' => $data['email'],
'form_id' => $data['payment_page_id'],
'amount' => $data['amount_received'],
'currency' => $data['currency'],
),
) );
}, 10, 2 );
payment_page_subscription_created#
Runs when the first invoice of a Stripe subscription is paid, just before payment_page_payment_received runs for that same payment. It does not run for renewals.
Arguments: array $data, array $gateway_args (same shapes as payment_page_payment_received, with the stripe key)
payment_page_subscription_payment_received#
Runs once for each paid Stripe renewal invoice, after the first invoice has settled.
Arguments: \PaymentPage\Model\Payments $payment (the original subscription checkout), object $invoice (the Stripe Invoice)
payment_page_subscription_status_changed#
Runs for customer.subscription.created, customer.subscription.updated and customer.subscription.deleted events on a Payment Page subscription.
Arguments: \PaymentPage\Model\Payments $payment, string $event_type, object $subscription (the Stripe Subscription)
add_action( 'payment_page_subscription_status_changed', function ( $payment, $event_type, $subscription ) {
if ( 'customer.subscription.deleted' === $event_type ) {
// Remove access for $payment->email_address.
}
}, 10, 3 );
payment_page_subscription_payment_method_event#
Runs for setup_intent.succeeded, setup_intent.setup_failed and setup_intent.canceled events from a Payment Page subscription checkout.
Arguments: \PaymentPage\Model\Payments $payment, string $event_type, object $setup_intent (the Stripe SetupIntent)
The $payment object exposes the stored payment fields, including id, post_id (form ID), email_address, first_name, last_name, payment_gateway, payment_method, amount, currency, is_paid and is_live.
Cart recovery (Pro)#
Reminders go out from the hourly WP-Cron event payment_page_cart_recovery_sweep.
payment_page_cart_recovery_email#
Filters each reminder email after merge tags are filled in.
Arguments: array $mail (subject, body, headers), array $row (the abandoned-cart row: id, post_id, email_address, first_name, product_title, price, stage, created_at, updated_at, last_email_at), int $stage (reminder number, 1 to 3)
Returns: the $mail array. The body is sent as plain text unless you add a Content-Type header.
add_filter( 'payment_page_cart_recovery_email', function ( $mail, $row, $stage ) {
if ( 3 === $stage ) {
$mail['subject'] = 'Last reminder: ' . $mail['subject'];
}
$mail['headers'][] = 'Bcc: [email protected]';
return $mail;
}, 10, 3 );
payment_page_cart_recovery_capture_cap#
Filters how many new addresses one form can enroll per hour. Addresses over the limit are not saved.
Arguments: int $cap (default 100), int $post_id (form ID)
Returns: an integer. Return 0 for no limit.
add_filter( 'payment_page_cart_recovery_capture_cap', function ( $cap, $post_id ) {
return 42 === $post_id ? 500 : $cap;
}, 10, 2 );
Front end#
payment_page_force_universal_interface#
Payment Page loads its scripts only where it detects a form: a single payment form page, the [payment-page-payment-form] or [payment-page-success-details] shortcode in the page content, or the Payment Page Elementor widget. Return true to load them on a page it cannot detect, such as a popup or a custom template.
Arguments: bool $force (default false). Runs on template_redirect.
add_filter( 'payment_page_force_universal_interface', function ( $force ) {
return $force || is_page( array( 'pricing', 'donate' ) );
} );
payment_page_stripe_advanced_fraud_signals#
Sets the advancedFraudSignals option when Payment Page loads Stripe.js. It is off by default because browsers that block third-party cookies can stop the form from loading when it is on. Stripe Radar still scores payments either way.
Arguments: bool $enabled (default false)
add_filter( 'payment_page_stripe_advanced_fraud_signals', '__return_true' );
Payment methods#
payment_page_stripe_payment_methods_administration#
Filters the Stripe methods listed on the Payment Gateways screen.
Arguments: array $methods, keyed by method: ccard, ach_direct_debit, sepa, apple_pay, google_pay, alipay, wechat
payment_page_stripe_payment_methods_frontend#
Filters the Stripe methods a form offers. Each entry includes id, name, payment_method, has_recurring_support and image. A method removed here is also refused by the checkout routes.
Arguments: array $methods, array $active_payment_methods (method IDs enabled for the form)
add_filter( 'payment_page_stripe_payment_methods_frontend', function ( $methods, $active ) {
return array_values( array_filter( $methods, function ( $method ) {
return 'wechat' !== $method['id']; // Hide WeChat Pay.
} ) );
}, 10, 2 );
payment_page_paypal_payment_methods_administration#
Filters the PayPal methods listed on the Payment Gateways screen. The built-in method is standard_checkout (one-time payments only).
Arguments: array $methods
payment_page_paypal_payment_methods_frontend#
Filters the PayPal methods a form offers.
Arguments: array $methods, array $active_payment_methods
Forms, settings and admin#
payment_page_register_post_type_payment_form_args#
Filters the register_post_type() arguments for the pp_payment_form post type.
Arguments: array $args
add_filter( 'payment_page_register_post_type_payment_form_args', function ( $args ) {
$args['rewrite']['slug'] = 'pay'; // Form URLs become /pay/<form>/. Resave permalinks after.
return $args;
} );
payment_page_administration_form_field_map#
Filters the field groups shown in the form builder.
Arguments: array $field_groups
payment_page_administration_dashboard#
Filters the gateway data on the Payment Page dashboard (the payment_gateway part of the /administration/dashboard response).
Arguments: array $gateways, keyed stripe and paypal
payment_page_form_templates#
Filters the form template gallery. It applies to the list from the Payment Page template site, the last saved copy of that list, or the templates bundled with Payment Page when the site cannot be reached.
Arguments: array $templates
payment_page_update_settings#
Filters settings just before Payment Page saves them to the payment_page_settings option. The array holds only the keys being saved in that update.
Arguments: array $options
add_filter( 'payment_page_update_settings', function ( $options ) {
// Keep Stripe in test mode on staging.
if ( isset( $options['stripe_is_live'] ) && 'staging' === wp_get_environment_type() ) {
$options['stripe_is_live'] = 0;
}
return $options;
} );
Templates#
These hooks apply to templates Payment Page loads through its template loader: shortcode-payment-success.php (the [payment-page-success-details] shortcode) and its admin screens. To override a template, copy it from the plugin's templates/ folder to payment-page/ in your theme, for example your-theme/payment-page/shortcode-payment-success.php. The standalone payment form page (single-pp_payment_form.php) does not use these hooks.
payment_page_template_path#
Filters the theme folder searched for overrides.
Arguments: string $path (default 'payment-page/')
payment_page_locate_template#
Filters the template path found in the theme, or the plugin default when the theme has none.
Arguments: string $template, string $template_name, string $template_path
payment_page_get_template#
Filters the template file just before it is included.
Arguments: string $located, string $template_name, array $args, string $template_path, string $default_path
add_filter( 'payment_page_get_template', function ( $located, $template_name ) {
if ( 'shortcode-payment-success.php' === $template_name ) {
return plugin_dir_path( __FILE__ ) . 'templates/payment-success.php';
}
return $located;
}, 10, 2 );
payment_page_before_template_part and payment_page_after_template_part#
Run just before and just after a template is included.
Arguments: string $template_name, string $template_path, string $located, array $args
add_action( 'payment_page_after_template_part', function ( $template_name ) {
if ( 'shortcode-payment-success.php' === $template_name ) {
echo '<p class="thank-you-note">A receipt is on its way to your inbox.</p>';
}
} );
Freemius#
payment_page_fs_loaded#
Runs once the bundled Freemius SDK is set up, so payment_page_fs() is available.
Arguments: none
add_action( 'payment_page_fs_loaded', function () {
if ( payment_page_fs()->is_paying() ) {
// Code for paying customers only.
}
} );
Need a hook that is not listed here? Contact support. Adding a hook is better than editing plugin files.