~/alaska-targetingadmin/playbook

Billing playbook

How this dashboard is meant to be used, what payment schemes are available to a consultant, and the architectural reasoning behind the model. Reference doc — read once, search later.

architecture.md
Table of contents (click to expand)
  1. How this is built
  2. Payment schemes available to a consultant
  3. Payment methods (what Stripe accepts)
  4. Recommended workflows by client type
  5. Quick decision tree
  6. Per-template pricing reference (new in M7)
  7. Disputes, refunds, and partial payments (mechanics)
  8. Engagement-letter language (paste-ready) (new in M7)
  9. Refund + cancellation policy (stated terms) (new in M7)
  10. Year-end / tax — incl. Alaska specifics
  11. Admin UI cookbook (new in M7)
  12. Operational sanity
  13. The escape hatch — Stripe Dashboard

# Search the page for "edit me" to find every guess marked for verification.

How this is built

The model is a thin admin on top of Stripe. Stripe holds the canonical state — customers, invoices, payment methods, payment intents, payouts. This admin is your workflow on top of that data: faster invoice creation, opinionated templates, your own dashboard view, branded client portal.

Three reasons it's built this way:

  1. Stripe handles the hard parts. PCI scope, dispute mediation, dunning emails, refund processing, tax calculations, payout scheduling, 1099-K reporting at year-end, fraud detection — none of that lives in our code. We just talk to Stripe's API for everything money-related.
  2. Admin focuses on speed. The Stripe Dashboard is comprehensive but slow — every action takes 3-5 clicks. This admin trades comprehensiveness for the 80% of actions you take repeatedly: create + send invoice from template, look up "did client X pay yet", see outstanding balance. Those should each be one click.
  3. Branded edges. The client-facing pieces (invoice email, hosted pay page, receipt) come from Stripe — but they wear your brand color, logo, sender name, and message. The internal workflow stays on alaskatargeting.com.

What lives where

module SourceOfTruth
  CUSTOMERS         = "stripe"     # customer profiles, payment methods
  INVOICES          = "stripe"     # invoice docs, paid/unpaid, PDFs
  PAYMENTS          = "stripe"     # charges, refunds, disputes
  RECURRING         = "stripe"     # subscriptions, auto-charge schedules
  TEMPLATES         = "alaskatargeting.com" # product + workflow defaults
  CLIENT_PROFILES   = "alaskatargeting.com" # notes, multi-contact, history
  QUOTES            = "alaskatargeting.com" # pre-invoice drafts
  AUDIT_LOG         = "alaskatargeting.com" # who did what when
end

When Stripe's data and our cache disagree, Stripe wins. The admin's local SQLite is a performance + UX layer, not a source of truth.


Payment schemes available to a consultant

Stripe supports a wide range of billing models. The right one depends on what you're selling and what kind of cash flow you want. Most consultancies use 2-3 in combination.

1. One-off project invoice

Use when: Fixed-scope, fixed-fee project. "Build me a polling instrument and crosstabs deck for $12K."

Mechanics: One invoice, one line item, due-by date (typically Net 30 in professional services), client pays via Stripe-hosted page.

Pros: Simple, predictable for both sides. Easy to scope and bill.

Cons: All your cash flow risk is at the end — if the client delays paying, you've already done the work.

Mitigation: Use the next scheme (deposit + balance) for projects over $X.

2. Deposit + balance (50/50 or other split)

Use when: Project amount is large enough that you'd feel exposed delivering without payment. Typical threshold: anything over ~2 weeks of work.

Mechanics: Two invoices — first is "deposit, due on signing" (sent at engagement start), second is "balance, due on delivery" (sent when work product is delivered). Both reference the same project. The deposit is non-refundable in your engagement letter.

Pros: Eliminates the worst cash-flow risk. Filters out clients who aren't serious (anyone who balks at the deposit was going to disappear later).

Cons: Two billing touches per project. Some clients push back on deposits ("we don't pay upfront for services").

3. Monthly retainer (recurring)

Use when: Ongoing strategic advisory, multi-cycle engagements, long-running campaigns.

Mechanics: A Stripe Subscription generates an invoice automatically on the same day every month. Client pays once on initial setup; subsequent months auto-charge their saved payment method (preferred) or send-and-wait email.

