Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Paypal Laravel Package

srmklive/paypal

A Laravel package for the PayPal REST API that also works as a standalone PHP client. Covers orders, payments, subscriptions, billing plans, invoices, payouts, disputes, and more, with PHP 8.2–8.5 and Laravel 12/13 support.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • The package is a thin API client, not a payments platform. It wraps PayPal REST v2 endpoints (Orders, Subscriptions, Payments, Payouts, Invoices, Disputes, Vault v3, Reporting, Partner Referrals) with almost no domain abstraction. That is the correct shape for an anti-corruption layer at the edge of your payments domain — business rules, order state, idempotency, and reconciliation stay in your code, which is where they belong for auditability.
  • Laravel side is standard: service provider, facade (\PayPal::setProvider()), publishable config/paypal.php, env-driven credentials. Standalone mode (new PayPalClient + setApiCredentials()) with no framework dependency means the same client can back a queue worker, CLI reconciliation job, or a non-Laravel service — useful if payments logic is extracted later.
  • Pluggable transport matters architecturally: setClient() accepts any PSR-18 client, so an organisation-standard HTTP client (proxy, mTLS, OpenTelemetry tracing, custom retry policy) can be injected without forking. Note the built-in retry middleware applies only to the default Guzzle client — teams injecting their own client inherit the retry problem too.
  • Statefulness is per-instance (access token, currency, partner attribution ID, exception mode). In a request-per-process model this is fine; in long-lived workers (Octane, Swoole, queue daemons) the team must confirm token refresh and config isolation across jobs.

Integration feasibility

  • Effort is low for the happy path: composer require, publish config, set six env vars, getAccessToken(), createOrder() → redirect to the payer-action link → capturePaymentOrder(). Realistically 2–5 engineer-days for a production-grade order/capture/refund flow including webhooks and tests; materially more for subscriptions, disputes, or payouts.
  • Hard gates: PHP 8.2–8.5 and Laravel 12/13 only on the maintained v3.1 line. Any team on Laravel 10/11 must upgrade the framework before or alongside adoption. That is a scheduling dependency, not a package problem, but it is the first thing to confirm.
  • README is genuinely good for a package of this size: per-API sections, a v1→v2 endpoint mapping table, a copyable Fastlane walkthrough, and explicit error-handling modes. There is no separate documentation site, so the README is the contract.
  • Sandbox credentials and the PayPal developer dashboard are prerequisites outside the package's control; test-account provisioning is usually the slowest external step.

Technical risk

  • Governance/support risk is the dominant one. Independent community project, explicitly not affiliated with or endorsed by PayPal, MIT, no vendor SLA. Only v3.1 is marked maintained; v1.0, v2.0, and v3.0 are all unmaintained. Bus factor is effectively the maintainer set of one repository.
  • API-surface breadth is a liability masquerading as a feature. Covering Orders, Subscriptions, Invoices, Disputes, Payouts, Partner Referrals, and Reporting means many endpoints are lightly exercised in the wild. Depth of correctness per endpoint should be assumed proportional to popularity, not to test-coverage badge claims.
  • Retry semantics on money movement. Exponential backoff on 5xx/429/network errors (default 2 retries) is right for GETs and wrong-by-default for non-idempotent POSTs. Captures need PayPal PayPal-Request-Id idempotency keys managed by your code; the package does not own a request-key store. This is the single most likely source of duplicate-charge incidents.
  • Error-handling default is silent. Errors return ['error' => ...] unless withExceptions() is called. A team that forgets an isset($response['error']) check ships a payment flow that fails open into success paths. Recommend mandating withExceptions() in the integration standard.
  • PCI scope is favourable. Redirect-based Orders v2 means card data never touches your servers — SAQ A-ish posture. Fastlane and Payment Method Tokens (Vault v3, Apple/Google Pay) push more surface client-side and require careful handling of setup tokens.
  • Local webhook verification (verifyWebHookLocally() with in-memory cert caching) removes a PayPal API roundtrip per event — a real availability and latency win — but shifts responsibility for trust-anchor rotation and cache invalidation onto your process lifecycle.
  • Metadata red flags to verify, not act on: Dependents: 0 contradicts 1,151 stars and the badge/download position, so treat it as a registry-scan artefact; the 2026-10-02 last-release date is inconsistent with the current date and should be checked against the actual Packagist tag before any planning assumption rests on it.

