When someone applies a discount code at checkout, Paid Memberships Pro updates the price right away, but it does not tell the member how much they are saving or whether their recurring price changed too. This recipe adds a clear price breakdown to the checkout page the moment a valid code is applied: the original price, the discounted price, how much the member is saving, and the new recurring price if the code changes it.

PMPro checkout page showing the original price, discounted price, and savings after a discount code is applied

Do You Need This Recipe?

You need this recipe if you run discount codes at checkout and want members to see exactly what they are paying, now and on renewal. Skip it if you do not use discount codes, or if your checkout template already shows pricing clearly on its own.

Best Practices and Considerations

  • This only fires through the discount code AJAX call, so it reacts the moment someone enters a valid code. It does nothing on page load and nothing for an invalid code.
  • It targets PMPro’s default checkout markup (#pmpro_level_cost, #pmpro_message_bottom). If your checkout page is heavily customized, confirm those elements still exist before relying on this recipe.
  • The “You save” line only shows when there is an actual savings, so a $0-discount code (like a free-trial or access-only code) will not show a confusing “$0.00 saved” line.
  • It also checks for a changed recurring price, useful for discount codes that modify a level’s billing cycle, not just the up-front payment.

About the Code Recipe

The function compares the membership level a member is purchasing against the discounted version of that level PMPro passes in after a valid code is applied. It builds a small HTML message from the difference (original price, discounted price, savings, and a changed recurring price if there is one), clears out any previous version of that message first (so switching discount codes mid-checkout does not stack up old messages), and then writes the message into two places on the checkout page: right under the price, and again near the Submit and Check Out button.

Understanding the pmpro_applydiscountcode_return_js Hook

This hook fires inside the inline <script> tag that PMPro’s discount code AJAX service returns after checking a code at checkout. Anything echoed inside it becomes literal JavaScript sent to the browser, which is why this recipe builds HTML strings and echoes them wrapped in jQuery(...) calls instead of enqueuing a script file.

It passes four parameters:

  • $discount_code (string): the code the member typed.
  • $discount_code_id (int): the code’s ID.
  • $level_id (int): the ID of the level being purchased, before the discount.
  • $code_level (level object): the level after the discount code is applied. This is where the adjusted initial_payment and billing_amount actually live, and it is what the recipe compares against the original level.

The Code Recipe

Adding the Recipe to Your Website

You can add this recipe to your site by creating a custom plugin or using the Code Snippets plugin available for free in the WordPress repository. Read this companion article for step-by-step directions on either method.

How to Customize This Code Recipe

  • Turn off the bottom message (line 78): If you only want the price breakdown to appear once, delete or comment out the final echo line that appends the message to #pmpro_message_bottom.
  • Change the wording (lines 44–48): Edit the strings inside $html to match your site’s voice.
  • Adjust the recurring-price sensitivity (line 58): The 0.001 threshold filters out floating-point rounding noise. Only raise it if the recurring-price line appears when nothing actually changed.

There are multiple classes added to the strings this recipe outputs, giving you the freedom to style your discount message as needed. The class selectors for each string are:

  • .pmpro-discorig-message: applies a style to all of the strings at once.
  • .pmpro-original-price: applies a style to the “Original price” string.
  • .pmpro-discount-price: applies a style to the “Discounted price” string.
  • .pmpro-save-price: applies a style to the “You save” string.
  • .pmpro-recurring-price: applies a style to the new “Then [price] per [term]” string, shown only when a discount code changes the recurring price.

Add CSS targeting these classes through your theme’s Additional CSS or a child theme stylesheet. Here is an example that makes the discounted price red, bold, and uppercase, bumps up the original price’s font size, and makes the savings line large, green, and underlined:

PMPro checkout page with the discount savings message styled with custom CSS, discounted price in red and savings line enlarged in green:

/* Applied to all strings */
.pmpro-discorig-message {
	margin-bottom: 10px;
}

/* Applied to "Original Price" */
.pmpro-original-price {
	font-size: 2rem;
}

/* Applied to "Discount Price" */
.pmpro-discount-price {
	color: red;
	font-weight: bold;
	text-transform: uppercase;
}

/* Applied to "Save Price" */
.pmpro-save-price {
	font-size: 4rem;
	color: green;
	font-style: italic;
	font-weight: bold;
	margin-top: 30px;
	text-decoration: underline;
}

Adding the Custom CSS to Your Website

There are a few ways to add custom CSS to your membership site. Check out our guide on how to add CSS, which includes tutorials on adding CSS to your child theme, the Site Editor / Customizer, as well as in a stylesheet for PMPro Customizations.

Do not place custom CSS in any file in a theme that gets regularly updated or you will lose your code.

Bonus Tip: Use a browser extension such as Stylebot to write and preview custom CSS for your checkout page before adding it permanently.



Was this article helpful?
YesNo

Free Course: Membership Site Development—The Basics

Develop a deeper understanding of membership site development in this beginner-level course. Learn how to make your site work better, save yourself time and money, and improve your site's performance.

Featured Image for Membership Site Development Course: The Basics