PayPal POS for WooCommerce

PayPal POS for WooCommerce connects your WooCommerce store to your PayPal Point of Sale account. You manage your catalog in WooCommerce, push it to your PayPal POS product library, and sell at the counter with stock staying accurate on both sides.

WooCommerce is the source of truth. Products, prices, SKUs, barcodes and images flow from WooCommerce to PayPal POS. Stock syncs in both directions, so a sale in store updates WooCommerce and a sale online updates PayPal POS.

This plugin does not process payments.

Payments are taken on your PayPal POS hardware and app. To accept PayPal in your online store, use PayPal Payments for WooCommerce.

Requirements

↑ Back to top
  • WordPress 6.8 or higher
  • WooCommerce 10.2 or higher
  • PHP 8.2 or higher
  • An active PayPal POS account in a supported country:
  • A publicly reachable site over HTTPS. PayPal POS sends stock updates to your site through webhooks, which cannot reach localhost, 127.0.0.1 or password-protected staging sites.

Installation

↑ Back to top

Automatic installation

↑ Back to top
  1. Go to Plugins → Add New in your WordPress dashboard.
  2. Search for PayPal POS for WooCommerce and check that PayPal is listed as the author.
  3. Click Install Now, then Activate.

Manual installation

↑ Back to top
  1. Download the plugin archive from wordpress.org.
  2. Unpack it and upload the folder to wp-content/plugins via FTP.
  3. Go to Plugins → Installed Plugins and click Activate.

Connect your store

↑ Back to top

After activation, go to WooCommerce → Settings → PayPal Point of Sale. A guided setup walks you through four steps.

Check your currency, country and tax settings before you sync.

Prices only sync when these match on both sides. See Prices and taxes.

Step 1: Connect your account

↑ Back to top
  1. Click Connect. If you do not have a PayPal POS account yet, use Create account now first.
  2. Click Create an API key. This opens your PayPal POS back office with the key name and the permissions the plugin needs already filled in (read finance, purchases, user info and products, write products).
  3. Confirm with Create API key and copy the generated key.
  4. Paste the key into the field in WooCommerce and click Authenticate with PayPal Point of Sale.

If the key is rejected, the setup shows The API key you entered is invalid. Create a new key and try again. For security, the key is never shown again after saving.

Step 2: Choose how to build your library

↑ Back to top

The setup shows how many products it found on each side, then asks how to set up your PayPal POS library:

  • Add WooCommerce products – your WooCommerce products and stock are added to the existing PayPal POS library.
  • Replace PayPal Point of Sale library – your existing PayPal POS library is deleted and replaced with your WooCommerce products and stock.

Replace deletes your current PayPal POS library.

If you are unsure, choose Add WooCommerce products, or back up your library first.

Step 3: Decide about prices

↑ Back to top
  • Sync prices – prices come from WooCommerce and stay up to date there.
  • Don’t sync prices – products sync with a price of 0 and you set prices in your PayPal POS product library.

If your settings do not allow price sync, this step explains exactly what does not match and the option is disabled. You can still continue without prices.

Step 4: Sync and finish

↑ Back to top

The sync runs in the background and shows its progress. When it is done, click Complete setup. From then on, product changes in WooCommerce sync automatically and stock stays in step in both directions.

Prices and taxes

↑ Back to top

In PayPal POS, all prices include tax. In WooCommerce, that depends on your settings. Prices therefore only sync when all of the following are true:

  • The currency is the same in WooCommerce and PayPal POS.
  • The store country is the same on both sides.
  • Taxes are enabled in WooCommerce (WooCommerce → Settings → General → Enable tax rates and calculations).
  • At least one tax rate is configured in WooCommerce → Settings → Tax, and every tax class used by a product has a matching rate row.

If something is missing, the setup names it: Currency: X in PayPal Point of Sale, Y in WooCommerce, Country: X in PayPal Point of Sale, Y in WooCommerce, Taxes are disabled in WooCommerce, or Tax rates not added in WooCommerce. Fix it in WooCommerce, then reload the step.

