Search by

flowcheckdnb-cpu / module-abandoned-cart

flowcheckdnb-cpu

AI brand-voice abandoned-cart recovery emails for Magento 2 + Hyvä, powered by Google Gemini

Package info

github.com/flowcheckdnb-cpu/magento2-abandoned-cart

Type:magento2-module

pkg:composer/flowcheckdnb-cpu/module-abandoned-cart

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v0.23.0 2026-05-29 14:07 UTC

README

Latest Version License PHP Version

AI brand-voice abandoned-cart recovery emails for Magento 2 + Hyvä, powered by Google Gemini.

Features

  • Cron-driven scanner that finds abandoned carts and dispatches recovery emails
  • Per-stage AI-generated subject + preheader + body in your configured brand voice (via Google Gemini 2.5 Flash, free tier)
  • Static-template fallback when the API is unavailable or unconfigured — pipeline never silently drops a customer
  • Dedup-safe send log with UNIQUE(quote_id, stage_key)
  • Per-store-view brand voice (name, voice description, tone, locale)
  • Admin configuration tree under Stores → Configuration → Magebit → Abandoned Cart
  • PHPStan level 9 + PHPCS (Magento2 / PSR-12 / Slevomat) clean

Status

v0.13.0 — original plan complete (OOS filter + integration tests).

Implemented:

  • Three-stage abandoned-cart cadence: stage 1 reminder, stage 2 follow-up, stage 3 with auto-generated coupon
  • Low-stock urgency email — separate cron, fires daily when any cart item drops to qty ≤ threshold but is still > 0; carries its own coupon from a separate admin-selected rule
  • AI generator (Google Gemini) + static template fallback per email type
  • Cron-driven scanner with send-log dedup keyed on (quote_id, stage_key) — stage keys for low-stock embed the date so the unique constraint enforces a natural daily cap
  • CouponIssuer mints unique codes from any admin-selected cart price rule (requires use_auto_generation=1 on the rule)
  • Generated coupon is rendered as a prominent banner AND mentioned naturally in AI body copy
  • sales_order_place_after observer that suppresses future sends once the customer buys
  • Token-signed recovery link in every email — restores the quote into the visitor's session and redirects to /checkout/cart
  • API key redaction in error logs
  • One-click unsubscribe: every email carries an unsubscribe link that flips the unsubscribed flag on every log row for the (customer_email, store_id) pair. Both finders consult that flag before yielding candidates.
  • Admin send-log grid at Marketing → Communications → Abandoned Cart Log — filterable/sortable columns (Type, Recipient, Store, Status, AI?, Coupon, Recovered At, Unsubscribed?), CSV/Excel export, mass-delete and mass-mark-unrecovered actions.
  • Personalized coupon codes: codes are prefixed with the customer's sanitized first name (or email local-part when no name is on file), e.g. VERONICA-AB3F instead of 0GK2IY2HCNVB. Magento's coupon generator still guarantees uniqueness via the random suffix.
  • Product images + redesigned emails: every email shows a cart-items grid (thumbnail · name · qty · line price) above the AI body copy. Card layout on a soft canvas, dashed coupon banner, primary CTA. Low-stock template gets a red urgency pill and red CTA.
  • Style rotation: each send randomly picks one of 7 rhetorical approaches (curious question, vivid observation, playful, brief, scene-setting, friend-texting, direct statement) so the same customer reading stages 1/2/3 doesn't see the same "Hey {name}" pattern three times.
  • Admin test-send button on the send-log grid. Dispatches one preview email of the selected type to any recipient using a synthetic sample cart — no coupon minted, no log row written.
  • Unit test suite (26 tests, 57 assertions, ~20 ms) covering MarkdownRenderer, StaticTemplateFallback, Gemini\ResponseParser, and CouponIssuer (including all coupon-prefix sanitization edge cases).
  • Out-of-stock + disabled-product filter: AbandonedCartFinder skips quotes whose items are all non-salable so customers aren't asked to recover empty carts.
  • Integration tests scaffolded for SendLogRepository (4 tests: dedup constraint, stage-key separation, recovered flag, per-store unsubscribe). Run via vendor/bin/phpunit -c dev/tests/integration/phpunit.xml.dist once the Magento integration sandbox DB is configured.

Planned for v1.0.0+:

  • Recovery-click tracking
  • GDPR consent flow at checkout
  • Customer-group targeting

Requirements

  • Magento Open Source / Commerce 2.4.8 or newer
  • PHP 8.3+
  • Google Gemini API key (free at aistudio.google.com) — optional, falls back to static templates without one

Installation

composer require flowcheckdnb-cpu/module-abandoned-cart
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:clean

Configuration

Stores → Configuration → Magebit → Abandoned Cart:

Group Fields
General Enable module, sender identity, unsubscribe route
Stages Per-stage delay + email template
Low-stock Threshold, template, coupon rule, frequency cap (planned)
Brand voice Brand name, voice description, tone, locale
Gemini API Encrypted API key, model selector, kill-switch, request timeout

Then ensure two trans_email/ident_*/name config rows are populated (Magento requires both email and name for sender identities) and run cron — either via the natural heartbeat or:

bin/magento cron:run --group=default

Verifying

Backdate an active quote into the stage-1 window and force-run cron. The email should land at your configured SMTP destination (e.g. Mailpit in local development).

UPDATE quote SET is_active=1, updated_at=NOW() - INTERVAL 2 HOUR WHERE entity_id=...;

License

OSL-3.0 — see LICENSE.