PayPal Button Options

PayPal Checkout Button Options for Merchant Pages

This document summarizes practical PayPal JavaScript SDK button patterns that merchants can use when placing PayPal-family payment options on product, cart, and checkout pages. The focus is on the current PayPal JavaScript SDK reference and PayPal’s standalone button guidance for standard checkout integrations.

The stack of buttons looks like this:

PayPal button stack

SDK version and integration context

For most current merchant integrations, the relevant client-side library is PayPal’s JavaScript SDK loaded from https://www.paypal.com/sdk/js. PayPal’s current developer reference documents this SDK as the standard client-side entry point for rendering PayPal-supported payment methods, including PayPal buttons, marks, messages, and related checkout components.

In practical terms, most merchants do not version-pin the script URL with a visible v5 or v6 style path for standard web checkout. Instead, they load the current PayPal JavaScript SDK with query parameters such as client-id, components, enable-funding, disable-funding, currency, and intent, then configure behavior through paypal.Buttons() on the page.

Common integration particulars

These points are common to most merchant integrations using PayPal Checkout on the web:

  • The SDK script tag must include the merchant client ID in the client-id query parameter.
  • The page usually includes components=buttons when rendering checkout buttons, and may add funding-eligibility, marks, or messages depending on the UX being implemented.
  • The button configuration is created through paypal.Buttons({...}), typically with createOrder, onApprove, and onError callbacks.
  • When a merchant wants precise control over which PayPal-family buttons appear, PayPal recommends standalone funding-source rendering rather than relying only on the default smart button stack.
  • Eligibility still matters even in a merchant-controlled layout, so each standalone button should be checked with isEligible() before rendering.

Button display models

PayPal supports a few common display models for merchants, and the right one depends on how much control is needed over the checkout presentation.

ModelMerchant experienceBest use case
Smart button stackOne button container; PayPal decides which eligible options to show.Fastest default integration on product or checkout pages.
Standalone buttonsMerchant renders individual buttons such as PayPal, Venmo, or Pay Later separately by funding source.When the page design needs explicit placement or only a selected subset of methods.
Marks with radio buttonsMerchant uses PayPal marks as part of a broader payment selector UI.When PayPal is shown alongside cards or other payment methods in a form flow.

A common merchant request is to show only PayPal, Venmo, and Pay Later. PayPal’s standalone button documentation supports that pattern by rendering one button per funding source, while Venmo specifically requires enable-funding=venmo in the SDK script.

That approach is usually preferable when the merchant wants clean, explicit wallet choices on the page instead of letting the smart stack decide everything automatically. It also keeps the implementation maintainable, because each payment option follows the same rendering pattern and remains eligibility-aware.

Example: standalone PayPal, Venmo, and Pay Later

The following example is suitable as a merchant-facing pattern for product, cart, or checkout placement. It intentionally limits the visible PayPal-family options to PayPal, Venmo, and Pay Later, while still using PayPal’s recommended eligibility check before rendering each standalone button.

<div id="paypal-btn"></div>
<div id="venmo-btn"></div>
<div id="paylater-btn"></div>
 
<script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID&components=buttons,funding-eligibility&enable-funding=venmo&currency=USD&intent=capture"></script>
<script>
  const sources = [
    { fundingSource: paypal.FUNDING.PAYPAL, selector: '#paypal-btn' },
    { fundingSource: paypal.FUNDING.VENMO, selector: '#venmo-btn' },
    { fundingSource: paypal.FUNDING.PAYLATER, selector: '#paylater-btn' }
  ];
 
  sources.forEach(({ fundingSource, selector }) => {
    const button = paypal.Buttons({
      fundingSource,
      createOrder(data, actions) {
        return actions.order.create({
          purchase_units: [
            { amount: { value: '49.99' } }
          ]
        });
      },
      onApprove(data, actions) {
        return actions.order.capture();
      },
      onError(err) {
        console.error(fundingSource, err);
      }
    });
 
    if (button.isEligible()) {
      button.render(selector);
    } else {
      document.querySelector(selector)?.remove();
    }
  });
</script>

Why the array pattern is useful

The sources array is not a special PayPal requirement by itself; it is a clean merchant-side coding pattern for mapping each funding source to a target container. The underlying reason for the pattern is that paypal.Buttons() accepts a single fundingSource per button instance, so multiple standalone options require multiple button instances and multiple render targets.

This keeps the implementation concise and easy to extend. For example, a merchant can add paypal.FUNDING.CREDIT later with one more object in the array instead of duplicating the entire render block.

Important eligibility and market notes