If prices can sync but your tax inclusion setting differs (you enter prices excluding tax in WooCommerce, PayPal POS expects prices including tax, or the other way round), prices are recalculated during sync and your margins change. The setup warns you before you continue.

Not using taxes? Do not disable taxes in WooCommerce, that blocks price sync. Instead keep taxes enabled, add a tax rate with Rate % set to 0, and set your PayPal POS tax rate to 0%.

For help with WooCommerce tax settings themselves, see the WooCommerce tax documentation.

What syncs, and in which direction

↑ Back to top
ItemDirection
Product nameWooCommerce → PayPal POS
Description (first 1024 characters)WooCommerce → PayPal POS
PriceWooCommerce → PayPal POS (if price sync is on)
SKUWooCommerce → PayPal POS
BarcodeWooCommerce → PayPal POS
Product imageWooCommerce → PayPal POS
StockBoth directions

Product changes are queued the moment you update the product in WooCommerce. Stock changes are near real-time in both directions. The only delays we see come from slow hosting.

Two more behaviours worth knowing:

  • Inventory tracking is switched on in PayPal POS automatically for products that manage stock in WooCommerce. If a product does not manage stock in WooCommerce, its stock is not tracked.
  • Deleting a product in PayPal POS unlinks it from WooCommerce. The WooCommerce product stays, but it is no longer connected until it syncs again.

Which products can sync

↑ Back to top

Only simple and variable products sync. Grouped and external products are not supported and do not show the PayPal Point of Sale tab.

Every product must be:

  • Published, with catalog visibility not hidden
  • Purchasable, so it needs a price
  • Not excluded from sync (see Exclude a product)
  • Assigned a tax class that has a tax rate row, with a valid country code (use the dropdown, for example GB rather than UK)
  • Stock quantity of 99,999 or less

Variable products have extra limits:

  • At least 1 purchasable variation, and no more than 99 variations
  • No more than 3 variation attributes
  • Each attribute value between 1 and 30 characters, never empty
  • The same tax class on every variation when prices sync
  • Either “any” variations or discrete variations, not a mix of both

A variable product with no variations is not valid for sale in WooCommerce, so it does not sync. Delete the last variation and the product disappears from your PayPal POS library.

Images: JPEG, PNG, GIF, TIFF and BMP sync, between 2.5 KB and 5 MB and between 50×50 and 5000×5000 pixels. WebP is not supported.

Day-to-day settings

↑ Back to top

Once connected, WooCommerce → Settings → PayPal Point of Sale shows your connection status, the date of the first import, how many products are syncing, and whether prices are syncing. From here you can:

  • Change Price synchronization between Sync prices and Don’t sync prices
  • Change how Existing products are handled on sync
  • Open your PayPal POS product library or account, or order hardware
  • Disconnect the integration. You are asked to confirm, and reconnecting means going through the setup again.

Exclude a product

↑ Back to top

Open the product, go to the PayPal Point of Sale tab in the Product data box, and tick Exclude from Sync?. The product stays online only and shows the status Excluded in the product list.

Barcodes

↑ Back to top

Barcodes let your staff scan a product at the counter instead of searching for it. They sync from WooCommerce to your PayPal POS library.

  • Simple product: Product data → PayPal Point of Sale → Product barcode.
  • Variable product: one barcode field per variation, in Product data → Variations.

Type the barcode, or click Scan barcode to use a camera. Pick the barcode type, allow camera access in your browser, and hold the barcode fully inside the camera window. Then click Update.

Supported types: the default set (EAN 13, EAN 8, EAN extended, Code 128, Code 39), Code 128, Code 39, Code 39 VIN, Code 93, EAN-13, EAN-8, EAN extended, UPC-A, UPC-E, Codabar, I2 of 5, and Standard 2 of 5.

Check the sync status

↑ Back to top

The product list at Products → All Products has a PayPal Point of Sale column showing why a product is or is not synced. You can hide it via Screen Options.

