PayPal payments
Updated November 3, 2026
Accept PayPal next to Stripe at checkout, for one-time sales and subscriptions. This needs ReleaseCart Pro and a PayPal Business account.
What you need
- ReleaseCart Pro, active next to the free ReleaseCart plugin. Without Pro, Stripe is the only payment option.
- A PayPal Business account.
- A REST app in the PayPal Developer Dashboard. It gives you a client ID and a secret. Create one app for the sandbox, for testing, and one for live payments. PayPal's REST API guide explains how to get the credentials.
When PayPal is set up, it shows at checkout next to Stripe, and the buyer picks one.
Connect PayPal
- Open ReleaseCart → Settings → Payments, then the PayPal tab.
- Pick the Mode: Sandbox (test) while you test, or Live for real payments.
- Fill in the client ID, the client secret and the webhook ID for that mode. The webhook ID comes from Add the PayPal webhook.
- Click Save.
| Field | What it does |
|---|---|
| Mode | Decides which set of credentials ReleaseCart uses: Sandbox (test) or Live. |
| Sandbox client ID, Live client ID | The client ID of the matching REST app. |
| Sandbox webhook ID, Live webhook ID | The ID PayPal shows for the webhook you add for that app. ReleaseCart needs it to check that a webhook really came from PayPal. |
| Sandbox client secret, Live client secret | The secret of the matching REST app. ReleaseCart stores it encrypted and never shows it again: after you save, the field is empty with the placeholder "Saved". Leave it blank to keep the stored secret, or type a new one to replace it. |

ReleaseCart keeps the sandbox and live credentials apart, so you can fill in both and switch Mode without typing them again. Only the current mode's credentials and webhook ID are used. While Mode is Sandbox, ReleaseCart refuses live webhooks, so do not switch a live store to Sandbox to test.
PayPal shows at checkout once the current mode has a client ID and a client secret. The secret is encrypted with your site's SECURE_AUTH_KEY. If that constant is missing, saving a new secret fails with "The PayPal secret could not be encrypted. Confirm SECURE_AUTH_KEY is set on this site."
Add the PayPal webhook
PayPal tells ReleaseCart about payments, refunds and subscription changes through a webhook. Without it, PayPal refunds and subscription renewals never reach ReleaseCart. PayPal's webhooks guide covers the steps in the dashboard.
- In the PayPal Developer Dashboard, open your REST app. Use the sandbox app for sandbox mode.
- Add a webhook with this URL, using your own domain:
https://yourstore.example/wp-json/releasecart/v1/webhooks/paypal. PayPal sends webhooks only to an HTTPS address. - Subscribe the webhook to the events in the table below, or to all events. If you also pay affiliates through PayPal, add the payout events listed there.
- Copy the webhook ID that PayPal shows into the matching webhook ID field in ReleaseCart, and save.
Do the same for your live app, with its own webhook and webhook ID.
| Event | What ReleaseCart does with it |
|---|---|
PAYMENT.CAPTURE.COMPLETED |
Completes a one-time order. |
PAYMENT.CAPTURE.REFUNDED, PAYMENT.CAPTURE.REVERSED |
Records a refund on the order. |
PAYMENT.SALE.COMPLETED |
Records the first payment of a subscription, then each renewal. |
BILLING.SUBSCRIPTION.PAYMENT.FAILED, BILLING.SUBSCRIPTION.SUSPENDED |
Moves the subscription to past due and starts dunning. |
BILLING.SUBSCRIPTION.CANCELLED |
Marks the subscription Cancelled. |
BILLING.SUBSCRIPTION.EXPIRED |
Marks the subscription Expired. |
ReleaseCart asks PayPal to verify each webhook with the webhook ID. A webhook that arrives while the webhook ID is empty or wrong is refused.
How a PayPal purchase works
When Stripe and PayPal are both set up, the checkout shows a Payment method choice. With Stripe picked, the Pay now button shows under the choice, and the card fields open after the buyer clicks it. Picking PayPal swaps it for a Continue with PayPal button. With only PayPal set up, the checkout shows the PayPal button and no choice.

