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

Laravel Purchases Laravel Package

imdhemy/laravel-purchases

Laravel Purchases helps you validate and manage in-app purchases and subscriptions from Apple App Store and Google Play. It provides receipt verification, server notification handling, and subscription lifecycle tools with a Laravel-friendly API.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. imdhemy/laravel-purchases sits at the exact seam where a Laravel backend meets the mobile app stores: it wraps Apple App Store / StoreKit 2 and Google Play Billing receipt validation behind a small set of contracts (Receipt, Purchase, Subscription, Transaction) and a Purchases facade, plus optional webhook routes for App Store Server Notifications V2 and Google Real-time Developer Notifications. For a Laravel monolith or modular monolith with a server-authoritative entitlement model, that is a clean fit — it is a library, not a service, so it introduces no new runtime, no new datastore, and no vendor contract. It is a poor fit for teams who want entitlement logic outsourced entirely (RevenueCat/Superwall territory) or for polyglot stacks where PHP is not the system of record for purchases.

Integration feasibility. High. Standard Composer install, publishable config, publishable migrations, service provider auto-discovery. Credentials are configuration-driven (Apple shared secret / .p8 API key + issuer ID + key ID; Google service-account JSON). The main integration work is not the package — it is the surrounding plumbing: secure secret storage, a public HTTPS webhook endpoint, GCP Pub/Sub topic + push subscription for Google, and an internal entitlement model that the package's models should not replace.