Pros: Predictable revenue. Lowest billing overhead (you don't lift a finger after setup). Compounds client lifetime value.

Cons: Hardest scheme to land — clients hesitate to commit to recurring spending. Once landed, surprisingly sticky.

Pricing tip: Retainers should bundle "value of access to you" + "guaranteed minimum deliverables" + "first-priority queue position". The deliverables alone shouldn't equal the retainer amount.

4. Milestone billing

Use when: Longer multi-month projects with natural breakpoints. "Phase 1 plan: $10K. Phase 2 fieldwork: $25K. Phase 3 analysis: $15K."

Mechanics: Issue an invoice at each completed milestone. Client pays per milestone (typically Net 15-30). Engagement letter pre-defines milestones and amounts so it's not a renegotiation.

Pros: Cash flow tracks delivery. Easy to expand/contract scope mid-project (drop a milestone, add a milestone).

Cons: More billing touches. Milestone definitions can be argued ("is the polling complete?").

5. Time + materials (hourly billing)

Use when: Genuinely uncertain scope; client wants to keep you on call.

Mechanics: Track hours, bill monthly (or per project) at an agreed rate. Send invoices with hours-by-day breakdown.

Pros: Pure correlation between effort and revenue. Easy to expand scope (just bill more hours).

Cons: Caps your earning potential at your effective hourly rate — you're trading time for money instead of selling outcomes. Clients scrutinize timesheets. Misaligns incentives: efficient work means lower revenue.

Strong recommendation: Avoid T&M for most consulting work. It's a race to the bottom. Use fixed-fee or value-based pricing whenever you can predict the scope.

6. Value-based / outcome-based

Use when: You can credibly tie your fee to a measurable outcome the client cares about.

Mechanics: "We'll build you the polling + targeting infrastructure for a $X base fee, plus a $Y bonus if the candidate wins by >3 points on the universe we modeled." Or: "$X retainer + a $Y bonus if measured turnout in the target precincts beats baseline by >15%."

Pros: Aligns your incentive with the client's. Justifies premium pricing on the floor. Best clients prefer it.

Cons: Hard to negotiate. Outcomes are noisy (one race lost doesn't mean bad work). Requires careful contract drafting.

7. Pay-what-you-want / suggested donation

Use when: Rarely. Sometimes for community work, pro bono with a tip jar, or initial relationship building.

Mechanics: Use the public /pay/ page with no pre-filled amount. Client decides.

Pros: Zero friction. Surprising upside (people often pay more than you'd quote).

Cons: Unpredictable revenue. Easily abused.


Payment methods (what Stripe accepts)

MethodFee (US)SettlementWhen to use
Card (Visa, MC, Amex, Discover)2.9% + 30¢2 business daysDefault. Use for invoices under ~$5K.
ACH Direct Debit0.8%, capped at $53-5 business daysBig invoices ($5K+) — saves you real money. Slower clearance.
Apple Pay / Google Pay / LinkSame as cardsSame as cardsAuto-shown on supported devices. Free to enable.
Wire transfer$0 to Stripe (bank fees apply)1-2 business daysVery large invoices ($50K+) or international clients. Manual reconciliation — handle outside Stripe.
Klarna / Afterpay5.99% + 30¢Instant to youBNPL. Skip — not a consulting client need.

Practical default for this admin: Card + ACH Direct Debit + Apple/Google Pay + Link, all enabled. Stripe shows the relevant methods to each client automatically based on their device + browser.

Fees in practice — the ACH discount

On a $5,000 invoice paid by card: Stripe takes $145.30 (2.9% + 30¢). Same invoice paid by ACH: Stripe takes $5 (the cap). That's a $140 difference per $5K invoice. For larger invoices the math is even better. If you find yourself sending $10K+ invoices regularly, mention "ACH preferred for the lower fee" in your engagement letter — most B2B clients prefer ACH anyway.


Recommended workflows by client type

Client typeSchemeTemplatePayment method default
Competitive AK federal race (Senate, House, Governor)Retainer + project milestonesretainer_monthly + ad-hocACH (large amounts)
State legislative raceFixed-fee project + tracking pollspolling_wave + polling_trackingMixed
Party committee / DPCC / state partyMonthly retainer (cycle)retainer_monthlyACH auto-charge
501(c)(4) / advocacy orgProject-basedvoter_file_targeting, polling_waveACH
One-off RFP responseFixed-fee deposit + balancecustom_project (split into 2)Card OK
Friend / introductoryOne-off ad-hocintelligence_brief or custom_one_offCard

When to use what — quick decision tree


Per-template pricing reference

The seven Stripe templates and what each one is meant to represent. Default amounts came from the initial template seed — [edit me: verify each price against your actual current rates before using these in quotes]. Adjust per-client at quote/invoice time as needed.

TemplateDefaultWhat's includedCommon modifiers
retainer_monthly
Monthly strategic advisory
$15,000/mo [edit me] Bi-weekly strategy call, ad-hoc memos as situations develop, first-priority queue position, light/unscheduled data pulls. Annual prepay → 1 month free. Half-cycle (90-day) engagement → 10% premium per month. Add project line items on top for polling, voter-file work, etc.
polling_wave
Single benchmark or message-test poll
$12,000 [edit me] N=400 likely-voter sample, instrument design (~12 min), live fielding, weighted toplines + crosstabs, narrative memo. Larger N (+$X per 100 LVs), regional oversamples, longer instrument, multi-language fielding.
polling_tracking
Repeat tracking wave on existing instrument
$8,000 [edit me] N=300 LV on the previously-fielded instrument, weighted toplines + brief delta memo. Requires a prior polling_wave. Larger N, daily tracking (separate pricing structure), regional booster.
voter_file_targeting
Universe + score build
$7,500 [edit me] LV propensity model, persuasion model, contact universe build, export to client's vendor (L2, NGP, etc.) + methodology memo. Multiple race-specific universes, custom score features, refresh after each voter-file update.
field_program
GOTV plan + collateral
$10,000 [edit me] Door universe, walk + call lists, script design, daily tracking dashboard. Does NOT include canvassers themselves. Larger universe, mail integration, multi-jurisdiction.
bisg_imputation
Race imputation pass
$3,500 [edit me] BISG join on a provided list, sensitivity check vs. self-ID where available, output CSV + methodology memo. Multiple lists, BIFSG instead of BISG, ensemble approach.
intelligence_brief
One-off research memo
$2,500 [edit me] Topic-focused research, ~5-page memo with citations, single revision. Weekly monitoring rhythm → escalate to retainer_monthly instead. Rush turnaround (<72h) → +50%.

How modifiers work in this admin: The default amount populates when you pick a template at /admin/invoices/new or /admin/quotes/new. Either edit the line item to the modified amount, or add additional line items below. The template metadata (key, product, price) sticks with the invoice for reporting even when you tweak the dollar amount.


Disputes, refunds, and partial payments

Refunds

Issued from /admin/invoices/<id> or Stripe Dashboard. Full or partial. Stripe deducts from your next payout. The original processing fee is non-refundable on full refunds before Aug 2023 (current policy: Stripe refunds the fee). Refunds typically settle to client's card in 5-10 days. Document the reason in your audit log so future-you knows.

Voiding unpaid invoices

An unpaid invoice (status: open, past_due, or uncollectible) can be voided. Voiding marks it as null — client gets a "this invoice has been voided" email. Use when you've decided not to bill, or you've discovered an error after the invoice was sent. If you need to fix an error and still bill, void + reissue with the correction.

Partial payments

Stripe Invoicing supports them. Useful when a client wants to pay half now, half later, and you're flexible. Mark collection_method=send_invoice and set allow_partial_payment=true. The invoice stays in open status with the remaining balance until fully paid.

Disputes (chargebacks)

If a client disputes a card payment, Stripe holds the disputed amount and gives you 7-14 days to submit evidence. Win rate depends entirely on the quality of your evidence — invoice PDF, engagement letter, email confirming acceptance, work product delivered. Always keep clean email records and signed engagement letters; they're 90% of what wins a dispute. Stripe sends an email when a dispute opens; respond within 24 hours.


Engagement-letter language (paste-ready)

Boilerplate paragraphs to drop into a Word/PDF engagement letter or paste into a Stripe quote memo. All of this is a starting point — have your attorney review before relying on any of it for a real engagement. Bracket markers [like this] are placeholders you fill per-engagement.

Scope of work (template)

Alaska Targeting will provide [scope of services — be specific].

Deliverables:
  - [Deliverable 1, e.g., "Topline + crosstabs in PDF"]
  - [Deliverable 2, e.g., "Narrative memo, 5-7 pages"]
  - [Deliverable 3, optional]

The engagement begins [start date] and concludes upon delivery
of the final deliverable above or [end date], whichever occurs first.
Changes to scope require written agreement and may incur additional fees.

Payment terms (template)

Total fee: [$amount], billed via Stripe invoice.

Schedule: [Pick one]
  (a) 100% on delivery (Net 30)
  (b) 50% deposit on signing, 50% on delivery (each Net 30)
  (c) Monthly retainer, [$X]/month, auto-charged on the
      [1st] of each month via ACH

Late fee: [edit me: 1.5%/mo compounding] on amounts
unpaid past 30 days from invoice date.

Preferred payment method: ACH Direct Debit. Card accepted; client
bears the convenience-fee differential [edit me: optional clause].

Termination

Either party may terminate this engagement with [30] days'
written notice. Upon termination:

  - Client owes payment for all work performed through the
    termination date, plus any non-cancellable third-party costs
    (e.g., voter file licenses, polling field costs already incurred).

  - Deposits paid for fixed-fee work are [non-refundable].
    For terminated retainers, see "Refund + cancellation policy" below.

  - Alaska Targeting will deliver any work product completed but
    not yet delivered as of the termination date, within
    [14] days, in exchange for payment per the above.

IP & data ownership

All work product (memos, analyses, models, voter file builds,
target universes) becomes Client's property upon full payment.

Alaska Targeting retains the right to:
  (a) reference the engagement in case studies (Client name omitted
      unless separately authorized),
  (b) use de-identified, aggregate methodological learnings in
      future work,
  (c) retain working files for [3] years for reference and
      potential dispute response.

Third-party datasets (e.g., L2 voter file, NGP/VAN data) remain
governed by their original vendor licenses. Client is responsible
for any data-license costs accrued during the engagement unless
otherwise specified.

Confidentiality

Both parties agree to keep confidential any non-public information
shared during the engagement, including polling cross-tabs,
strategic plans, donor lists, and internal client decision-making.

This obligation survives termination indefinitely for strategic
plans and [5] years for all other materials. Either party may
disclose confidential information if required by law, court order,
or regulatory inquiry, with prompt notice to the other party.

Limitation of liability

Alaska Targeting's total liability under this engagement is
limited to fees paid by Client in the [6] months preceding
the claim. Neither party is liable for indirect, consequential,
or punitive damages (lost election, lost donor relationships,
campaign opportunity costs, etc.).

[edit me: have your attorney decide whether to also include a
disclaimer of warranties about polling accuracy, model performance,
or election outcomes — these are noisy by nature].

Refund + cancellation policy (stated terms)

This is the policy you tell clients on request, distinct from the mechanics of how to issue a refund (above). Default values below are starter language — [edit me: confirm each one matches what you actually want to offer].

Engagement typeIf client terminatesIf you terminate
Monthly retainer Pro-rated refund through termination date, less a [one-month] minimum. [edit me] Pro-rated refund through termination date, no minimum.
Fixed-fee project (deposit + balance) Deposit non-refundable. Balance owed for [75%] of work performed. [edit me] Deposit non-refundable. Balance billed only for work delivered.
Time + materials Billed for hours worked through termination date. Billed for hours worked through termination date.
Pay-what-you-want / /pay/ page Refund on request within [14] days. [edit me] N/A.

Disputed work

Client may withhold disputed amounts pending good-faith resolution. Disputes unresolved after 30 days are subject to [binding arbitration under Alaska state law, venue Anchorage]. [edit me]

Stripe processing fees

Stripe currently refunds processing fees on full refunds issued within 90 days of payment. Partial refunds retain the original fees. Built into the math — no special action required.


Year-end / tax

Stripe issues you a 1099-K in January for any year where you process >$5,000 in payments (federal threshold; some states are lower). Available in Dashboard → Reports.

For your own accounting, export the full year's payment activity from /admin/invoices/ (CSV export, all-time view — [edit me: CSV export isn't built yet; M8 may add it. For now pull from Stripe Dashboard → Reports → Billing]). Hand to your accountant.

This admin doesn't (yet) sync to QuickBooks / FreshBooks. If you start needing that, Stripe has a few official integrations that work without our involvement (Stripe → QuickBooks Online sync at dashboard.stripe.com/apps).

Alaska tax landscape (sole-operator perspective)

Alaska is friendlier than most states for a solo consultant. [edit me: have your accountant confirm every line below against your actual entity setup (sole prop / LLC / S-corp) and municipality].

Tax / feeWhat you oweWhen
State income taxNone — Alaska doesn't have one.
State sales taxNone at the state level. Some municipalities charge local (Juneau 5%, Soldotna 3%, Wasilla 2.5%). Anchorage and Fairbanks: 0%. Consulting services are usually exempt regardless — [edit me: verify with your accountant for your municipality + service mix].
AK Business License$50/year from AK Dept of Commerce, Division of Corporations, Business and Professional Licensing.Annual renewal (Dec 31).
Federal income taxSchedule C on personal 1040 (sole prop or single-member LLC). S-corp election changes the math — [edit me].Annually, April 15.
Federal quarterly estimated taxForm 1040-ES. Pay 25% of estimated annual liability each quarter to avoid underpayment penalty.Apr 15, Jun 15, Sep 15, Jan 15.
Self-employment tax15.3% (12.4% Social Security + 2.9% Medicare) on net earnings up to the SS wage base; 2.9% Medicare-only above. Add 0.9% Additional Medicare over $200K solo / $250K MFJ. Half deductible on personal 1040.Computed with annual return.
1099-K (issued to you by Stripe)Auto-issued in January for >$5K processed (federal). State thresholds vary.Arrives Jan 31.
1099-NEC (you issue to others)Required for any contractor / subcontractor you pay >$600 in a year. File with IRS + send to contractor. [edit me: relates to deferred M3 Stripe Connect feature if you ever pay subs].Send by Jan 31.

Common deductions worth tracking through the year

[edit me: confirm with your accountant before relying on any line above — deductibility depends on entity structure, audit-defense posture, and personal/business commingling tests].


Admin UI cookbook

Click trails for the actions you'll take most often. Everything here can also be done in the Stripe Dashboard — these are the shortcuts.

Send a payment reminder

/admin/invoices/ → click the invoice → click Send reminder → confirm. Triggers Stripe to re-email the hosted pay page link to the client.

Mark an invoice paid out-of-band (check, wire, cash)

/admin/invoices/ → open invoice → Mark paid (out of band) → confirm. Stripe records the invoice as paid without moving money. Use only when payment really did arrive via a non-Stripe channel.

Refund (partial or full)

/admin/invoices/ → open invoice (must be in paid status) → Refund → enter amount (blank = full) → confirm. Final. Stripe deducts from your next payout. Refunds typically settle to the client's card in 5-10 days.

Generate + share a client portal link

/admin/clients/ → click client → scroll to the portal.yml block → click Copy → paste into your email to the client. They land on a friendly page showing their open invoices with "Pay now" buttons, pending quotes, and downloadable past receipts. No login required. Treat the URL as a shared secret — anyone with it can see the account.

Send a quote, then convert to invoice on accept

/admin/quotes/new → fill out the 5-step form → Finalize + send PDF. Stripe generates a signable PDF and emails the client. When they accept (or you mark accepted on their behalf from /admin/quotes/detail/?id=…), Stripe auto-creates the invoice. It appears in /admin/invoices/ within seconds via the webhook.

Duplicate an invoice (rebill for the same thing)

/admin/invoices/ → open invoice → Duplicate as new draft. Copies line items, client, template. New invoice opens in draft — edit if needed, then send.

Void an invoice sent in error

/admin/invoices/ → open invoice → Void → confirm. Final. Client gets a "this invoice has been voided" email automatically. If you need to fix and rebill, click Duplicate as new draft first, then void the original.

Find a client fast

/admin/clients/ → use browser find (Cmd-F on Mac, Ctrl-F on Windows) on the client list. Or filter the invoice list at /admin/invoices/ by client name (use the filter tabs + browser find together).

Check who did what (audit trail)

/admin/audit/ → most recent 100 audit events with actor (your CF Access email), action (create / void / refund / etc.), resource (invoice / quote / client), and timestamp.

Confirm CF Access is wired (debugging)

/api/admin/whoami → returns {ok: true, email: "..."} if your Cloudflare Access session is healthy. 401 means re-login needed.


Operational sanity


The escape hatch — Stripe Dashboard

Everything this admin does, you can also do directly in the Stripe Dashboard. If anything here breaks or you want to do something the admin doesn't support yet, dashboard.stripe.com is always available. Your data is never lost.