2 min readAug 11, 2026by jakub

Changelog

Current version: 1.0.0

1.0.0 — 2026-07-30

First release, incorporating the full transactional-hardening review cycle. Run bin/magento setup:upgrade, flush all caches AND restart PHP-FPM/opcache before serving traffic — postings verify that their idempotency key persisted and refuse to commit against a stale schema.

Schema (additive)

  • qoliber_rewardpoints_transaction.idempotency_key (unique) — at-most-once business postings, enforced by the database.
  • qoliber_rewardpoints_transaction.gross_amount — signed processed points next to the granted amount (cap/clamp forfeits are visible and can never be re-awarded).
  • qoliber_rewardpoints_balance.points_debt — refund revocations survive a zero balance; future credits settle debt before becoming spendable.
  • New transaction status 4 (RESERVED) and action pending_marker.
  • Point-value columns are BIGINT (amount, remaining, gross_amount, balance, pending_balance, points_debt, lifetime_earned) — no practical accumulation ceiling.

Behaviour

  • Spent points are RESERVED before payment placement: an insufficient balance aborts checkout before any payment call; failed submits release the reservation; an hourly cron resolves stranded reservations by their order's fate (existing order → settle, cancelled/missing → release).
  • Every order/invoice/creditmemo/promo posting carries an idempotency key; replayed or concurrent events post exactly once.
  • Expiry debits exactly the surviving overdue remainders under the balance lock; reminder emails aggregate current remainders per customer.
  • Dynamic-price bundles earn through their child rows (checkout-time safe).
  • CSV import: complete prevalidation (all-or-nothing), batch/row idempotency (re-running a file resumes), notifications off, --dry-run on the CLI; imports post under the import ledger action (previously admin_adjust), and enforce the same maximum-adjustment magnitude bound as manual adjustments.
  • Reconciliation understands reservations and points debt; --fix re-derives each balance under its row lock, and also reports FIFO-remainder drift.
  • Order cancellation compensates (restores spent points, cancels the pending earn) only AFTER the cancellation is durably committed, via an OrderManagementInterface::cancel after-plugin. A failed order save can no longer leave an active order with points already refunded; a compensation failure surfaces and is reported by reconciliation as an unrestored cancelled order.
  • Concurrency-safe reward caps: the referral signup daily cap runs under a per-advocate lock, and the once-per-product review award is keyed on (customer, website, product) so the unique index enforces it atomically.
  • Reward-points history resolves the pooled balance owner, matching the balance read — B2B shared pools see the shared ledger, not just the acting member's rows.

Packaging

  • qoliber/reward-points-graph-ql requires core ^1.0 and the GraphQL modules whose schema types it extends.
  • Uninstall removes the invoice/creditmemo columns.
Changelog — Reward Points — Marketing — Extensions | qoliber Docs