CampgroundTickets/docs/fluentforms-donor-discount.md
Hank fb2fdcb6b8 Add secret-gated public donor-eligibility lookup for checkout discount
GET /api/public/donor-eligibility?key=&email= returns only {eligible, tier}
(member/donor) — no names or dollar amounts — gated by PUBLIC_LOOKUP_SECRET,
rate-limited (30/min), and CORS-restricted to PUBLIC_LOOKUP_ORIGIN. Lets the
FluentForms checkout unlock a donor discount by email. Docs + ready-to-paste
form snippet in docs/fluentforms-donor-discount.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-08 22:09:25 +00:00

4.3 KiB

FluentForms → donor discount lookup

FluentForms has no native way to query an external database from a field. This wires it up with a small Custom JS block that calls our secret-gated endpoint and unlocks a discount when the entered email belongs to a donor/member.

Endpoint

GET https://scan.beartariacampgrounds.com/api/public/donor-eligibility?key=<SECRET>&email=<email>
  • key = the value of PUBLIC_LOOKUP_SECRET (set in the backend .env).
  • Returns minimal JSON — never names or dollar amounts:
    • {"eligible": true, "tier": "member"}
    • {"eligible": true, "tier": "donor"}
    • {"eligible": false, "tier": null}
  • Rate-limited (30/min/IP) and CORS-restricted to PUBLIC_LOOKUP_ORIGIN (default https://tickets.beartariacampgrounds.com).

The secret is visible in page source, so treat this as deterrence, not security. It only gates a discount and reveals a yes/no + tier, so the blast radius is small. Rotate the secret by changing PUBLIC_LOOKUP_SECRET and redeploying.

Form setup

  1. On the ticket form add a Custom HTML element (or use FluentForms Pro's custom JS). Give your email field a known name (default FF email).
  2. Decide the discount mechanism. Two common options:
    • Coupon: configure a coupon in the form's payment settings; the JS auto-fills + applies it for eligible emails.
    • Conditional price: add a hidden field (e.g. donor_tier) and use FluentForms conditional logic to show a discounted payment option when it equals member/donor.
  3. Paste the snippet below into the Custom HTML element, editing the marked constants and the applyDiscount() body to match your form.

Snippet

<div id="donor-status" style="margin:6px 0;font-size:14px;"></div>
<script>
(function () {
  var API = "https://scan.beartariacampgrounds.com/api/public/donor-eligibility";
  var KEY = "REPLACE_WITH_PUBLIC_LOOKUP_SECRET";
  var EMAIL_SELECTOR = 'input[name="email"]';       // adjust to your field
  var statusEl = document.getElementById("donor-status");
  var lastChecked = "";

  function applyDiscount(tier) {
    // ── EDIT THIS to your form's discount mechanism ──────────────────
    // Option A — set a hidden field that conditional logic keys off:
    var hidden = document.querySelector('input[name="donor_tier"]');
    if (hidden) { hidden.value = tier; hidden.dispatchEvent(new Event("change", {bubbles:true})); }
    // Option B — auto-apply a coupon (uncomment + set the code):
    // var coupon = document.querySelector('.ff_coupon_wrapper input[type="text"]');
    // if (coupon) { coupon.value = "DONOR"; coupon.dispatchEvent(new Event("input",{bubbles:true}));
    //   var btn = document.querySelector('.ff_coupon_wrapper button'); if (btn) btn.click(); }
    // ─────────────────────────────────────────────────────────────────
  }
  function clearDiscount() {
    var hidden = document.querySelector('input[name="donor_tier"]');
    if (hidden) { hidden.value = ""; hidden.dispatchEvent(new Event("change", {bubbles:true})); }
  }

  function check(email) {
    if (!email || email === lastChecked) return;
    lastChecked = email;
    statusEl.textContent = "Checking donor status…";
    fetch(API + "?key=" + encodeURIComponent(KEY) + "&email=" + encodeURIComponent(email))
      .then(function (r) { return r.json(); })
      .then(function (d) {
        if (d && d.eligible) {
          statusEl.textContent = (d.tier === "member" ? "🐻 Member" : "⭐ Donor") + " discount applied!";
          statusEl.style.color = "#1b7f3b";
          applyDiscount(d.tier);
        } else {
          statusEl.textContent = "";
          clearDiscount();
        }
      })
      .catch(function () { statusEl.textContent = ""; });
  }

  function bind() {
    var el = document.querySelector(EMAIL_SELECTOR);
    if (!el) { return setTimeout(bind, 500); }   // form may render late
    el.addEventListener("blur", function () { check(el.value.trim().toLowerCase()); });
  }
  bind();
})();
</script>

Test

curl "https://scan.beartariacampgrounds.com/api/public/donor-eligibility?key=<SECRET>&email=adam21stevens@gmail.com"
# -> {"eligible":true,"tier":"member"}