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

Plorea Laravel Package

memberflow/plorea

Plorea is a Laravel package for building membership workflows: define plans, manage member access, and add subscription-ready features to your app with a clean, configurable API. It streamlines gated content and member management.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The package is a thin, idiomatic Laravel SDK over an external payment API: a Plorea facade, DTOs (Amount, Refund, status objects), PHP enums (Channel, RecurringType), typed exceptions (PloreaException, PaymentAlreadyPaidException), and a fluent builder per resource (payments(), payByLink(), paymentMethods(), subscriptions()). That is exactly the shape a Laravel codebase wants — it slots into a service layer without an adapter, and its design assumptions (cache locks, queues, scheduled commands, event listeners) match framework primitives the app already runs. It is a payment-orchestration SDK, not a payment processor: Plorea sits between the app and Adyen, so the integration surface we own is business logic (references, merchant routing, booking, reconciliation), not card data. That is a favourable fit.

Integration feasibility. High for the hosted payment-link path — roughly ten lines to a working link, with firstOrCreate() solving duplicate-reference drift out of the box. Medium for the full surface: webhooks need a durable ingest table, CSRF exclusion, queued deduplicating listeners and a scheduled backstop; embedded web checkout adds Adyen Web v6 client work, CSP rules and origin whitelisting done by a human at Plorea; native adds iOS/Android Drop-in, universal links / App Links files and another whitelisting round-trip. Card storage has no webhook at all and must be polled. None of this is hard, but it is not a one-sprint integration, and several steps have external lead time.

Technical risk. Ranked:

Risk Severity Notes
Unproven package (0 stars, 0 dependents, single vendor) High We are the de facto QA. No community CVE surface, but also no peer review of money-handling code
Non-atomic firstOrCreate() High Server has no idempotency key; double-submit creates duplicate links unless we hold a per-reference cache lock
At-most-once webhooks High A 500 permanently loses the event; requires persist-before-process plus a poller backstop
Silent environment misconfiguration High PLOREA_ENVIRONMENT defaults to test; since 2026-10-13 a live key with the variable unset returns 403 on every call
Retry amplification High Default retry behaviour on non-idempotent writes double-bills; must set PLOREA_RETRY_TIMES=0 or prove idempotency
PII leakage via $session->raw Medium Carries tenant, shopper reference and customer id; only toCheckout() may cross the wire
Unverified channels Medium Android Drop-in on device, native 3DS2 and a live environment value are all unobserved per the vendor's own docs
Two-layer vendor dependency Medium Package → Plorea → Adyen: three change cadences, one ambiguous escalation path

The documentation is genuinely above average — the skill files read like operational runbooks (go-live checklist, failure modes, "unverified, do not promise these"). That partially offsets the zero-star signal, but documentation is not a support contract.

Key questions. What SLA and support channel does Plorea offer, and who debugs when Plorea blames Adyen? What is the versioning/deprecation policy — is the API contract semver-stable? Is there an OpenAPI spec or changelog we can diff against? What is our PCI scope in writing (SAQ A for hosted, SAQ A-EP for embedded Drop-in), and will Plorea attest to it? Where do shopper references and customer ids reside, and is that GDPR-defensible for our DPA? What is the error taxonomy — which exceptions are retryable, which are terminal? Can we vendor or fork the package under MIT if upstream stalls? What happens to in-flight sessions if Plorea has an outage — is there a status endpoint we can poll independently?

Integration Approach

Stack fit. Requires a distributed cache for locks (Redis, not array/file if we run multiple app nodes), a reliable queue worker, a running scheduler for the backstop poller, and an HTTP client with a circuit breaker. The webhook route must be CSRF-exempt and excluded from any auth middleware. Client-side, Adyen Web v6 is a separate npm dependency with its own upgrade track and its own CSP allowlist (checkoutshopper-* and issuer 3DS frames, live hosts differing from test).

