# PayPal & Venmo Integration

Accept PayPal and Venmo payments using the Widget SDK. Both follow the same integration pattern — the SDK renders provider-branded buttons, and the customer's button click triggers the checkout flow.

## How It Works

The SDK renders provider-branded buttons directly on your page. When the customer clicks one, the SDK opens the provider's checkout flow. After the customer completes checkout, the SDK delivers a token via `onTokenizationComplete`. There is no separate `tokenize()` call — the button click is the trigger. For complete reference, see [SDK reference](/docs/ui-sdk-reference).

## Step 1 — Load the SDK

```html
<script src="https://cdn.<env>.nelnetpay.com/sdk/v1.0.0/widget-sdk.js"></script>
```

## Step 2 — Add a button container

Add an empty element where you want the payment buttons to appear.

```html
<div id="paypalVenmo-button"></div>
```

## Step 3 — Initialize the SDK

Create a `Widget` instance with your PayPal client ID and entity ID. Define your callbacks including `onCancel` for handling user cancellations.

```js
const wg = new Widget({
  entityId: '<ENTITY_ID>',

  onTokenizationComplete: (result) => {
    // Forward result.token to your backend
  },

  onError: (error) => {
    // Handle errors — see Error Codes in SDK reference
  },

  onCancel: (payload) => {
    // User closed the PayPal/Venmo popup without completing
  }
});
```

## Step 4 — Set the session token and mount

Set a fresh session token via `updateSessionToken()`, then call `mount()` with the desired payment method. The SDK loads the PayPal SDK internally and renders the buttons — no additional scripts are needed.

**PayPal only:**

```js
const sessionToken = await fetchSessionToken();
wg.updateSessionToken(sessionToken);

wg.mount('#paypalVenmo-button', {
  paymentMethod: 'paypal',
  paypal: {
    returnUrl: 'https://example.com/success',
    cancelUrl: 'https://example.com/cancel'
  }
});
```

**Venmo only:**

```js
const sessionToken = await fetchSessionToken();
wg.updateSessionToken(sessionToken);

wg.mount('#paypalVenmo-button', {
  paymentMethod: 'venmo',
  paypal: {
    returnUrl: 'https://example.com/success',
    cancelUrl: 'https://example.com/cancel'
  }
});
```

**Both PayPal and Venmo (paypalVenmo):**

```js
const sessionToken = await fetchSessionToken();
wg.updateSessionToken(sessionToken);

wg.mount('#paypalVenmo-button', {
  paymentMethod: 'paypalVenmo',
  paypal: {
    returnUrl: 'https://example.com/success',
    cancelUrl: 'https://example.com/cancel'
  }
});
```

When the customer clicks a button, the provider checkout opens. After they complete it, `onTokenizationComplete` is invoked with the token.

## Step 5 — Process the payment

Send the `token` to your backend. Your server submits it to the [Payments API](https://docs.nelnetpay.com/apis/osi-payments-api/other/processpaymentrequest) to process the charge.

## Refreshing the session token

The session token is set via `updateSessionToken()` and used when the customer clicks the payment button. If the customer may wait before clicking, you can refresh the token at any time without re-rendering the buttons:

```js
const freshToken = await fetchSessionToken();
wg.updateSessionToken(freshToken);
```

## Complete example

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Checkout</title>
</head>
<body>
  <h1>Checkout</h1>

  <div id="paypalVenmo-button"></div>

  <script src="https://cdn.nelnetpay.com/sdk/v1.0.0/widget-sdk.js"></script>
  <script>
    async function fetchSessionToken() {
      const res = await fetch('/api/session-token');
      const data = await res.json();
      return data.sessionToken;
    }

    const wg = new Widget({
      entityId: '<ENTITY_ID>',

      onTokenizationComplete: (result) => {
        // Forward result.token to your backend
      },

      onError: (error) => {
        // Handle errors
      },

      onCancel: (payload) => {
        // User cancelled
      }
    });

    (async () => {
      const sessionToken = await fetchSessionToken();
      wg.updateSessionToken(sessionToken);

      wg.mount('#paypalVenmo-button', {
        paymentMethod: 'paypalVenmo',
        paypal: {
          returnUrl: window.location.origin + '/success',
          cancelUrl: window.location.origin + '/cancel'
        }
      });
    })();
  </script>
</body>
</html>
```