Skip to content

Integration cookbook

Audience: customer engineering team adapting Evospin for a new deployment. Sibling: the existing recipes in this directory (add-rest-endpoint.md, add-prisma-model.md, …) are internal "add a thing" patterns. This cookbook covers the customer-shaped customisations — swap a provider, add a game, change branding, add a locale.

Each recipe is grounded in a real extension point that already exists in the codebase, with file paths verified by grep at the time of writing (2026-04-25). A recipe that depends on a {{TBD}} interface (i.e. the pattern exists but the abstraction is not formalised) calls that out explicitly so customers can plan friction.

How to use this cookbook

  1. Skim the index below. Pick the recipe whose goal matches your customisation.
  2. Check the prerequisites. Most recipes assume the doppler / database / observability stack is already running locally — see docs/onboarding/ and docs/business/integration-options.md for "is this customisation in our supported pattern?".
  3. Follow the sub-recipe end-to-end. Each recipe ends with a verification step.
  4. Cross-link to the relevant SOT artefact: API surface in docs/api-reference/, data model in docs/data-model/, env keys in docs/env-reference.md.

Recipes

# Goal Recipe Time Files touched Prerequisites
1 Add a new payment provider (analogous to CCPAYMENT / NowPayments / SkinDeck) add-payment-provider.md 1–2 days code + 1–3 weeks integration testing apps/api/src/payment/provider/integration/<name>/, Doppler, Prisma PaymentProviderName enum, docs/api-reference/api.md entry Provider sandbox creds, signed integration agreement, jurisdictional approval
2 Add a new house game (analogous to dice / plinko / mines / limbo) add-game.md 2–4 days backend + 2–4 days frontend apps/api/src/casino/house/<game>/, libs/games/src/house-games.config.ts, ebit-fe/src/app/[locale]/games/originals/<game>/, BullMQ producer if async settlement Game spec (RTP, RNG rule), provably-fair sign-off, art assets
3 Customise branding for a white-label deployment customize-branding.md 0.5–2 days ebit-fe/public/, ebit-fe/src/styles/, ebit-fe/messages/{locale}.json, SendGrid templates, domain DNS Brand kit (logo set, colour tokens, fonts), customer copy review
4 Add a new external game-provider integration (analogous to PM8 / ST8 / BGaming / Evogames) add-game-provider-integration.md 1–3 weeks apps/api/src/casino/slots/providers/<provider>/, signature/auth module, wallet RPC, webhook controller, Doppler Provider technical onboarding, HMAC/JWT scheme docs, jurisdictional whitelist
5 Add a new language to dropbet add-locale.md 0.5–1 day code + 1–2 weeks translation ebit-fe/src/i18n/routing.tsx, ebit-fe/messages/<locale>.json, optional RTL CSS, SendGrid template variants Reviewed translation file, locale code (BCP-47), date/number-format spec
6 Replace the KYC vendor (Sumsub → another) swap-kyc-provider.md 1–2 weeks code + 2–4 weeks compliance apps/api/src/kyc/, Doppler SUMSUB_* keys, webhook handler, KYC state machine Compliance / legal sign-off, vendor sandbox, jurisdictional KYC matrix
7 Toggle a feature flag for a customer enable-feature-flag.md minutes (toggle) — 1 day (new flag) GitLab Unleash UI, apps/api/src/system/feature-flag/, frontend feature-flag client GitLab Unleash project access, flag naming convention agreed
8 Add a new currency (fiat or crypto) change-currency-or-add-currency.md 1–2 weeks Prisma CurrencySymbol enum, exchange-rates provider config, payment provider mapping, FE currency picker CoinGecko id (or alternative rate source), payment provider support per currency, jurisdictional approval

Selection criteria

Use the table above to filter by what you need; here are the common triage paths:

  • "Customer wants to launch in a new region" — almost always recipes 3 (branding) + 5 (locale) + 6 or 7 (KYC + feature flags) + 8 (currency). Plan for 4–8 weeks.
  • "Customer wants to add their own crypto wallet" — recipe 1 (payment provider). Plan for 1–3 weeks plus regulatory.
  • "Customer wants to expand their game catalogue" — recipe 2 (house game) for in-house, or recipe 4 (external provider) for licensed content.
  • "Customer wants to A/B test a feature" — recipe 7 (feature flag).
  • "Customer wants to swap our KYC for theirs" — recipe 6, but this is the highest-friction customisation; review the friction notes in the recipe before quoting.

Cross-cutting prerequisites

Every recipe assumes:

  • The local stack is running (ebit-api/ and ebit-fe/ per docs/onboarding/ day 1).
  • Doppler config for the relevant project is accessible (DOPPLER_TOKEN exported per docs/env-reference.md §Doppler).
  • The customer has signed off on the architectural change, not just the technical task — recipes 1, 4, 6, 8 in particular have compliance / commercial implications that must be cleared before code lands. See docs/delivery/prerequisites.md and docs/delivery/risks.md.
  • For any change that touches the public API, the change is reflected back into the SOT: regenerate the OpenAPI snapshot + Postman collection per docs/api/sync-postman.sh and append a docs/api/changelog.md entry.

Conventions used in the recipes

  • File paths follow the STYLE guidepath:line format relative to the relevant repo root (ebit-api/, ebit-fe/, ebit-admin-fe/).
  • Code blocks are annotated with the destination filename in a comment on line 1.
  • "Canonical example" in each recipe points at the existing implementation that you copy and adapt — never write the integration from scratch.
  • Compliance / commercial / external-blocker steps are tagged [non-engineering] so a code-only contributor can spot them and route to the right team.
  • Each recipe ends with a Verification section listing the curl / log line / dashboard panel to confirm the integration is live.

Friction map (where customers will hit the most resistance)

These are the three recipes where the abstraction is least formalised and customers should expect to push code into shared modules, not just add their own:

  1. Recipe 1 (payment provider) — there is no PaymentProviderInterface in the strict sense; each provider gets its own module + service + webhook controller, and the routing through PaymentProviderService is hand-wired in apps/api/src/payment/provider/payment-provider.module.ts. Adding a fourth provider means editing the central module, not just adding a folder. Customer friction: medium.
  2. Recipe 4 (game provider integration) — same shape as recipe 1, but with extra work because the wallet RPC crosses services via Redis pub/sub (ExternalControllerClient) and the OTel context is not propagated (see docs/audits/perf-trace-coverage-audit.md §"transport gap"). Customer-side debugging will require correlating by user/session id, not trace id. Customer friction: high.
  3. Recipe 6 (swap KYC vendor) — the current Sumsub abstraction lives at apps/api/src/kyc/ but is vendor-specific, not a strategy pattern. Replacing Sumsub means rewriting most of the KYC module, not swapping a class. Customer friction: very high; quote 4+ weeks.

Runnable examples (sibling)

For copy-paste-ready TypeScript samples that complement the recipes above, see ../../code-examples/:

Folder Pairs with
auth/ every recipe — gives you a logged-in session
webhooks/ recipe 1 (payment provider), recipe 4 (game provider), recipe 6 (KYC vendor)
partner-integration/ recipes 1, 2, 4, 8 — smoke test after the integration lands
observability/ add-otel-span.md
websocket-client/ any UI customisation that needs live balance / bet / chat events
load-test-clients/ recipes 1 / 2 / 4 / 8 — validate your customisation under load

Each folder is self-contained (npm install && npm run tsc) and verified with npx tsc --noEmit.