Merchants should expect funding availability to vary by shopper context. Venmo availability depends on eligibility and is explicitly enabled through the SDK parameter rather than appearing by default, while Pay Later also depends on buyer and merchant eligibility conditions.

PayPal’s partner-facing standalone documentation also notes that, for US and UK merchants enabling Pay Later style offers, PAYLATER and CREDIT may both be relevant because the buyer experience can vary based on eligibility. That detail matters when merchants want the widest financing coverage rather than only the simplified three-button layout shown above.

Operational guidance for merchant pages

For most merchant pages, the same base implementation principles apply whether the buttons live on product detail, mini-cart, cart, or checkout pages.

  • Use a single SDK script load on the page and configure the necessary components through query parameters.
  • Keep the order creation logic consistent with the final checkout amount shown to the shopper.
  • Use standalone buttons only when the merchant truly wants curated placement or a restricted option set; otherwise, the smart stack is simpler to maintain.
  • Always guard standalone rendering with isEligible() so ineligible methods do not create broken or empty UI states.
  • Treat Venmo as a deliberate merchant choice, because it requires explicit SDK enablement and may not be available in all shopper contexts.

Merchant recommendation

For merchants who want a simple wallet-focused presentation, showing PayPal, Venmo, and Pay Later as standalone options is a strong pattern because it is explicit, easy to place in a designed layout, and aligned with PayPal’s documented funding-source approach.

For merchants who want the least custom logic, the smart button stack remains the better default because PayPal handles the eligible mix automatically in a single container. The right decision comes down to whether the page is optimized for control of presentation or for minimizing implementation complexity.


Venmo — testing vs production experience (Embedded SDK)

This document covers Venmo via the PayPal JavaScript SDK — an embedded Venmo button on the merchant checkout page. It explains sandbox vs production UX, presentationMode behavior (auto / popup), why desktop sandbox may show web login (popup or same-tab) instead of a QR code, and what you need for end-to-end testing (including a real Venmo account).


Scope

This doc applies only to Embedded SDK integrations using PayPal JS SDK v6:

  • Load https://www.sandbox.paypal.com/web-sdk/v6/core (sandbox) or production equivalent
  • createInstance({ components: ["venmo-payments", ...] })
  • createVenmoOneTimePaymentSession() with venmoSession.start({ presentationMode }, orderPromise)
  • <venmo-button> web component on the checkout page
  • Order lifecycle via session callbacks (onApprove, etc.) and merchant/PSP backend completion

Venmo is US-only and USD-only, and is subject to PayPal eligibility rules (region, currency, device, buyer account).

Legacy SDK v5 (paypal.Buttons({ fundingSource: 'venmo' }) with enable-funding=venmo) does not expose presentationMode. PayPal chooses UX internally — often same-tab web login on desktop sandbox.


SDK v5 vs v6 (Embedded Venmo)

Classic v5 Smart Payment ButtonsSDK v6 Venmo session
Loaderpaypal.com/sdk/js?...&enable-funding=venmosandbox.paypal.com/web-sdk/v6/core
Venmo buttonpaypal.Buttons({ fundingSource: 'venmo' })<venmo-button> + createVenmoOneTimePaymentSession
Presentation controlNone — PayPal decidespresentationMode: "auto" or "popup" on session.start()
Order shapeBare order id string{ orderId: string } promise

Use v6 when you need to influence whether Venmo web login opens in a popup window vs same-tab navigation.


Presentation modes for testing (SDK v6)

Venmo session.start() accepts presentationMode:

ModeBehavior (sandbox desktop)
autoRecommended. Tries popup web login first; falls back if popups are blocked or unavailable
popupForces a popup window for Venmo web login (id.venmo.com)
Fallback (blocked popups)Same-tab navigation to id.venmo.com — merchant page is replaced by Venmo sign-in

All of the above are web login flows in sandbox — not the production desktop QR modal.

PayPal v6 reference: auto tries popup first and may fall back to modal in some scenarios; for Venmo on desktop web, popup or same-tab redirect to web login is typical in sandbox.

Popup blockers: If the browser blocks popups, popup mode may fail with a recoverable error; retry with auto or allow popups for the harness origin.


Embedded SDK flow

After the shopper clicks Venmo, the SDK — not the merchant — decides whether to app-switch (mobile), show a production desktop QR, or open Venmo web login in a popup or same tab. The merchant page is not left via a hosted approval_url redirect integration.


Sandbox vs production UX

PayPal documents the following behavior for embedded SDK Venmo (Test Venmo in sandbox):