Common statuses:

  • Synced – linked to a product in your PayPal POS library.
  • Not synced / Syncable – not sent yet, but nothing blocks it.
  • Not syncable – shown together with the reason below.
  • Excluded, Not published, Not visible, Not purchasable, Unsupported product type.
  • No tax rate – the product’s tax class has no rate row in WooCommerce.
  • No variations, Too many variations, No variation attributes, Too many variation attributes, more than 3, Empty variation attribute value, Too long variation attribute value, more than 30 letters, Variations have differing taxes.
  • Stock cannot be greater than 99999.
  • Undefined status code, check WC logs – see the logs below.

Logs and system report

↑ Back to top
  • Logs: WooCommerce → Status → Logs, then pick paypal-point-of-sale-[…] from the dropdown and click View.
  • System report: WooCommerce → Status → Get system report → Copy for support. It includes a PayPal Point of Sale section with your integration status.

Log names changed in version 2.0.0.

Entries are now written to paypal-point-of-sale-[…]. Older logs are still stored under zettle-pos-integration-[…].

Troubleshooting

↑ Back to top

Stock from PayPal POS does not reach WooCommerce

↑ Back to top

Stock updates arrive as webhooks, so your site must be reachable from the internet. First reproduce it: change the stock of a product in your PayPal POS back office and check whether WooCommerce follows. Then work through these causes:

  1. Your site URL changed. Deactivate and reactivate the plugin, which re-registers the webhooks. If that does not help, disconnect and run the setup again.
  2. Plugin or theme conflict. Switch to a default theme and disable everything except WooCommerce and this plugin. See How to test for conflicts.
  3. Your host blocks the requests. Firewalls sometimes read incoming webhooks as an attack. Ask your host whether requests from https://products.izettle.com/ and https://oauth.zettle.com/ are blocked.

Stock numbers look multiplied or wrong

↑ Back to top

Usually another plugin writing stock at the same time. Run the conflict test above. You can also check status.zettle.com for service incidents.

I turned on inventory tracking in PayPal POS and nothing happened

↑ Back to top

Enable stock management for the product in WooCommerce. Tracking follows the WooCommerce setting.

Switching from another PayPal POS or Zettle plugin

↑ Back to top

Clear the products out of your PayPal POS library before you run our setup. This plugin links products through IDs it creates during onboarding, so products created by another plugin cannot be adopted and you would end up with duplicates.

Multilingual plugins

↑ Back to top

Translation plugins such as MultilingualPress or WPML create a separate product per language, and each one syncs as its own PayPal POS product. There is no way to merge them, so we recommend excluding additional language products from the sync.

Local installations

↑ Back to top

On a local site (localhost or 127.0.0.1) PayPal POS cannot reach you, so stock updates and image sync do not work. For testing, you can send placeholder images instead by adding this to wp-config.php:

putenv('IZETTLE_PLACEHOLDER_IMAGES_ENABLED=1');

For developers

↑ Back to top

Barcodes can come from another plugin instead of our custom field:

  • paypal-point-of-sale.barcode.value – receives a WC_Product (simple product or variation) and returns the barcode string.
  • paypal-point-of-sale.barcode.standard-input-ui-enabled – return false to hide our barcode input.

Add the filters before the WordPress init hook runs at priority 10. Example using the GTIN field of the Germanized plugin:

add_filter(
    'paypal-point-of-sale.barcode.value',
    function (string $barcode, \WC_Product $product): string {
        return (string) $product->get_meta('_ts_gtin');
    },
    10,
    2
);

add_filter('paypal-point-of-sale.barcode.standard-input-ui-enabled', '__return_false');

Using the old filter names?

Only the paypal-point-of-sale.* names above are supported. If your custom code still hooks zettle-pos-integration.barcode.*, update it.

Related Products

Grow your business with increased sales and an enhanced shopping experience — at no extra cost.

The official PayPal Enterprise Payments extension for WooCommerce. Accept credit cards, PayPal, Apple Pay, Google Pay, Venmo, ACH Direct...

Use of your personal data
We and our partners process your personal data (such as browsing data, IP Addresses, cookie information, and other unique identifiers) based on your consent and/or our legitimate interest to optimize our website, marketing activities, and your user experience.