ArtisanPack UI
DocsEcommerce PaypalChangelog

Ecommerce Paypal Changelog

Latest: v1.0.0

All notable changes to this package are documented here. The format follows Keep a Changelog, and the package follows Semantic Versioning.

[Unreleased]

[1.0.0] - 2026-11-10

The first release of the PayPal gateway for the ArtisanPack UI ecommerce engine. It runs on engine 1.3, PHP 8.3, and Laravel 12 or 13, and is licensed under MIT.

Added

  • Package foundation: service provider, config (artisanpack.ecommerce-paypal), migrations, publish tags (ecommerce-paypal-config, -assets, -migrations, -views, -lang), SatelliteRegistry registration, and the PayPalUninstaller (keeps data by default; --purge deletes the current mode's vault tokens at PayPal).
  • Configuration and settings: sandbox and live modes, credentials, webhook ids (several during a rotation), webhook verification mode, intent, branding, per-method switches, Pay Later messaging placements, vaulting, HTTP timeouts and retries, and logging. A paypal group in the engine's settings registry overlays the config, keeps the client secret and webhook ids as secrets, and refuses settings that can't work (missing credentials, live credentials PayPal rejects, vaulting without PayPal or cards, Apple Pay without a domain file).
  • PayPal API client: built on Laravel's HTTP client, with a cached OAuth token, PayPal-Request-Id on every mutating call, retries with backoff for timeouts, 429s, and 5xxs, typed resources for Orders, Payments, Vault, Webhooks, and Disputes, PayPalApiException with PayPal's debug id, and a redactor for credentials, card data, vault ids, and payer personal data.
  • Gateway family: paypal (PayPal, Pay Later, Venmo), paypal-card, paypal-apple-pay, and paypal-google-pay, each its own checkout choice, with per-cart availability by method switch, currency allowlist, and total.
  • Payments:
    • Order payloads with items, breakdown, shipping, experience context, and PayPal's decimal rules (HUF, JPY, TWD), reconciled to the engine's totals;
    • payment sessions with normalized statuses;
    • idempotent capture for the capture and authorize intents, decline handling, and the INSTRUMENT_DECLINED restart flow;
    • voids, and the authorization lifecycle: ecommerce-paypal:authorizations:reauthorize, scheduled daily, reauthorizes after the 3-day honor period and warns 2 days before expiry;
    • full and partial refunds with translated decline messages;
    • the 3-D Secure liability-shift policy (methods.card.require_liability_shift).
  • Webhooks:
    • local signature verification against PayPal's certificate (host allowlist, freshness, certificate checks, caching) or postback verification;
    • event mapping for the whole gateway family through the engine's SharesWebhookEndpoint;
    • queued handlers for pending, completed, and denied captures, dashboard refunds and reversals, disputes (order notes, timeline entries, and hooks), and vault token changes.
  • Storefront drivers for ecommerce-storefront-livewire: paypal-buttons, paypal-card-fields (PayPal-hosted fields with 3-D Secure), paypal-apple-pay (with the /.well-known/apple-developer-merchantid-domain-association route, from contents, a file, or a URL), and paypal-google-pay.
  • Shared JS module paypal-checkout.js (prebuilt in dist/): loadSdk, mountButtons, mountCardFields, mountApplePay, mountGooglePay, and mountMessages, for the Livewire drivers and React and Vue storefronts.
  • Pay Later messaging: the <x-ecommerce-paypal::pay-later-message> Blade component and the live artisanpack-ecommerce-paypal-pay-later-message Livewire component that follows the cart total.
  • Saved payment methods:
    • ecommerce_paypal_customers and ecommerce_paypal_payment_tokens tables holding references and display data only;
    • saving PayPal and cards during checkout, returning-buyer id_tokens, and paying with a saved card, from the Livewire drivers and from API storefronts through the engine's payment_options (save_payment_method, saved_payment_method; the gateways implement AcceptsPaymentOptions), with saved-card refusals answered as 422 saved-payment-method-unavailable / saved-payment-method-invalid;
    • a "Saved payment methods" account page and menu entry;
    • REST endpoints under me/paypal/payment-methods (list, remove, make default);
    • erasure when the engine deletes a customer.
  • Admin order panel for ecommerce-admin-livewire: mode, PayPal Order, capture, and authorization ids with dashboard links, payer, funding source, liability shift, authorization expiry, and disputes, behind order.view.
  • Setup commands: ecommerce-paypal:install, ecommerce-paypal:verify-credentials, and ecommerce-paypal:webhooks:register.
  • Vault housekeeping: ecommerce-paypal:prune-vault, scheduled daily, erases saved payment methods whose engine customer no longer exists (deleting them at PayPal) and prunes removed methods after vault.prune_after_days (PAYPAL_VAULT_PRUNE_AFTER_DAYS, default 30). Erasure deletes each token at PayPal separately, retries only the ones PayPal may still accept, and logs what it couldn't delete; --purge stops before dropping the tables when a deletion failed.
  • Currencies PayPal takes in whole units (HUF, TWD): PayPal isn't offered for a total that isn't a whole unit, and a fractional refund is refused before PayPal is called.
  • Webhook resilience: webhook_tolerance_seconds (PAYPAL_WEBHOOK_TOLERANCE_SECONDS, default 3 days, 0 turns the check off) so PayPal's own retries verify; the processing job retries for 24 hours and logs a final failure; capture status moves only forward under the order's lock; a denied pending capture marks the order's payment failed through the engine; a refund the store recorded as failed is settled when PayPal completes it; and PAYMENT.AUTHORIZATION.VOIDED is recorded.
  • Hooks: ap.ecommerce.paypal.orderPayload, .clientOptions, and .supportedCurrencies filters; ap.ecommerce.paypal.captured, .captureDenied, .authorizationExpiring, .disputeCreated, .disputeUpdated, .disputeResolved, and .webhookEvent actions.
  • Return and cancel URLs: PayPal Orders send the shopper back to the storefront's checkout return route whether they approve or cancel (cancel_url defaults to return_url), so a cancel on PayPal's full-page flow lands on the payment step with "Your payment wasn't completed" instead of the start of checkout.
  • Content-Security-Policy: ecommerce-paypal:install prints PayPal's JS SDK v5 sources (*.paypal.com, *.paypalobjects.com, *.venmo.com on script-src, style-src, connect-src, frame-src, child-src, and img-src, plus the Apple Pay and Google Pay hosts). paypal-checkout.js gives the scripts it adds the page's CSP nonce (or the csp_nonce client option), as nonce and PayPal's data-csp-nonce, so a nonce-based policy works.
  • Testing support: PayPalFake with recorded fixtures for faking PayPal's API in host applications.
  • Quality: contract verification for all four gateways (ecommerce:verify-satellite), a PayPal sandbox integration suite, a browser suite for the drivers, WCAG 2.2 AA work on the drivers and account page, and English, Spanish, French, and German catalogues with the SDK locale mapped from the app locale.
  • Documentation: installation, PayPal app setup and going live, configuration and settings reference, payment methods, Apple Pay and Google Pay go-live steps, saved payment methods, webhooks, CSP, troubleshooting, hooks, the JS module, and an upgrade guide.

Stay in the Loop

Monthly tips, tutorials and package updates — plus a free Quick Start cheat sheet.

Subscribe
Edit this page on GitHub