Drupal Commerce payments with PayPal

Adding PayPal checkout to Drupal Commerce with Commerce PayPal: which flow to choose, how to configure, map and refund payments, and what to test before go-live.

On this page

How Drupal Commerce takes PayPal payments with Commerce PayPal

A store team that wants PayPal alongside cards, or instead of them, needs to know that Commerce PayPal is the contributed Drupal.org module that adds PayPal as a payment gateway to Drupal Commerce, and that two decisions shape most of the work: which checkout flow the store uses and how refunds are processed. Drupal core and contributed modules hosted on Drupal.org are licensed under GPL-2.0-or-later, and there is no paid edition of Drupal itself, so the module costs nothing to download. The PayPal account, its contract terms and its transaction fees are set by PayPal and are a separate commercial relationship that the store owns. Before scoping anything, confirm on the module's Drupal.org project page the current Commerce PayPal release, the Drupal Commerce versions it supports and the PayPal APIs it calls, because this topic did not come with release data and those details change between releases.

The main architectural choice is between on-site and off-site flows. In an off-site flow, the buyer is redirected to PayPal or a PayPal-hosted field, so card data never reaches the store's servers, which typically keeps PCI DSS scope smaller. In an on-site flow, the store collects or handles more of the payment interaction within its own checkout, which can offer a more integrated look but generally brings more of the payment page into the store's compliance boundary. Ask the module maintainers and your acquirer or QSA which flow your PayPal setup supports, which buttons and funding sources it can display, and how it handles the order state while the buyer is away on PayPal. Plan the currencies, markets and any alternative methods you want before you pick a flow, because the choice limits what the checkout can show.

Refunds and partial refunds need the same care as checkout. Confirm whether Commerce PayPal issues refunds from the Drupal Commerce admin, how it maps a refund to the original capture and whether it records the PayPal refund identifier on the order's payment record. Decide who is allowed to issue refunds, how they are logged, and how disputes and chargebacks reach the store so that order status and accounting stay aligned. Webhook handling deserves a test plan of its own: confirm which PayPal events the module listens for, how it verifies them, and what happens when a notification arrives late or twice. Ask any implementation partner to quote the sandbox testing, the reconciliation checks against PayPal reports and the handover of refund procedures as separate line items, since those drive most of the effort after go-live.

What a PayPal checkout build needs before work starts

A PayPal checkout build depends on a few platform, account and network conditions being in place before any module is configured. The cards below cover what must exist, what must be decided and what must be confirmed with PayPal and your own environment.

A supported Drupal core line

Start on a Drupal core line that is still receiving security coverage. Drupal 11 requires PHP 8.3 or later, while Drupal 10 reaches end of life on December 9, 2026, so a build started now on Drupal 10 would need an upgrade soon after launch. Confirm the PHP and database versions the chosen Commerce PayPal release supports before you fix the stack, since the module's own requirements can be narrower than core's.

A working Drupal Commerce store

PayPal checkout is added to an existing checkout flow, so the store must already take orders end to end. Products, tax, shipping, the order workflow and at least one test order should complete before you add a payment gateway. Problems found later are harder to separate from payment issues, and a store that cannot complete a checkout without PayPal gives you no baseline to compare against.

A PayPal business account with sandbox and live credentials

You need a PayPal business account, a sandbox environment for testing and live credentials for production. Keep sandbox and live API credentials in separate records and confirm who at your organization owns each one. Ask your finance team which PayPal features are enabled on the account, such as card payments or Pay Later, because some options depend on the account's region and settings rather than on the Drupal module.

HTTPS on the storefront

The storefront must be served over HTTPS with a valid certificate before PayPal will return customers to it. Check the certificate chain from outside your network, not only from inside, because intermediate certificate gaps often pass in browsers on internal machines and fail for customers. Decide now which hostnames receive checkout traffic, since redirect and return URLs are tied to them.

A callback URL reachable from PayPal

