DOCS

PayPal

PayPal is included in the free Fundations plugin. No Pro license is required. It uses the PayPal Orders API v2 and redirects donors to PayPal to complete payment.

Paypal settings screen

Why use PayPal

PayPal is the fastest way to start accepting donations. You need only a PayPal Business account and a set of API credentials. Donors can pay with their PayPal account or with a credit or debit card without creating a PayPal account.

What it does

When a donor submits the donation form with PayPal selected:

  1. Fundations calls the PayPal Orders API v2 to create an order and retrieves an approval URL.
  2. The donor is redirected to PayPal to log in and confirm the payment.
  3. On return to your site, Fundations calls the PayPal capture endpoint to complete the charge.
  4. If the payment is already captured (for example because a webhook arrived before the donor returned), the capture step is skipped.
  5. The donation is marked as paid, stats are updated, and a confirmation email is sent.

A webhook endpoint (POST /wp-json/get-fund/v1/paypal-webhook) also receives real-time notifications from PayPal. This handles cases where the donor does not return to your site after payment.

How to set it up

  1. Log in to developer.paypal.com.
  2. Go to My Apps and Credentials and create a new app under the Live tab.
  3. Copy the Client ID and Client Secret.
  4. In WordPress, go to Fundations, then Settings, then the PayPal tab.
  5. Paste your Client ID and Client Secret into the Live fields.
  6. For testing, repeat the process using the Sandbox tab on the PayPal developer dashboard and paste those credentials into the Test fields.
  7. Set the mode to Test while verifying, then switch to Live when ready.
  8. Save the settings.
Paypal credentials fields

Optional: webhook signature verification

By default, Fundations accepts all incoming PayPal webhook notifications without verifying the source. To enable verification:

  1. In the PayPal developer dashboard, open your app and go to Webhooks.
  2. Add a webhook pointing to https://yoursite.com/wp-json/get-fund/v1/paypal-webhook.
  3. Select the events: CHECKOUT.ORDER.APPROVED, PAYMENT.CAPTURE.COMPLETED, PAYMENT.CAPTURE.DENIED, CHECKOUT.ORDER.VOIDED.
  4. Copy the Webhook ID (not the endpoint URL).
  5. Paste it into the Webhook ID field in Fundations PayPal settings.

With the Webhook ID configured, each incoming notification is verified against PayPal’s signature API before being processed. Without it, any POST to your webhook endpoint is accepted, which is a security consideration on public sites.

Settings reference

SettingDescription
Test modeWhen enabled, uses sandbox credentials and PayPal sandbox
Test Client IDSandbox app Client ID
Test Client SecretSandbox app Client Secret
Test Webhook IDSandbox webhook ID for signature verification (optional)
Live Client IDProduction app Client ID
Live Client SecretProduction app Client Secret
Live Webhook IDProduction webhook ID for signature verification (optional)

What you can and cannot do

You can:

  • Accept PayPal account payments and card payments from donors globally.
  • Test using PayPal sandbox credentials before going live.
  • Enable webhook signature verification using a Webhook ID.

You cannot:

  • Accept payments without redirecting donors to PayPal (the plugin uses the redirect flow, not PayPal’s JS SDK or Smart Buttons).
  • Process recurring donations with PayPal (recurring is currently disabled in Fundations).
  • Use PayPal as the gateway for WooCommerce product orders through the Fundations WooCommerce integration; those orders are created after payment completes on whichever gateway the donor used.

Troubleshooting

Donation stays in pending status after the donor returns

The capture API call happens when the donor lands back on your site. If the page load is interrupted, the capture may not complete. Fundations will also process the payment via the webhook when PayPal sends a PAYMENT.CAPTURE.COMPLETED notification. Check that your webhook endpoint is reachable and that no security plugin or firewall blocks POST requests to /wp-json/.

Webhook notifications not processed

Confirm the webhook URL in the PayPal dashboard matches https://yoursite.com/wp-json/get-fund/v1/paypal-webhook exactly. If you have a Webhook ID configured, verify it matches the one PayPal shows for this endpoint. Without a matching Webhook ID, verification is skipped but the endpoint still needs to be reachable.

Payment shows as approved but donation not marked paid

PayPal’s approval status means the donor authorized the payment, but the actual charge happens during capture. If the capture call fails (for example, due to insufficient funds or a network error), the donation will not be marked paid. Check the PHP error log for PayPal API error responses.

Test mode credentials returning errors

Sandbox and live credentials are separate apps in the PayPal developer dashboard. Make sure you are copying credentials from the Sandbox tab and entering them in the Test fields in Fundations settings.

Developer reference

Hooks fired by the PayPal path

HookTypeWhen firedParameters
get_fund_donation_completedActionAfter a successful payment (webhook or return)$donation_id (int), $data (array)

The $data array contains: amount, action_id, donor_name, donor_email.

Note: The PayPal trait calls stats sync, raised-amount update, and confirmation email methods directly. It does not fire get_fund_donation_paid. If you need to hook into PayPal payments specifically, use get_fund_donation_completed. For a gateway-agnostic hook that fires for Mollie and Stripe as well, see the donation system documentation.

REST endpoint

POST /wp-json/get-fund/v1/paypal-webhook

No authentication. Handles: CHECKOUT.ORDER.APPROVED, PAYMENT.CAPTURE.COMPLETED, PAYMENT.CAPTURE.DENIED, CHECKOUT.ORDER.VOIDED.

Signature verification is performed only when a Webhook ID option is configured. Without it, all POST requests to this endpoint are accepted.

Relevant options

Option keyTypeNotes
get_fund_paypal_test_modeboolDefaults to true
get_fund_paypal_test_client_idstring
get_fund_paypal_test_secretstring
get_fund_paypal_live_client_idstring
get_fund_paypal_live_secretstring
get_fund_paypal_test_webhook_idstringOptional; skips verification if empty
get_fund_paypal_live_webhook_idstringOptional; skips verification if empty
get_fund_donation_thank_you_pageintWP page ID used as the return URL after payment