Skip to content

On-pack code entry

The full recipe for a code-entry promotion: the shopper types the unique code from the pack with their details, Loranj burns the code and saves the entry.

Validate as they type

const check = promo.validate(input);
// { ok: true } or { ok: false, errors: { email: "Enter a valid email address" } }

Custom fields are keyed as answers.<key> in errors. Validation here is a convenience; Loranj validates again on the server.

Submit and handle every result

const result = await promo.submitEntry(input, { turnstileToken });

switch (result.status) {
  case "accepted": // result.entryId: show success
  case "invalid": // result.errors by field: show inline errors
  case "invalid_code": // the code doesn't exist for this campaign
  case "code_used": // someone has already used this code
  case "entry_limit_reached": // this person has entered the maximum times
  case "closed": // after the end date
  case "not_started": // before the start date
  case "bot_check_failed": // reset the Turnstile widget and try again
  case "rate_limited": // wait result.retryAfter seconds
}

Retries are safe

Each submission carries an idempotency key. The SDK retries network and server errors with the same key, and reuses it if the shopper presses "Try again". A code is never redeemed twice, and the shopper never sees "code used" for their own entry. Double clicks send one request.

Codes

Codes are generated in batches in the dashboard and downloaded once for printing. Loranj stores only a keyed hash, so they can't be read back. Input is normalised (case, spaces and dashes), and codes avoid lookalike characters.