PayPal sends notifications and returns customers to URLs your site exposes. The callback endpoint must be reachable from the public internet, not only from your corporate network, and must not sit behind a login or a firewall rule that blocks PayPal's traffic. Test it from outside your network with a sandbox transaction before you rely on it, and make sure a reverse proxy or web application firewall does not alter the request body the module verifies.

A PCI scope decision

The flow you choose determines how much card data touches your servers. An off-site redirect keeps card entry on PayPal's pages, while an on-site card form that posts through your own infrastructure widens your PCI DSS scope. Record the flow decision with your security or compliance lead before configuration, and ask your qualified assessor to confirm the resulting scope. DeployOpen prepares evidence for the review, but the assessment itself is performed by an independent assessor.

On-site or off-site: choosing the PayPal checkout flow

In an off-site flow, the shopper leaves the store at payment, completes the purchase on PayPal's pages, and returns to the store to confirm the order. The store never receives card data, which generally keeps the store's PCI DSS scope narrower than a flow where card fields sit on the store's own pages. Confirm with the Commerce PayPal release you plan to use which redirect or hosted button options it provides, and whether the module supports them in the Drupal version you run.

  • PCI DSS scope: The store handles payment redirects and return URLs but does not collect card numbers. Your assessor will still review how the store is hosted and how return and cancel pages are protected.
  • Shopper experience: Shoppers may see a context switch and a second login or review step on PayPal's site, which can affect abandonment. Plan how the return to the store is presented and what happens if the shopper closes the window.
  • Checkout states to test: Test approved, cancelled, pending, declined and returned-without-completion paths, plus a shopper who returns after a timeout.
  • Template and JavaScript work: Usually limited to checkout pane configuration and the order review page, with minimal custom JavaScript. Check how the module handles the return step in your theme.
  • Ask your partner: Which redirect or hosted button options does your module release support, and how are returns matched to orders?

Confirm the exact flow names in your release before you commit to a design.

Configuring Commerce PayPal in a Drupal Commerce store, step by step

This sequence takes a Drupal Commerce store from a clean codebase to a tested PayPal gateway, with each step closed by a check you can observe in the sandbox. It is written so your team can confirm every menu name and configuration key against the release you install.

  1. Confirm the release and prerequisites

    Before installing anything, confirm which Drupal core and Drupal Commerce versions your store runs, and check that the Commerce PayPal release you plan to use declares support for them. Confirm the PHP version your Drupal core requires on the Drupal.org PHP requirements page, since the current major version sets a minimum. Record the decision in your project notes so the build team and reviewers work from the same baseline. The step is done when someone outside the build team can state the Drupal core, Commerce and Commerce PayPal versions from the notes alone.

  2. Install Commerce PayPal with Composer

    A developer adds the Commerce PayPal project to the site's Composer manifest in a feature branch, runs the install, and commits the updated lock file so every environment gets the same version. Dependencies are resolved through Composer, not by copying files into the codebase by hand. Run the site's database and configuration updates in a local or staging environment first. The check is that the module appears in the extension list, and composer show reports the expected version in each environment.

  3. Enable the module and its dependencies

    Enable Commerce PayPal through the extension administration page or with Drush, and confirm that the Commerce payment modules it depends on are enabled alongside it. Export the resulting configuration so the change is tracked in version control and can be deployed to other environments. Note any warnings the status report shows, because a missing dependency often appears there before it causes a checkout error. The check is a clean status report and a configuration export that includes the enabled module.

  4. Create PayPal REST app credentials in the sandbox

    A store administrator with access to the PayPal developer dashboard creates a sandbox REST application and copies the sandbox client ID and secret into a secure store, never into the repository. Confirm the exact application and credential labels in the dashboard at the time of setup, because PayPal changes its developer interface over time. Give the application a name that identifies the store and environment. The check is that a sandbox account can authenticate with the stored credentials, which you can confirm in the gateway form test in the next step.

  5. Add a PayPal payment gateway in Commerce

    In the Commerce payment gateway administration area, a site builder adds a new gateway, selects the PayPal plugin, and chooses the integration flow your business decided on, either on-site fields or an off-site redirect. Enter the sandbox credentials and save the gateway with its machine name recorded. Confirm the option names for the flow on your installed release, since they can differ between versions. The check is a saved gateway that lists the chosen flow and shows no credential validation errors.

  6. Set sandbox mode and notification settings

    Set the gateway environment to sandbox and confirm that no production credentials are present in the configuration. Register the webhook or IPN notification URL for your sandbox environment in the PayPal dashboard, using the exact path shown in the gateway settings on your release, and select the event types the module documents. Use a publicly reachable HTTPS endpoint for the sandbox site, since PayPal must be able to call it. The check is a webhook delivery listed as successful in the PayPal dashboard after a test event is sent.

  7. Enable the gateway on the checkout payment step

    Open the checkout flow configuration for the store and enable the new PayPal gateway on the payment step, leaving the other gateways in place until testing is complete. Review the order of payment options and any conditions that limit which gateway a shopper sees, such as currency or country. Clear caches so the checkout reflects the change. The check is that a test shopper sees the PayPal option on the payment step and that the option is absent when the conditions are not met.

  8. Place test orders and verify order states

    Run test checkouts in the sandbox using test buyer accounts, covering a successful payment, a cancelled payment, and a declined or failed payment. For each case, confirm that the Commerce order moves to the state your workflow expects and that the payment record shows the matching status. Trigger a refund in the sandbox and confirm the refund is recorded against the original payment. Keep the results in a test log that the business and the developers can review. The check is a documented test matrix where every case produces the expected order and payment state.

