Skip to main content

Accept PayPal donations alongside NationBuilder Payments

Give donors a PayPal option on your Donation (v2) page while NationBuilder Payments continues to process cards and digital wallets.


Some of your supporters prefer PayPal. They may have a PayPal balance, their payment details are already saved, and they trust the checkout. Offering PayPal next to your card form helps those donors complete a gift instead of abandoning the page.

This guide shows you how to add a PayPal option to your Donation (v2) page.

📌 Note: This setup does not connect PayPal as a NationBuilder payment processor. PayPal collects the money in your own PayPal account. Because NationBuilder never processes the PayPal charge, this approach is unaffected by the deprecation of third-party payment processors.

How this works

There are two pieces:

  • Your Donation (v2) page keeps NationBuilder Payments as its processor for cards, Apple Pay, Google Pay, and Link.

  • A PayPal button on that page sends donors who prefer PayPal to a PayPal-hosted checkout. The gift lands in your PayPal account.

What you get

  • Donors choose their preferred payment method.

What to plan around

  • PayPal gifts are processed by PayPal, so PayPal's fees and payout schedule apply, not NationBuilder Payments rates.

  • Donors cannot cancel a PayPal recurring gift from the Supporter Portal. They cancel with PayPal directly. You also cannot cancel a PayPal recurring gift from NationBuilder. It must be canceled in your PayPal account.

  • PayPal does not collect employer and occupation. If you have reporting obligations that require them, plan accordingly.

Before you begin

You will need:

  • A Donation (v2) page using NationBuilder Payments.

  • A custom website theme. You cannot edit a stock theme directly.

  • A PayPal business account with a hosted donate button or subscription plan configured.

  • Comfort editing theme templates, or a certified NationBuilder partner to make the changes for you.


Adding the PayPal logo to a Donation (v2) page

Donors need to see the PayPal mark before they decide to abandon the page. A text link that simply reads "PayPal" converts far less well than the recognized logo.

Choose a placement

Two placements work well, and the right one depends on how prominent you want the option to be.

Above the amount selector

The PayPal link sits near the top of the form, before the donor has started filling anything in. Use this when a meaningful share of your donors prefer PayPal and you want them diverted early rather than halfway through the form.

Inside the "Pay with" section

The PayPal button sits alongside the card option, presented as one payment method among several. Use this when PayPal is a secondary option and you want the card form to stay the default path.

Get your PayPal button assets

PayPal requires you to use its official button artwork. Do not recreate the logo yourself or use a copy from an image search.

  1. Sign in to your PayPal business account.

  2. Go to Pay & Get Paid > PayPal buttons and create a Donate button (for one-time gifts) or a Subscribe button (for recurring gifts).

  3. PayPal generates the button code. Copy two things from it:

  • The image URL, which begins with https://www.paypalobjects.com/

  • Your hosted_button_id, a string of letters and numbers.

  • Keep these somewhere handy. You will paste them into your theme in the next section.


Theme implementation guide

All of the code in this section goes into pages_show_donation_v2_wide.html in your custom theme.

Find the file

  1. Navigate to Theme > Current custom theme > Files.

  2. Open pages_show_donation_v2_wide.html.

Find the right insertion point

Scroll to the "Pay with" section of the template. In every theme except Momentum, look for the literal words "Pay with". In Momentum-based themes, you will see {{ t_forms_pay_with }} instead.

The section looks roughly like this:

<div>
<h3>Pay with</h3>
</div>

<div id="payment-methods">
{% if page.donation_v2.express_payment_activated? %}
<div id="donation-v2-payment-request"></div>
{% endif %}
<div id="cc-request-button">
<button type="button" class="button"><i id="credit-card-icon"></i>Credit Card</button>
</div>
</div>

<div id="cc-info">
<div>{% payment_field 'card' %}</div>
</div>

Place your PayPal block after the closing </div> of payment-methods and before cc-info.

⚠️ Do not place the PayPal block inside <div id="payment-methods">. NationBuilder hides that entire div when no express payment method is detected on the donor's device, which would hide your PayPal button along with it on most desktop browsers.

Two further rules apply to every theme:

  • The code must sit between {% form_for donation %} and {% endform_for %}.

  • Do not place it inside the {% if request.current_order %} conditional. That branch handles event ticketing, where this functionality is not designed to work.

Theme-specific markup

Each stock theme uses a different grid framework, so the wrapper markup differs. The inner link is identical in all four.

Replace [YOUR_PAYPAL_IMAGE_URL] and [YOUR_HOSTED_BUTTON_ID] with the values you copied from PayPal.

Aware

Aware uses a Bootstrap 2 grid (row-fluid and span12).

<div class="row-fluid nb-paypal-option">
<div class="span12">
<p class="nb-paypal-divider">Or</p>
<a id="nb-paypal-link"
class="nb-paypal-button"
href="https://www.paypal.com/donate?hosted_button_id=[YOUR_HOSTED_BUTTON_ID]"
target="_blank"
rel="noopener">
<img src="[YOUR_PAYPAL_IMAGE_URL]" alt="Donate with PayPal" />
</a>
</div>
</div>

Action

Action uses a Bootstrap 3 grid (row and col-md-12).

<div class="row nb-paypal-option">
<div class="col-md-12">
<p class="nb-paypal-divider">Or</p>
<a id="nb-paypal-link"
class="nb-paypal-button"
href="https://www.paypal.com/donate?hosted_button_id=[YOUR_HOSTED_BUTTON_ID]"
target="_blank"
rel="noopener">
<img src="[YOUR_PAYPAL_IMAGE_URL]" alt="Donate with PayPal" />
</a>
</div>
</div>

Raise

Raise uses Bootstrap 4 conventions (form-group).

<div class="form-group nb-paypal-option">
<p class="nb-paypal-divider">Or</p>
<a id="nb-paypal-link"
class="nb-paypal-button"
href="https://www.paypal.com/donate?hosted_button_id=[YOUR_HOSTED_BUTTON_ID]"
target="_blank"
rel="noopener">
<img src="[YOUR_PAYPAL_IMAGE_URL]" alt="Donate with PayPal" />
</a>
</div>

Momentum

Momentum uses Bootstrap 4 conventions and drives its visible text through translation variables rather than hardcoded strings.

<div class="form-group nb-paypal-option">
<p class="nb-paypal-divider">Or</p>
<a id="nb-paypal-link"
class="nb-paypal-button"
href="https://www.paypal.com/donate?hosted_button_id=[YOUR_HOSTED_BUTTON_ID]"
target="_blank"
rel="noopener">
<img src="[YOUR_PAYPAL_IMAGE_URL]" alt="Donate with PayPal" />
</a>
</div>

📌 Note for Momentum: the words "Or" and the image alt text above are hardcoded in English. Momentum renders the rest of the donation form through translation variables, so on a multilingual site these two strings will not translate with the rest of the page. If you run your site in more than one language, replace them with your own translation variables.

Add the styling

Add this to the bottom of your theme.scss file. Adjust the colors and spacing to match your theme.

.nb-paypal-option {
margin: 1rem 0 1.5rem;
text-align: center;

.nb-paypal-divider {
position: relative;

margin-bottom: 1rem;
color: #6c757d;
font-size: 0.875rem;
text-transform: uppercase;
letter-spacing: 0.05em;

&::before,
&::after {
content: "";
position: absolute;
top: 50%;
width: calc(50% - 2rem);
border-top: 1px solid #dee2e6;
}

&::before { left: 0; }
&::after { right: 0; }

}

.nb-paypal-button {
display: inline-block;

img {
max-width: 100%;
height: auto;
border: 0;
}

&:hover { opacity: 0.85; }
}
}

Carry the donor's selected amount through to PayPal

Without this step, a donor who selects $50 on your page arrives at PayPal with an empty amount field and has to type it again. Many will not.

Add this script at the bottom of pages_show_donation_v2_wide.html, below the existing donation script tag. Be sure to add your button and plan IDs.
​

 
<script>
(function () {
var ONE_TIME_URL = "https://www.paypal.com/donate?hosted_button_id=[YOUR_HOSTED_BUTTON_ID]";
var RECURRING_URL = "https://www.paypal.com/webapps/billing/plans/subscribe?plan_id=[YOUR_PLAN_ID]";

var link = document.getElementById("nb-paypal-link");
if (!link) { return; }

function selectedAmount() {
var checked = document.querySelector('input[name="donation[amount]"]:checked');
var typed = document.querySelector('input[name="donation[amount]"][type="text"]');
var raw = (checked && checked.value) || (typed && typed.value) || "";
return raw.replace(/[^0-9.]/g, "");
}


function isRecurring() {
var selected = document.querySelector('.donation-v2-occurence-radio input:checked');
if (!selected) { return false; }
return /month|annual|year/i.test(selected.value);
}


function updateLink() {
if (isRecurring()) {
link.href = RECURRING_URL;
return;
}
var amount = selectedAmount();
link.href = amount
? ONE_TIME_URL + "&amount=" + encodeURIComponent(amount)
: ONE_TIME_URL;
}

document.addEventListener("change", updateLink);
document.addEventListener("keyup", updateLink);
updateLink();
})();
</script>

📌 Pro-tip: The .donation-v2-occurence-radio selector matches the stock themes. If your theme has been heavily customized, right-click your live donation page, choose Inspect, and confirm the class name on your one-time/monthly selector before you publish.

Test before you publish

  1. Preview the page and confirm the PayPal button appears below the card option.

  2. Select each donation amount in turn and hover the PayPal link. The amount in the URL should update each time.

  3. Switch to Monthly and confirm the link changes to your subscription URL.

  4. Check the page on a mobile device. The express payment buttons change what is visible on mobile, so confirm your PayPal button is still positioned sensibly.

  5. Make a small live donation through PayPal and confirm it arrives in your PayPal account.

Did this answer your question?