Two stacks sit behind this app: a Vaud cantonal-bank account that holds the money, and TWINT SA’s real-time payment rail that moves it. A useful integration is not one ingestion problem pretending to be two — it is two ingestion problems wearing the same icon. The recommended route reflects that split.
BCV TWINT is the BCV-branded build of the national TWINT wallet. The cardholder authenticates through BCV Mobile (with BCV smartID), the wallet draws from a current or joint BCV account, and TWINT’s rail clears the payment to a person, a terminal, an online checkout, a parking meter or a charity. For an integrator this means the data sits in two ledgers — the BCV core, and TWINT’s event store — and a working build has to map them onto one event timeline before any downstream use case (reconciliation, fraud signal, expense feed, loyalty matching) is honest.
Where the data sits inside BCV TWINT
| Data domain | Origin inside the app | Granularity | Typical use |
|---|---|---|---|
| Wallet events | TWINT event store, mirrored into the BCV account | Per-event: amount, counterparty type, channel (P2P / merchant / QR terminal / parking / voucher) | Expense feeds, real-time spend signals, reconciliation |
| Linked-account statement | BCV core-banking (the current or joint account behind the wallet) | Settled lines, value date, IBAN-masked counterparty | Account aggregation, audit, daily reconcile |
| Loyalty membership | TWINT side of the app (Supercard, Cumulus, Jelmoli are explicit examples in the listing) | Scheme link state + receipt match where supplied | Loyalty enrichment of transactions |
| Parking sessions | Wallet-side state, refunded for unused time | Session start/end, zone, refund amount | Mobility expense, employee reimbursement |
| Saved-merchant preferences | Wallet (SBB, Swisscom, Migros named as examples) | Merchant + saved-as-default flag | Subscription / recurring-merchant detection |
| Buy-now-pay-later state | TWINT-side, 30-day window per the listing | BNPL line + due date | Cash-flow forecast, credit-risk signal |
| Vouchers and super deals | Wallet-side | Voucher inventory, expiry | Reward inventories, gift-card resale parity |
Eligibility constraints sit alongside the data and shape what a build can actually return: a user has to be a private individual on an eligible BCV account, holding a Swiss mobile number, and BCV TWINT is private-use-only (the app description rules out merchant-side receiving via send-money). These are surfaces a careful integrator surfaces back to the client up front, not at QA.
The three routes that actually fit this wallet
Three authorized routes are on the table for BCV TWINT. None of them are exclusive — most builds combine two.
1. Authorized interface integration of the wallet (the spine for most builds)
Under the user’s consent and within an NDA, we instrument the BCV TWINT app and the BCV Mobile companion, characterize the request/response and event-push surfaces the wallet uses with its own backend, and lift the parts the integrator needs into a normalized event stream. This reaches the wallet-side surfaces — TWINT events, loyalty link state, parking sessions, vouchers, BNPL — that no bank-aggregation channel exposes. Durability is medium: BCV and TWINT SA do iterate, and we plan for a re-validation pass into ongoing maintenance.
2. SIX bLink consented multibanking (where the read is account-level)
For the BCV-account side of the picture — statement, balance, standing-order context — the right channel is bLink, the SIX-operated open-banking platform whose retail multibanking launched on 25 November 2025 (per the SIX media release). bLink is a market-driven, consent-based interface that depends on the third-party provider posture; we coordinate the TPP onboarding with the client during the engagement. bLink does not return the TWINT event stream or wallet-side state, which is why it is route 2 and not route 1.
3. User-consented credential and export flow
For one-shot extracts (audit, dispute, migration) we can run a consented credential or export pull against the BCV Mobile / BCV TWINT pair. Cheaper, slower, and lighter on infrastructure than the live integration. It is the right answer when the use case is a finite pull, not a continuous feed.
The recommendation for a typical BCV TWINT build: route 1 carries the wallet, route 2 carries the account, route 3 sits in the corner for one-off pulls. We come back with a written scope of which surfaces go on which route.
What lands in your repo when this build ships
- Runnable source (Python and Node.js). The wallet event endpoint, idempotent ingestion of TWINT events, the daily reconciliation script against the BCV statement, and a thin abstraction so the same caller hits live or a fixture file. Code-first, because it is what an ingestion team needs on day one.
- Webhook handler and signature verification. An HMAC-signed fan-out edge that turns the poll into push, with retry/backoff, replay protection, and an idempotency-key contract documented in the README.
- Test harness with replayable fixtures. Recorded responses for the surfaces above, plus a thin live-mode against a consenting BCV account that we arrange with you during onboarding (no sandbox is a precondition; the harness runs against fixtures by default).
- Batch reconciliation tool. Pairs TWINT events to BCV statement lines, flags drift (late-arriving events, reversals, parking refunds), and emits a daily diff report.
- Normalized OpenAPI surface. An OpenAPI 3.1 spec for the event stream plus a small JSON schema for the loyalty sub-surface — same shape regardless of whether the upstream call was the wallet or bLink.
- Auth-flow report. The smartID → BCV Mobile → TWINT consent chain mapped out, with the two distinct re-auth windows clearly labelled.
- Interface documentation and a compliance / data-retention memo. What is logged, what is hashed, what is dropped, and how the consent record is stored so it survives an audit.
An ingestion sketch for the BCV-linked wallet
Illustrative — names confirmed during the build, not a vendor-published contract.
# Pull, normalized to the integrator's stable shape
GET /v1/bcv-twint/wallet/events?since=2026-04-01T00:00:00Z
Authorization: Bearer <consent-bound token, per-account>
X-Idempotency-Key: 0c5b...
# 200 OK
{
"wallet_id": "...",
"linked_bcv_iban_masked": "CH** **** **** **** **42",
"currency": "CHF",
"events": [
{
"id": "twint_evt_...",
"kind": "p2p_sent | p2p_received | merchant | qr_terminal | parking | voucher | bnpl",
"amount": 42.50,
"counterparty": { "type": "user | merchant | charity", "display": "..." },
"occurred_at": "2026-04-12T08:11:32+02:00",
"settled_from": "bcv_account | credit_card",
"loyalty": [ { "scheme": "Supercard", "linked": true } ],
"reconciliation": { "bcv_statement_id": null, "state": "pending" }
}
],
"next_since": "2026-04-12T08:11:32+02:00"
}
# Webhook fan-out (when push semantics are requested)
POST https://<your-host>/twint-events
X-Signature: hmac-sha256=...
X-Replay-Window: 300
{ "event_id": "twint_evt_...", "kind": "p2p_received", "amount": 12.00, ... }
# Error contract (excerpt)
# 401 consent_expired -> renew TWINT consent (separate from BCV smartID)
# 423 smartid_reauth_needed -> BCV Mobile must re-auth the cardholder
# 409 reconciliation_drift -> a TWINT event arrived late; the daily diff will catch it
Two non-obvious things about wiring this app
These are the items that, in practice, separate a build that runs from one that silently expires. We design for them up front.
- BCV smartID and TWINT consent are two windows, not one. BCV smartID authenticates the cardholder into BCV Mobile, which is the trust anchor that lets TWINT confirm a payment. The TWINT consent that lets an integration read the wallet has its own lifetime. We map both into the session model so the integration knows which re-auth to trigger, and which error to surface — confusing them is the single most common reason TWINT integrations fail in week six.
- TWINT events and BCV statement lines are not the same record. A TWINT spend appears in both ledgers, with different identifiers and clearing semantics, and reversals/late arrivals are normal on the rail. The build we deliver normalizes the two into a single event ledger with idempotent dedup and a daily reconciliation pass; an integrator who treats either ledger as authoritative on its own ends up with double-spends on month-end.
- Loyalty surfaces are sub-windowed. Supercard, Cumulus and Jelmoli linkage lives on the TWINT side, and each scheme has its own opt-in and refresh contract. We scope these as a separate sub-feed with its own access window and document which were active at the time of the build.
Swiss consent posture, FINMA, and what bLink actually means here
Switzerland’s open-banking posture is market-driven, not mandated. FINMA monitors the space but has not imposed a PSD2-style obligation; the working standards have come from the industry, primarily through Swiss FinTech Innovations (SFTI) and its Common API working group, and the production platform is SIX’s bLink. SIX’s 25 November 2025 launch of retail multibanking on bLink — eight participating banks and two third-party providers at go-live, with more than thirty banks committed to the data interface, per the SIX release — is the relevant baseline for what is currently consented and consentable.
For the wallet side, the dependable basis is the cardholder’s own authorization to the integrator, recorded with timestamp and scope, and operated under an NDA where the integrator’s upstream contract requires one. Compliance posture on our side is the constant: authorized, logged, data-minimized, written into the deliverable as a retention memo. Personal data is processed under the Swiss Federal Act on Data Protection (revFADP, in force since September 2023, per the SIF page we cite below) and, where the integrator is European, the GDPR via the standard transfer mechanisms — both stated as how the build operates, not as walls in front of starting it.
Refresh cadence, drift, and what can go stale
A TWINT event lands in seconds. A reversal can land hours later. Parking refunds appear when the user closes the session early. Daily reconciliation against the BCV statement is the safety net; without it, late events look like duplicates and refunds look like new debits. The deliverable carries the diff report so an operator can see, every morning, what TWINT and BCV disagree about and why. Plan re-validation on the wallet-side interface roughly every quarter, since the BCV and TWINT release cadence does iterate.
What we checked while writing this up
Mapping reviewed 2026-05-27 by the OpenFinance Lab integration desk. The factual claims above were checked against the following primary sources:
- BCV — BCV TWINT product page (eligibility, limits, account-linking model)
- TWINT — BCV TWINT issuer page (TWINT SA licensing posture)
- SIX — 25 Nov 2025 launch of multibanking on bLink (participating banks, TPP count)
- SIX bLink — Swiss open-banking platform (interface basis for the account route)
- Swiss State Secretariat for International Finance — Open Finance position (market-driven, no regulatory mandate to date)
Neighbouring wallets in the same integration space
Listed for ecosystem framing, not ranking. An integrator who needs BCV TWINT data often needs at least one of these on the same stack.
- PostFinance Pay — PostFinance’s in-house wallet, account-linked, same in-store / online surfaces as TWINT in many merchants.
- Apple Pay (Switzerland) — card-linked, distinct event model; relevant where a card-on-file path needs reconciling with a TWINT path.
- Google Pay — same shape as Apple Pay on the data side; Android-cardholder coverage.
- Revolut — offers a Swiss IBAN and a parallel real-time wallet; common when an aggregator needs both Swiss-resident and cross-border data.
- Wise — multi-currency account oriented at FX-heavy users; statement-style data, well documented.
- Neon — neobank with its own banking-app wallet on top of a Hypothekarbank Lenzburg account; a frequent peer in Swiss multibanking screens.
- Yuh — Postfinance/Swissquote joint venture; wallet + investing surfaces in one app.
- Klarna — the BNPL parallel; relevant if the build needs to compare TWINT’s 30-day BNPL feature against Klarna’s instalments.
Questions the BCV TWINT integrator usually asks
What is the realistic refresh cadence for BCV TWINT events, and can a webhook surface be derived for new transactions?
Inside BCV’s stack, an event lands on the linked account in near-real-time once TWINT settles — usually seconds. The conservative default we ship is a 30-second polling pull against the wallet event endpoint; a derived webhook surface (we receive once on our edge, fan-out to your endpoint signed) is built when push semantics are wanted. A daily reconciliation pass against the BCV statement closes the loop if a TWINT event arrived late or was reversed.
Are the linked loyalty cards (Supercard, Cumulus, Jelmoli) on the same authorization that reaches transactions?
Not quite. The loyalty integrations live on the TWINT side of the app and each scheme has its own opt-in. They are reachable under the same consenting user, but the access window and refresh contract differ from BCV transaction history. The deliverable documents which schemes were active at integration time and which read as read-only.
If SIX bLink multibanking exists, why not route everything through there?
bLink is the right channel for account aggregation across Swiss banks, and where the requirement is read-only statement data on the BCV account, that is the route we recommend — we coordinate the third-party-provider posture with the client. bLink does not, however, give you the TWINT-rail event stream, the linked loyalty schemes, parking sessions, or wallet-side UX state. A BCV TWINT build usually needs both: bLink for the account, authorized interface integration for the wallet.
What does the BCV smartID step mean for the integration’s session model?
BCV smartID is BCV Mobile’s authenticator and the trust anchor that lets the TWINT app confirm a payment. The integration we hand over carries an explicit session model that knows when smartID needs to re-authenticate the user separately from when TWINT consent needs renewing. They are different windows, and conflating them is a common reason integrations silently expire in production.
Screens of the wallet
App profile (factual recap)
BCV TWINT (package id ch.bcv.twint, per its Play Store listing) is the BCV-issued build of the Swiss TWINT wallet, published by Banque Cantonale Vaudoise under licence from TWINT SA. It links a current or joint BCV account to the TWINT rail and is restricted to private individuals aged 7 and over, with individual signing authority, a Swiss mobile number, and BCV Mobile installed. Spending limits cited on the BCV product page are CHF 1,500/day for P2P and CHF 5,000/day for in-store / online purchases. Feature surfaces include P2P send/receive, contactless in-store payments at TWINT-compatible terminals, online checkouts that accept TWINT (SBB, Swisscom, Migros named as examples in the listing), 30-day buy-now-pay-later at participating merchants, linked loyalty cards (Supercard, Cumulus, Jelmoli per the listing), parking sessions with partial refunds, QR-code fuel payments, charity donations, super-deal vouchers, mobile-plan subscriptions and digital vouchers. BCV TWINT is private-use only; the send-money feature is not available to merchants.
The build sits between a cantonal-bank account and the TWINT rail it spends on, so the engagement is scoped that way. Source-code delivery starts at USD 300 and is paid after we hand over runnable code and you confirm it does what you asked; or a hosted endpoint where you pay per call, no upfront fee. First drop typically lands in one to two weeks. Talk to the integration desk with the surfaces you actually need, and a written scope comes back.