Technical risk.

  • Platform API drift is the dominant risk. Apple is actively retiring the legacy verifyReceipt endpoint in favor of the App Store Server API; Google Play Billing has moved through several major versions. A wrapper library must chase both. Release cadence is a positive signal — 1.19.2 → 1.20.0 shipped with a focused feature (immutable subscription and renewal dates, PR #533) rather than a stall — but it remains a single-maintainer project (bus factor 1) with MIT licensing and zero dependent packages — meaning no downstream library has stress-tested its interfaces, and there is no ecosystem pressure to preserve backward compatibility.
  • Model-layer coupling is now slightly deeper. 1.20.0 changes how the package casts subscription and renewal timestamps (immutable date objects). That is a non-breaking minor bump on its face, but it lands squarely in the package's Subscription model — the exact surface the "don't use the shipped tables as your system of record" guidance is meant to insulate you from. Teams that consumed these attributes directly will see changed object semantics (immutability affects in-place mutation patterns, ->addDay()-style code, and JSON/array serialization shape) even without a schema migration.
  • Notification semantics are under-specified in most integrations. Apple delivers out-of-order, duplicated, and replayed notifications; refunds/revocations, grace periods, billing retry, offer codes, promotional offers, and family sharing are all real states. Whether the package's normalization covers your catalog edge cases must be verified against your actual product set, not the README.
  • Trust boundary. Webhook signature verification (JWS for Apple; OIDC push auth for Google Pub/Sub) is security-critical and easy to get subtly wrong. This deserves an explicit security review, not a code review.
  • Blast radius of the shipped models. Using the package's Purchase/Subscription tables as your system of record couples your domain to a third-party schema — and, as of 1.20.0, to its date-casting conventions.
  • Testability. Sandbox/TestFlight/license-tester flows are slow and manual; automated coverage of the failure paths requires deliberate test doubles.

Key questions.

  1. Which platforms and which billing generations (StoreKit 1 legacy vs. StoreKit 2 / App Store Server API; Play Billing v6 vs. v7+) are actually in scope for the next 12 months?
  2. Does the package's normalized subscription state cover grace period, billing retry, account hold, pause, upgrade/downgrade proration, and revocation — or do we build that layer?
  3. Who owns the webhook endpoint's authentication and replay protection — the package or us?
  4. Is there a funded plan for the bus-factor-1 dependency (internal fork, pinned version, or upstream contribution commitment)?
  5. Do we need multi-tenant app credentials (one bundle ID / package name per tenant)? If so, the singleton config model may need adaptation.
  6. Do any of our consumers read the package's Subscription date attributes directly (API resources, reporting jobs, admin screens)? If yes, 1.20.0 requires a compatibility check on immutable-date semantics before adoption.
  7. What is our fallback if the maintainer stops shipping within 6 months?

Integration Approach

Stack fit. Requires a modern PHP/Laravel baseline (PHP 8.x, Laravel 10+). Assumes a queue-capable runtime (Redis/SQS/database queue) and a relational database for persistence. It fits a Laravel-first organization with an existing entitlement or account service; it does not fit organizations standardizing on a mobile-BFF in Node/Go or on a managed entitlement vendor.

Migration path. The package is best adopted behind an internal adapter interface (EntitlementGateway) rather than called directly from controllers. That makes three migration scenarios tractable: (a) from hand-rolled cURL validation — the adapter absorbs the difference and lets you shadow-run both paths and diff results; (b) from RevenueCat or a similar vendor — the adapter becomes a swap point, so vendor exit is a strategy decision rather than a rewrite; (c) greenfield — build the adapter first so the package is replaceable before it is load-bearing. The 1.20.0 date-casting change is precisely the kind of churn this boundary absorbs; it is a second concrete argument for building the adapter before the first production call.

Compatibility. Pin the exact version and lockfile; verify the PHP/Laravel support matrix against your platform version before committing. 1.20.0 is a minor release and reads as additive/non-breaking, but "immutable dates" is a behavioral change to model attributes, not a new endpoint — so the compatibility check is: (i) run your existing test suite against 1.20.0, (ii) diff serialized subscription payloads before/after, (iii) confirm no code mutates the returned date objects in place, and (iv) confirm no migration is required or, if one ships, that it coexists with your schema conventions (UUIDs vs. auto-increment, timestamps, soft deletes). Watch transitive dependencies on Google API client and Guzzle, which often conflict with other installed packages.

Sequencing.

  1. Week 1 — Spike. Sandbox validation for one Apple product and one Google product end-to-end in a throwaway branch. Confirm credential flow, response shape, and error taxonomy. Pin 1.20.0 here and record the date-semantics behavior as part of the spike output.
  2. Weeks 2–3 — Domain design. Define your entitlement model independently of the package's tables. Write the adapter interface and map package entities onto it. Decide what is persisted vs. derived — and normalize package dates to your own immutable representation at the adapter edge.
  3. Weeks 3–4 — One platform to production. Ship iOS validation + App Store Server Notifications behind a feature flag. Instrument everything.
  4. Weeks 5–6 — Second platform. Add Google Play plus Pub/Sub push. Reuse the idempotency and reconciliation machinery.
  5. Week 7+ — Reconciliation and hardening. Nightly job that re-queries store state for subscriptions in ambiguous states, closing the gap for any dropped webhook.

Do not start with both platforms in parallel; the second platform is where the abstraction either holds or breaks. Upgrade to future minors (1.21.x+) on a defined cadence — monthly review, quarterly adoption — rather than at release time.

Operational Impact

Maintenance. Low surface area (no infrastructure, no sidecar) but non-zero ongoing cost: platform API deprecations, credential rotation (Apple .p8 keys, Google service accounts), and dependency bumps. 1.20.0 does not change this budget, but it does illustrate the shape of the cost: a small, well-scoped feature release that still requires a read of the diff and a test run because it touches model semantics. Budget roughly 1–2 engineer-days per month plus an unplanned 1–2 week surge once or twice a year when Apple or Google ships a breaking change. Treat the pinned version as a deliberate decision with a documented upgrade owner.

Support. No commercial SLA; MIT-licensed community project with a single primary maintainer. There is no vendor to escalate to. Mitigation: wrap behind the adapter, keep a fork-ready posture, and pre-authorize a "maintain ourselves if abandoned" contingency in the technical roadmap. The zero-dependents metric means upstream interface changes will not be socially dampened by other consumers — you are effectively the first integrator for any breaking change. The 1.20.0 release is mildly reassuring on liveness (active, reviewable, scoped changes) but does not move the bus-factor number.

Scaling. Validation calls are network-bound to Apple/Google, so they must be queued and cached (validation results, Google OAuth tokens, Apple keys). Webhook handlers must be idempotent and ordering-tolerant — assume duplicates and out-of-order delivery. Plan for monotonically growing notification-history tables with a retention/archive policy. Throughput is generally modest (purchase and renewal events, not request-path traffic), so the scaling story is about correctness under retry, not raw QPS.

Failure modes to instrument explicitly.

  • Credential expiry or revocation → 401/403 from both stores, silently blocking all validation.
  • Store API 5xx / timeout → must not grant or revoke entitlement; requires retry with a bounded queue and a dead-letter path.
  • Duplicate or replayed notifications → double-granting or double-revoking entitlements without an idempotency key.
  • Sandbox vs. production cross-contamination → test purchases polluting production entitlement data.
  • Missed webhook (endpoint downtime) → subscription state drift; only the nightly reconciliation job catches this.
  • Date/timezone handling on subscription and renewal timestamps → off-by-one renewals, premature expiry, or grace-period logic that fires early. Narrower in scope than the others, but newly relevant given 1.20.0's immutable date casts; assert on boundary cases in tests.
  • Unhandled states (grace period, billing retry, refund, upgrade mid-cycle) → incorrect access decisions that surface as support tickets and, for refunds, as revenue leakage.
  • Google Pub/Sub push auth not validated → forged entitlement grants.

Ramp-up. Expect 2–4 weeks for one mid-level backend engineer to reach production confidence on the first platform, plus a second engineer for cross-review on the security boundary (webhook auth, secret handling) and one mobile engineer for sandbox test harnesses. Prerequisites that are frequently underestimated: App Store Connect Admin and Play Console Admin access, a GCP project with Pub/Sub permissions, and a publicly reachable HTTPS endpoint in the environment where webhooks land — none of which the TPM can defer to the integration week.

TPM recommendation. Adopt, but as a validated implementation detail behind an internal entitlement abstraction, not as the domain model. The package is recent, well-shaped, and appropriately licensed; 1.20.0 is a small, contained feature release that reinforces the liveness signal without changing the risk profile. The material risks remain single-maintainer dependency and the inherent volatility of store APIs — both contained by the adapter boundary and a reconciliation job. Gate the decision on the week-one spike proving credential flow and notification signature verification on real sandbox traffic, and add the 1.20.0 date-semantics check to that spike's exit criteria.

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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource