EP Ecommerce PayPal
EP Ecommerce PayPal handles PayPal payments for EP Ecommerce using the PayPal REST API v2 (Orders). Implements the standard server-create, client-approve, server-capture flow, with OAuth2 access token management, webhook verification, and optional PayPal Subscriptions for recurring billing.
Published by ElmsPark Studio.
Overview
Section titled “Overview”- PayPal Orders API v2 with a proper server-side create and capture, not the legacy Express Checkout.
- PayPal JS SDK buttons on the frontend with configurable colour and shape.
- Sandbox and live credential pairs with mode switching.
- OAuth2 access token managed internally with request-level caching.
- Webhook verification via PayPal’s
verify-webhook-signatureAPI. - Admin refunds via the Captures API.
- Coexists with EP Ecommerce Stripe — both render into the same payment slot, so customers can pick their preferred method.
- PayPal Subscriptions support when EP Ecommerce Subscriptions is active.
Requirements
Section titled “Requirements”- PageMotor 0.8.2b or later
- EP Ecommerce (base plugin)
- EP Suite base class
- EP Ecommerce Products for the checkout UI
- A PayPal Developer account with REST API credentials
- EP Ecommerce Subscriptions (optional, for recurring billing via PayPal)
Setting up PayPal
Section titled “Setting up PayPal”Step 1 — Create the PayPal app
Section titled “Step 1 — Create the PayPal app”- Log in to the PayPal Developer Dashboard.
- Under Apps & Credentials, click Create App.
- Name it (e.g. “PageMotor ecommerce”), pick Merchant, click Create App.
- Copy the Client ID and Secret for both the Sandbox and Live environments.
Step 2 — Configure the plugin
Section titled “Step 2 — Configure the plugin”Open Plugin Settings → EP Ecommerce PayPal.
- Enable PayPal payments. Toggle on.
- Mode. Sandbox for testing, Live for production.
- Sandbox credentials. Client ID and secret.
- Live credentials. Client ID and secret for production.
Step 3 — Set up the webhook
Section titled “Step 3 — Set up the webhook”- Back in the PayPal Developer Dashboard, open your app.
- Scroll to Webhooks, click Add Webhook.
- Webhook URL: copy from the plugin settings page (displayed in the Webhook section).
- Event types to subscribe to:
PAYMENT.CAPTURE.COMPLETEDPAYMENT.CAPTURE.DENIED- If using subscriptions, also:
BILLING.SUBSCRIPTION.ACTIVATED,BILLING.SUBSCRIPTION.CANCELLED,BILLING.SUBSCRIPTION.EXPIRED,PAYMENT.SALE.COMPLETED.
- Save. Copy the generated Webhook ID.
- Paste the Webhook ID into the plugin’s Webhook ID setting for signature verification.
How the payment flow works
Section titled “How the payment flow works”- Customer clicks the PayPal button on your site.
- Plugin exchanges Client ID + Secret for an OAuth2 access token (cached per request).
- Plugin creates a PayPal Order with the product amount and purchase details.
- PayPal JS SDK renders the button, customer approves in a PayPal popup.
- Frontend receives the approved order ID, sends it to the plugin’s capture endpoint.
- Plugin calls PayPal’s Capture API to finalise the payment.
- PayPal fires
PAYMENT.CAPTURE.COMPLETEDto your webhook. - Plugin verifies the webhook signature, marks the order paid, triggers fulfilment.
- Customer sees success message, receives EP Email confirmation.
Subscription flow (with EP Ecommerce Subscriptions)
Section titled “Subscription flow (with EP Ecommerce Subscriptions)”When subscription products are purchased via PayPal:
- Plugin creates a PayPal Subscription object via the Subscriptions API.
- Customer approves the subscription in PayPal’s popup.
- PayPal fires
BILLING.SUBSCRIPTION.ACTIVATED— plugin grants initial access. - On each renewal, PayPal fires
PAYMENT.SALE.COMPLETED— plugin extends access. - On cancel or expire, PayPal fires
BILLING.SUBSCRIPTION.CANCELLEDorBILLING.SUBSCRIPTION.EXPIRED— plugin revokes access according to your cancellation-policy setting.
Refunds
Section titled “Refunds”From the EP Ecommerce orders list, any paid PayPal order has a Refund button:
- Full refund. Refunds the entire capture.
- Partial refund. Enter an amount.
- Refund is submitted to PayPal’s Captures API. Status updates when PayPal confirms.
- As with Stripe, fulfilment reversal is business-rule dependent and not automatic.
Coexistence with Stripe
Section titled “Coexistence with Stripe”Both payment providers render into the same .ep-ecommerce-payment-slot div in the checkout. If both are active, the customer sees both options and picks their preferred method. Each provider independently tracks its own orders, so there’s no cross-contamination.
Payment description
Section titled “Payment description”What appears on the customer’s PayPal account as the purchase description. Defaults to the product name; supports {product_name} placeholder. PayPal has no strict length limit like Stripe, but keep it readable.
Troubleshooting
Section titled “Troubleshooting”“PayPal buttons don’t appear on the checkout”
Section titled ““PayPal buttons don’t appear on the checkout””Check the browser console. Common causes:
- Client ID is wrong or empty.
- Mode is set to Live but you’re using sandbox credentials, or vice versa.
- PayPal JS SDK is being blocked by an ad-blocker or CSP header. Loosen CSP if needed.
“Webhook signature verification fails”
Section titled ““Webhook signature verification fails””The Webhook ID saved in the plugin doesn’t match the one in PayPal. Rotate in PayPal, paste the new ID, try again.
“Sandbox works, Live fails with authentication error”
Section titled ““Sandbox works, Live fails with authentication error””Live credentials must come from the live side of your PayPal app (same dashboard, different toggle). Mixing sandbox Client ID with live Secret is a common trip-up.
“Orders stay in Pending forever”
Section titled ““Orders stay in Pending forever””The webhook isn’t reaching your site, or is being rejected. Check PayPal Developer Dashboard → Webhooks → your webhook → event history. Failed deliveries show status codes. Common causes: firewall blocking PayPal IPs, HTTPS certificate issues, wrong URL path.
“I get a refund error ‘Capture not found’”
Section titled ““I get a refund error ‘Capture not found’””The payment was authorised but not captured, or was captured through a different flow (direct Express Checkout instead of Orders API). These cases happen on very old orders. Refund through PayPal directly.
Feedback and corrections
Section titled “Feedback and corrections”For a quick question about this plugin, EP Support inside your admin is the fastest option. The chat widget sits on every EP plugin settings page and knows which one you’re on, with starter questions and links preloaded for that exact screen.
For anything bigger — a bug report, a feature request, or a “how do I…” that needs a real reply — open a ticket at help.elmspark.com. A real person, helped by AI, writes the reply. Usually within a few hours. Tickets don’t disappear into the void.