# PayPal Here Web SDK (/archive/paypal-here/sdk-dev/web)



> **Note:** **Important:** PayPal Here is [deprecated](https://www.paypal.com/us/cshelp/article/paypal-here-deprecation-help299). PayPal doesn't accept new integrations but continues to support existing integrations.

## Overview [#overview]

The PPH Web SDK is a single page script and is designed to be integrated on your final Payment or Checkout page.

The following restrictions apply to this SDK:

* Available only to the US region.
* Available only on Windows desktop/laptop browsers. Phone/Tablet mobile browsers are not supported.
* USB is the only supported connection method.
* No multi-card reader support: if two USB readers are connected, the SDK automatically connects to the first one it recognizes.

> **Note:** **Note:** The card readers that are supported with this SDK are the [Chip Card Reader](https://www.paypal.com/us/business/pos/payments/card-reader), the [Chip and Tap Reader](https://www.paypal.com/us/business/pos/payments/card-reader), and the Verifone P400 reader. You can order the Chip Card Reader from our [web store](https://us.paypal-here.com/card-readers/) as normal but the Chip and Tap readers and P400 readers need manual configuration to allow the USB connection. Therefore, if you would like to order Chip and Tap readers or Verifone P400 readers, please send an email to [pph-inquiry@paypal.com](mailto:pph-inquiry@paypal.com).

## Integration [#integration]

Similar to PayPal Here's iOS and Android SDKs, the Web SDK uses standard OAuth to authenticate. Make sure that you have already [created your REST App](/archive/paypal-here/sandbox-testing/configuring-accounts#create-a-rest-application) and have reviewed the [Merchant Onboarding](/archive/paypal-here/merchant-onboarding) section of the documentation.

### Setup [#setup]

PayPal Here Web SDK uses a headless standalone desktop application (PPHWebInterface) to interact with connected card readers. The one-time setup must be done before you can process payments and must be done on each machine. PayPal recommends using a separate setup page for the `setupUI`. Include the following snippet in your setup page:

<div className="pl-[1.625rem]" />

```html lineNumbers
<button type="button" id='setupPPH' onclick='onSetupPayPalHereBtnClicked()'>Setup PayPal Here</button>
```

<div className="pl-[1.625rem]" />

```javascript lineNumbers
function onSetupPayPalHereBtnClicked() {
  pphwebsdk.Setup.startUIFlow().then(function (completionStep) {
      // PPHWebInterface has been installed and, if clicked, a test of the connected card reader was completed.
      // setup is complete
  });
}
```

To make sure that the setup has been completed on your computer prior to processing payments, call `isSetupComplete()`. If it hasn't completed yet, call the `startUIFlow` as mentioned above. Otherwise, if it has already completed, you can continue on to your payment flow.

<div className="pl-[1.625rem]" />

```javascript lineNumbers
pphwebsdk.Setup.isSetupComplete().then(function() {
    // Continue to payment flow
}).catch(function(err) {
    // Run startUIFlow to setup SDK
});
```

> **Note:** **Note:** The `isSetupComplete()` method should be the first thing that you run and the response of that should dictate the next step in the process. If it's a success you will continue on with the payment flow and if it's not, then you should run `startUIFlow` to complete the setup.

### Accepting payments [#accepting-payments]

Once everything has been set up, follow the steps in the order listed here to accept payments:

> **Note:** **Note:** See [Object references](#object-references) later in this section for details on various options for the different objects in this flow.

1. **Create identity.** This is similar to the `initializeMerchant` function of the iOS and Android SDKs. It tells the SDK which merchant account is receiving the payment and in which environment. For more information on token management, please refer to the [PayPal Here Onboarding Process](/archive/paypal-here/merchant-onboarding#paypal-here-onboarding-process).

   ```javascript lineNumbers
   var identity = pphwebsdk.Identity.create(access_token).refreshUrl(refresh_url).environment(environment);
   ```

   | Attribute      | Type   | Description                                                                                                       |
   | -------------- | ------ | ----------------------------------------------------------------------------------------------------------------- |
   | `access_token` | String | **Required**<br />Valid access token for the merchant account.                                                    |
   | `refresh_url`  | String | **Optional**<br />URL that the SDK will reach out to refresh the access token when it expires.                    |
   | `environment`  | Enum   | **Required**<br />Needs to either be `pphwebsdk.Types.Environment.LIVE` or `pphwebsdk.Types.Environment.SANDBOX`. |
2. **Payment configuration.** Even though you can process transactions with default values, the SDK allows you to customize the flow depending on your needs. [Payment configuration](/archive/paypal-here/sdk-dev/web#payment-configuration) is required for subscribing to events and customizing the payment flow. The following code snippet creates a default configuration:

   ```javascript lineNumbers
   var payment_config = pphwebsdk.PaymentConfiguration.create();
   ```

   Starting with version 1.1.1, the reader connection is handled by the payment configuration. You will create a reader object and then specify the connection type and reader manufacturer.

   ```javascript lineNumbers
   var reader = payment_config.reader();
         reader.connectionType(pphwebsdk.Types.ReaderConnectionType.USB);
         reader.manufacturer(pphwebsdk.Types.Manufacturers.MIURA);
   ```

   | Object             | Description                                           | Values                                                                                                                            |
   | ------------------ | ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
   | `connectionType()` | Accepts enum value for the reader connection type.    | `pphwebsdk.Types.ReaderConnectionType.USB`                                                                                        |
   | `manufacturer()`   | Accepts enum value for the reader being connected to. | `pphwebsdk.Types.Manufacturers.MIURA`<br />`pphwebsdk.Types.Manufacturers.INGENICO`<br />`pphwebsdk.Types.Manufacturers.VERIFONE` |

   > **Note:** **Note:** The `MIURA` manufacturer correlates to the [Chip Card Reader](https://www.paypal.com/us/business/pos/payments/card-reader), the `INGENICO` manufacturer correlates to the [Chip and Tap Reader](https://www.paypal.com/us/business/pos/payments/card-reader), and the `VERIFONE` manufacturer correlates to the Verifone P400 reader which is only available for use with the Web SDK at this time.
3. **Create order.** In order to process [payments](/archive/paypal-here/sdk-dev/web#order) or [refunds](/archive/paypal-here/sdk-dev/web#order-for-refund), you need an order. The following snippet shows how to create an order for a payment and add items to it:

   ```javascript lineNumbers
   var order = pphwebsdk.Order.create();
     order.item('Cake').price(1.00).quantity(3);
     order.item('Coffee').price(2.00).quantity(3);
   ```
4. **Process payment.** Once you have the identity, payment configuration, and order ready, you can then accept the payment. The following snippet shows how to process a sale transaction:

   ```javascript lineNumbers
   var payment = pphwebsdk.Payment.create(identity, payment_config);
     payment.for(order).as(pphwebsdk.Types.PaymentMethod.CARD).sale();
   ```

   As part of the payment flow, the SDK will automatically prompt for any reader firmware updates that may be available. You'll need to subscribe to the success or failure events on the `Reader` object to get the status of said updates:

   ```javascript lineNumbers
   // Readers will automatically prompt for the update if there is one available. There are two events, on the Reader object, that will fire after an update.
   pphwebsdk.Reader.subscribe
     .firmwareUpdateSuccess(function (upgradedDevice) {
       // Reader firmware update was a success
     })
     .firmwareUpdateFailure(function (err) {
       // Reader firmware update failed - handle accordingly
     });
   ```

   When the reader firmware update is done successfully, the SDK will simply continue on with the payment flow without you having to action anything. If the not now option was pressed on the reader firmware update UI, then you will need to call `pendingUpdateInstall()` to trigger that firmware update flow and install the update. If there is a firmware update, it needs to be completed successfully before you will be able to process another transaction. You can also call `pendingUpdateInstall()` prior to making a payment if you'd like to proactively check for any firmware updates available.

   ```javascript lineNumbers
   pphwebsdk.Reader.pendingUpdateInstall();
   ```

## Object references [#object-references]

The following tables outline the different options for the objects mentioned above:

### Payment configuration [#payment-configuration]

| Object               | Description                                                                                                           | Default                      |
| -------------------- | --------------------------------------------------------------------------------------------------------------------- | ---------------------------- |
| `create()`           | Creates a new `PaymentConfiguration`.                                                                                 | N/A                          |
| `subscribe`          | Subscribe to [payment events](/archive/paypal-here/sdk-dev/web#events).                                               | No events are subscribed to. |
| `useQuickChip`       | Enables Quick Chip functionality and disables contactless payments.                                                   | Disabled.                    |
| `showPromptInReader` | When used with the Chip Card Reader, this displays the prompt to Tap/Insert/Swipe the card on the card reader screen. | Enabled.                     |
| `showPromptInClient` | This displayes the prompt, in the client application, to Tap/Insert/Swipe the card.                                   | Enabled.                     |
| `hidePromptInReader` | When used with the Chip Card Reader, this hides the prompt to Tap/Insert/Swipe the card on the card reader screen.    | Disabled.                    |
| `hidePromptInClient` | This hides the prompt, in the client application, to Tap/Insert/Swipe the card.                                       | Disabled.                    |

### Payment [#payment]

| Object              | Description                                                                                |
| ------------------- | ------------------------------------------------------------------------------------------ |
| `for(order)`        | Reference to the [order instance](/archive/paypal-here/sdk-dev/web#order).                 |
| `as(paymentMethod)` | Reference to [payment method types](/archive/paypal-here/sdk-dev/web#paymentmethod-types). |
| `sale()`            | Process the payment as a sale.                                                             |
| `authorize()`       | Process the payment as an authorization to be captured later.                              |
| `refund()`          | Process a refund.                                                                          |

> **Note:** **Note:** `sale()`, `authorize()`, and `refund()` are action calls that need to be last in the chain, as noted in the [samples](/archive/paypal-here/sdk-dev/web#samples).

### Order [#order]

| Object                | Description                                                            |
| --------------------- | ---------------------------------------------------------------------- |
| `item(name)`          | Create a new [item](/archive/paypal-here/sdk-dev/web#item).            |
| `remove(item)`        | Remove an item.                                                        |
| `number(orderNumber)` | Custom order number. Similar to the invoice number of iOS and Android. |
| `tip(amount)`         | Adds gratuity to the order.                                            |

### PaymentMethod types [#paymentmethod-types]

Refer to the [samples](/archive/paypal-here/sdk-dev/web#samples) for more details on the usage of these payment method types.

| Type            | Values                           |
| --------------- | -------------------------------- |
| `PaymentMethod` | `CASH`, `CHECK`, `KEYIN`, `CARD` |

### Item [#item]

| Object               | Description                   |
| -------------------- | ----------------------------- |
| `quantity(quantity)` | Quantity of given item(s).    |
| `price(price)`       | Price of the individual item. |

### Order for refund [#order-for-refund]

| Object                  | Description                                                                                                                                                      |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `create()`              | Create a refund for an existing order.                                                                                                                           |
| `on(transactionNumber)` | This is the transaction number that was received as part of the transaction record with the `onPaymentSuccess` [event](/archive/paypal-here/sdk-dev/web#events). |
| `with(invoiceId)`       | This is the PayPal invoice ID that was received as part of the transaction record with the `onPaymentSuccess` [event](/archive/paypal-here/sdk-dev/web#events).  |
| `for(refundAmount)`     | Amount to be refunded. Can either be a partial or full refund.                                                                                                   |

### Events [#events]

Event handlers are functions that are subscribed to as part of the `PaymentConfiguration`. These events may have arguments as mentioned below. Refer to the [samples](/archive/paypal-here/sdk-dev/web#samples) for details on how these events are implemented.

| Event                         | Argument            | Description                                                                                                              |
| ----------------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `onMerchantInitializeSuccess` | `merchant`          | The `merchant` object will contain necessary information about the merchant account.                                     |
| `onMerchantInitializeFailure` | `error`             | The `error` object will contain necessary information about the error to better understand what went wrong.              |
| `onConnectReaderSuccess`      | `details`           | The `details` object will contain necessary information about the connected reader.                                      |
| `onConnectReaderFailure`      | `error`             | The `error` object will contain necessary information about the error to better understand what went wrong.              |
| `NoDevicesFound`              | empty               | This event fires when there are no devices able to be connected to.                                                      |
| `onPaymentSuccess`            | `transactionRecord` | The `transactionRecord` will contain the `transactionNumber` and PayPal `invoiceId`.                                     |
| `onPaymentFailure`            | `error`             | The `error` object will contain necessary information about the error to better understand what went wrong.              |
| `onRefundSuccess`             | `transactionRecord` | The `transactionRecord` will contain the `transactionNumber` for the refund.                                             |
| `onRefundFailure`             | `error`             | The `error` object will contain necessary information about the error to better understand what went wrong.              |
| `onCaptureSuccess`            | `captureId`         | The `captureId` is the transaction ID from captureing the authorization.                                                 |
| `onCaptureFailure`            | `error`             | The `error` object will contain necessary information about the error to better understand what went wrong.              |
| `onVoidSuccess`               | empty               | This event is fired when an authorization has been successfully voided.                                                  |
| `onVoidFailure`               | `error`             | The `error` object will contain necessary information about the error to better understand what went wrong.              |
| `onVaultSuccess`              | `vaultRecord`       | The `vaultRecord` will contain the `vaultId` that is used later with Braintree code to charge the stored payment method. |
| `onVaultFailure`              | `error`             | The `error` object will contain necessary information about the error to better understand what went wrong.              |

## Samples [#samples]

Below are some simple samples for event handlers, reader updates, payment, and refund:

### Event handlers [#event-handlers]

<div className="pl-[1.625rem]" />

```javascript lineNumbers
var payment_config = pphwebsdk.PaymentConfiguration.create();
  payment_config.subscribe
    .onConnectReaderSuccess(function (details) {
      //Details of card reader provided
    })
    .onConnectReaderFailure(function (err) {
      //Unable to connect to reader - handle error scenario
    })
    .onMerchantInitializeSuccess(function (merchant) {
      //Merchant initialized successfully
    })
    .onMerchantInitializeFailure(function (err) {
      //Unable to intialize merchant - handle error scenario
    })
    .onPaymentSuccess(function (txnRecord) {
      //Payment success
    })
    .onPaymentFailure(function (err) {
      //Payment failed - handle error scenario
    });
```

### Payment with full options [#payment-with-full-options]

<div className="pl-[1.625rem]" />

```javascript lineNumbers
var identity = pphwebsdk.Identity.create(access_token).refreshUrl(refresh_url).environment(environment);

  var payment_config = pphwebsdk.PaymentConfiguration.create();
  payment_config.subscribe
    .onConnectReaderSuccess(function (details) {
      //Details of card reader provided
    })
    .onConnectReaderFailure(function (err) {
      //Unable to connect to reader - handle error scenario
    })
    .onMerchantInitializeSuccess(function (merchant) {
      //Merchant initialized successfully
    })
    .onMerchantInitializeFailure(function (err) {
      //Unable to intialize merchant - handle error scenario
    })
    .onPaymentSuccess(function (txnRecord) {
      //Payment success
    })
    .onPaymentFailure(function (err) {
      //Payment failed - handle error scenario
    });

  var reader = payment_config.reader();
  reader.connectionType(pphwebsdk.Types.ReaderConnectionType.USB);
  reader.manufacturer(pphwebsdk.Types.Manufacturers.MIURA);

  var order = pphwebsdk.Order.create();
  order.item('Cake').price(1.00).quantity(3);
  order.item('Coffee').price(2.00).quantity(3);
  order.tip(1.00);

  var payment = pphwebsdk.Payment.create(identity, payment_config);
  payment.for(order).as(pphwebsdk.Types.PaymentMethod.CARD).sale();
```

### Refund [#refund]

<div className="pl-[1.625rem]" />

```javascript lineNumbers
var identity = pphwebsdk.Identity.create(access_token).refreshUrl(refresh_url).environment(environment);

  var payment_config = pphwebsdk.PaymentConfiguration.create();
  payment_config.subscribe
    .onRefundSuccess(function (txnRecord) {
      //Payment success
    })
    .onRefundFailure(function (err) {
      //Payment failed - handle error scenario
    });

  var reader = payment_config.reader();
  reader.connectionType(pphwebsdk.Types.ReaderConnectionType.USB);
  reader.manufacturer(pphwebsdk.Types.Manufacturers.MIURA);

  var order = pphwebsdk.Order.create().on(txnId).with(ppInvoiceId).for(totalAmount);

  var payment = pphwebsdk.Payment.create(identity, payment_config);
  payment.for(order).as(pphwebsdk.Types.PaymentMethod.CARD).refund();
```

When your integration is complete, check the [going live](/archive/paypal-here/sdk-dev/going-live) page to ensure that you have everything ready for activation. Once that is working, you can implement other [customizations](/archive/paypal-here/sdk-dev/customizations) that are available with the SDK into your integration.
