npm package: @piranhastudios/paypal
Description: PayPal Payment Module Provider plugin for Medusa v2. Supports authorization, capture, refunds, and webhooks.
Author: Piranha Studios
Latest version: 0.0.1

# @piranha-studios/paypal

A PayPal Payment Module Provider plugin for [Medusa v2](https://medusajs.com). Adds PayPal as a payment option in your Medusa store with support for authorization, capture, refunds, and webhook handling.

## Features

- PayPal order creation with authorize or capture intent
- Automatic capture mode (configurable)
- Payment authorization and later capture
- Refunds (full and partial)
- Payment session updates when order amounts change
- Webhook signature verification and event handling
- Sandbox and production environment support

## Prerequisites

- Medusa v2 application (`@medusajs/medusa` >= 2.4.0)
- Node.js >= 20
- A [PayPal Developer](https://developer.paypal.com/) account with REST API credentials

## Installation

```bash
npm install @piranha-studios/paypal
# or
yarn add @piranha-studios/paypal
```

## Configuration

### 1. Environment Variables

Add the following to your Medusa application's `.env`:

```env
PAYPAL_CLIENT_ID=your_paypal_client_id
PAYPAL_CLIENT_SECRET=your_paypal_client_secret
PAYPAL_ENVIRONMENT=sandbox
PAYPAL_AUTO_CAPTURE=false
PAYPAL_WEBHOOK_ID=your_paypal_webhook_id
```

| Variable | Required | Description |
|---|---|---|
| `PAYPAL_CLIENT_ID` | Yes | Your PayPal REST API Client ID |
| `PAYPAL_CLIENT_SECRET` | Yes | Your PayPal REST API Client Secret |
| `PAYPAL_ENVIRONMENT` | No | `sandbox` (default) or `production` |
| `PAYPAL_AUTO_CAPTURE` | No | `true` to capture immediately, `false` (default) to authorize first |
| `PAYPAL_WEBHOOK_ID` | No | PayPal Webhook ID for signature verification |

### 2. Medusa Configuration

Add the PayPal provider to your `medusa-config.ts`:

```ts
import { Modules } from "@medusajs/framework/utils"

module.exports = defineConfig({
  // ...
  modules: [
    {
      resolve: "@medusajs/medusa/payment",
      options: {
        providers: [
          {
            resolve: "@piranha-studios/paypal/providers/paypal",
            id: "paypal",
            options: {
              client_id: process.env.PAYPAL_CLIENT_ID!,
              client_secret: process.env.PAYPAL_CLIENT_SECRET!,
              environment: process.env.PAYPAL_ENVIRONMENT || "sandbox",
              autoCapture: process.env.PAYPAL_AUTO_CAPTURE === "true",
              webhook_id: process.env.PAYPAL_WEBHOOK_ID,
            },
          },
        ],
      },
    },
  ],
})
```

### 3. Enable PayPal for a Region

In the Medusa Admin dashboard:

1. Go to **Settings > Regions**
2. Select your region
3. Under **Payment Providers**, enable `pp_paypal_paypal`
4. Save

### 4. PayPal Webhooks (Production)

To receive payment notifications from PayPal:

1. Go to the [PayPal Developer Dashboard](https://developer.paypal.com/dashboard/applications)
2. Create a webhook pointing to:
   ```
   https://your-backend-url.com/hooks/payment/pp_paypal_paypal
   ```
3. Subscribe to these events:
   - `PAYMENT.AUTHORIZATION.CREATED`
   - `PAYMENT.CAPTURE.COMPLETED`
   - `PAYMENT.CAPTURE.DENIED`
   - `PAYMENT.AUTHORIZATION.VOIDED`
4. Copy the **Webhook ID** into your `PAYPAL_WEBHOOK_ID` env var

## Storefront Integration

Install the PayPal React SDK in your storefront:

```bash
yarn add @paypal/react-paypal-js
```

Add to your storefront `.env.local`:

```env
NEXT_PUBLIC_PAYPAL_CLIENT_ID=your_paypal_client_id
```

Then add PayPal components to your checkout flow. See the [Medusa PayPal integration guide](https://docs.medusajs.com/resources/commerce-modules/payment/payment-provider/paypal) for full storefront setup instructions, including:

- `PayPalWrapper` — initializes the PayPal SDK context
- `PayPalPaymentButton` — renders PayPal buttons and handles order approval
- Payment method selection handling

## How It Works

### Payment Flow

1. **Customer selects PayPal** — `initiatePayment` creates a PayPal order and returns an approval URL
2. **Customer approves on PayPal** — the PayPal button handles the approval flow
3. **Order is placed** — `authorizePayment` authorizes (or captures, if `autoCapture` is enabled) the payment
4. **Admin captures payment** — `capturePayment` captures a previously authorized payment
5. **Admin refunds payment** — `refundPayment` issues a full or partial refund

### Provider ID

The provider is registered as `pp_paypal_paypal` (format: `pp_{identifier}_{id}`).

## API Reference

| Method | Description |
|---|---|
| `initiatePayment` | Creates a PayPal order |
| `authorizePayment` | Authorizes or captures the PayPal order |
| `capturePayment` | Captures an authorized payment |
| `refundPayment` | Refunds a captured payment |
| `updatePayment` | Updates the PayPal order amount |
| `deletePayment` | No-op (PayPal orders expire automatically) |
| `retrievePayment` | Retrieves order details from PayPal |
| `cancelPayment` | Voids an authorized payment |
| `getPaymentStatus` | Maps PayPal order status to Medusa status |
| `getWebhookActionAndData` | Processes incoming PayPal webhooks |

## License

MIT

Learn more about [Medusa’s architecture](https://docs.medusajs.com/learn/introduction/architecture) and [commerce modules](https://docs.medusajs.com/learn/fundamentals/modules/commerce-modules) in the Docs.

## Community & Contributions

The community and core team are available in [GitHub Discussions](https://github.com/medusajs/medusa/discussions), where you can ask for support, discuss roadmap, and share ideas.

Join our [Discord server](https://discord.com/invite/medusajs) to meet other community members.

## Other channels

- [GitHub Issues](https://github.com/medusajs/medusa/issues)
- [Twitter](https://twitter.com/medusajs)
- [LinkedIn](https://www.linkedin.com/company/medusajs)
- [Medusa Blog](https://medusajs.com/blog/)