How PayPal payment states map to Drupal Commerce orders and payments

This table compares each PayPal event or status with the Drupal Commerce object it touches and the action the store should take. Read it as a starting model for support and finance, then confirm each row against the Commerce PayPal version you install, because event handling differs between releases and between on-site and off-site flows.

PayPal event or statusDrupal Commerce object affectedAction the store takes
Order created, not yet approvedOrder in draft or checkout state, no payment recordHold the order in checkout. Do not reserve stock or send confirmation until approval is recorded.
Order approved by buyerOrder in checkout, payment method not yet chargedConfirm the approval reference is returned to the checkout step before the order advances to completion.
Payment capturedCommerce payment in completed state, order marked paidRecord the PayPal transaction identifier on the payment and advance the order to paid and fulfillable.
Authorization voidedCommerce payment in voided state, order not paidRelease any reservation, mark the payment voided and ask the buyer to retry or choose another method.
Partial refund issuedRefund payment linked to the original payment, order remains paidCreate a refund for the partial amount, store its PayPal refund identifier and adjust the order balance.
Full refund issuedRefund payment for the full amount, order balance at zeroCreate a full refund, store its identifier and move the order to a refunded or canceled state per your workflow.
Dispute or chargeback openedPayment flagged for review, no automatic order changeConfirm in the release whether dispute events are received. If not, handle disputes manually in your PayPal account and log them.
PayPal transaction identifier stored on the Commerce paymentPayment entity remote ID fieldStore the capture or refund identifier on each payment so support and finance can match Drupal records to PayPal reports.

How refunds work and who approves them

Decide before launch where a refund may start, because a refund can be issued from the Drupal admin through the Commerce PayPal integration or directly in the PayPal dashboard, and the two records must stay in sync. If both paths are open, staff will eventually refund an order in one place and not record it in the other, leaving the Commerce payment balance and the PayPal balance different. Test each refund action the module exposes in a staging store, confirm which actions it supports (full refund, partial refund, and whether it can void an authorization), and only then promise those actions to the client. Confirm these points with the module's documentation and your own test results rather than assuming parity with the PayPal dashboard.

The most common refund error is confusing a capture with an authorization. A capture moves funds that have already been authorized, so the refund returns money that was settled. A void cancels an authorization that was never captured, so no money moves to the customer. In a delayed-capture flow, staff must void an open authorization instead of refunding it, and the module's order states must show which of the two happened. Partial refunds need the same care: a partial refund leaves a remaining balance on the original payment, and each refund should be traceable to the specific order items or amount it covers.