EnvironmentDesktop browserMobile + Venmo appMobile without Venmo app
SandboxWeb login flow (popup or same-tab) — no desktop QRApp-switch to Venmo appWeb login flow
ProductionQR code modal (scan with Venmo app)App-switch to Venmo appWeb login flow

Why desktop sandbox shows web login, not a QR code

If you click an embedded Venmo button on a desktop browser in sandbox and see Venmo web login at id.venmo.com (in a popup or the same tab), that is expected behavior.

PayPal explicitly states:

In the production environment, consumers will experience QR code-based checkout on their desktop browser. Sandbox testing of the desktop QR code is currently unavailable.

Do not treat popup vs same-tab web login as a misconfiguration. Desktop QR is a production-only SDK experience.

Production desktop QR flow

On live credentials, clicking the embedded Venmo button on desktop opens a QR modal overlay. The shopper scans with the Venmo app, approves in-app, and the SDK returns to onApprove on the merchant page.


Real Venmo account required for testing

PayPal sandbox provides PayPal sandbox personal and business accounts for API and wallet testing. Venmo is different: PayPal lists self-service test account creation under Venmo features not supported in sandbox (Pay with Venmo — test). There is no fake Venmo buyer you can spin up in the PayPal Developer Dashboard the way you create @personal.example.com sandbox PayPal accounts.

To complete an end-to-end embedded SDK Venmo approval in sandbox, you must use a real Venmo account:

Test scenarioWhat you need
Mobile app-switch (recommended for sandbox)Real Venmo iOS or Android app installed and logged in with a real Venmo account. Browser must be Safari on iOS or Chrome on Android (PayPal eligibility requirement).
Desktop sandbox web loginAuthenticate through Venmo’s web login with a real Venmo identity. A PayPal sandbox personal account email alone is not sufficient.
Production desktop QRLive merchant credentials; scan QR with Venmo app logged into a real account.

Important nuance: Even though you use a real Venmo account, the transaction still runs in PayPal sandbox when using sandbox client IDs — no real money moves. PayPal cannot simulate a fake Venmo wallet the way it simulates PayPal sandbox buyers, so the Venmo payer identity must be real.

Not applicable here: Braintree’s fake-venmo-account-nonce is for Braintree server-side tokenization tests only. Embedded PayPal JS SDK integrations do not use Braintree nonces.


Eligibility and troubleshooting

Currency and region

  • Currency: USD only. Non-USD SDK sessions typically fail Venmo eligibility.
  • Region: US merchant and US buyer context.

Button visibility

Check v6 eligibility before rendering:

SDK v6 eligible venmo=true

If eligible=false, do not show the Venmo button. Common causes:

  • Non-USD currency
  • PayPal eligibility rules (region, device, merchant configuration)
  • Sandbox merchant not Venmo-enabled

Changing currency or buyer context requires re-initializing the SDK instance and re-checking eligibility.

Common confusion

ObservationExplanation
eligible=true but desktop shows web login, not QRExpected in sandbox. Desktop QR is production-only.
Venmo button missing entirelyEligibility failed — check currency, region, and SDK logs.
Popup on one test, same-tab redirect on anotherpresentationMode, popup blockers, or browser differences — both are valid sandbox web login.
Same-tab id.venmo.com after choosing popupPopup blocked — allow popups or use auto with fallback.
Full-page navigation after clicking Venmo in sandboxVenmo web login in same tab — not a missing QR widget.

Sandbox error amounts

PayPal supports negative-path testing in sandbox with specific order amounts (Pay with Venmo — test):

AmountError scenario
12.34INSUFFICIENT_FUNDS
21.43ACCOUNT_CLOSED
11.45ACCOUNT_FROZEN
10.23SUSPECTED_FRAUD
13.42GENERIC_DECLINE
OtherSUCCESS

Set the order amount to one of these values before clicking the Venmo button.


How to test (Embedded SDK v6)

  1. Load PayPal JS SDK v6 core with venmo-payments component and USD currency.
  2. Render <venmo-button>; confirm findEligibleMethods().isEligible("venmo") before display.
  3. Wire createOrderPromise to return { orderId } from your backend or PSP session.
  4. Set Venmo presentation mode to auto or popup on the harness (or your integration).
  5. Allow popups for the merchant origin when testing popup mode.
  6. For the most representative sandbox flow, use mobile Safari or Chrome with the Venmo app installed and a real Venmo account (app-switch).
  7. On desktop sandbox, expect web login (popup or same-tab) — do not expect a QR code.
  8. Handle onApprove and complete the payment on your backend (capture or PSP completion).
  9. For production desktop QR, validate with live credentials — treat as a go-live checklist item.