Kasha POS
Accept Every Payment. Grow Faster.
A complete payment acceptance platform purpose-built for SME merchants in Switzerland and Brazil. From tap-to-pay cards to local mobile wallets, instant settlement to credit anticipation — everything a small business needs to get paid, in one place.
Executive Summary
The Starting Point
Kasha has zero clients today. We are building from scratch, which means every product decision must be laser-focused on what wins an SME merchant in the first meeting. There is no legacy to protect, no existing base to migrate — just a blank canvas and the urgency to ship something that merchants actually want to pay for.
This is NOT just a card terminal. Card acceptance is table stakes — every competitor already does it. Kasha POS is a full payment acceptance platform that covers the entire spectrum of how SME merchants get paid:
- Cards (tap & go via Adyen) — Visa, Mastercard, Amex, PostFinance. NFC contactless on the merchant's own phone (SoftPOS / Tap to Pay) or via a connected terminal.
- QR & mobile payments — CH TWINT (Switzerland's #1 mobile wallet, 5M+ users), BR Pix (Brazil's instant payment rail, 150M+ users).
- Open banking (direct IBAN settlement) — Bypass card networks entirely. Merchants receive funds directly into their bank account via SIC (CH) or Pix (BR), cutting fees to near zero.
- Payment anticipation (credit) — Killer differentiator. Merchants can advance their future card receivables and get cash today. In Brazil, this is a R$200B+ annual market. In Switzerland, it is virtually non-existent — a greenfield opportunity.
The Vision: "Square but Broader"
Think of Square, but designed from day one for multi-market, multi-payment-method reality. Square succeeded by making card acceptance dead simple for small businesses in the US. But in Switzerland and Brazil, cards are only part of the story. TWINT and Pix are dominant local rails that Square doesn't touch.
Kasha POS is a single platform where any small business can accept any local payment method, get settled fast, and access credit based on their sales history. The merchant doesn't need to juggle three different apps, two different terminals, and a separate lending relationship. One app. One dashboard. One settlement account. One credit line.
The credit piece is what transforms Kasha from a payment tool into a financial platform. A merchant who depends on Kasha for both payments and working capital is a merchant who never churns.
Market Analysis
CH Switzerland
Demographics & Economy
- Population: 8.8 million
- GDP per capita: ~$93,000 (among the highest globally)
- Currency: Swiss Franc (CHF)
- Languages: German, French, Italian, Romansh
- Digital readiness: Extremely high; smartphone penetration >95%
Payment Landscape
- Cards dominate POS: Visa, Mastercard, and PostFinance Card are the primary card schemes. Amex has limited but growing acceptance. Debit cards (Visa Debit, Debit Mastercard) have largely replaced the legacy Maestro network.
- TWINT is #1 mobile payment: Over 5 million active users (in a country of 8.8M). Peer-to-peer, in-store QR, e-commerce. Backed by major Swiss banks. Growing 30%+ YoY in transaction volume. Merchants pay 0.5–1.0% per transaction.
- Apple Pay / Google Pay: Growing rapidly for contactless in-store payments. Ride on existing card rails (Visa/MC), so no separate merchant integration needed — just NFC terminal support.
- Cash declining but not dead: Still ~30% of POS transactions by volume, especially in German-speaking Switzerland and for low-value purchases.
SME Landscape
- 600,000+ SMEs (99.7% of all companies)
- Legacy terminal providers: SIX Payment Services (now Worldline) dominates with traditional hardware terminals. Long contracts (24–36 months), high fees (1.5–2.5%), opaque pricing.
- Pain points: Expensive hardware rental (CHF 30–80/month), slow settlement (T+2 standard), no integrated analytics, separate TWINT setup required, no credit products.
- SoftPOS is new: Apple Tap to Pay launched in CH in 2023. Very few providers offer it natively. Most merchants still don't know they can accept cards on their iPhone without extra hardware.
Kasha Opportunity in CH
- SoftPOS Modern Tap to Pay on iPhone/Android — zero hardware cost
- TWINT Native integration via Adyen (most competitors require separate setup)
- Lower fees 1.2–1.5% via Adyen vs. 1.5–2.5% legacy
- Fast settlement T+1 or same-day vs. industry-standard T+2
- Anticipation Virtually no competitor offers receivables-based credit to SMEs at POS level
BR Brazil
Demographics & Economy
- Population: 215 million
- GDP per capita: ~$9,000
- Currency: Brazilian Real (BRL)
- Language: Portuguese
- Digital readiness: High; 170M+ smartphone users, Pix adoption is world-leading
Payment Landscape
- Pix dominates everything: 150M+ registered users (70% of the population). Instant, 24/7, near-zero cost. QR-code based at POS. Launched by Banco Central do Brasil in Nov 2020 and has already surpassed cards in transaction count. Merchants love it because settlement is instant and fees are minimal (0–0.5%).
- Cards still strong for installments: Brazil's unique "parcelamento" (installment) culture means consumers routinely split purchases into 2–12 monthly installments on their credit card. Merchants absorb the cost but gain higher average tickets. This creates the receivables that drive the anticipation market.
- Pix Tap to Pay: Launched February 2025 by Banco Central. Allows NFC-based Pix payments (no QR code needed). Game-changer for speed at POS. Early adoption phase.
- Boleto declining: Traditional bank slip payment. Still used for e-commerce and billing but declining at physical POS. Settlement T+1, flat fee ~R$3.50.
- Crypto/stablecoins emerging: BRZ (Brazilian Real stablecoin by Transfero) enables instant, low-cost settlement. Growing ecosystem of merchants accepting crypto, especially in tech-forward segments.
SME Landscape
- 20M+ micro and small businesses (MEI + ME + EPP categories)
- Underbanked: Many micro-merchants have limited banking relationships. POS providers (maquininhas) like Stone, PagSeguro, Cielo, and Mercado Pago are often their primary financial touchpoint.
- Credit-dependent: Small merchants in Brazil live and die by "antecipacao" (receivables anticipation). When a customer pays in 6 installments, the merchant doesn't see that money for 6 months — unless they advance it. Anticipation rates range from 1.5–3.5% per month.
- High competition: Stone, PagSeguro, Cielo, Rede, Mercado Pago, Sumup, InfinitePay all compete aggressively. Differentiation is hard on payments alone — credit and ecosystem services are the battleground.
Kasha Opportunity in BR
- Pix Tap to Pay Early mover on NFC-based Pix (launched Feb 2025)
- Anticipation R$200B+ annual market. Offer competitive rates via Transfero rails.
- Crypto settlement BRZ stablecoin via Transfero — instant settlement, hedge against BRL volatility
- Integrated platform Most competitors are payment-only. Kasha bundles POS + credit + banking.
- WhatsApp integration Critical channel for Brazilian SMEs. Receipts, notifications, booking confirmations all via WhatsApp.
Market Comparison
| Feature | CH Switzerland | BR Brazil |
|---|---|---|
| Population | 8.8 million | 215 million |
| GDP per capita | ~$93,000 | ~$9,000 |
| SME count | 600,000+ | 20,000,000+ |
| Dominant local payment | TWINT (5M+ users) | Pix (150M+ users) |
| Card installments | Not common | Essential (parcelamento, 2–12x) |
| Settlement standard | T+2 (legacy), T+1 (modern) | T+1 cards, instant Pix |
| Anticipation market | Virtually non-existent | R$200B+ annually |
| Primary PSP | Adyen | Transfero + Adyen |
| Crypto settlement | Not planned (Phase 4+) | BRZ stablecoin via Transfero |
| Regulatory environment | FINMA-regulated, strict AML/KYC | Banco Central-regulated, Pix mandated |
| Average POS ticket | CHF 25–50 | R$30–80 |
| Key messaging channel | Email / SMS | WhatsApp (mandatory) |
| Competitive landscape | SIX/Worldline (legacy), SumUp | Stone, PagSeguro, Cielo, Mercado Pago |
| Kasha wedge | SoftPOS + TWINT + lower fees | Anticipation + Pix Tap + crypto |
Merchant Personas & Use Cases
Six representative merchant personas that define our target segments. Each persona includes their daily reality, pain points, and the exact POS flow Kasha would provide. These personas drive every product decision — if a feature doesn't help at least two of these merchants, we don't build it.
Rosa's Hair Salon
BR Solo EntrepreneurProfile
- Business: Solo barber / hairdresser in Sao Paulo suburb
- Daily volume: 15 clients/day, average ticket R$45
- Current payments: Pix (70%), cash (25%), occasional card (5%)
- Tech: Android smartphone, WhatsApp for all client communication
- Booking: Clients book via WhatsApp messages (no formal system)
- Pain point: Cannot accept card payments without expensive maquininha. Loses clients who don't have Pix or cash. No idea what her daily revenue actually is until she counts cash at night.
What Rosa Needs from Kasha
- Accept card payments on her phone (SoftPOS / Tap to Pay)
- Generate Pix QR codes from the app (not her bank app)
- Track which client paid and for what service
- See daily revenue in real-time (not end-of-day counting)
- Send receipts via WhatsApp automatically
- Access anticipation when she needs cash for supplies
POS Flow
Modules Used
POS CRM Banking Anticipation
Marco's Phone Repair
CH Service + DepositsProfile
- Business: Mobile phone & electronics repair shop in Zurich
- Daily volume: 8–10 repair jobs/day, average ticket CHF 120
- Current payments: Card (60%), TWINT (25%), cash (15%)
- Tech: iPhone, iPad at counter, simple website with booking form
- Booking: Online form + walk-ins. Inspection first, then quote.
- Pain point: Collects deposits manually (TWINT to personal account), then has to remember who paid what. No link between the repair job and the payments. Loses track of partial payments. Sends invoices via PDF email — clunky and often unpaid.
What Marco Needs from Kasha
- Create a "booking" / repair job in POS linked to client
- Collect deposit (e.g., 50% upfront) linked to that job
- Track partial payment status: deposit paid, remaining due
- Send professional invoice for remaining amount via email/SMS
- Accept TWINT natively in the same app (no separate TWINT setup)
- End-of-day reconciliation: what's collected vs. outstanding
POS Flow
Modules Used
POS Bookings Invoicing CRM Banking
Ana's Boutique
BR Retail + CatalogueProfile
- Business: Small fashion boutique in Belo Horizonte, 30+ SKUs
- Daily volume: 10–20 sales/day, average ticket R$95
- Current payments: Card with installments (50%), Pix (35%), cash (15%)
- Tech: Android phone, Instagram for marketing, no POS system
- Inventory: Managed in a notebook. Often sells items she doesn't have, or doesn't know what to restock.
- Pain point: No connection between what she sells and what's in stock. Card installments (parcelamento) mean she doesn't get the money for months. Wants to sell on Instagram/WhatsApp but has no online catalogue linked to payments.
What Ana Needs from Kasha
- Light catalogue / product management (name, price, photo, quantity)
- POS linked to catalogue — selecting an item decrements stock
- Accept card installments (parcelamento up to 12x)
- Restock alerts when items fall below threshold
- Anticipate installment receivables to maintain cash flow
- Shareable product links for Instagram/WhatsApp sales
POS Flow
Modules Used
POS Catalogue Banking Anticipation CRM
Thomas's Bakery
CH High Volume / Quick ServiceProfile
- Business: Neighbourhood bakery in Bern, 2 employees
- Daily volume: 100+ transactions/day, average ticket CHF 8
- Current payments: TWINT (40%), card (35%), cash (25%)
- Tech: iPad at counter, printed TWINT QR code taped next to the register
- Speed is everything: Morning rush (7–9 AM) sees 40+ transactions in 2 hours. Any friction = lost customers.
- Pain point: TWINT QR is static (personal account), so he can't see which TWINT payment matches which sale. Card terminal is slow (chip insert, wait, sign). End-of-day reconciliation takes 30+ minutes. No real-time view of how the day is going.
What Thomas Needs from Kasha
- Ultra-fast checkout: tap card or scan TWINT in under 5 seconds
- Dynamic TWINT QR (amount pre-filled, auto-matched to transaction)
- Quick item buttons (Croissant CHF 3.50, Coffee CHF 4.80, Bread CHF 6.00)
- Real-time sales dashboard (live counter: transactions, revenue, payment split)
- One-tap end-of-day reconciliation report
- Optional receipt (most customers don't want one for CHF 3.50 croissant)
POS Flow
Modules Used
POS Banking
Fernanda's Nail Studio
BR Anticipation Power UserProfile
- Business: Nail salon in Rio de Janeiro, 2 nail techs + Fernanda
- Daily volume: 12–18 appointments/day, average ticket R$80
- Current payments: Card (55%, mostly credit with installments), Pix (35%), cash (10%)
- Tech: iPhone, WhatsApp Business for appointments, PagSeguro maquininha
- Booking: Appointment-only. Clients book via WhatsApp. 30% deposit required.
- Pain point: Credit anticipation is her #1 need. 55% of revenue comes through credit cards with 30-day receivables (or longer with installments). She can't pay her nail techs or buy supplies without advancing those receivables. Current anticipation rate is 3.2%/month with PagSeguro. She feels trapped.
What Fernanda Needs from Kasha
- Appointment/booking management with deposit collection
- Split payments: 30% deposit at booking (Pix), 70% at service (card)
- Clear view of receivables: what's coming, when, from which cards
- Anticipation: select receivables to advance, get funds next business day
- Competitive anticipation rates (target: 1.8–2.5%/month vs. 3.2% at PagSeguro)
- WhatsApp appointment reminders + payment links
POS Flow
Modules Used
POS Bookings Banking Anticipation CRM
Lucas's Café + Coworking
CH Hybrid Business ModelProfile
- Business: Café on ground floor, coworking space upstairs, in Lausanne
- Daily café volume: 60–80 transactions/day, average ticket CHF 12
- Coworking: 20 desks, CHF 250/month per desk, 15 active members
- Current payments: Card (50%), TWINT (30%), cash (20%) for café; bank transfer for coworking
- Tech: MacBook, iPad at café counter, iPhone
- Pain point: Two completely separate revenue streams managed in two separate systems. Café POS (SumUp) has no concept of subscriptions. Coworking billing done manually via email invoices. No unified view of total business revenue. Chasing coworking payments is time-consuming.
What Lucas Needs from Kasha
- Quick POS for café (same as Thomas's bakery — speed is key)
- Recurring billing for coworking subscriptions (monthly auto-charge)
- Unified dashboard: café revenue + coworking revenue in one view
- Split reporting by revenue type (food/drink vs. coworking)
- Automatic payment reminders for overdue coworking invoices
- Member management: who's active, who's churning, who's late on payment
POS Flow (Café)
Subscription Flow (Coworking)
Modules Used
POS Invoicing Banking CRM
Use Case Matrix
Mapping each core use case to the personas it serves and the Kasha modules required.
| Use Case | Persona(s) | Payment Flow | Modules Involved |
|---|---|---|---|
| Quick checkout (single payment) | Rosa, Thomas, Lucas (café) | Select items/amount → pay (card tap or QR) → receipt → done | POS Banking |
| Deposit + final payment (split) | Marco, Fernanda | Create job/booking → collect deposit → service → collect remainder | POS Bookings Invoicing CRM Banking |
| Card installments (parcelamento) | Ana, Fernanda | Select items → customer chooses installment count → card payment split over months | POS Banking |
| Catalogue / inventory sale | Ana | Select items from catalogue → pay → stock decremented → restock alert | POS Catalogue Banking |
| Receivables anticipation | Rosa, Ana, Fernanda | View receivables → select amount to advance → confirm → funds next day | Anticipation Banking |
| Recurring billing / subscriptions | Lucas (coworking) | Create subscription → auto-charge monthly → reminder on failure → retry | Invoicing CRM Banking |
| Invoice & payment link | Marco, Lucas | Create invoice → send link (email/SMS/WhatsApp) → customer pays online → confirmed | Invoicing Banking |
| End-of-day reconciliation | All personas | Tap "Close day" → see all transactions by method → match to settlements → export | POS Banking |
| Client/CRM management | Rosa, Marco, Fernanda, Lucas | Track client history, payment patterns, last visit, lifetime value | CRM |
| WhatsApp receipts & notifications | Rosa, Ana, Fernanda (BR personas) | Payment confirmed → auto-send receipt + thank you via WhatsApp | POS CRM |
Payment Methods Matrix
Complete overview of every payment method Kasha POS will support, organized by rollout phase. Each method includes the country, provider integration, settlement timeline, indicative fees, and implementation phase.
Full Payment Methods Table
| Payment Method | Country | Provider | Settlement | Fee (indicative) | Status |
|---|---|---|---|---|---|
| Cards (Visa / Mastercard / Amex) | CH BR | Adyen | T+1 (CH), T+1 (BR) | 1.2–1.8% | Phase 1 |
| TWINT | CH | Adyen | T+1 | 0.5–1.0% | Phase 1 |
| Apple Tap to Pay | CH BR | Adyen | T+1 | Included in card fee | Phase 1 |
| Pix (QR Code) | BR | Transfero | Instant | 0.5% | Phase 1 |
| Pix Tap to Pay (NFC) | BR | Transfero | Instant | 0.5% | Phase 2 |
| PostFinance Card | CH | Adyen | T+1 | 0.8% | Phase 2 |
| Open Banking (SIC / eBill) | CH | Direct IBAN | Same-day | CHF 0.20 flat | Phase 2 |
| Boleto Bancário | BR | Transfero | T+1 | R$3.50 flat | Phase 3 |
| BRZ Stablecoin | BR | Transfero | Instant | 0.3% | Phase 3 |
| Crypto (BTC / ETH / USDC) | BR | Transfero | Via BRZ conversion | 1.0% | Phase 4 |
Payment Strategy: Local First, Cards Always
Accept local payment methods first (TWINT for Switzerland, Pix for Brazil), then expand. Card acceptance is table stakes — every competitor already does it, and merchants expect it. It is necessary but not sufficient to win.
The real differentiation comes from three pillars:
- Local payment integration — TWINT and Pix are not afterthoughts; they are first-class citizens in the Kasha POS experience. Dynamic QR codes, instant confirmation, automatic reconciliation. Most competitors treat local methods as add-ons with clunky separate flows.
- Settlement speed — In Switzerland, the industry standard is T+2 (merchants wait 2 business days to see their money). Kasha targets T+1 via Adyen, with same-day for open banking. In Brazil, Pix is already instant, and card settlement via Transfero targets T+1. Faster money = happier merchants = lower churn.
- Credit via anticipation — This is the lock-in mechanism. Once a merchant depends on Kasha for working capital (advancing their card receivables at competitive rates), switching to a competitor means losing access to that credit line. In Brazil, this is a R$200B+ annual market dominated by POS providers. In Switzerland, it is virtually non-existent — a greenfield opportunity where Kasha can be first.
Phase 1 focus: Cards + TWINT (CH) + Pix QR (BR). These four payment methods cover ~90% of SME transaction volume in both markets. Ship fast, prove the model, then layer on PostFinance, open banking, Pix NFC, stablecoins, and crypto in subsequent phases.
Rollout Phases
Cards (Visa/MC/Amex) via Adyen, TWINT via Adyen, Apple Tap to Pay, Pix QR via Transfero. Core POS app, merchant onboarding, basic dashboard. Goal: First 50 merchants live in CH + BR.
Pix Tap to Pay (NFC), PostFinance Card, Open Banking (SIC), payment anticipation (BR), booking/deposit flows, invoicing module. Goal: 200+ merchants, anticipation generating revenue in BR.
Boleto support, BRZ stablecoin settlement, catalogue/inventory module, recurring billing, anticipation in CH (pilot), advanced analytics. Goal: 500+ merchants, multi-module adoption >40%.
Crypto payments (BTC/ETH/USDC), multi-store support, API for third-party integrations, white-label POS for partners, cross-border settlement (CH ↔ BR). Goal: Platform ecosystem, partner channel, 1000+ merchants.
5. Architecture Overview
Kasha POS is not a standalone product -- it is a native module within the Kasha microservice
ecosystem. Every design decision follows the established patterns: separate service and UI
repositories, RabbitMQ-based inter-service communication, PostgreSQL with TypeORM, and
deployment through the shared Kasha infrastructure. The diagram below shows how
lr-pos-service and lr-pos-ui fit alongside the existing services.
System Architecture Diagram
┌─────────────────────────────────────────────────────────────────┐
│ CLIENT LAYER │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ lr-pos-ui│ │lr-admin │ │lr-cashier│ │ lr-client-ui │ │
│ │(merchant)│ │ -ui │ │ -ui │ │ (end user) │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └──────┬───────┘ │
└───────├──────────────├──────────────├───────────────├───────────┘
│ │ │ │
┌───────▼──────────────▼──────────────▼───────────────▼───────────┐
│ lr-api-gateway │
│ (REST + WebSocket + RabbitMQ) │
└───────┬──────────────┬──────────────┬───────────────┬───────────┘
│ │ │ │
┌───────▼────┐ ┌──────▼─────┐ ┌────▼──────┐ ┌────▼──────────┐
│ lr-pos │ │lr-invoicing│ │lr-banking │ │lr-booking │
│ -service │ │ -service │ │ -service │ │ -service │
│ │ │ │ │ │ │ │
│ Merchants │ │ Invoices │ │ Accounts │ │ Appointments │
│ Terminals │ │ Receipts │ │ Transfers │ │ Deposits │
│ Txns │ │ Line Items │ │ Payouts │ │ Scheduling │
│ Settlement │ │ │ │ │ │ │
│ Anticipatn │ │ │ │ │ │ │
└──────┬─────┘ └────────────┘ └───────────┘ └───────────────┘
│
┌──────▼──────────────────────────────────────────────────────────┐
│ PAYMENT PROVIDERS │
│ ┌──────────┐ ┌───────────┐ ┌──────────────┐ │
│ │ Adyen │ │ Transfero │ │ SIC/Open │ │
│ │ (CH+BR) │ │ (BR) │ │ Banking (CH) │ │
│ │ │ │ │ │ │ │
│ │ Cards │ │ Pix │ │ IBAN Transfer│ │
│ │ TWINT │ │ BRZ │ │ Same-day │ │
│ │ Tap2Pay │ │ Crypto │ │ │ │
│ └──────────┘ └───────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────┘
lr-pos-service owns the payment lifecycle --
merchant onboarding, terminal registration, transaction processing, settlement, anticipation,
and reconciliation. It delegates invoice creation to lr-invoicing-service,
fund transfers to lr-banking-service, and stock management to
lr-catalogue-service via RabbitMQ events. No synchronous HTTP calls between
services.
Key Architectural Decisions
| Decision | Choice | Rationale |
|---|---|---|
| CH Card acquiring | Adyen | Already integrated in Kasha, covers TWINT + Tap to Pay |
| CH Bank settlement | Own merchant IBAN via SIC | Lower fees, direct relationship, open banking |
| BR Primary PSP | Transfero | Pix native, instant settlement, BRZ stablecoin, crypto bridge |
| BR Card backup | Adyen | International cards (Visa/MC) for tourists + cross-border |
| BR Anticipation | In-house scoring + Kasha treasury | Core differentiator for retail, receivables-backed |
| CH Credit | Adyen Capital (Phase 4) | Merchant lending based on txn history, managed by Adyen, requires 4+ months of transaction history per Adyen's rules |
| SoftPOS | Apple Tap to Pay + Pix Tap to Pay | No hardware cost, phone-as-terminal |
| Service communication | RabbitMQ (pure RPC) | Follows Kasha microservice pattern, all inter-service via message queues |
| Database | PostgreSQL | Follows existing pattern, TypeORM entities |
| Repo pattern | Separate lr-pos-service + lr-pos-ui | Follows existing Kasha microservice architecture |
Infrastructure Stack
Backend (lr-pos-service)
- Node.js + TypeScript
- NestJS framework
- TypeORM + PostgreSQL
- RabbitMQ for inter-service messaging
- Redis for caching & rate limiting
- Jest for unit & integration tests
Frontend (lr-pos-ui)
- Next.js 14+ (App Router)
- TypeScript
- Tailwind CSS
- i18n: English, Portuguese, German, French, Italian
- WebSocket for real-time payment status
- PWA-ready for mobile merchant use
6. PSP Integration Layer
The POS service abstracts all payment provider interactions behind a unified provider
interface. Each PSP has a dedicated provider module in
src/providers/{psp-name}/ that implements the common contract while exposing
provider-specific capabilities. This design allows merchants to accept payments across
multiple providers without the UI or business logic knowing the underlying PSP.
CH BR Adyen Integration
Adyen serves as the primary PSP for Switzerland and handles international card payments in Brazil. The integration covers the full merchant lifecycle from sub-merchant onboarding through to settlement and capital lending.
API Surface
- Terminal API -- In-person card-present payments via physical terminals or SoftPOS devices
- Checkout API -- Online and QR-code-based payments, including TWINT for Swiss customers
- Platforms API -- Sub-merchant management using the marketplace model; each Kasha merchant is a sub-merchant under Kasha's Adyen platform account
- TWINT via Local Payment Methods -- Adyen's native TWINT integration for the Swiss market, presented as a payment option alongside cards
- Apple Tap to Pay via SoftPOS SDK -- Enables merchants to accept contactless payments directly on iPhone, no additional hardware required
- Adyen Capital -- Merchant lending for CH only, available in Phase 4. Requires a minimum of 4 months of transaction history per client before an offer can be extended (Adyen's policy)
- Webhook Notifications -- Real-time payment status updates (AUTHORISATION, CAPTURE, REFUND, CHARGEBACK) delivered to
lr-pos-servicevialr-api-gateway
AdyenService Interface
// src/providers/adyen/adyen.interface.ts
interface IAdyenService {
/**
* Create a new payment request via Adyen Checkout or Terminal API.
* Determines the correct API based on the payment channel (in-person vs online).
* @param dto - Payment creation parameters (amount, currency, method, merchantRef)
* @returns Payment result with PSP reference and status
* @throws AdyenApiError if the request fails
*/
createPayment(dto: ICreatePaymentDto): Promise<IPaymentResult>;
/**
* Capture a previously authorised payment.
* @param pspReference - Adyen's unique payment reference
* @param amount - Amount to capture (supports partial capture)
* @returns Capture result with updated status
*/
capturePayment(pspReference: string, amount: IAmount): Promise<ICaptureResult>;
/**
* Refund a captured payment (full or partial).
* @param pspReference - Adyen's unique payment reference
* @param amount - Amount to refund
* @returns Refund result with PSP refund reference
*/
refundPayment(pspReference: string, amount: IAmount): Promise<IRefundResult>;
/**
* Create a sub-merchant account under Kasha's Adyen platform.
* Used during merchant onboarding to set up payment processing.
* @param dto - Merchant details (legal name, address, bank account)
* @returns Created sub-merchant with Adyen account holder ID
*/
createSubMerchant(dto: ICreateSubMerchantDto): Promise<ISubMerchant>;
/**
* Register a device for Apple Tap to Pay (SoftPOS).
* Links the merchant's iPhone to their Adyen terminal profile.
* @param dto - Device details (model, OS version, merchant terminal ID)
* @returns Registered device with activation code
*/
registerSoftPosDevice(dto: IRegisterDeviceDto): Promise<IDevice>;
/**
* Check and initiate a capital offer for a Swiss merchant.
* Only available for merchants with 4+ months of transaction history.
* @param merchantId - Internal Kasha merchant ID
* @returns Capital offer details, or null if merchant is not eligible
*/
initiateCapitalOffer(merchantId: string): Promise<ICapitalOffer | null>;
}
initiateCapitalOffer method checks this
prerequisite before making the API call.
BR Transfero Integration
Transfero is the primary PSP for Brazil, providing native Pix integration, BRZ stablecoin settlement, and a crypto on-ramp. This enables Brazilian merchants to accept the most popular local payment methods while optionally settling in stablecoins for currency stability.
API Surface
- Pix API -- Instant payment via QR code generation (dynamic and static), Pix Copy & Paste, and Pix Tap to Pay (NFC-based Pix on Android devices)
- BRZ Stablecoin Settlement -- Merchants can opt to receive settlement in BRZ (real-pegged stablecoin) instead of BRL, reducing exposure to banking delays and enabling instant cross-border value transfer
- Crypto On-ramp -- Accept BTC and ETH payments from customers; funds are automatically converted to BRZ or BRL at the time of transaction, shielding the merchant from volatility
- Merchant Management API -- Create and manage merchant accounts, configure settlement preferences (BRL vs BRZ), set up Pix keys
- Webhook Notifications -- Real-time Pix confirmation (typically under 3 seconds), settlement status, and crypto conversion confirmations
TransferoService Interface
// src/providers/transfero/transfero.interface.ts
interface ITransferoService {
/**
* Create a Pix payment with dynamic QR code.
* Generates a unique QR code for the specific transaction amount.
* @param dto - Pix payment details (amount, merchantPixKey, description)
* @returns Pix result with QR code data, copy-paste code, and transaction ID
* @throws TransferoApiError if QR generation fails
*/
createPixPayment(dto: ICreatePixDto): Promise<IPixResult>;
/**
* Create a Pix Tap to Pay (NFC) payment session.
* Enables the merchant's Android device to receive Pix via NFC tap.
* @param dto - Tap payment details (amount, device ID, merchant ID)
* @returns Tap session with NFC payload and timeout
*/
createPixTapPayment(dto: IPixTapDto): Promise<IPixTapResult>;
/**
* Initiate BRZ stablecoin settlement for a batch of transactions.
* Converts accumulated BRL to BRZ and transfers to merchant's wallet.
* @param dto - Settlement details (merchant ID, amount, destination wallet)
* @returns Settlement result with BRZ amount and transfer hash
*/
createBrzSettlement(dto: IBrzSettlementDto): Promise<ISettlementResult>;
/**
* Query the real-time status of a Pix transaction.
* @param transactionId - Transfero transaction reference
* @returns Current Pix status (PENDING, CONFIRMED, EXPIRED, RETURNED)
*/
getPixStatus(transactionId: string): Promise<IPixStatus>;
/**
* Register a new merchant with Transfero.
* Sets up Pix keys, settlement preferences, and compliance data.
* @param dto - Merchant registration details (CPF/CNPJ, bank account, Pix key)
* @returns Created merchant with Transfero merchant ID
*/
createMerchant(dto: ICreateMerchantDto): Promise<IMerchant>;
/**
* Generate a static QR code for a merchant (reusable, no fixed amount).
* Customer enters the amount when scanning. Ideal for tipping or variable pricing.
* @param merchantId - Internal Kasha merchant ID
* @returns Static QR code with image URL and Pix copy-paste payload
*/
generateStaticQrCode(merchantId: string): Promise<IStaticQrCode>;
}
CH Banking Provider -- Direct IBAN Settlement
For Swiss merchants, Kasha offers direct IBAN-based settlement bypassing traditional payment processor settlement cycles. This uses the Swiss Interbank Clearing (SIC) system and open banking APIs for a lower-cost, faster settlement path.
Capabilities
- SIC (Swiss Interbank Clearing) -- CHF transfers through the Swiss National Bank's real-time gross settlement system. Enables same-day settlement for qualifying merchants with verified IBANs
- Open Banking APIs -- Account verification, balance checks, and automated reconciliation via PSD2-compliant open banking connections to Swiss banks
- Same-day Settlement -- Qualifying merchants (verified identity, 30+ days active, no chargebacks) receive funds on the same business day. Standard merchants receive T+1 settlement
Settlement Tiers
| Tier | Criteria | Settlement Speed | Fee |
|---|---|---|---|
| Instant | 90+ days active, no chargebacks, verified IBAN | Same-day (SIC) | 0.15 CHF per transfer |
| Standard | 30+ days active, verified identity | T+1 | 0.10 CHF per transfer |
| New | All new merchants | T+2 | 0.10 CHF per transfer |
Provider Routing Logic
The POS service automatically routes each payment to the correct provider based on the merchant's country, the selected payment method, and the customer's preference. The routing decision is transparent to the merchant UI.
Payment Request Received
|
v
+-----------+
| Country? |
+-----+-----+
|
+----+----+
| |
v v
CH BR
| |
v v
Method? Method?
| |
+--+ +--+--+--+
| | | | | |
v v v v v v
Card TWINT Pix Card BRZ Crypto
| | | | | |
v v v v v v
Adyen Adyen T A T T
r d r r
a y a a
n e n n
s n s s
f f f
e e e
r r r
o o o
A = Adyen T = Transfero
7. POS Sessions & Payment Flows
lr-pos-service works.
What is a POS Session?
A POS session represents a single payment interaction between a merchant and a customer. It encapsulates the full lifecycle from initiation to settlement. A session is not just a payment -- it carries context about why the payment exists, what is being paid for, and how the payment connects to other parts of the Kasha ecosystem.
A session can be any of the following:
Simple Walk-in Purchase
A bakery, cafe, or food truck. The merchant enters an amount, the customer taps or scans. No booking, no catalogue -- just a quick payment.
Session type: SIMPLE
Service Completion Payment
A barber or nail salon. The service is complete, the merchant collects payment. May reference a booking but does not require one.
Session type: SERVICE
Deposit Collection (Booking-linked)
A repair shop or auto mechanic. A booking exists, and the merchant collects a deposit (e.g., 30%) before starting work. The session references the booking ID.
Session type: DEPOSIT
Final Payment (Booking Closure)
The repair is complete. The remaining amount (70%) is collected. The session closes out the booking and the associated invoice.
Session type: FINAL_PAYMENT
Catalogue Sale with Stock Impact
A boutique or small shop. Items are selected from the catalogue, stock is checked and decremented on successful payment.
Session type: CATALOGUE_SALE
Mixed (Catalogue + Booking)
A salon where services and retail products are combined in a single transaction, potentially linked to an appointment booking.
Session type: MIXED
Session Lifecycle
Every POS session transitions through a well-defined set of states. Some states are
optional depending on the session type (e.g., ITEMS_ADDED only applies to
catalogue sales). The lifecycle is enforced by a state machine in the session service.
The merchant initiates a new session. This can happen via: (a) manually entering an amount on the POS terminal, (b) selecting items from a catalogue, (c) receiving an automatic trigger from a booking that requires a deposit or final payment. The session record is created in the database with a unique session ID, the merchant and terminal references, and the session type.
For catalogue-based sales or mixed sessions, the merchant adds line items -- either by scanning barcodes/SKUs or by browsing the catalogue on the POS UI. Each line item includes product reference, quantity, unit price, and applicable tax. The session total is recalculated as items are added or removed.
The total payment amount is finalized. For simple sessions, this is the manually entered amount. For catalogue sales, this is the sum of line items minus any discounts. For booking-linked sessions, deposits are deducted from the outstanding balance. Discounts, tips, and taxes are calculated and locked at this stage.
The customer is presented with available payment options. The options shown depend on the merchant's country, enabled payment methods, and available devices. In Switzerland: tap card, TWINT QR, Apple Tap to Pay. In Brazil: Pix QR, Pix Tap, card tap, crypto QR. The session is now awaiting customer action.
The customer has initiated payment (tapped, scanned, or confirmed). The request is routed to the correct PSP (Adyen or Transfero) based on the payment method and country. The POS UI shows a processing indicator. A timeout is set (30 seconds for cards, 5 minutes for Pix QR, 60 seconds for Pix Tap). If the timeout expires, the session transitions to PAYMENT_FAILED.
The PSP confirms successful payment via webhook or synchronous response. The transaction is recorded with the PSP reference, payment method, amount, currency, and timestamp. The session total is marked as paid. If this is a deposit, the booking's deposit status is updated. RabbitMQ event
pos.payment.completed is published.
A digital receipt is created and linked to the session. If the merchant has invoicing enabled, this triggers an event to
lr-invoicing-service to create or
update an invoice. The receipt can be sent to the customer via email, SMS, or
WhatsApp (based on merchant preference). A QR code linking to the receipt is
displayed on the POS screen.
The funds arrive in the merchant's account. Settlement timing depends on the country, payment method, and merchant's settlement tier: same-day for qualified Swiss merchants via SIC, T+1 for standard Swiss merchants, instant for Brazilian Pix, D+1 for Brazilian card transactions (or D+0 with anticipation). The settlement record links the transaction to the bank transfer.
Session-to-Invoice Link
Every completed POS session generates a receipt. If the merchant has invoicing enabled
(which is the default for all merchants), the receipt automatically triggers an invoice
action in lr-invoicing-service via RabbitMQ. The exact behavior depends on
the session type:
| Session Type | Invoice Behavior | Invoice Status |
|---|---|---|
| Walk-in purchase (SIMPLE) | Auto-generated simple invoice (receipt) with a single line item for the payment amount | PAID |
| Booking deposit (DEPOSIT) | Partial invoice created with a deposit line item. References the booking ID. Shows total service cost vs amount paid | PARTIALLY_PAID |
| Booking final payment (FINAL_PAYMENT) | Existing invoice updated -- remaining amount collected, all line items marked as settled | PAID |
| Catalogue sale (CATALOGUE_SALE) | Invoice with line items matching catalogue items, including SKU, quantity, unit price, and tax | PAID |
Payment Flow Diagrams
The following three flows illustrate the most common POS scenarios, each demonstrating different session types, provider integrations, and cross-module interactions.
Flow 1: Simple Walk-in CH BR
Scenario: A customer buys a coffee and pastry at a bakery. The merchant enters the total amount. The customer pays by tapping their card (CH) or scanning a Pix QR code (BR).
Customer Merchant POS lr-pos-service PSP (Adyen/Transfero) | | | | | Orders coffee | | | |------------------>| | | | | | | | | Enter amount (CHF 7) | | | |--------------------->| Create session | | | | (type: SIMPLE) | | | | | | | Show payment options | | | |<---------------------| | | | | | | Taps card / Scans QR | | |------------------>| | | | | Payment request | | | |--------------------->| Route to PSP | | | |------------------------>| | | | | | | | Payment confirmed | | | |<------------------------| | | | | | | Success + Receipt | | | |<---------------------| | | | |--> RabbitMQ: | | Receipt (QR/email)| | pos.payment.completed| |<------------------| | --> invoicing | | | | | Total time: <10 seconds (card) / <5 seconds (Pix)
Flow 2: Booking + Deposit + Final Payment CH BR
Scenario: A customer books a phone repair at a repair shop. A 30% deposit is collected at booking time. After repair is complete, the remaining 70% is collected. The entire flow spans two POS sessions linked to a single booking.
Phase 1: Booking + Deposit
==========================
Client books repair via lr-booking-service
|
v
lr-booking-service creates booking (status: CONFIRMED, deposit_required: true)
|
| RabbitMQ: booking.deposit.required
v
lr-pos-service creates POS session (type: DEPOSIT, booking_id: BK-001)
|
v
Merchant POS shows: "Deposit required: CHF 60.00 (30% of CHF 200.00)"
|
v
Customer pays deposit (card / TWINT / Pix)
|
v
lr-pos-service records transaction, publishes pos.payment.completed
|
+--> lr-invoicing-service creates invoice (status: PARTIALLY_PAID)
| Line item: "Phone repair deposit - 30%" CHF 60.00
|
+--> lr-booking-service updates booking (deposit_status: PAID)
Phase 2: Repair + Final Payment
================================
Merchant completes repair, marks booking as COMPLETED
|
| RabbitMQ: booking.completed
v
lr-pos-service creates POS session (type: FINAL_PAYMENT, booking_id: BK-001)
|
v
Merchant POS shows: "Final payment: CHF 140.00 (remaining on BK-001)"
|
v
Customer pays remaining amount
|
v
lr-pos-service records transaction, publishes pos.payment.completed
|
+--> lr-invoicing-service updates invoice (status: PAID)
| Line item added: "Phone repair - final payment" CHF 140.00
|
+--> lr-booking-service updates booking (status: CLOSED)
|
+--> Receipt sent to client (email/SMS/WhatsApp)
Flow 3: Catalogue Sale with Stock CH BR
Scenario: A customer at a boutique selects two items. The merchant scans or selects the items from the catalogue. Stock is checked, payment is processed, stock is decremented, and an invoice with line items is generated.
Customer Merchant POS lr-pos-service lr-catalogue-service | | | | | Selects items | | | |------------------>| | | | | | | | | Scan/select items | | | |------------------->| Create session | | | | (type: CATALOGUE_SALE)| | | | | | | | Check stock | | | |--------------------->| | | | | | | | Stock confirmed | | | |<---------------------| | | | | | | Cart: | | | | Silk scarf x1 CHF 45 | | | Earrings x1 CHF 28 | | | ───────────────── | | | | Total: CHF 73 | | | |<-------------------| | | | | | | Pays (card/Pix) | | | |------------------>| | | | |------------------->| Process payment | | | |--> PSP | | | | | | | | Payment confirmed | | | | | | | | RabbitMQ: pos.sale.completed | | |--------------------->| | | | | Decrement stock: | | | | Silk scarf: 12 -> 11 | | | | Earrings: 5 -> 4 | | | | | | | | Stock check: | | | | Earrings below | | | | threshold (5)! | | | | | | | catalogue.stock.low | | | |<---------------------| | | | | | | Receipt + restock | | | | alert | | | |<-------------------| | | | | | | Receipt | | --> lr-invoicing: | |<------------------| | Invoice with 2 | | | | line items (PAID) |
Session State Machine
The session lifecycle is enforced by a finite state machine. Invalid transitions are rejected, ensuring data consistency. The following diagram shows all valid transitions:
┌─────────┐
│ CREATED │
└────┬────┘
│
┌─────────┼─────────┐
│ │ │
v v v
┌────────────┐ ┌──────────────┐
│ITEMS_ADDED │ │ AMOUNT_SET │◄──── (simple/booking sessions
└─────┬──────┘ └──────┬───────┘ skip ITEMS_ADDED)
│ │
└──────┬─────────┘
│
v
┌─────────────────┐
│ PAYMENT_PENDING │
└────────┬────────┘
│
v
┌────────────────────┐
│PAYMENT_PROCESSING │
└─────────┬──────────┘
│
┌─────────┼──────────┐
│ │ │
v v v
┌──────────┐ ┌──────────┐ ┌──────────────┐
│COMPLETED │ │ FAILED │ │ EXPIRED │
└────┬─────┘ └──────────┘ └──────────────┘
│
v
┌────────────────┐
│RECEIPT_GENERATED│
└───────┬────────┘
│
v
┌──────────┐
│ SETTLED │
└──────────┘
Error states: PAYMENT_FAILED and
PAYMENT_EXPIRED are terminal states from which a new session must be
created. There is no "retry" on a failed session -- the merchant creates a fresh
session. This keeps the audit trail clean: every session ID maps to exactly one payment
attempt.
8. Cross-Module Integration
The POS service does not operate in isolation. It is deeply integrated with five other Kasha
microservices via RabbitMQ event-driven messaging. Every integration follows the same
pattern: lr-pos-service publishes domain events, and the consuming service
reacts asynchronously. No synchronous HTTP calls are made between services -- all
communication goes through the message queue, ensuring loose coupling and resilience.
lr-pos-service is the
source of truth for payment data. Other services subscribe to POS events to
maintain their own projections. If a downstream service is temporarily unavailable, messages
are queued in RabbitMQ and processed when the service recovers. No payment data is ever
lost.
Integration Map
┌─────────────────┐
│ lr-luma-service │
│ (AI Agent) │
│ │
│ Query sales data │
│ Trigger refunds │
│ Business insights│
└────────┬─────────┘
│
┌────────────────────┐│┌────────────────────┐
│ │││ │
v v│v v
┌──────────────────┐ ┌────────┴──────────┐ ┌──────────────────┐
│lr-booking-service│ │ │ │ lr-crm-service │
│ │ │ lr-pos-service │ │ │
│ booking.deposit │◄──┤ ├──►│ Customer records │
│ .required │ │ Merchants │ │ Purchase history│
│ booking.completed│ │ Terminals │ │ Loyalty points │
│ │──►│ Transactions │ │ │
└──────────────────┘ │ Sessions │ └──────────────────┘
│ Settlement │
┌──────────────────┐ │ Anticipation │ ┌──────────────────┐
│lr-invoicing │ │ Reconciliation │ │lr-catalogue │
│ -service │ │ │ │ -service │
│ │◄──┤ ├──►│ │
│ Create invoices │ │ │ │ Stock decrement │
│ Update invoices │ └─────────┬──────────┘ │ Product lookup │
│ Close invoices │ │ │ Restock alerts │
└──────────────────┘ │ └──────────────────┘
│
v
┌──────────────────┐
│lr-banking-service │
│ │
│ Settlement xfers │
│ Anticipation │
│ disbursements │
│ Reconciliation │
└───────────────────┘
POS ↔ Invoicing (lr-invoicing-service)
Every POS payment can generate an invoice or receipt. The invoicing service is the system of record for all financial documents, while the POS service owns the payment lifecycle. Their integration ensures that every payment has a corresponding financial document.
Integration Points
- Receipt creation: Every completed POS session triggers invoice/receipt generation in the invoicing service
- Deposit tracking: Booking deposits create partial invoices with status
PARTIALLY_PAID. The invoice tracks the total owed vs. the amount collected - Final payment closure: When a final payment session completes, the existing invoice is updated to
PAIDand all line items are reconciled - Line item mapping: For catalogue sales, each POS line item (product, quantity, price, tax) maps directly to an invoice line item, ensuring tax compliance
RabbitMQ Events
| Event | Publisher | Consumer | Action |
|---|---|---|---|
pos.payment.completed |
lr-pos-service | lr-invoicing-service | Creates new invoice/receipt or updates existing invoice to PAID |
pos.deposit.collected |
lr-pos-service | lr-invoicing-service | Creates partial invoice (PARTIALLY_PAID) linked to booking |
pos.refund.completed |
lr-pos-service | lr-invoicing-service | Creates credit note against original invoice |
POS ↔ Banking (lr-banking-service)
The banking service manages the actual movement of funds -- from PSP settlement accounts to merchant bank accounts. The POS service tells the banking service when and how much to transfer; the banking service handles the how.
Integration Points
- Settlement transfers: When a settlement batch is ready, the POS service publishes the net amount and the merchant's bank details. The banking service initiates the transfer via SIC (CH) or Pix/TED (BR)
- Anticipation disbursements: When a merchant requests receivables anticipation (BR), the POS service calculates the eligible amount and fee, then instructs the banking service to disburse from Kasha's treasury
- Reconciliation: The banking service reports on confirmed bank movements. The POS service matches these against expected settlements to detect discrepancies
RabbitMQ Events
| Event | Publisher | Consumer | Action |
|---|---|---|---|
pos.settlement.ready |
lr-pos-service | lr-banking-service | Initiates bank transfer to merchant's account |
pos.anticipation.approved |
lr-pos-service | lr-banking-service | Disburses anticipation funds from Kasha treasury |
banking.transfer.confirmed |
lr-banking-service | lr-pos-service | Marks settlement as completed, updates reconciliation |
banking.transfer.failed |
lr-banking-service | lr-pos-service | Flags settlement for manual review, notifies merchant |
POS ↔ Bookings (lr-booking-service)
The booking service manages appointments and service scheduling. When a booking requires a financial transaction (deposit or final payment), it delegates to the POS service. This separation ensures that scheduling logic stays in the booking service while payment logic stays in the POS service.
Integration Points
- Deposit collection: When a booking is created with
deposit_required=true, the booking service emits an event. The POS service creates a deposit session pre-filled with the calculated deposit amount and linked to the booking ID - Final payment: When the merchant marks a booking as complete, the POS service creates a final payment session for the remaining balance. The amount is automatically calculated by subtracting any deposits already collected
- Booking reference: Every POS session that originates from a booking carries a
booking_idfield, enabling full traceability from appointment to payment to invoice - Configurable deposits: Deposit percentages and rules are configurable per service type in the booking service (e.g., 30% for repairs, 50% for custom orders, 0% for standard appointments)
RabbitMQ Events
| Event | Publisher | Consumer | Action |
|---|---|---|---|
booking.deposit.required |
lr-booking-service | lr-pos-service | Creates DEPOSIT session linked to booking, calculates deposit amount |
booking.completed |
lr-booking-service | lr-pos-service | Creates FINAL_PAYMENT session for remaining balance |
pos.deposit.collected |
lr-pos-service | lr-booking-service | Updates booking deposit_status to PAID |
pos.payment.completed |
lr-pos-service | lr-booking-service | Updates booking status to CLOSED (when final payment received) |
POS ↔ Catalogue (lr-catalogue-service)
Merchants who sell physical goods use the catalogue service to manage their product
inventory. The POS service integrates with the catalogue for item lookup during
sales and stock management after payment. The same catalogue powers both in-store
POS sales and online e-commerce via lr-ecommerce-service.
Integration Points
- Product lookup: The POS UI can browse the merchant's catalogue, search by name, or scan barcodes/SKUs. Product data (name, price, image, stock count) is fetched from the catalogue service
- Stock validation: Before finalizing a sale, the POS service checks that sufficient stock is available for each line item. If an item is out of stock, the sale cannot proceed for that item
- Stock decrement: On successful payment, the POS service publishes a
pos.sale.completedevent containing the list of items sold and their quantities. The catalogue service decrements stock accordingly - Restock alerts: When stock falls below a merchant-configured threshold, the catalogue service emits a
catalogue.stock.lowevent. This triggers a notification to the merchant via the POS UI and/or push notification
RabbitMQ Events
| Event | Publisher | Consumer | Action |
|---|---|---|---|
pos.sale.completed |
lr-pos-service | lr-catalogue-service | Decrements stock for each sold item (SKU + quantity) |
pos.sale.reversed |
lr-pos-service | lr-catalogue-service | Restores stock on refund/reversal |
catalogue.stock.low |
lr-catalogue-service | lr-pos-service | Displays restock alert on merchant's POS dashboard |
catalogue.item.updated |
lr-catalogue-service | lr-pos-service | Refreshes cached product data (price changes, descriptions) |
POS ↔ CRM (lr-crm-service)
The CRM integration is optional but valuable. When enabled, the POS service can link payments to customer profiles, enabling merchants to track purchase history, spending patterns, and loyalty. This transforms the POS from a simple payment tool into a customer relationship channel.
Integration Points
- Customer linking: At payment time, the merchant can optionally link the transaction to a customer profile (by phone number, email, or loyalty card). This is never required -- walk-in anonymous payments are always supported
- Purchase history: Linked payments appear in the customer's CRM profile, giving the merchant visibility into spending patterns, visit frequency, and product preferences
- Loyalty & visit tracking: The CRM service can maintain loyalty points or visit counts based on POS transactions. Merchants can configure rewards (e.g., "10th coffee free") that are applied automatically
RabbitMQ Events
| Event | Publisher | Consumer | Action |
|---|---|---|---|
pos.payment.completed |
lr-pos-service | lr-crm-service | Updates customer record with transaction (if customer linked) |
pos.payment.completed |
lr-pos-service | lr-crm-service | Increments loyalty points / visit counter |
crm.reward.earned |
lr-crm-service | lr-pos-service | Displays reward notification on POS ("Customer earned a free item!") |
POS ↔ Luma AI (lr-luma-service)
Luma is Kasha's AI agent. It can query POS data to answer merchant questions in natural language, trigger POS actions on behalf of the merchant, and proactively surface business insights. The POS service exposes a set of query and action endpoints that Luma can invoke via RabbitMQ RPC calls.
Luma Can Query POS Data
- "How much did we make today?" -- Luma queries the POS analytics endpoint for today's transaction totals, broken down by payment method
- "What's our best-selling item this week?" -- Luma queries POS + catalogue data to rank items by sales volume and revenue
- "Show me all refunds from last month" -- Luma queries the transaction history with filters for refund transactions
- "Compare this month's sales to last month" -- Luma queries POS analytics for period-over-period comparison
Luma Can Trigger POS Actions
- "Refund the last transaction" -- Luma identifies the most recent completed transaction and initiates a refund via the POS service
- "Send a receipt to the customer" -- Luma triggers receipt re-send for a specified transaction
- "What's my anticipation balance?" -- Luma queries the merchant's available anticipation amount and current terms (BR only)
POS Feeds Luma's Business Insights
- Daily sales summaries are published as events that Luma indexes for trend analysis
- Anomaly detection: unusual transaction volumes, high refund rates, or settlement delays are flagged to Luma for proactive merchant notification
- Peak hour analysis: POS session timestamps help Luma identify busiest periods and suggest staffing or pricing optimizations
RabbitMQ Interactions
| Pattern | Initiator | Responder | Description |
|---|---|---|---|
| RPC Query | lr-luma-service | lr-pos-service | Luma requests sales data, transaction history, analytics |
| RPC Action | lr-luma-service | lr-pos-service | Luma triggers refund, receipt resend, or other POS actions |
| Event | lr-pos-service | lr-luma-service | Daily summaries, anomaly alerts, settlement notifications |
Complete Event Catalogue
For reference, here is the complete list of RabbitMQ events published and consumed by
lr-pos-service:
Events Published by POS
| Event Name | Payload Summary | Consumers |
|---|---|---|
pos.payment.completed |
sessionId, merchantId, amount, currency, paymentMethod, pspReference, customerId? | invoicing, booking, crm, luma |
pos.deposit.collected |
sessionId, bookingId, merchantId, depositAmount, totalAmount | invoicing, booking |
pos.refund.completed |
sessionId, originalSessionId, refundAmount, reason | invoicing, catalogue, crm |
pos.sale.completed |
sessionId, merchantId, items[{sku, quantity, price}] | catalogue |
pos.sale.reversed |
sessionId, items[{sku, quantity}] | catalogue |
pos.settlement.ready |
merchantId, netAmount, currency, bankDetails, transactionIds[] | banking |
pos.anticipation.approved |
merchantId, amount, fee, receivableIds[], disbursementDetails | banking |
Events Consumed by POS
| Event Name | Publisher | POS Action |
|---|---|---|
booking.deposit.required |
lr-booking-service | Creates DEPOSIT session linked to booking |
booking.completed |
lr-booking-service | Creates FINAL_PAYMENT session for remaining balance |
banking.transfer.confirmed |
lr-banking-service | Marks settlement as completed |
banking.transfer.failed |
lr-banking-service | Flags settlement for review, notifies merchant |
catalogue.stock.low |
lr-catalogue-service | Displays restock alert on POS dashboard |
catalogue.item.updated |
lr-catalogue-service | Refreshes cached product data in POS |
crm.reward.earned |
lr-crm-service | Shows reward notification on POS terminal |
9. Payment Anticipation Engine
BR Brazil: In-House Receivables Advance
How It Works
When a merchant accepts a card payment in Brazil, the acquirer (Adyen) holds the funds for up to 30 days before settling. This is standard industry practice, but it creates severe cash flow problems for SMEs who need working capital now to pay suppliers, staff, and rent.
- Standard flow: Merchant accepts card → Adyen holds funds → settlement at T+30 → merchant waits a full month
- Kasha anticipation flow: Merchant accepts card → requests anticipation → Kasha advances funds at 1-2% discount → merchant receives funds next business day
- Kasha treasury funds the advance from its own capital reserves
- At T+30, Adyen settles the full original amount to Kasha, closing the loop
- The spread (1-2% fee) is pure margin for Kasha, with risk managed by the scoring algorithm
This is massive for Brazilian SMEs. The antecipacao de recebiveis market exceeds R$200 billion annually, and traditional banks charge 2-5% for equivalent services. Kasha's 1-2% rate is highly competitive.
Risk Scoring Algorithm
Every anticipation request is evaluated by an automated risk scoring engine that assesses merchant reliability and determines approval, maximum amount, and fee rate.
// src/modules/anticipation/anticipation.interface.ts
interface IRiskScoringInput {
merchantId: string;
monthlyVolume: number; // average monthly card volume
chargebackRate: number; // % of transactions charged back
merchantTenureMonths: number; // how long on the platform
requestedAmount: number; // how much they want to anticipate
totalReceivables: number; // total outstanding receivables
}
interface IRiskScoringResult {
grade: 'LOW' | 'MEDIUM' | 'HIGH' | 'REJECTED';
maxApprovedAmount: number;
suggestedFeePercent: number; // 1.0% for LOW, 1.5% for MEDIUM, 2.0% for HIGH
reasons: string[];
}
// ──────────────────────────────────────────────────────
// Scoring factors:
// ──────────────────────────────────────────────────────
// - Chargeback rate > 1% → penalty (+1 risk level)
// - Monthly volume consistency → 3-month std dev analysis
// (high variance = unpredictable revenue = higher risk)
// - Merchant tenure < 3 months → higher risk (insufficient history)
// - Request > 80% of receivables → higher risk (over-leveraged)
// - HARD LIMIT: Never approve > 90% of total receivables
// ──────────────────────────────────────────────────────
function calculateRiskScore(input: IRiskScoringInput): IRiskScoringResult {
let riskPoints = 0;
const reasons: string[] = [];
// Factor 1: Chargeback rate
if (input.chargebackRate > 0.02) {
return { grade: 'REJECTED', maxApprovedAmount: 0, suggestedFeePercent: 0,
reasons: ['Chargeback rate exceeds 2% threshold'] };
}
if (input.chargebackRate > 0.01) { riskPoints += 2; reasons.push('Elevated chargeback rate'); }
// Factor 2: Merchant tenure
if (input.merchantTenureMonths < 1) {
return { grade: 'REJECTED', maxApprovedAmount: 0, suggestedFeePercent: 0,
reasons: ['Minimum 1 month tenure required'] };
}
if (input.merchantTenureMonths < 3) { riskPoints += 1; reasons.push('Limited platform history'); }
// Factor 3: Receivables ratio
const ratio = input.requestedAmount / input.totalReceivables;
if (ratio > 0.9) { riskPoints += 3; reasons.push('Exceeds 90% cap - will be reduced'); }
else if (ratio > 0.8) { riskPoints += 1; reasons.push('High receivables utilization'); }
// Determine grade and fee
const grade = riskPoints <= 1 ? 'LOW' : riskPoints <= 3 ? 'MEDIUM' : 'HIGH';
const feeMap = { LOW: 1.0, MEDIUM: 1.5, HIGH: 2.0 };
const maxAmount = Math.min(input.requestedAmount, input.totalReceivables * 0.9);
return { grade, maxApprovedAmount: maxAmount, suggestedFeePercent: feeMap[grade], reasons };
}
Anticipation Request Flow
The end-to-end process from merchant request to fund disbursement:
Merchant opens the anticipation dashboard in lr-pos-ui. The system displays all pending receivables grouped by settlement date, showing amounts due at T+10, T+20, T+30, etc.
Merchant selects which receivables to anticipate — either by date range (e.g., "advance everything due in the next 30 days") or by specific amount (e.g., "I need R$5,000 now").
The system runs the risk scoring algorithm and calculates the fee: fee = requestedAmount × feeRate. For example, R$10,000 at 1.5% risk grade = R$150 fee. The net disbursement is R$9,850.
Merchant sees a clear summary: "Receive R$9,700 tomorrow instead of R$10,000 in 30 days." They review the fee breakdown and confirm the anticipation request.
Kasha treasury disburses funds to the merchant via Pix (instant, preferred) or standard bank transfer (same-day). Pix disbursements typically arrive within seconds.
At T+30, Adyen settles the full original amount (R$10,000) to Kasha's settlement account. The R$300 spread (fee) is Kasha's gross margin on the anticipation.
CH Switzerland: Adyen Capital (Phase 4)
Adyen Capital — Merchant Lending
Unlike Brazil's in-house receivables advance model, Switzerland leverages Adyen Capital, a merchant lending product managed entirely by Adyen. This is not a receivables advance — it is a proper loan product.
- Eligibility: Requires a minimum of 4 months of transaction history on the Kasha platform (Adyen's internal underwriting rules)
- Risk ownership: Adyen manages all credit risk, underwriting, and collections — Kasha has zero balance sheet exposure
- Revenue model: Kasha earns a commission on each loan originated through the platform
- Repayment: Automatic deduction as a percentage of daily card sales — no fixed monthly installments
- Availability: Planned for Phase 4 of the Kasha POS rollout, after sufficient merchant transaction history is established
Anticipation Model Comparison
| Feature | BR Brazil (In-House) | CH Switzerland (Adyen Capital) |
|---|---|---|
| Type | Receivables advance (antecipacao) | Merchant loan (credit facility) |
| Risk Owner | Kasha (treasury-funded) | Adyen (fully managed) |
| Min. Tenure | 1 month on platform | 4 months on platform |
| Fee / Rate | 1-2% flat discount fee | Varies (Adyen sets pricing) |
| Settlement Speed | Next business day (via Pix: instant) | Per Adyen Capital terms |
| Max Amount | Up to 90% of outstanding receivables | Based on Adyen's internal scoring |
| Repayment | Automatic at T+30 (Adyen settlement) | % of daily card sales |
| Phase | Phase 1 | Phase 4 |
10. Merchant Onboarding
A streamlined onboarding process is critical for merchant acquisition. Kasha POS aims for a fully digital, self-service onboarding flow that gets merchants from sign-up to accepting payments in under 5 business days (CH) or under 3 business days (BR).
Onboarding Flow
Merchant registers via lr-pos-ui (self-service) or lr-admin-ui (assisted by Kasha sales team). Core information collected: business name, country of operation (CH or BR), primary contact name, email, phone number, and business category (MCC code).
Know Your Business — the compliance backbone. Merchant uploads business registration documents, beneficial ownership declarations, and identity verification for authorized representatives. Documents are validated against government registries (Handelsregister for CH, Receita Federal for BR).
Once KYB clears, the system automatically creates a sub-merchant account with the relevant PSP. For Adyen: account holder created via the Adyen Platforms API. For Transfero (BR crypto): merchant account provisioned via Transfero's API. This step includes PSP-side KYB verification as well.
Merchant provides payout destination details. CH Swiss IBAN (must be a Swiss-domiciled bank account). BR Brazilian bank account number + agency + Pix keys (CPF/CNPJ, email, phone, or random key). Bank account ownership is verified against KYB data.
Merchant registers their payment acceptance device. For SoftPOS: install the Kasha POS app on iPhone (Tap to Pay) and pair the device with their merchant account. For QR-based payments: system generates a static QR code linked to the merchant's account for display at the point of sale.
Merchant performs a low-value test payment (CHF 1.00 or R$1.00) to verify the complete payment chain: card/QR acceptance → PSP processing → webhook receipt → transaction recording. Test transactions are flagged and automatically refunded.
POS is activated for production payments. Merchant receives a confirmation email with getting-started guides, support contacts, and a link to their live dashboard. Settlement schedule begins with the first real transaction.
KYB Requirements by Country
| Requirement | CH Switzerland | BR Brazil |
|---|---|---|
| Business Registration | Handelsregister (Commercial Register) extract, dated within 3 months | CNPJ certificate (Cartao CNPJ) from Receita Federal |
| ID Verification | Passport or national ID card (Swiss or EU/EFTA) | CPF + RG (identity card) or CNH (driver's license) |
| Beneficial Owners | UBO declaration for all persons with >25% ownership | QSA (Quadro de Socios e Administradores) from Receita Federal |
| Bank Account | Swiss IBAN (bank confirmation letter or statement) | Brazilian bank account details + active Pix keys |
| Tax Registration | UID number (Unternehmens-Identifikationsnummer) | Inscricao Estadual and/or Inscricao Municipal |
| PCI Compliance | Self-Assessment Questionnaire (SAQ) appropriate to integration type | SAQ or PCI MPoC certification for SoftPOS deployments |
| Approval Timeline | 2-5 business days | 1-3 business days |
Adyen Sub-Merchant Setup (Marketplace Model)
Platform Architecture
Kasha operates as an Adyen Platforms account holder — a marketplace model where Kasha is the platform and each merchant is a sub-merchant (referred to as an "account holder" in Adyen terminology).
- Split payments: Every transaction is automatically split between Kasha's commission account and the merchant's payout balance. No manual reconciliation needed.
- Automated KYB: Adyen's verification API handles identity checks, document validation, and screening against sanctions lists. Results are relayed back to Kasha via webhooks.
- Payout scheduling: Each sub-merchant has configurable payout schedules (daily, weekly, or on-demand) to their registered bank account.
- Multi-country: A single Adyen Platforms integration supports both CH and BR sub-merchants, with country-specific compliance handled by Adyen's regional entities.
11. Terminal & SoftPOS Strategy
Kasha POS's primary strategy is phone-as-terminal — eliminating the need for dedicated payment hardware. This dramatically lowers the barrier to entry for SME merchants who cannot justify the cost of traditional POS terminals.
SoftPOS: Phone as Terminal
CH BR Apple Tap to Pay on iPhone
The flagship payment acceptance method. Uses the NFC chip built into modern iPhones to accept contactless card payments directly on the device.
- Technology: NFC (Near Field Communication) via Apple's Tap to Pay SDK
- Integration: Adyen
TapToPaySDKembedded in the Kasha POS iOS app - Hardware required: None — just an iPhone XS or later
- Accepted methods: Visa, Mastercard, Amex (contactless), Apple Pay, Google Pay (via NFC)
- Compatibility: iPhone XS, XR, 11, 12, 13, 14, 15, 16 series and later
- Certification: PCI MPoC (Mobile Payments on COTS) compliant
- User flow: Open app → enter amount → customer taps card/phone → payment processed → receipt sent
BR Pix Tap to Pay
A groundbreaking Brazil-specific innovation launched by the BCB (Banco Central do Brasil) in February 2025.
- Technology: NFC-based phone-to-phone Pix payment
- How it works: Customer taps their phone against the merchant's phone — no QR code scanning needed
- Integration: Transfero SDK for Pix payment processing
- Speed: Instant settlement (Pix is real-time)
- Cost: Zero or near-zero transaction fees (Pix is free for individuals)
- Advantage: Combines the convenience of tap-to-pay with the instant settlement of Pix
- Availability: Android and iOS devices with NFC capability
QR Code Payments
Dynamic QR Codes
Generated per transaction with the payment amount encoded directly in the QR code. The customer simply scans and confirms — no need to manually enter an amount.
- BR Pix QR codes: Standard format defined by BCB (Banco Central). Generated via Transfero API. Contains merchant ID, amount, and transaction reference.
- CH TWINT QR codes: Generated via Adyen integration. TWINT is Switzerland's dominant mobile payment app with 5M+ active users.
- Use case: Standard retail transactions where the merchant enters the amount and presents the QR code to the customer on screen.
Static QR Codes
A permanent QR code assigned to the merchant. The customer scans and manually enters the payment amount. Ideal for high-throughput, low-friction environments.
- BR Pix static QR: Printed and displayed at the counter. Customer scans with any banking app, enters the amount, and confirms.
- CH TWINT static QR: Merchant's permanent TWINT code displayed at point of sale.
- Use case: Quick-service restaurants, market stalls, tipping jars, food trucks — anywhere speed matters more than amount control.
Phase 3+ Optional Hardware Partnerships
While SoftPOS is the core strategy, some merchants may require physical hardware for specific use cases. Starting in Phase 3, Kasha will offer optional hardware through partnerships:
- Bluetooth card readers: Compact readers (e.g., Adyen S1F2L) for merchants who want a dedicated device for chip-and-PIN or magstripe fallback
- Bluetooth thermal printers: 58mm/80mm receipt printers for merchants who need physical receipts (restaurants, retail)
- Customer-facing displays: Small screens showing transaction amount, payment confirmation, and branding
- Cash drawer integration: For merchants who still handle cash alongside digital payments — drawer opens automatically on cash tender
All hardware will be optional add-ons, never mandatory. The core value proposition remains zero-hardware payment acceptance.
Terminal Management
Terminal Entity Model
Every terminal — whether a SoftPOS device (iPhone), a static QR code, or a physical card reader — is registered, tracked, and managed as a first-class entity in the system.
// src/modules/terminal/terminal.interface.ts
interface ITerminal {
/** Unique terminal identifier (UUID v4) */
id: string;
/** Reference to the owning merchant */
merchantId: string;
/** Terminal type determines capabilities and payment methods */
type: 'SOFTPOS_IOS' | 'SOFTPOS_ANDROID' | 'QR_STATIC' | 'QR_DYNAMIC' | 'CARD_READER';
/** Current operational status */
status: 'ACTIVE' | 'INACTIVE' | 'SUSPENDED';
/** Device metadata (populated for SoftPOS and card readers) */
deviceInfo?: {
model: string; // e.g., "iPhone 15 Pro", "Galaxy S24"
os: string; // e.g., "iOS 18.2", "Android 15"
appVersion: string; // e.g., "1.4.2"
};
/** Timestamp of the most recent transaction on this terminal */
lastTransactionAt?: Date;
/** Lifetime transaction count for this terminal */
totalTransactions: number;
/** When this terminal was first registered */
createdAt: Date;
}
Terminal management capabilities include:
- Remote status control: Suspend or deactivate terminals from the admin dashboard (e.g., if a device is reported stolen)
- Version tracking: Monitor app versions across the fleet to ensure merchants are running compatible software
- Activity monitoring: Detect inactive terminals (no transactions in 30+ days) and trigger re-engagement flows
- Multi-terminal support: A single merchant can register multiple terminals (e.g., one iPhone per checkout lane)
12. Settlement & Treasury
Settlement is the process of moving funds from the customer's payment through the payment service provider and ultimately into the merchant's bank account. Kasha POS manages the complete settlement lifecycle, including commission deduction, multi-currency treasury, and automated reconciliation.
Settlement Flow
The end-to-end money movement from customer payment to merchant payout:
Payment is initiated via card tap (NFC), QR code scan (Pix or TWINT), or direct Pix transfer. The payment data is captured by the Kasha POS app and sent to the appropriate PSP.
Adyen or Transfero captures the payment, performs authorization with the card network or bank, and confirms the transaction. A webhook notification is sent to lr-pos-service with the transaction result.
Funds arrive in Kasha's settlement account according to the PSP's settlement schedule: T+1 for card payments via Adyen, instant for Pix via Transfero, same day for SIC/Open Banking in Switzerland.
Kasha's platform fee is deducted from the settled amount. This is handled automatically via Adyen's split payment configuration. Example: on a CHF 100 payment, Kasha retains CHF 0.50 (0.5% platform fee) before payout. PSP fees (Adyen's processing fee) are deducted separately.
The net amount (after PSP fees and Kasha commission) is transferred to the merchant's registered bank account. CH Via IBAN bank transfer (SIC clearing). BR Via Pix (instant) or TED/DOC bank transfer.
Automated matching of POS transactions ↔ PSP settlement reports ↔ bank account movements. Every transaction is traced from initiation to final payout. Discrepancies are flagged immediately for manual review.
Settlement Timelines
| Payment Method | PSP Settlement | Merchant Payout | Total (End-to-End) |
|---|---|---|---|
| Card CH | T+1 via Adyen | Same day or T+1 | T+1 to T+2 |
| TWINT CH | T+1 via Adyen | Same day | T+1 |
| SIC/Open Banking CH | Same day | Same day | Same day |
| Pix BR | Instant via Transfero | Instant or T+1 | Instant to T+1 |
| Card BR | T+1 via Adyen | T+1 (or next day with anticipation) | T+1 to T+30 |
| BRZ Stablecoin BR | Instant | Instant | Instant |
Note Brazilian card settlements have a T+30 standard timeline from the acquirer. The T+1 payout shown above is achieved through Kasha's anticipation engine (Section 9), which advances receivables at a 1-2% discount.
Multi-Currency Treasury
Currency Architecture
Kasha's treasury operates on a country-contained model — each country maintains its own currency and settlement infrastructure with no cross-currency settlement required between countries.
CH Swiss Treasury (CHF)
- All settlements in Swiss Francs (CHF)
- Settled via SIC (Swiss Interbank Clearing) or Adyen payout
- FX for international cards handled by Adyen at point of capture
- Merchant always receives CHF regardless of customer's card currency
BR Brazilian Treasury (BRL)
- All settlements in Brazilian Reais (BRL)
- Settled via Pix (instant) or standard bank transfer (TED)
- Optional: BRZ stablecoin settlement for crypto-forward merchants
- FX for international cards handled by Adyen at point of capture
- No cross-currency settlement: CH operations are entirely in CHF, BR operations entirely in BRL. This simplifies treasury management and eliminates FX risk at the platform level.
- FX at PSP level: When a tourist in Zurich pays with a USD Visa card, Adyen handles the USD → CHF conversion. Kasha and the merchant only ever see CHF.
- BRZ stablecoin option: Brazilian merchants can opt to receive settlement in BRZ (a BRL-pegged stablecoin) via Transfero, providing exposure to the crypto ecosystem while maintaining BRL-equivalent value.
Reconciliation Engine
Automated Three-Way Matching
The reconciliation engine performs automated matching across three data sources to ensure every cent is accounted for:
The reconciliation process runs automatically on a daily schedule:
- Transaction ↔ PSP matching: Every POS transaction is matched against the corresponding PSP settlement record using the unique transaction reference (PSP reference ID). Validates that the settled amount equals the expected amount minus fees.
- PSP ↔ Bank matching: PSP settlement batches are matched against incoming credits on Kasha's bank statements. Ensures that the total settled by the PSP matches the total credited to the bank account.
- Discrepancy handling: Any mismatches (amount differences, missing settlements, duplicate entries) are automatically flagged and queued for manual review by the operations team.
- Daily reports: Automated reconciliation reports generated each morning covering the previous day's settlements, including match rate, discrepancy count, and outstanding items.
Settlement Architecture Overview
13. Backend Service: lr-pos-service
NestJS 11 microservice following existing Kasha patterns.
Pure RPC controllers — no HTTP decorators.
The API Gateway handles all HTTP routing and forwards commands over RabbitMQ.
TypeORM with PostgreSQL for persistence.
RabbitMQ (LR_POS_SERVICE queue) for inter-service communication.
Module Structure
lr-pos-service/
├── src/
│ ├── main.ts # Bootstrap, RabbitMQ consumer (LR_POS_SERVICE queue)
│ ├── config/
│ │ ├── config.ts # registerAs('app'), env vars
│ │ ├── config.module.ts # Joi validation, defaults
│ │ └── config.service.ts # Typed config getters
│ ├── modules/
│ │ ├── app.module.ts # Root module
│ │ ├── health/ # Health check (heap memory)
│ │ ├── merchant/ # Merchant onboarding, KYB, sub-accounts
│ │ │ ├── merchant.interface.ts # IMerchant, ICreateMerchantDto, enums
│ │ │ ├── merchant.entity.ts # TypeORM: pos_merchants table
│ │ │ ├── merchant.service.ts # CRUD + status transitions
│ │ │ ├── merchant.controller.ts # @MessagePattern RPC handlers
│ │ │ └── merchant.module.ts
│ │ ├── terminal/ # SoftPOS registration, QR terminal mgmt
│ │ ├── transaction/ # Payment processing orchestration
│ │ ├── session/ # POS session lifecycle (NEW)
│ │ │ ├── session.interface.ts # ISession, SessionStatus enum
│ │ │ ├── session.entity.ts # pos_sessions table
│ │ │ ├── session.service.ts # Create, addItems, setAmount, complete
│ │ │ └── session.controller.ts # RPC: pos_create_session, pos_add_items, etc.
│ │ ├── settlement/ # Payout scheduling, bank transfers
│ │ ├── anticipation/ # Payment anticipation (credit) engine
│ │ ├── reconciliation/ # Match transactions ↔ settlements
│ │ ├── webhook/ # Adyen + Transfero webhook handlers (HTTP)
│ │ └── analytics/ # Sales reports, payment method breakdown
│ ├── providers/
│ │ ├── adyen/ # Adyen SDK wrapper
│ │ ├── transfero/ # Transfero API wrapper
│ │ └── banking/ # Direct IBAN settlement (SIC)
│ └── common/
│ └── services/
│ └── rabbitmq-clients.ts # ClientProxy providers
├── test/
│ └── bootstrap.ts
├── Dockerfile # Multi-stage (dev/prod)
├── package.json
└── tsconfig.json
Key Entities
NEW pos_sessions — Central Session Entity
Every payment interaction starts as a session. Sessions link to bookings, invoices, CRM customers, and catalogue line items.
@Entity('pos_sessions')
export class SessionEntity {
@PrimaryGeneratedColumn('uuid') id: string;
@Column('uuid') merchantId: string;
@Column('uuid', { nullable: true }) terminalId: string;
@Column('uuid', { nullable: true }) customerId: string; // link to CRM
@Column('uuid', { nullable: true }) bookingId: string; // link to booking
@Column('uuid', { nullable: true }) invoiceId: string; // link to invoice
@Column({ type: 'enum', enum: SessionStatus }) status: SessionStatus;
@Column({ type: 'enum', enum: SessionType }) type: SessionType;
// WALK_IN, BOOKING_DEPOSIT, BOOKING_FINAL, CATALOGUE_SALE
@Column('jsonb', { nullable: true }) lineItems: ILineItem[]; // items from catalogue
@Column('decimal', { precision: 12, scale: 2 }) amount: number;
@Column('decimal', { precision: 12, scale: 2, default: 0 }) depositAmount: number;
@Column('varchar', { length: 3 }) currency: string; // CHF or BRL
@Column({ type: 'enum', enum: PaymentMethod, nullable: true }) paymentMethod: PaymentMethod;
@Column('uuid', { nullable: true }) transactionId: string; // link to pos_transactions
@CreateDateColumn() createdAt: Date;
@UpdateDateColumn() updatedAt: Date;
}
pos_merchants
Merchant onboarding and KYB state.
id (uuid PK) | businessId (uuid) | legalName (varchar) | tradingName (varchar)
country (enum: CH, BR) | taxId (varchar) | kybStatus (enum) | adyenSubAccountId (varchar)
transferoMerchantId (varchar) | bankAccount (jsonb) | status (enum) | createdAt | updatedAt
pos_transactions
Individual payment records linked to sessions and terminals.
id (uuid PK) | merchantId (uuid) | terminalId (uuid) | sessionId (uuid)
amount (decimal 12,2) | currency (varchar 3) | paymentMethod (enum)
status (enum: PENDING, AUTHORIZED, CAPTURED, FAILED, REFUNDED)
pspReference (varchar) | pspProvider (enum: ADYEN, TRANSFERO)
refundedAmount (decimal 12,2) | metadata (jsonb) | createdAt | updatedAt
pos_terminals
Registered payment acceptance devices.
id (uuid PK) | merchantId (uuid) | type (enum: SOFTPOS, QR_STATIC, QR_DYNAMIC)
label (varchar) | deviceFingerprint (varchar) | status (enum: ACTIVE, INACTIVE, SUSPENDED)
lastActivityAt (timestamp) | totalVolume (decimal 14,2) | createdAt | updatedAt
pos_settlements
Scheduled and completed payouts to merchant bank accounts.
id (uuid PK) | merchantId (uuid) | amount (decimal 12,2) | currency (varchar 3)
status (enum: PENDING, PROCESSING, COMPLETED, FAILED) | scheduledDate (date)
completedAt (timestamp) | bankReference (varchar) | transactionIds (uuid[]) | createdAt
pos_anticipations
Receivables advance requests and disbursements.
id (uuid PK) | merchantId (uuid) | grossAmount (decimal 12,2) | feeAmount (decimal 12,2)
netAmount (decimal 12,2) | feeRate (decimal 5,4) | status (enum: REQUESTED, APPROVED, DISBURSED, REJECTED)
receivableIds (uuid[]) | disbursedAt (timestamp) | createdAt | updatedAt
pos_reconciliations
Transaction-to-settlement matching records.
id (uuid PK) | transactionId (uuid) | settlementId (uuid) | status (enum: MATCHED, UNMATCHED, DISPUTED)
pspAmount (decimal 12,2) | settledAmount (decimal 12,2) | discrepancy (decimal 12,2) | createdAt
RPC Endpoints @MessagePattern
All handlers use @MessagePattern decorators. No HTTP verbs — the API Gateway translates REST to RPC.
| Pattern | Method | Description |
|---|---|---|
pos_create_session |
create | Create new POS session |
pos_add_session_items |
addItems | Add line items to session |
pos_complete_session |
complete | Process payment and complete |
pos_create_merchant |
create | Register new merchant |
pos_get_merchant |
findById | Get merchant details |
pos_update_merchant |
update | Update merchant info |
pos_create_terminal |
create | Register terminal/device |
pos_get_terminals |
findByMerchant | List merchant’s terminals |
pos_get_transactions |
findWithFilters | List transactions with filters |
pos_refund_transaction |
refund | Issue refund |
pos_get_settlements |
findWithFilters | List settlements |
pos_create_anticipation |
create | Request receivables advance |
pos_get_anticipations |
findByMerchant | List anticipation requests |
pos_get_sales_summary |
getSummary | Sales analytics |
pos_get_daily_sales |
getDailySales | Daily breakdown |
Webhook Controller HTTP Exception
Webhooks from Adyen and Transfero are the sole exception to the pure-RPC pattern.
External PSPs POST notifications directly to HTTP endpoints, so these controllers use standard
@Post() decorators. The API Gateway proxies these requests through to lr-pos-service
without RabbitMQ translation.
@Controller('webhooks')
export class WebhookController {
@Post('adyen')
async handleAdyen(@Body() notification: AdyenNotification) {
// Verify HMAC signature
// Update transaction status (AUTHORIZED, CAPTURED, FAILED, REFUNDED)
// Emit pos.payment.completed event
}
@Post('transfero')
async handleTransfero(@Body() notification: TransferoNotification) {
// Verify webhook signature
// Update Pix payment status
// Emit pos.payment.completed event
}
}
Inter-Service Events RabbitMQ
Events Published by lr-pos-service
| Event | Consumed By |
|---|---|
pos.session.created |
Analytics, CRM |
pos.session.completed |
Invoicing, CRM, Analytics |
pos.payment.completed |
Invoicing, CRM, Settlement |
pos.settlement.ready |
Banking service (payout) |
pos.stock.sold |
Catalogue (stock decrement) |
pos.anticipation.disbursed |
Banking, Notifications |
Events Consumed by lr-pos-service
| Event | Action |
|---|---|
booking.deposit.required |
Create deposit session (type: BOOKING_DEPOSIT) |
booking.completed |
Create final payment session (type: BOOKING_FINAL) |
catalogue.item.updated |
Sync item prices in active sessions |
banking.payout.completed |
Update settlement status to COMPLETED |
14. Frontend: lr-pos-ui
Next.js 15 App Router with [lang]/ internationalised routing.
Built on @kashatech/lr-fe-framework for the API fetch wrapper and React Query integration,
and @kashatech/lr-fe-components for the shared UI component library.
Page Structure
src/app/[lang]/
├── dashboard/page.tsx # Today's sales, payment breakdown, settlement status
├── transactions/page.tsx # Live feed with filtering (card, Pix, TWINT, QR)
├── sessions/page.tsx # Active POS sessions, session history
├── anticipation/page.tsx # Available receivables, request advance, active loans
├── terminals/page.tsx # Registered devices, status, last activity
├── settlement/page.tsx # Bank account, upcoming/completed payouts
└── settings/page.tsx # Payment methods config, IBAN, Pix keys, profile
Key Components
TransactionFeed
Real-time scrolling list of transactions with status badges (CAPTURED PENDING), payment method icons (card, Pix, TWINT, QR), and formatted amounts. Filterable by method, status, and date range. Uses React Query with a short polling interval for near-real-time updates.
SessionCard
Displays an active POS session’s current state: status indicator, line items list with quantities and prices, running total, deposit vs. remaining balance, and a payment method selector. Supports the full session lifecycle from creation through item addition to payment completion.
AnticipationCalculator BR
Interactive widget for Brazilian merchants. Select receivables by date range to see the available gross amount. Fee calculation updates in real time as the selection changes. Clear comparison: “Receive R$X tomorrow” vs. “Wait 30 days for R$Y”. Confirm button triggers the anticipation request with a confirmation dialog.
TerminalCard
Device card showing terminal type (SoftPOS or QR), a colour-coded status LED (green = active, grey = inactive, red = suspended), last transaction timestamp, and cumulative volume. Click-through to terminal detail and transaction history.
SettlementTimeline
Vertical timeline visualisation of settlements. Each node shows the settlement amount, scheduled date, and current status with colour coding: PENDING, PROCESSING, COMPLETED. Completed nodes show the bank reference and actual completion timestamp.
SalesDashboard
Charts and summary cards for the dashboard page. Revenue breakdown by payment method (doughnut chart), daily sales trend (line chart), and top products if the catalogue module is linked (horizontal bar chart). Stat cards at the top show today’s total, transaction count, average ticket, and next settlement amount.
SidebarItems
Navigation structure with grouped sections:
Services Layer Fetch Wrapper Pattern
Each domain has a dedicated service file that wraps the @kashatech/lr-fe-framework
request helper. Services are pure functions — no state, no hooks. They map 1:1 to API
Gateway endpoints.
// src/services/sessions.service.ts
export const createSession = async ({ businessId, data }) => {
return await request.post({
path: `/businesses/${businessId}/pos/sessions`,
config: { data },
});
};
export const addSessionItems = async ({ businessId, sessionId, items }) => {
return await request.post({
path: `/businesses/${businessId}/pos/sessions/${sessionId}/items`,
config: { data: { items } },
});
};
export const completeSession = async ({ businessId, sessionId, paymentMethod }) => {
return await request.post({
path: `/businesses/${businessId}/pos/sessions/${sessionId}/complete`,
config: { data: { paymentMethod } },
});
};
export const getSessions = async ({ businessId, params }) => {
return await request.get({
path: `/businesses/${businessId}/pos/sessions`,
config: { params },
});
};
Hooks Layer React Query Pattern
Custom hooks wrap the service functions with React Query for caching, background refetching,
and optimistic updates. Query keys follow the
[DOMAIN_KEY, { filters }] convention for targeted invalidation.
// src/hooks/use-sessions.ts
const SESSIONS_QUERY_KEY = 'pos-sessions';
export const useSessions = (status?: SessionStatus) => {
const { businessId } = useBusinessContext();
const { data, isLoading, isFetching } = useQuery({
queryKey: [SESSIONS_QUERY_KEY, { businessId, status }],
queryFn: () => getSessions({ businessId, params: { status } }),
enabled: !!businessId,
});
return { sessions: data?.data ?? [], isLoading, isFetching };
};
export const useCreateSession = () => {
const { businessId } = useBusinessContext();
const queryClient = useQueryClient();
return useMutation({
mutationFn: (data: ICreateSessionDto) =>
createSession({ businessId, data }),
onSuccess: () =>
queryClient.invalidateQueries({ queryKey: [SESSIONS_QUERY_KEY] }),
});
};
export const useCompleteSession = () => {
const { businessId } = useBusinessContext();
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ sessionId, paymentMethod }: ICompleteSessionDto) =>
completeSession({ businessId, sessionId, paymentMethod }),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: [SESSIONS_QUERY_KEY] });
queryClient.invalidateQueries({ queryKey: ['pos-transactions'] });
},
});
};
15. API Gateway Integration
New routes added to lr-api-gateway under the /businesses/:id/pos/ namespace.
The gateway translates REST HTTP requests into RabbitMQ RPC calls targeting the
LR_POS_SERVICE queue. Authentication and rate-limiting are handled at the gateway level.
REST Endpoints
| Method | Path | RPC Pattern | Description |
|---|---|---|---|
| POST | /businesses/:id/pos/sessions |
pos_create_session |
Create POS session |
| POST | /businesses/:id/pos/sessions/:sid/items |
pos_add_session_items |
Add items to session |
| POST | /businesses/:id/pos/sessions/:sid/complete |
pos_complete_session |
Complete session |
| GET | /businesses/:id/pos/sessions |
pos_get_sessions |
List sessions |
| POST | /businesses/:id/pos/merchants |
pos_create_merchant |
Register merchant |
| GET | /businesses/:id/pos/merchants/:mid |
pos_get_merchant |
Get merchant |
| PUT | /businesses/:id/pos/merchants/:mid |
pos_update_merchant |
Update merchant |
| POST | /businesses/:id/pos/terminals |
pos_create_terminal |
Register terminal |
| GET | /businesses/:id/pos/terminals |
pos_get_terminals |
List terminals |
| GET | /businesses/:id/pos/transactions |
pos_get_transactions |
List transactions |
| POST | /businesses/:id/pos/transactions/:tid/refund |
pos_refund_transaction |
Refund transaction |
| GET | /businesses/:id/pos/settlements |
pos_get_settlements |
List settlements |
| POST | /businesses/:id/pos/anticipations |
pos_create_anticipation |
Request advance |
| GET | /businesses/:id/pos/anticipations |
pos_get_anticipations |
List advances |
| GET | /businesses/:id/pos/analytics/summary |
pos_get_sales_summary |
Sales summary |
| GET | /businesses/:id/pos/analytics/daily |
pos_get_daily_sales |
Daily breakdown |
Gateway Implementation Pattern
Each route follows the same pattern: extract path parameters and body, send an RPC message
to the LR_POS_SERVICE queue via ClientProxy, and return the result.
Authentication middleware validates the JWT and attaches the business context before the route handler.
// lr-api-gateway/src/modules/pos/pos.routes.ts
router.post('/businesses/:businessId/pos/sessions', async (req, res) => {
const result = await rabbitMQClient.send(
{ cmd: 'pos_create_session' },
{ ...req.body, businessId: req.params.businessId }
);
res.json(result);
});
router.post('/businesses/:businessId/pos/sessions/:sessionId/items', async (req, res) => {
const result = await rabbitMQClient.send(
{ cmd: 'pos_add_session_items' },
{ ...req.body, businessId: req.params.businessId, sessionId: req.params.sessionId }
);
res.json(result);
});
router.post('/businesses/:businessId/pos/sessions/:sessionId/complete', async (req, res) => {
const result = await rabbitMQClient.send(
{ cmd: 'pos_complete_session' },
{ ...req.body, businessId: req.params.businessId, sessionId: req.params.sessionId }
);
res.json(result);
});
router.get('/businesses/:businessId/pos/transactions', async (req, res) => {
const result = await rabbitMQClient.send(
{ cmd: 'pos_get_transactions' },
{ businessId: req.params.businessId, ...req.query }
);
res.json(result);
});
Webhook Routes Direct HTTP Passthrough
Webhook endpoints bypass the RabbitMQ RPC pattern entirely. External PSPs (Adyen, Transfero)
POST notifications directly to these URLs. The API Gateway proxies these requests through to
the lr-pos-service webhook controller over HTTP, not RabbitMQ.
POST /webhooks/pos/adyen → lr-pos-service webhook controller (Adyen notifications)
POST /webhooks/pos/transfero → lr-pos-service webhook controller (Transfero/Pix notifications)
These routes are unauthenticated at the JWT level but verified via PSP-specific HMAC signatures within the webhook controller itself.
16. Luma AI Integration
POS domain tools for Luma, the Kasha AI assistant
(lr-luma-service). These tools allow merchants to query their POS data and
perform actions through natural language conversation. Read tools execute immediately;
write tools require explicit merchant confirmation before execution.
New Luma Tools for POS
| Tool | Action | Example Prompt |
|---|---|---|
pos_get_sales |
Read | “How much did we sell today?” |
pos_get_transactions |
Read | “Show me the last 10 transactions” |
pos_get_settlement_status |
Read | “When is my next payout?” |
pos_get_anticipation_options |
Read | “How much can I anticipate?” |
pos_create_refund |
Write (confirm) | “Refund the last transaction” |
pos_request_anticipation |
Write (confirm) | “I need cash now, anticipate R$5000” |
pos_get_terminal_status |
Read | “Is my terminal working?” |
pos_get_daily_report |
Read | “Give me today’s sales report” |
Luma Quick Action Chips POS Context
When a merchant is on the POS dashboard, Luma detects the page context and displays relevant quick-action chips. These are pre-built prompts that the merchant can tap to instantly query common POS data without typing.
Example Conversation
A typical merchant interaction with Luma on the POS dashboard:
pos_get_sales_summary tool]“Today you’ve made R$2,340 across 47 transactions.
• Pix: R$1,200 (28 txns)
• Card: R$980 (15 txns)
• Cash: R$160 (4 txns)
Your next settlement of R$1,890 is scheduled for tomorrow.”
pos_get_anticipation_options tool]“You have R$8,500 in card receivables available for anticipation. At your current rate (1.5%), you’d receive R$8,372.50 tomorrow.
Would you like me to submit the request?”
pos_request_anticipation with confirmation]“Anticipation requested: R$8,372.50 will be deposited to your account via Pix by tomorrow morning.”
Tool Registration Pattern
POS tools are registered in lr-luma-service following the existing tool provider pattern.
Each tool defines its name, description, parameter schema, and an execute function
that sends an RPC call to lr-pos-service and formats the response for the LLM.
// lr-luma-service/src/tools/pos/pos-get-sales.tool.ts
export const posGetSalesTool: LumaTool = {
name: 'pos_get_sales',
description: 'Get sales summary for the merchant. Returns total revenue, ' +
'transaction count, and breakdown by payment method for a given date range.',
parameters: {
type: 'object',
properties: {
dateFrom: { type: 'string', format: 'date', description: 'Start date (ISO)' },
dateTo: { type: 'string', format: 'date', description: 'End date (ISO)' },
},
},
actionType: 'read',
async execute(params, context) {
const result = await rabbitMQClient.send(
{ cmd: 'pos_get_sales_summary' },
{ merchantId: context.merchantId, ...params }
);
return formatSalesSummary(result);
},
};
17. Phased Rollout
Kasha POS is delivered in five distinct phases over 12 months, moving from a focused MVP to a full-featured payment acceptance platform. Each phase builds on the previous one, adding new payment methods, deeper integrations, and advanced financial services.
Phase 1 Foundation — Months 1–2
The minimum viable product. Everything a merchant needs to accept their first payment and see their money. Ship fast, prove the model, get merchants live.
- Core POS session lifecycle: create → pay → receipt
- Adyen integration: card payments CH, TWINT CH
- Transfero integration: Pix QR payments BR
- Basic merchant onboarding (manual KYB)
- SoftPOS: Apple Tap to Pay CH
- Simple transaction list + daily summary
- Receipt generation (digital)
lr-pos-service+lr-pos-uideployed- API Gateway routes added
Phase 1 Deliverables
Phase 2 Growth — Months 3–4
The revenue phase. Payment anticipation lands as the killer feature for Brazil. New payment methods expand coverage. Cross-module integrations start connecting POS to the rest of the Kasha platform.
- Payment anticipation engine BR — Killer Feature
- Pix Tap to Pay BR
- PostFinance Card CH
- Open Banking / SIC settlement CH
- Booking integration (deposit collection, final payments)
- Invoice auto-generation from POS sessions
- Settlement dashboard with payout tracking
- CRM integration (link payments to customers)
Phase 3 Expansion — Months 4–6
Deepening the platform. Catalogue integration turns POS into a lightweight retail system. New payment methods (Boleto, BRZ stablecoin) round out coverage. Analytics become actionable.
- Catalogue integration (light stock management)
- Barcode/SKU scanning in POS session
- Boleto payments BR
- BRZ stablecoin settlement BR
- Advanced analytics (revenue trends, payment mix, top products)
- Multi-terminal support per merchant
- Automated reconciliation engine
- Merchant self-service onboarding (automated KYB via Adyen)
Phase 4 Credit & Advanced — Months 6–9
Financial services layer. Adyen Capital unlocks merchant lending in Switzerland (requires 4+ months of transaction history per client). Crypto payments via Transfero open a new channel. Risk scoring matures.
- Adyen Capital integration CH — requires 4+ months tx history per client
- Crypto payments via Transfero (BTC/ETH → BRZ auto-convert) BR
- Advanced risk scoring for anticipation
- Hardware terminal partnerships (optional Bluetooth readers)
- Customer-facing payment page (QR code links to payment form)
- Luma AI full integration (all POS tools)
Phase 5 Scale — Months 9–12
Platform maturity. Multi-location support, franchise management, white-label capabilities, and marketplace settlement transform Kasha POS from a single-merchant tool into an enterprise-grade platform.
- Multi-location merchant support
- Franchise / chain management
- Advanced reporting and exports
- White-label POS for partners
- Marketplace settlement (multi-vendor)
- International card acceptance optimization
- Performance optimization for high-volume merchants
Timeline Overview
Cards + TWINT + Pix QR. Core POS lifecycle. Basic dashboard. First merchants live.
Anticipation engine (BR). Pix NFC. PostFinance. Open Banking. Booking + invoice integration.
Catalogue + scanning. Boleto + BRZ. Multi-terminal. Automated reconciliation. Self-service onboarding.
Adyen Capital (CH). Crypto payments. Advanced risk scoring. Hardware terminals. Luma AI integration.
Multi-location. Franchise management. White-label. Marketplace settlement. Performance optimization.
18. Regulatory Compliance
Payment acceptance is one of the most regulated domains in fintech. Kasha operates in two distinct regulatory environments — Switzerland and Brazil — each with its own set of requirements for payment processing, data protection, anti-money laundering, and financial licensing.
CH Switzerland
- FINMA — Financial Market Supervisory Authority. Kasha needs appropriate licensing for payment services. FINMA regulates all financial intermediaries in Switzerland, including payment service providers.
- PCI DSS — Payment Card Industry Data Security Standard. Required for card acceptance. Level 4 merchant (< 1M txns/year) needs SAQ-A or SAQ-B depending on integration method.
- PCI MPoC — Mobile Payment on COTS (Commercial Off-The-Shelf). Required for SoftPOS (Apple Tap to Pay). Adyen handles this via their certified SDK, which has passed MPoC evaluation.
- FADP (nDSG) — Swiss Federal Act on Data Protection. Data localization is not strictly required but recommended. Customer data handling must comply with the revised FADP that entered into force September 2023. Consent management, data minimization, and breach notification obligations apply.
- TWINT Terms — TWINT AG participation requirements via Adyen. Adyen is an authorized TWINT acquirer, so Kasha merchants are onboarded through Adyen's TWINT integration without needing direct TWINT AG agreements.
- AML/KYC — Anti-Money Laundering requirements for merchant onboarding. Beneficial ownership declaration required. Swiss AML Act (AMLA/GwG) applies to all financial intermediaries. Adyen handles merchant verification as the licensed acquirer.
BR Brazil
- BCB (Banco Central do Brasil) — Central Bank regulates all payment institutions. Pix regulations apply to all participants in the Pix ecosystem. Transfero is a licensed payment institution, so Kasha operates under Transfero's regulatory umbrella for Pix services.
- PCI DSS — Same global standard, enforced by card brands (Visa, Mastercard) through local acquirers. Applies to any entity that stores, processes, or transmits cardholder data.
- PCI MPoC — Required for Pix Tap to Pay implementation. The NFC-based Pix payment acceptance on merchant phones must comply with COTS security standards.
- LGPD — Lei Geral de Proteção de Dados (Brazilian GDPR). Requires customer consent for data collection, data minimization principles, breach notification within reasonable time, and appointment of a Data Protection Officer (DPO). Fines up to 2% of revenue (capped at R$50M per infraction).
- Antecipação Regulations — BCB Resolution 264/2022. Rules for receivables registration and anticipation. Receivables must be registered in approved registrars (TAG, CIP, CERC). Merchants have the right to choose their anticipation provider. Transparent fee disclosure is mandatory.
- PIX Regulations — BCB rules for Pix participants. QR code standards (static and dynamic), settlement rules (instant, 24/7/365), dispute resolution (MED — Mecanismo Especial de Devolução), and transaction limits apply.
- CNPJ/CPF Requirements — Tax identification for merchants (CNPJ — Cadastro Nacional da Pessoa Jurídica) and customers (CPF — Cadastro de Pessoas Físicas). Required for all financial transactions and merchant onboarding in Brazil.
Compliance Matrix
| Regulation | Country | Impact | Responsibility | Phase |
|---|---|---|---|---|
| PCI DSS | CH BR | Card acceptance | Adyen (PCI Level 1 certified) | Phase 1 |
| PCI MPoC | CH BR | SoftPOS | Adyen SDK certified | Phase 1 |
| FINMA | CH | Payment license | Kasha legal | Phase 1 |
| FADP / nDSG | CH | Data protection | Kasha engineering | Phase 1 |
| BCB Payment Institution | BR | Pix participation | Transfero (licensed) | Phase 1 |
| LGPD | BR | Data protection | Kasha engineering | Phase 1 |
| AML / KYC | CH BR | Merchant onboarding | Adyen verification API | Phase 1 |
| BCB Res. 264/2022 | BR | Receivables anticipation | Kasha legal + engineering | Phase 2 |
| TWINT Terms | CH | TWINT acceptance | Via Adyen | Phase 1 |
| Crypto Regulations | BR | BRZ / crypto payments | Transfero (licensed) | Phase 3 |
19. Capability Map
The complete inventory of all POS capabilities, organized by domain. This map serves as the definitive reference for what Kasha POS can do across its full lifecycle from MVP to scale.
Payment Acceptance
- Accept card payments (Visa, Mastercard, Amex)
- Accept TWINT payments CH
- Accept Pix payments via QR code BR
- Accept Pix Tap to Pay BR
- Accept Apple Tap to Pay on iPhone
- Accept PostFinance Card CH
- Accept open banking payments CH
- Accept Boleto BR
- Accept BRZ stablecoin BR
- Accept crypto (BTC/ETH via Transfero) BR
- Process refunds (full and partial)
- Handle chargebacks
POS Sessions
- Create walk-in payment sessions
- Create booking-linked deposit sessions
- Create booking final payment sessions
- Create catalogue-based sale sessions
- Add line items from catalogue
- Apply discounts
- Split payments (partial amounts)
- Link session to customer (CRM)
- Link session to booking
- Link session to invoice
- Generate digital receipts
Merchant Management
- Merchant registration and onboarding
- KYB verification (per country)
- PSP sub-merchant account creation
- Bank account / Pix key management
- Payment method configuration
- Business profile management
Terminal Management
- Register SoftPOS devices (iPhone)
- Generate static QR codes
- Generate dynamic QR codes per transaction
- Monitor terminal status and health
- Track terminal transaction volume
Settlement & Treasury
- Automated payout scheduling
- Multi-currency settlement (CHF, BRL)
- Real-time settlement tracking
- Bank transfer via SIC CH
- Pix instant settlement BR
- BRZ stablecoin settlement BR
- Settlement reconciliation
Payment Anticipation (Credit)
- View available receivables BR
- Calculate anticipation fees
- Risk scoring (in-house) BR
- Request receivables advance BR
- Next-day disbursement via Pix BR
- Adyen Capital merchant lending CH Phase 4
- Anticipation history and reporting
Analytics & Reporting
- Real-time sales dashboard
- Payment method breakdown
- Daily / weekly / monthly trends
- Top products (with catalogue)
- Settlement reports
- Reconciliation reports
- Export to CSV / PDF
Cross-Module Integration
- Auto-generate invoices from POS sessions
- Sync with booking deposits and final payments
- Decrement catalogue stock on sale
- Update CRM customer purchase history
- Luma AI query and action tools
- Banking service payout integration