Write down who can issue refunds, the approval limit above which a second person must sign off, and what the log must record for each refund event: the order number, amount, currency, initiating user, approver, reason and the PayPal transaction identifier. Finance should reconcile PayPal settlement reports against Commerce payment records on a set cadence, so that fees, partial refunds and disputes are matched to orders. Ask your PayPal account team and your finance lead to agree the reconciliation method and the owner of any unmatched item before go-live, and plan for the audit trail to be kept in your own systems.

Securing PayPal credentials, webhooks and PCI scope

Payment security on a Drupal Commerce store depends on where PayPal credentials live, who can move money, and whether webhook events are trusted before orders change. These cards cover the controls that connect those decisions and the scope questions they raise for your environment.

Keep REST credentials out of the database

The REST client ID and secret for each PayPal account should be supplied through environment variables or a secrets manager, not typed into the gateway form where they are stored in the Drupal database and copied into backups. Keep the sandbox and live credentials in separate stores so a test configuration cannot charge real cards. Check that exports of configuration, database dumps and repository history contain no secret values, and rotate any secret that has appeared in a ticket, log or commit.

Restrict gateway and refund permissions

Commerce gives administrators broad rights over payment gateways, payments and orders, and refunds are an outflow of money that should not sit with every store manager. Create a dedicated role for refund actions, require a second reviewer for refunds above a threshold your finance team sets, and log who issued each refund. Review role assignments on a schedule, since staff changes often leave old administrative access in place.

Verify webhook authenticity before changing orders

PayPal notifies the store of payment status changes through webhooks, and a forged or replayed request must never mark an order as paid or trigger fulfillment. Confirm that the module verifies the signature on each incoming event against your webhook ID, rejects events for other accounts, and records the event ID so duplicates are ignored. Ask your developer to test a tampered payload and a replayed event in the sandbox before go-live.

Stay on supported Drupal and module releases

Drupal core ships bugfix releases on the first Wednesday of each month and security releases on the third Wednesday, and Commerce and the PayPal module need to keep pace with those cycles. Check the PHP version your Drupal major requires before upgrading the runtime, and confirm that the PayPal module has a stable release for your Drupal version rather than a development branch. Subscribe to Drupal Security Team advisories and assign an owner to apply them within a timeframe your risk policy sets.

Document how the flow sets PCI DSS scope

The choice between an on-site card form and an off-site PayPal redirect or hosted fields determines which systems handle cardholder data, and therefore how much of your environment falls into PCI DSS scope. Write down the flow for each payment method, the systems that receive or forward card data, and the points where your servers only see a PayPal transaction ID. DeployOpen can prepare this evidence and diagrams, but independent assessors decide the scope and whether you are compliant.

How to test PayPal flows before go-live

Test every PayPal path a shopper can take before any real money moves, and write the expected order state next to each one. Set up sandbox buyer and merchant accounts for the PayPal environment your Commerce PayPal configuration points to, and confirm that the payment gateway is set to the sandbox mode, not the live one. Then walk through approved payments, declined payments, and checkouts the shopper abandons on the PayPal page. For each case, record what the order shows in Drupal Commerce, whether the payment record exists, and whether the stock and confirmation email behave as your design intends. Returns from PayPal without completing payment deserve their own cases, because the customer lands back on the store with an order that is still in a checkout step.

Next, test the events that arrive after the shopper leaves the page. Replay or trigger duplicate notifications for the same transaction and confirm the store records one payment, not two. Run full and partial refunds, including a second partial refund that brings the total to the original amount, and check that the order balance, payment record and any refund status match what PayPal reports in the merchant account. Test a multi-currency order if you sell in more than one currency, and compare the captured total with tax, shipping and discounts line by line. Confirm the exact notification and webhook settings with your PayPal account team and Commerce PayPal documentation, because the event names and endpoints depend on the integration version you install.

