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.