← Back to home

Business rules & controls

The control surface that risk, finance, and compliance teams use to keep a Flourish program safe, predictable, and within budget. Every campaign runs on a stack of guardrails — some configured once at setup, some live during the campaign, some delegated to your team's webhook handlers.

The four control layers

Flourish provides controls at four layers of the engagement engine. Most production programs use all four; the combination is what makes the system safe under real-world conditions.

1

Budget

Caps the total spend on a campaign. Configured before launch, adjustable mid-campaign.

2

Eligibility

Decides who can participate. Combines segment scoping with a real-time eligibility check at payout.

3

Quality

Filters which events count. Excludes verification charges, low-value transactions, ineligible categories.

4

Reversal

Automatic claw-back when a transaction is reversed, charged back, or flagged after the reward already accrued.

Budget control

Predictability of spend is the #1 question from finance teams. Flourish gives you four budget levers that compose.

Per-mission prize size

Every mission has a fixed prize amount (or a fixed wheel-tier distribution). Configured once at setup; bounded above by the mission's target. Changing it requires a configuration update from Flourish ops — not a runtime risk.

Example: "Spend 1,000 BRL → earn 30 BRL." A user cannot earn more than 30 BRL from this mission per cycle, regardless of overspending.

Time-bounded windows

Campaigns can have hard mission_start_date and mission_end_date values. Outside the window, the mission is invisible — users do not see it, do not earn from it, do not have residual claims.

Example: "June 1 to June 30 only" caps total exposure to one month of qualifying activity.

Segment-scoped reach

Every mission is scoped to one or more segments. A campaign that targets only your "premium" cohort cannot pay out to anyone outside that cohort. You control segment membership via REST API; you can adjust mid-campaign if you need to expand or contract.

Example: "Cashback bonus for tier-gold customers only" caps the addressable population to whoever you've assigned to tier-gold.

Limit Booster redemption caps

For credit-limit-redemption campaigns (Limit Booster feature), each tenant has configurable monthly redemption limits per user. Beyond the limit, the redemption attempt is rejected platform-side.

Eligibility & access

Before any reward leaves the wallet, two checks happen in sequence.

Segment membership (always)

The mission only matches events from users in its scoped segments. A user removed from a segment stops earning on that mission immediately — no further events advance their progress.

You manage segments via PUT /api/v3/customers/{customer_code}/segments/{segment_code} and the corresponding DELETE. Idempotent; safe to run from a daily reconciliation job.

Real-time eligibility check (configurable per tenant)

For tenants with eligibility-required enabled, Flourish calls your GET /eligibility endpoint at the moment a cashback cycle closes, before posting the Reward Notification. Your endpoint returns a binary eligible / not-eligible response. If not eligible, no payout fires.

Use it for: KYC level checks, account-status flags (frozen, fraud-flagged, dormant), regulatory holds, balance thresholds — anything that can change between accrual and payout.

Per-tenant feature flags

Whether eligibility is required, which event types are accepted, which campaigns are active — all configurable per tenant during onboarding and adjustable thereafter via Flourish ops.

Event quality & matching

Not every event should count. Flourish filters at two points: at the matcher (Flourish-side) and at push time (your side).

Status-based filtering (automatic)

Card transactions only count toward missions when their transaction_status is AUTHORIZED or CONFIRMED. Statuses like CANCELLED, REVERSED, CHARGEBACK, and SUSPECTED_FRAUD do not advance progress.

This is enforced by the platform; you do not need to filter on your side.

Per-mission matching rules (Flourish-side)

Each mission can be scoped at setup to count only events with specific values on event fields — merchant category code (MCC), bill type, payment method, transfer corridor, amount thresholds. The matcher compares one field at a time to a static value or a list.

Examples: "Count only groceries (MCC 5411 or 5412)." "Count only PIX bill payments." "Count only transfers above 100 USD." "Count only transfers to Mexico."

Configured by Flourish ops at mission setup. The matcher is intentionally simple — it cannot compare two fields against each other (e.g., payment_date <= due_date); for those cases, see "Push-side filtering" below.

Push-side filtering (your side)

For criteria the matcher cannot express — "on-time payment", "amount above some user-specific threshold", anything requiring two-field comparison — filter at push time. Either don't push the event at all, or push it through PUT /api/v3/generic-events with a stable event_name that already encodes the filter (e.g., on_time_bill_payment).