Finish with a short live-mode trial using a low-value order and a refund of that order, then have finance review a test log that records every sandbox and live case, its expected result, actual result, and the reconciliation entry in the PayPal statement. Finance sign-off should cover totals, refunds and fee treatment, not only whether the page loaded. Ask your implementation partner or internal team to confirm the scope, owners and retest triggers in writing before go-live, so that any later module update or PayPal change repeats the affected cases.

Common PayPal failures in Drupal Commerce and how to fix them

This table pairs each common symptom on a Drupal Commerce PayPal checkout with its likely cause and the fix, and names the first check to run. Read it top to bottom when a payment problem appears, starting with the check in the fix column before changing code or configuration. The main takeaway is that most failures trace to credentials, notification handling or mismatched amounts, so verify those before rebuilding the checkout.

SymptomLikely causeFix and first check
Orders stay in pending after the shopper approves on PayPalPayPal returned the shopper to the site, but the server-side capture or the return notification never reached CommerceCheck the PayPal transaction log for a capture status, then confirm the notification endpoint responds with a success code. Capture or complete the payment and update the order state once the status is confirmed
Duplicate orders or duplicate payments after repeated return or notification handlingThe return URL and the webhook both create or complete the same order, or the shopper reloads the return pageConfirm the order is keyed to the PayPal order ID and that completion runs only once. Make the handler idempotent so a repeated notification returns the existing order
Live checkout fails while sandbox works, or the reverseClient ID and secret come from the wrong environment, or the gateway is set to live mode with sandbox keysCompare the gateway mode with the credential set in use. Confirm the API base and keys belong to the same PayPal app and environment before going live
PayPal webhooks never arrive or fail with delivery errorsThe public URL is not HTTPS, a firewall, WAF or reverse proxy blocks PayPal's requests, or the path is redirectedRequest the webhook URL from outside your network and confirm it returns the expected status over HTTPS. Review firewall and WAF logs for blocked requests from PayPal, then re-send a test event
PayPal shows a different amount or currency than the Commerce orderOrder currency, tax or shipping adjustments, or rounding differ between Commerce and the PayPal request, or the currency is not enabled for the accountCompare the order total, currency code and line items in both systems for one failed order. Confirm the store currency is supported by the PayPal account and that adjustments are sent in the request
Refund issued in PayPal does not change the Commerce paymentThe refund was made in the PayPal dashboard, which sends no matching update to Commerce, or the refund notification is not handledConfirm whether the refund notification reached the site and was processed. Record refunds through the Commerce payment workflow where possible, and reconcile PayPal and Commerce totals after any manual refund
Checkout pane or PayPal button is missing or broken after a theme changeTemplates or libraries overridden in the old theme no longer match the checkout markup, or the PayPal script is not attachedClear caches, then check the browser console for failed script loads. Compare the checkout templates in the active theme with the module defaults and reapply the overrides

Questions buyers ask before hiring help with PayPal in Drupal Commerce

What drives the cost of a PayPal integration in Drupal Commerce?

The main cost drivers are the checkout flow, the number of currencies and payment methods, the refund and reconciliation rules, and the amount of custom checkout work. An off-site flow with one currency and standard refunds is the smallest scope. An on-site flow that keeps card fields on your own pages adds security review, broader browser and device testing, and more work on order states. Each extra currency or payment method adds configuration, sandbox testing and reconciliation rules. Ask for a written quote that lists each of these items separately and names the testing scope, so you can compare options on the same basis.

Can an in-house Drupal developer set up PayPal payments alone?

Yes, for a standard configuration, an in-house developer who already knows Drupal and Drupal Commerce can usually install and configure the PayPal payment method and test it with sandbox credentials. The harder part is usually not the code. Your PCI DSS scope depends on the flow you choose and how card data moves through your site, so security input is needed before launch. Refund authority, partial refunds and the way refunds appear in accounting need finance sign-off. Plan those reviews even when your own developer does the build.

What do we need to provide before PayPal work starts?

Before work starts, you typically need to provide the following inputs in writing or through a secure channel:

  • A PayPal business account, with administrator access for the person who will configure API credentials
  • Sandbox and live credentials, delivered securely and never by plain email
  • Decisions on the checkout flow, supported currencies and payment methods
  • Refund authority, including who may issue full or partial refunds and any approval thresholds
  • A staging site that matches production's Drupal and Commerce setup
  • Named contacts from finance and security who can approve reconciliation rules and scope

Missing decisions on refund authority are the most common reason a launch date slips.

How long does a PayPal integration take in Drupal Commerce?

The duration depends on the scope, so no fixed timeline applies to every store. The main variables are the checkout flow, the number of payment methods and currencies, custom checkout changes, and how many approval cycles finance and security require. Ask for a written plan that separates configuration, build, sandbox testing, staged testing with live credentials and launch, with a named owner for each step. A plan that gives no time for reconciliation review or refund testing is unlikely to hold. Agree the plan in writing before work starts.

What usually goes wrong with PayPal payments in a Drupal store?

The most common failures are mismatched credentials between sandbox and live, return or notification URLs that point at the wrong environment, orders left in a pending state after a customer returns from PayPal, and refunds issued in PayPal but not recorded in Commerce. Currency rounding and store currency mismatches also cause reconciliation gaps. Test each case with sandbox orders, including cancelled payments, declined payments and partial refunds. Keep a log of payment events so support staff can trace any order from the storefront to PayPal and back.

Should refunds be handled in Drupal Commerce or in PayPal?

Choose one system of record for refunds and state the choice in writing. If refunds are issued only in PayPal, Commerce orders can show money still held, which breaks accounting. If refunds are issued only in Commerce, the integration must call PayPal correctly, so test full and partial refunds in sandbox before launch. Whichever path you choose, define who holds refund authority, how approvals are recorded, and how your reconciliation matches PayPal settlement reports to Commerce payment records. Finance should own the rules, and engineering should prove them in testing.

What ongoing work follows launch for PayPal payments?

After launch, the recurring work includes updating the Commerce and PayPal-related modules as new releases come out, rotating API credentials on a schedule, and running reconciliation checks between PayPal and Commerce. Drupal core bugfix releases come on the first Wednesday of each month and security releases on the third Wednesday, so payment code needs regular regression testing against them. Drupal 12 is scheduled for the week of December 7, 2026, so confirm module compatibility before any core upgrade. Keep a written runbook for credential rotation and refunds. Ongoing support can be arranged as a retainer when it is agreed in writing.

How DeployOpen scopes and delivers a PayPal checkout build

DeployOpen plans, builds, documents and supports Drupal Commerce payment setups inside your own infrastructure, with the PayPal flow chosen against your checkout, compliance scope and refund process. Engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts.

How we scope

  • Written scope covers which PayPal options, on-site or off-site flows, and markets your store needs.
  • Scope records the Drupal Commerce version, Commerce PayPal configuration, and sandbox and live accounts involved.
  • Scope sets out refund, partial refund and failed-payment handling, with who approves each case in your team.

How we build

  • Configure the PayPal payment gateway in Drupal Commerce for the checkout flow agreed in scope.
  • Test payment, capture, void, refund and webhook events in PayPal sandbox before any live credentials are used.
  • Review card and redirect data paths so the PCI DSS scope of your environment is documented for your assessor.

How we hand over

  • Deliver configuration records, environment variable inventory and a runbook for checkout and refund operations.
  • Document test cases, results and known limits so your team can repeat verification after changes.
  • Walk your operations and finance staff through reconciliation between Drupal Commerce orders and PayPal transactions.

How we support

  • Ongoing support, Drupal and module upgrades, and continuous testing are available as retainers after handover.
  • Retainers can cover monitoring of payment errors and review of Commerce PayPal release notes before upgrades.
  • Confirm the support hours, response expectations and upgrade cadence in the written retainer scope before signing.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.