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.

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:
- Fundations calls the PayPal Orders API v2 to create an order and retrieves an approval URL.
- The donor is redirected to PayPal to log in and confirm the payment.
- On return to your site, Fundations calls the PayPal capture endpoint to complete the charge.
- If the payment is already captured (for example because a webhook arrived before the donor returned), the capture step is skipped.
- 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
- Log in to developer.paypal.com.
- Go to My Apps and Credentials and create a new app under the Live tab.
- Copy the Client ID and Client Secret.
- In WordPress, go to Fundations, then Settings, then the PayPal tab.
- Paste your Client ID and Client Secret into the Live fields.
- For testing, repeat the process using the Sandbox tab on the PayPal developer dashboard and paste those credentials into the Test fields.
- Set the mode to Test while verifying, then switch to Live when ready.
- Save the settings.

Optional: webhook signature verification
By default, Fundations accepts all incoming PayPal webhook notifications without verifying the source. To enable verification:
- In the PayPal developer dashboard, open your app and go to Webhooks.
- Add a webhook pointing to
https://yoursite.com/wp-json/get-fund/v1/paypal-webhook. - Select the events:
CHECKOUT.ORDER.APPROVED,PAYMENT.CAPTURE.COMPLETED,PAYMENT.CAPTURE.DENIED,CHECKOUT.ORDER.VOIDED. - Copy the Webhook ID (not the endpoint URL).
- 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
| Setting | Description |
|---|---|
| Test mode | When enabled, uses sandbox credentials and PayPal sandbox |
| Test Client ID | Sandbox app Client ID |
| Test Client Secret | Sandbox app Client Secret |
| Test Webhook ID | Sandbox webhook ID for signature verification (optional) |
| Live Client ID | Production app Client ID |
| Live Client Secret | Production app Client Secret |
| Live Webhook ID | Production 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
| Hook | Type | When fired | Parameters |
|---|---|---|---|
get_fund_donation_completed | Action | After 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 key | Type | Notes |
|---|---|---|
get_fund_paypal_test_mode | bool | Defaults to true |
get_fund_paypal_test_client_id | string | |
get_fund_paypal_test_secret | string | |
get_fund_paypal_live_client_id | string | |
get_fund_paypal_live_secret | string | |
get_fund_paypal_test_webhook_id | string | Optional; skips verification if empty |
get_fund_paypal_live_webhook_id | string | Optional; skips verification if empty |
get_fund_donation_thank_you_page | int | WP page ID used as the return URL after payment |