Skip to main content

Gamified campaigns

Server-Resolved Gamification: The Wheel Must Not Choose the Prize

Why gamified campaign outcomes should be allocated and stored before scratch, wheel, slot, or tap-to-reveal interfaces display them.

11 min read

By Published Last updated

A reveal mechanic is presentation. Prize allocation is a data and control decision. When those responsibilities are combined in the browser, inventory, retries, downstream delivery, and campaign review become much harder to trust. Resolve the outcome once on the server, persist it, and make every interface reveal that same result.

Complete the response before resolving the outcome

Gamification should not decide whether a form submission exists. Store and validate the completed response first, then evaluate the configured campaign outcome against that response identifier. This establishes a durable participation record even if prize allocation or Salesforce delivery later fails.

In OK Flows, the submit path creates the response and completion event before invoking server-side prize allocation. The resulting gamification event is tied to that response, which keeps participation, outcome, reveal state, and downstream delivery traceable to the same completed action.

  • Response identity exists before reward allocation.
  • A failure to allocate or deliver does not erase the submitted answers.
  • Partial drafts remain outside completed participation.
  • The same response identifier anchors retries and investigation.

Make allocation idempotent per response

Refreshing a success page, repeating a network request, or reopening a reveal should not create another chance to win. Before drawing, the allocation function checks whether the response already has a stored award and returns that existing result when present.

This is the most important baseline control in the current implementation: one recorded prize or no-reward outcome per response. It does not, by itself, enforce one participation per person, email address, device, day, or campaign window. Those broader limits require a verified identity strategy and server-side enforcement appropriate to the campaign.

Resolve inventory in the same authority boundary

Prize probability is meaningful only while inventory is available. The allocator locks the form configuration during allocation, counts existing awards, excludes exhausted prizes, and records the selected outcome. Discount-code prizes derive their inventory from configured unique codes and select an unused code when awarded.

The reveal interface receives the result after this work. It never decrements inventory, chooses a code, or decides that a wheel segment is a win. A participant can alter animation timing in their browser without changing the server-stored outcome.

  • Configured probabilities are clamped to the supported range.
  • Prizes with no probability or available inventory are skipped.
  • Discount codes are normalized and not intentionally awarded twice within a form.
  • No-reward is a first-class stored result rather than an interface error.

Treat the reveal as an interaction record

Direct, scratch, tap-to-crack, wheel, and slot mechanics can all present the same class of server-resolved outcome. Their purpose is to shape anticipation and engagement, not to introduce a second random decision.

Record whether the result was actually revealed and when. That creates a useful distinction between participation, allocation, and reveal completion. It also supports mechanic-level reporting without implying that a hidden but already allocated prize was never awarded.

Deliver the resolved outcome—not a visual approximation

The Salesforce payload should use the server result that the participant received. OK Flows can include the gamification mode, reveal mechanic, outcome type, entries, points, prize identifier, prize name, discount code, and a rule trace in mapped CloudPage delivery.

Salesforce explains that Journey Data preserves the state captured when the entry event fires. If gamification attributes will drive decision splits, personalization, or fulfillment, ensure the entry payload contains the authoritative stored result and a contact key that matches the intended participant.

  • Do not reconstruct a win from the wheel segment shown in the browser.
  • Use the stored response and outcome identifiers for fulfillment reconciliation.
  • Keep delivery failure separate from allocation and reveal success.
  • Avoid exposing discount codes in analytics or logs that do not require them.

Understand the current randomness boundary

The current allocator uses PostgreSQL random() to draw a value against configured prize probabilities. PostgreSQL documents this function as a deterministic pseudorandom generator that is fast but unsuitable for cryptographic applications.

That distinction matters for regulated, high-value, adversarial, or independently audited promotions. Such campaigns may require a cryptographically secure or externally certified draw mechanism, stronger identity and frequency enforcement, immutable audit evidence, and formal review. Do not describe the current allocator as cryptographically secure or independently certified.

Campaign configuration is not automatic compliance

A mode label such as sweepstakes or manual fulfillment does not create official rules, determine eligibility, satisfy geographic restrictions, calculate tax obligations, or establish a lawful promotion. Those requirements differ by campaign and jurisdiction and need qualified legal and operational owners.

Before launch, define who may participate, how identity is verified, which limits are enforced on the server, how prizes are fulfilled, what happens when inventory or delivery fails, and how long participation evidence is retained.

  • Eligibility and geographic scope.
  • Participation and frequency limits.
  • Start/end time and timezone authority.
  • Probability disclosure and prize inventory.
  • No-purchase route when required.
  • Fulfillment, support, disputes, and deletion handling.

Test the outcome as a state machine

Test more than the animation. Repeat the allocation call for one response, exhaust an inventory item, consume the last discount code, interrupt the reveal, retry a failed Salesforce delivery, and confirm that each surface still refers to the same stored outcome.

The campaign is technically coherent when completion, allocation, reveal, delivery, and fulfillment can fail independently without causing a second draw or contradicting one another.