Migration path. Greenfield is clean: build the webhook ingest table and the reconciliation job before the first payment. From an incumbent PSP, run parallel: feature-flag by merchant org number, dual-write payment state, keep the legacy provider live for merchants who have not completed KYC, and reconcile daily for a full billing cycle before cutting over. Preserve external references verbatim — firstOrCreate()'s suffix chain (-1, -2) means a reference can be superseded, so the mapping table must record the suffix chain, not just the base.

Compatibility. Pin the package version exactly and pin Laravel/PHP minors in CI. Client-side Adyen Web v6 is version-pinned independently of the PHP package — treat them as two upgrades. Origin and app-identifier whitelisting is manual and must be requested per environment and per customer-owned domain; agree the process for adding a domain before a merchant asks, because it fails late as a CORS error.

Sequencing.

  1. Commercial + credentials: API key, tenant id, PLOREA_PLATFORM, webhook secret, test vs live keys, named support contact.
  2. Sandbox: link creation, status(), PaymentAlreadyPaidException handling, cache-lock wrapper.
  3. Webhook endpoint: persist-first, dedupe on $event->eventId, queued listeners, CSRF exclusion, assertSent-style contract tests via Plorea::fake().
  4. Backstop poller: open payments, pending_setup past expiresAt, subscriptions()->needingAttention(). Refunds polled in hours, never reversed on timeout.
  5. Reconciliation + observability: alert on ResponseReceived with status ≥ 400, on ConnectionException, on stuck states; confirm Authorization is not logged.
  6. Embedded web checkout: Adyen Web v6 Drop-in, CSP, whitelisted staging domain (not localhost), redirectResult return page.
  7. Card storage / subscriptions → native iOS → native Android, each behind a flag.
  8. Merchant onboarding at scale: KYC is per org number, 1–5 business days, no KYC API — plan a self-serve payment link carrying the org number for pre-launch onboarding.
  9. Launch test per shipped surface with one low-value live payment and a refund.

Operational Impact

Maintenance. We absorb upstream churn ourselves. Budget for a quarterly dependency review and a "read the diff before bumping" policy on a package that moves money. Vendor or mirror the repo so a yanked tag cannot break builds. The Amount::nok() surface suggests NOK-only — confirm before assuming multi-currency, since a currency expansion would be a package-level change, not a config one.

Support. There is no community: no Stack Overflow corpus, no issue history, no dependents. Escalation is a named Plorea contact or nothing. Negotiate that contact before signing, write an internal runbook with the vendor's own silent-failure list, and assign a named owner. Finance needs a counterpart for KYC onboarding, payout holds and refund adjudication — this is not purely an engineering integration.

Scaling. HTTP-bound, so raw throughput is fine; the real costs are: cache-lock contention per reference under double-submit bursts, one extra status request per firstOrCreate() as the suffix chain lengthens, webhook worker concurrency during payout windows, and the card-setup poller — which has no webhook and therefore scales linearly with pending setups. Size the poller's interval and budget explicitly, and cap it so a stuck setup cannot poll forever.

Failure modes to design against. A 500 on a webhook loses the event permanently (persist first, replay from the backstop). A missing CSRF exclusion yields 419 on every delivery. PLOREA_ENVIRONMENT unset with a live key yields 403 everywhere. PLOREA_RETRY_TIMES left at default can double-create links or charges. Trusting onPaymentCompleted shows "paid" for Pending and Received — the server decides, always. Refund timeouts reported as failures create support tickets and incorrect books. A raw session DTO returned over HTTP leaks tenant and shopper identifiers. An unwhitelisted origin surfaces as a late CORS error in /sessions/{id}/setup.

Ramp-up. One backend engineer, roughly 2–3 weeks to a hardened hosted-link integration including webhook durability and reconciliation; a further 3–4 weeks for embedded web plus native, gated on Adyen client work and external whitelisting. Add finance/ops ramp for KYC and refunds, and support training on the silent-failure list specifically. Treat the vendor's "unverified" items — Android on device, native 3DS2, live environment — as unproven until we have observed them ourselves on a live low-value payment; do not let a product commitment depend on them. App-store policy must be decided early: real-world services and invoices are generally exempt from in-app purchase, digital goods are not.

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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource