Paypal
Интеграция PayPal для Medusa v2
PayPal for Medusa
Accept PayPal and credit card payments in your Medusa v2 store — built by an official PayPal Partner.
✨ What you get
| Feature | Details |
|---|---|
| 🔵 PayPal Buttons | One-click PayPal checkout for your customers |
| 💳 Card Payments | Secure credit & debit card fields, hosted by PayPal (PCI compliant) |
| 🛠 Admin Dashboard | Connect your PayPal account and manage everything from Medusa Admin |
| 🌍 Test & Live modes | Try everything safely in Sandbox before going live |
| 🔐 3D Secure | Extra card security, configurable in one click |
| 🔄 Reliable by design | Payments are verified with PayPal at every step — webhooks, retries, and safety nets are handled for you |
✅ Requirements
- Medusa v2.12+
- Node.js 20+
- PostgreSQL
🚀 Installation
In your Medusa backend folder, run:
⚙️ Setup — 5 steps
1. Add the plugin to
2. Run database migrations
npx medusa db:migrate3. Connect your PayPal account
- Start your Medusa server
- Open Medusa Admin → Settings → PayPal
- Choose Sandbox (testing) or Live (real payments)
- Click Connect to PayPal and follow the steps
That's it — your credentials are saved automatically. Webhooks are registered for you too.
💡 Prefer manual setup? Click Insert credentials manually and paste your Client ID and Secret from developer.paypal.com.
4. Turn PayPal on in your region
Go to Medusa Admin → Settings → Regions → your region and enable:
| Payment provider | What it is |
|---|---|
| PayPal Buttons | |
| Card payments |
5. Add PayPal to your storefront
The checkout UI comes as a separate package — install it in your storefront project:
📦 @easypayment/medusa-paypal-ui — ready-made PayPal components for Next.js storefronts, with a step-by-step guide.
🎨 Customize (optional)
Everything is managed in Medusa Admin → Settings → PayPal — changes apply instantly, no restart needed:
- PayPal Settings — turn PayPal on/off, button color, shape, and label
- Advanced Card Payments — turn card payments on/off, 3D Secure mode
- Additional Settings — capture vs. authorize, brand name shown at PayPal, invoice prefix
🔐 Going live — two things we recommend
- — set this to any long random text in your server's environment. Your PayPal credentials are then stored encrypted in the database. Keep the key safe: if it's lost, just reconnect PayPal.
- — set this to your backend's public address (e.g. ) so PayPal can reach your store for payment notifications.
Advanced options (for developers — everything works without these)
| Variable | Default | What it does |
|---|---|---|
| (request origin, if listed in ) | Storefront address used for PayPal return/cancel pages (can also be set in Admin) | |
| = refuse to save credentials unencrypted | ||
| (partner service nonce) | Only change this if you also run your own ; it must match the nonce that service puts in its onboarding links | |
| first entry | Restricts the onboarding popup to your admin URL | |
| Safety net that finishes an order when the payment succeeded but the buyer's browser closed. disables it | ||
| / | (off) / | Optional request limit for the public checkout routes |
| / | (off) / | Optional request limit for the webhook endpoint (separate from the above) |
| Rejects webhook deliveries older than this | ||
| When the retry job re-picks-up interrupted webhook events | ||
| / | (auto) | Manual webhook-id override (normally automatic) |
| Timeout for calls to PayPal | ||
| Fallback currency if none is configured | ||
| (unset) | Comma-separated URLs that receive operational alerts (including dead-lettered webhook events) | |
| In-process cache for plugin settings reads; disables | ||
| sends the cart's shipping address on PayPal orders () — improves PayPal Seller Protection eligibility | ||
| (built-in) | Override the partner onboarding service used by the connect flow | |
| / | (built-in) | Override the partner merchant ids used for onboarding |
Declined cards: when PayPal declines a capture, responds with a buyer-friendly plus a structured object — — so storefronts can show "insufficient funds, try another card" and decide whether to offer a retry.
Monitoring: operational counters live in the table; every webhook is recorded in with automatic retries (events that exhaust retries are dead-lettered and pushed to ); audit events are logged as JSON lines tagged (secrets redacted).
💬 Support
- 🐛 Found a bug? Open an issue
- 💡 Questions or feature requests? Start a discussion
- 🛍 Storefront UI package: @easypayment/medusa-paypal-ui
📄 License
MIT © Easy Payment