Idempotency by identifier

Every data ingestion endpoint deduplicates by a unique identifier on the event body: transaction_id, payment_id, event_id. Re-pushing the same identifier with the same payload is safe (returns 204 with no state change). Re-pushing with a different payload returns 409 PAYLOAD_CONFLICT — your retry library cannot accidentally double-count.

Fraud & reversal

The platform automatically reacts to negative signals from your core banking. You do not have to write reversal logic on your side.

Automatic cashback debit on negative status

When you PATCH /api/v3/card-transactions/{id}/status with CANCELLED, REVERSED, CHARGEBACK, or SUSPECTED_FRAUD, the cashback wallet automatically debits the corresponding amount from the user's accrued balance. If the cycle has not yet closed, the user simply has less to receive at month-end. If the cycle has already paid out, recovery is on your side — you have already moved real money.

Mission ledger immutability

The mission completion record is not erased on a reversal. The historical ledger (mission was completed at timestamp X) is preserved for audit. Only the wallet balance moves. This means analytics ("how many missions completed this month") and money flow ("how much was actually paid") are tracked separately.

Eligibility check at cycle close

Even if a chargeback hasn't yet arrived, you can refuse a payout via the eligibility webhook for any user-level reason — KYC pending, account frozen, internal fraud flag, regulatory hold. The cycle close calls your endpoint; you say no; nothing pays out.

Per-prize-type guarantees

Different prizes have different reversal semantics:

  • Cashback: automatic debit on negative status (above).
  • Game vouchers: not auto-reverted — once earned and spent on the wheel, the spin happened. (Vouchers are typically very low value.)
  • Limit Booster credit-limit redemptions: explicit reversal endpoint (POST /boost/reverse/{redemption_id}) that you call when your credit policy declines the increase.

Who owns what

Clear ownership across the three sides of every campaign — you, Flourish ops, and the platform engine. No black boxes.

DecisionOwnerNotes
Mission target, prize amount, time window Flourish ops Configured at setup. Adjustable mid-campaign on request.
Mission matching rules (MCC, bill type, transfer type) Flourish ops Single-field filters configurable per mission.
Wheel prize tiers and odds Flourish ops Configured per tenant via the platform's game backend.
Cashback wallet cycle (anchor, cash-out interval) Flourish ops One config per tenant; can be reset per customer if needed.
Segment definitions (which segments exist) Flourish ops Created during onboarding; new segments added on request.
Segment membership (which user is in which segment) Integrator You manage via REST API based on your tier criteria, KYC level, account age.
Event push (what counts as a qualifying action) Integrator You decide which events to push and when. Push-side filtering is your lever for criteria the matcher can't express.
Eligibility decisions at payout time Integrator Your webhook returns yes/no at cycle close. Used for KYC, fraud holds, account status checks.
Actual reward delivery (money, gift cards, points) Integrator You implement the deposit / credit / delivery in your core banking. Flourish never moves money on your behalf.
Credit-limit policy (Limit Booster acceptance) Integrator Flourish notifies of a credit-limit redemption; you evaluate against your credit policy and either approve or call the reversal endpoint.
Mission progress tracking Platform Automatic. You don't track this on your side.
Wallet balance & ledger Platform Append-only ledger. Auto-debit on negative transaction status.
Idempotency & deduplication Platform By event identifier on inbound events; by webhook identifier on outbound.

Audit & observability

Every state change is recorded and queryable. Auditors and finance reviewers see the full chain.

Mission ledger

Every mission completion writes an immutable row tagging user, mission, timestamp, and reward details. Available via API and exportable on request.

Wallet ledger

Every credit and debit on the cashback wallet is a separate ledger row with reference to the originating mission or status update. Append-only.

Webhook delivery records

Every Reward Notification, Mission Completion, and Eligibility check is logged with delivery status. Failed deliveries are retried; final state is preserved.

Event processed log

Every inbound event is recorded with a processed-at timestamp, plus the missions it advanced. Useful for "did this transaction count? why or why not?" investigations.

For your engineering team

Implementation reference

Webhook contracts, eligibility endpoint shape, idempotency semantics, error codes for status updates, and the full set of API responses for each control. The full developer documentation is behind a partner login.

Open the docs

Restricted area · partner credentials required

Want a controls walkthrough?

We can review the rule surface against your risk and finance team's checklist on a 30-minute call.

Talk to our team