bagisto/bagisto-reward-points
Bagisto Reward Points adds a loyalty points system to your Bagisto store. Customers earn points on purchases and redeem them at checkout, while admins configure earning rules, point values, and manage customer balances.
Architecture fit. This is a Bagisto module, not a generic Laravel package. It follows the platform's conventions — a service provider (likely Concord ModuleServiceProvider), src/Config/ for routing/menu/ACL, src/Models/ plus migrations for the points ledger, src/Listeners/ for order-lifecycle hooks, and Eloquent repositories behind contracts. That is a strong fit only if we are standardized on Bagisto. Outside Bagisto it has no reusable surface; the domain logic is thin enough that a greenfield build would be comparable effort with none of the version-coupling.
Integration feasibility. The install path is standard and low-ceremony — composer require, publish provider assets, php artisan migrate, optimize:clear. The friction is version matching: Bagisto majors differ in admin UI (Vue 2 → Vue 3) and provider conventions, so the package must be pinned to the exact core version we run. Installation into a staging instance that mirrors production is non-negotiable; there is no meaningful upstream support net.
Technical risk. The signals are unambiguous: 9 stars, 0 dependents, composite score ~1.02, no documentation beyond the README. The codebase is the documentation, which means we are acquiring source we must audit, not a product we can adopt. The highest-severity unknowns are all money-path:
order.placed instead of payment-confirmed mints free points on failed/abandoned payments.channel_id-scoped. If we run multiple storefronts in different currencies, retrofitting channel scoping later is materially harder than building it in.Key questions to close before commitment.
customer_id, order_id, type/reason?Stack fit. Confirmed Bagisto + Laravel + PHP, admin UI in Vue. Match composer.json constraints (bagisto/bagisto or webkul/*, PHP version) against our core first, before any install attempt.
Migration path.
EventServiceProvider, repositories.local/ namespace, tagged against the upstream commit we branched from, with a changelog from day one. Never edit vendor/.composer require, vendor:publish the provider, migrate, optimize:clear. Publish so config, migrations, translations, and admin assets are inspectable and overridable.migrate:rollback in staging to document the rollback story — if the package touches tables we depend on, deploy needs backup-and-restore, not just rollback.Compatibility. Three recurring failure classes: Vue 2 vs. Vue 3 admin assets (manifests as blank reward screens — compare package.json/webpack.mix.js against core and recompile admin assets after any composer update); Concord $moduleName mismatch (silent skip — no error, no points); and ACL/menu registration living in the database rather than code-on-boot (needs a seeding step per environment or admins lose the menu).
Sequencing. Validate the smallest meaningful loop end-to-end before building anything: admin creates a rule → customer places a qualifying order → points land in the account → same customer redeems at checkout. That single pass surfaces roughly 80% of the gaps — checkout redemption, clawback, expiry, currency scope — in an afternoon rather than a sprint. Only after that loop passes should we invest in the extension seams: a swappable earn calculator, a RedemptionRule policy interface, and a single audited ledger adapter (award/revoke/balance/assertReconciles) so refund, cancel, and manual adjustment all flow through one seam. Wire listeners to payment-confirmed events, not cart save, and gate every credit and debit with a dedupe key (order_id + reason) so double-fires and queue retries cannot double-mint.
Maintenance. With no upstream momentum, we own the fork outright. Every Bagisto core upgrade becomes a rebase task plus a mandatory re-test of the checkout path. That is a recurring schedule line, not a one-time cost, and it should be reflected in the roadmap before the pilot is approved.
Support. Expect a steady stream of "where are my points?" tickets. A scoped, read-only ledger view per customer — plus the ACL permission to grant it to the support role — is one of the highest-ROI additions we can make and should ship with the pilot, not after.
Scaling and correctness. A derived balance is always truthful but slow on cart loads; a stored balance is fast but drifts. Whichever the package uses, we need a nightly reconciliation (sum(ledger) == stored balance) with alerting on mismatch. Redemption must be wrapped in a transaction with a row lock, and tested with parallel requests. The expiry job we will almost certainly write must be idempotent (mark, don't re-expire), resumable (checkpoint per chunk), and monitored (alert when the daily expiry count falls outside an expected band, or liability silently inflates).
Failure modes to instrument. Points minted on unpaid orders; concurrent double-spend; balance drift with no alert; blank admin screens from a Vue mismatch; silent listener skip from a Concord misconfiguration; currency-blind redemption across storefronts; unexpired balances inflating the liability line. A Log::info in boot() plus a log line on every listener invocation is cheap insurance during rollout.
Ramp-up. Plan on engineering ownership from day one — this is a funded pilot, not a plugin install. Minimum test set before production: credit on paid order, no credit on failed order, debit on refund, full and partial-cancel clawback, capped redemption, concurrent redemption. Six tests, six ways this package can cost real money. If we cannot staff that, the honest recommendation is to defer loyalty to a mature vendor rather than absorb an unmaintained money-path dependency.
How can I help you explore Laravel packages today?