Key questions for the maintainer/team

  • Which PayPal capabilities do we actually need — Orders only, or Subscriptions / Disputes / Payouts / Partner Referrals?
  • Are we a PayPal partner or platform (BN code / setPartnerAttributionId) or a direct merchant?
  • Who owns this dependency internally, and what is the named upgrade cadence?
  • Have we confirmed the latest tagged release and its date against Packagist rather than the summary metadata?
  • Can we run the package's Pest suite and PHPStan level 7 in our own CI to validate our pinned version?
  • Do we have (or need) a request-id store for capture idempotency, and a reconciliation job against PayPal Reporting?
  • What is our framework version today, and is the Laravel 12/13 upgrade on the critical path?
  • Is forking acceptable as the continuity plan if upstream goes dormant? MIT permits it; do we have the PHP capacity?

Integration Approach

Stack fit

  • Clean fit for a Laravel 12/13 monolith or modular monolith on PHP 8.2+. The facade reads well inside service classes; prefer constructor-injecting Srmklive\PayPal\Services\PayPal or a thin internal PayPalGateway wrapper over the facade to keep the domain testable and the package swappable.
  • For non-Laravel consumers (reconciliation workers, finance tooling), standalone mode avoids spinning up the framework — pass credentials explicitly, no .env coupling.
  • If the organisation has a standard PSR-18 client (proxy, tracing, corporate retry policy), plan to inject it via setClient() and disable the built-in retry assumptions in your runbook.

Migration path

  • The forcing function is real and dated: PayPal sunsets /v1/payments in January 2027, and v1 Billing Agreements with it. Any custom create-payment/execute-payment or billing-agreement code must move to Orders v2 / Subscriptions v2 inside that window.
  • The package's own mapping table is directly usable as the migration spec: POST /v1/payments/payment + /execute → createOrder() + capturePaymentOrder(); createBillingAgreementToken()/createBillingAgreement() → addProductById() → addBillingPlanById() → setupSubscription().
  • Coming from earlier srmklive majors (v1.0/v2.0/v3.0, all unmaintained): the upgrade is coupled to the PHP 8.2 and Laravel 12 upgrade. Sequence as one programme of work, not two.
  • Behavioural changes to absorb rather than code around: float-precision fixes, URL-encoding fixes, invoice date normalisation, and added null guards. If we carry local workarounds for any of those, remove them during the upgrade or they will double-apply.

Compatibility

  • Config keys are stable enough that an existing config/paypal.php usually survives; new keys are additive (timeout, connect_timeout, max_retries). payment_action and notify_url remain but are largely vestigial in Orders v2 flows — do not let them imply behaviour they no longer drive.
  • Error contract differs by mode (array['error'] vs PayPalApiException with getHttpStatus(), getPayPalError()). Pick one per codebase; mixing modes is how silent failures appear.
  • Runtime config override via setApiCredentials() enables per-tenant or multi-account routing (marketplaces, regional entities) without a second deploy — worth designing for early if multi-currency or multi-entity is on the roadmap.

Sequencing

  1. Dependency gate: confirm Laravel/PHP versions, agree the framework upgrade if required, pin srmklive/paypal to an exact version in composer.json.
  2. Sandbox smoke test: token fetch, createOrder, redirect via payer-action, capturePaymentOrder, getCaptureIdFromOrder() persisted, partial and full refund.
  3. Webhooks: register in PayPal dashboard, implement verifyWebHookLocally(), add signature-failure logging, idempotent event handler, and a replay endpoint for operational recovery.
  4. Idempotency and reconciliation: request-id store for captures, nightly reconciliation against PayPal Reporting / transaction search, alerting on unallocated captures.
  5. Subscriptions (if in scope): products, plans, setupSubscription(), lifecycle webhook handling, dunning behaviour.
  6. Cutover: feature-flag the new flow, dual-run in sandbox with production-shaped data, then ramp live traffic in cohorts; keep the legacy path warm until reconciliation is clean for a full settlement cycle.
  7. Decommission legacy v1 code paths with explicit confirmation that no scheduled jobs or admin tools still call them.

Operational Impact

Maintenance

  • Ongoing cost is modest but non-zero: treat the package as a tracked dependency with a named owner, quarterly version review, and a composer.json exact pin. Budget roughly 2–4 engineer-days per quarter for currency, plus a discrete project for the January 2027 v1 sunset if legacy code exists.
  • Upstream is a single-maintainer community project with no commercial support. Continuity plan is fork-and-maintain under MIT. Decide in advance whether the team has the PHP depth to take that on, and keep the internal PayPalGateway wrapper thin so a fork or replacement is a contained change.
  • Documentation lives in the README. Internal runbooks (credential rotation, webhook re-registration, refund authority, dispute escalation) are ours to write; the package provides none.

Support

  • Escalation has two distinct tracks that must not be conflated: package-level defects go to GitHub issues with no SLA, while API-level behaviour (account limitations, holds, settlement timing, dispute outcomes) goes to PayPal merchant support. Train the on-call rota on the split, otherwise package issues get filed for PayPal policy problems and vice versa.
  • The disclaimer that the project is unaffiliated with PayPal matters for procurement and security review; expect a question about it in vendor assessment.

Scaling

  • The client is stateless apart from the per-instance access token, so horizontal scaling is straightforward. The watch item is token acquisition: PayPal access tokens live roughly nine hours, and getAccessToken() being called per request or per job creates a latency floor and a token-endpoint rate-limit risk under load. Cache tokens in your cache store and refresh with headroom; confirm current behaviour rather than assuming.
  • Retries interact with scale: default 2 retries with exponential backoff (500 ms → 8 s cap) on 5xx/429/network errors smooths transient PayPal instability but triples worst-case in-flight requests during an incident. Honour Retry-After (the client does when present) and cap concurrency to PayPal's rate limits per endpoint.
  • Webhook ingestion scales independently and should be queued and idempotent; local verification keeps per-event cost off the PayPal API budget.

Failure modes to instrument

  • Duplicate capture from retried non-idempotent POSTs — mitigate with PayPal-Request-Id, monitor capture-id uniqueness.
  • Silent error arrays treated as success — mandate withExceptions() and alert on PayPalApiException volume.
  • Token expiry mid-flight and refresh thundering herd — cache, pre-emptive refresh, jitter.
  • Webhook delivery gaps or cert-cache staleness — persist raw payloads, alert on verification-failure rate, expose a manual replay path.
  • Config bleed between sandbox and live — enforce PAYPAL_MODE per environment, fail deploys where live credentials appear outside production, never allow runtime mode override from user input.
  • Account-level restrictions (holds, limitations, negative balances) surfacing as generic API errors — reconcile daily so a blocked account is detected by finance before customers complain.
  • Partial captures, partial refunds, and currency rounding — assert totals on capture and refund against the order amount before marking an order paid.
  • Dispute and chargeback windows arriving after orders are closed — ensure the dispute endpoints are wired to a workflow, not just available.

Ramp-up

  • New developers reach a working sandbox order flow in under a day; the README is sufficient for that. The real ramp is PayPal domain semantics, not the package: intent CAPTURE vs AUTHORIZE, authorize/void vs capture/refund, partial refund rules, dispute lifecycle, webhook event coverage, and settlement timing.
  • Plan a short internal knowledge transfer and a payments-specific onboarding doc covering credential handling, capture idempotency, refund authority limits, and the reconciliation procedure. Without it, the team can ship a flow that works and still loses money at the edges — which is exactly the class of failure this package, as a thin client, will not catch for you.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
adachsoft/php-code-style