- The buyer picks PayPal and clicks Continue with PayPal.
- PayPal opens. The buyer logs in and approves the payment there, so card and PayPal login details never reach your site.
- PayPal sends the buyer back to your checkout page. ReleaseCart captures the payment and completes the order, and the page shows the thank-you message while it confirms.
- The receipt and any license keys go out the same way as for a Stripe order.
If the buyer cancels at PayPal, they return to your checkout page with an empty cart and add the items again. The pending order stays. If PayPal reports the payment as pending, the order stays pending until the webhook completes it.
Subscriptions with PayPal
Buyers can subscribe to a recurring tier with PayPal. ReleaseCart creates the PayPal product and billing plan for the tier the first time someone subscribes. ReleaseCart creates the plan once for each tier, currency and mode and reuses it, so a later change to the tier's price or trial never reaches PayPal. PayPal then charges each cycle, and ReleaseCart extends the license and records a renewal order on each payment.
Some things work differently from Stripe:
- With a free trial, the license is issued at the first charge, when the trial ends. PayPal sends no payment during the trial. Stripe issues the license at checkout.
- The first payment of a PayPal subscription is recorded by the webhook only. The order stays pending until
PAYMENT.SALE.COMPLETEDarrives. - Customers cancel a PayPal subscription in their own PayPal account. PayPal tells ReleaseCart, and the subscription is marked Cancelled. The license runs to the end of the paid period.
- The subscription manager's buttons, and plan changes, work for Stripe subscriptions only. For a PayPal subscription, they tell the customer to sign in to PayPal.
Refund a PayPal order
Refund a PayPal order from its order screen under ReleaseCart → Orders, the same way as a Stripe order. ReleaseCart sends the refund to PayPal and records it on the order. The orders page explains refunds.
A refund you make in your PayPal account on a one-time order reaches ReleaseCart through the webhook and is recorded on the order too. ReleaseCart does not pick up refunds made in PayPal on subscription payments.
Test in the sandbox
- Set Mode to Sandbox (test) and fill in the sandbox client ID, client secret and webhook ID.
- Buy something with a PayPal sandbox test account.
- Check that the order is completed under ReleaseCart → Orders and that the license was issued.
- When everything works, set Mode to Live (the sandbox webhook stops working then), fill in the live credentials and webhook ID, and make a small real payment to confirm.
Limits
- HUF and TWD do not work with PayPal. PayPal refuses the amount ReleaseCart sends in those currencies, so no money moves. Use Stripe for them, or price in another currency.
- The PayPal billing plan is created once for each tier, currency and mode. Changing the tier's price or trial later does not update it in PayPal.
- A PayPal subscriber with a free trial gets the license when the trial ends, not at checkout.
- PayPal subscriptions are managed in the customer's PayPal account. Cancel, resume, card changes and plan changes in the subscription manager are for Stripe only.
Common questions
Why does PayPal not show at checkout?
The client ID or the client secret for the current mode is missing, or the stored secret cannot be decrypted, for example after SECURE_AUTH_KEY changed. Save the secret again in that case. Check them on the PayPal tab, and check that Mode matches the credentials. Sandbox credentials work only in sandbox mode.
A PayPal payment went through, but the order is still pending. Why?
For a one-time order, ReleaseCart captures the payment when the buyer returns from PayPal. If the buyer never returns, nothing is captured. If PayPal reports the capture as pending, the order waits for the webhook. For a subscription, the first payment always waits for the webhook. Check that the webhook URL is https://yourstore.example/wp-json/releasecart/v1/webhooks/paypal with your domain, and that the webhook ID in ReleaseCart matches the one PayPal shows.
Why are refunds made in PayPal not showing on the order?
Refunds reach ReleaseCart only for one-time orders. For those, the webhook may be missing the refund events, or the webhook ID may be wrong. Check both.
For developers
PayPal plugs into ReleaseCart's payment gateway list, so the free plugin is not changed. These filters are available:
| Filter | What it changes |
|---|---|
releasecart_checkout_gateways |
The gateways offered at checkout, as ID to label. Reorder, relabel or hide a gateway. |
releasecart_paypal_return_url |
Where PayPal sends a buyer who approves. It receives the URL and the order. Keep the releasecart_paypal_return=<uuid> query argument on a front-end URL, or ReleaseCart never handles the return. |
releasecart_paypal_cancel_url |
Where PayPal sends a buyer who cancels. It receives the URL and the order. Keep the releasecart_paypal_cancel query argument on a front-end URL. |
releasecart_paypal_confirmation_url |
Where the buyer lands after an approved payment. It receives the URL and the order UUID. |