> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.onesignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Financial and fintech strategies

> Implementation hub for financial and fintech messaging — user IDs, KYC and security Tags, product-holding and transaction Custom Events, segments, and Journey playbooks for compliance, verification, cross-sell, and retention.

A financial and fintech messaging strategy targets apps where success depends on completed verification, secure account behavior, and sustained transaction activity. If your product handles deposits, trades, payments, or any user-attached financial data, this guide is for you.

This page is the implementation hub: which user identifier to set, what compliance and behavioral data to capture, which segments to build, and which Journeys drive verification, security, conversion, and retention. Each section links to the canonical docs for deeper detail.

<Note>
  Many fintech messages carry regulatory or jurisdictional disclosure requirements (e.g., Reg E, SEC, FINRA, GDPR financial data). Treat copy and frequency as compliance surfaces — review with your legal team before launching new flows. Nothing in this guide is legal advice.
</Note>

## Implementation roadmap

Work through these steps in order. Each one links to its section below.

<Steps>
  <Step title="Assign External IDs">
    Set a stable, app-side identifier on every authenticated user so push, email, and SMS tie to one profile across reinstalls. Critical for tying account, balance, and transaction data to messaging. [Jump to section](#identify-your-users-with-external-ids).
  </Step>

  <Step title="Add account properties as Tags">
    Start with `account_status`, `kyc_completed`, `2fa_enabled`, and `first_name`. They power every compliance and security Journey. [Jump to section](#tags).
  </Step>

  <Step title="Send user actions as Custom Events">
    Fire `signup_completed`, `verification_completed`, `first_transaction_completed`, and `transaction_completed` from your app or backend. [Jump to section](#custom-events).
  </Step>

  <Step title="Build lifecycle Segments">
    Compliance and growth audiences such as Unverified Users, 2FA disabled, Active Traders, and Dormant Accounts. [Jump to section](#segments).
  </Step>

  <Step title="Create lifecycle Journeys">
    Verification, 2FA setup, first-action promotions, transactional alerts, cross-sell and feature adoption, and re-engagement. [Jump to section](#journey-examples).
  </Step>
</Steps>

## Identify your users with External IDs

External IDs preserve identity across installs and tie push, email, and SMS to one customer profile. Use the unique identifier from your authentication, KYC, or core banking platform — for example, a Cognito or Auth0 `uid`, or your internal `customer_id`.

Set the External ID at signup, on every login, and on session resume. The OneSignal SDK does not assign it for you, and assigning it late or sporadically breaks attribution between messaging, KYC outcomes, and downstream transactions — making compliance audits and funnel analytics unreliable.

<Card title="External ID setup" icon="id-card" href="./users#external-id">
  Assign a unique identifier to each user so account state, verification status, and notifications follow them across devices and reinstalls.
</Card>

## Recommended data

Tags persist on the user profile (current state); Custom Events record discrete moments (what just happened). Use both — Tags drive compliance-aware segmentation and personalization, Custom Events trigger Journey entry and Wait Until conditions.

Fintech leans heavily on Tags for state (`account_status`, `kyc_completed`, `2fa_enabled`) because so much messaging is gated on whether the user is in a particular regulatory or onboarding stage. Custom Events handle the moments — verification submission, transactions, security changes — that move users between those states.

### Tags

Tags persist on the user profile and are used for segmentation and personalization. For boolean-style signals, set the Tag to `1` when true and **remove it** when false — segment with "tag exists" rather than storing `0`/`false` values.

<Tip>
  If you only set up four Tags, start with `account_status`, `kyc_completed`, `2fa_enabled`, and `first_name`. They power every compliance and security Journey.
</Tip>

#### Account and compliance state

| Tag              | Values                                              | Use                                                                                                                                                                                                                                                                                                                   |
| :--------------- | :-------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `account_status` | `unverified` / `pending` / `verified` / `suspended` | Lifecycle state — drives Journey entry, exit, and audience filters. Suspended users typically receive only transactional and account-recovery messages.                                                                                                                                                               |
| `kyc_completed`  | `1` (set when verified)                             | Confirms identity verification. Absence is your highest-priority compliance segment.                                                                                                                                                                                                                                  |
| `account_type`   | `personal` / `joint` / `business` / `trust`         | Account ownership structure. Drives disclosure and consent copy — joint, business, and trust accounts have different signing, authority, and notice requirements than personal accounts. For *which products* a user holds (checking, savings, credit card, etc.), use [Product holdings](#product-holdings) instead. |
| `risk_tier`      | `low` / `medium` / `high`                           | Drive frequency of security messaging and compliance disclosures based on risk classification. Powers the High-Risk Users segment for tighter security cadences.                                                                                                                                                      |
| `jurisdiction`   | ISO 3166-2 code (e.g., `US-CA`, `GB`, `DE`)         | Tailor disclosure copy, frequency caps, and channel choices by regulatory region. Use a coarser bucket (`us` / `eu` / `apac`) if your messaging policy doesn't vary at the state/province level.                                                                                                                      |
| `signup_date`    | Unix timestamp (seconds)                            | Account creation moment. Use [time operators](./time-operators) to trigger tenure-based Journeys — for example, "90 days after signup, send a credit card cross-sell" or "365 days, send an anniversary email."                                                                                                       |

#### Security and trust

| Tag                       | Values                                    | Use                                                                                                                    |
| :------------------------ | :---------------------------------------- | :--------------------------------------------------------------------------------------------------------------------- |
| `2fa_enabled`             | `1` (set when enabled)                    | Security state. Absence is the entry segment for the 2FA setup Journey.                                                |
| `email_verified`          | `1` (set when confirmed)                  | Required before sending any marketing or transactional email.                                                          |
| `phone_verified`          | `1` (set when confirmed)                  | Required before sending any SMS.                                                                                       |
| `password_last_changed`   | Unix timestamp (seconds)                  | Use [time operators](./time-operators) to prompt password rotation on policy intervals.                                |
| `marketing_consent_email` | `1` (set when granted, removed on revoke) | Required filter on every marketing email Journey. Absence excludes the user — transactional flows are unaffected.      |
| `marketing_consent_sms`   | `1` (set when granted, removed on revoke) | Required filter on every marketing SMS Journey. Especially important under TCPA and similar SMS-marketing regulations. |

#### Engagement and value

| Tag                           | Values                                                | Use                                                                  |
| :---------------------------- | :---------------------------------------------------- | :------------------------------------------------------------------- |
| `first_transaction_completed` | `1` (set when complete)                               | Confirms activation. Absence is the highest-leverage growth segment. |
| `last_transaction_date`       | Unix timestamp (seconds)                              | Drives recency-based win-back and dormancy messaging.                |
| `total_balance_cents`         | integer (as string)                                   | Power high-value-customer segments for premium offers.               |
| `customer_tier`               | `retail` / `premium` / `accredited` / `institutional` | Tailor copy, offers, and disclosures by customer classification.     |

#### Product holdings

Track which products and features a user has adopted. These Tags do double duty: as **filters** for cross-sell audiences ("checking but no card"), and as **exclusions** so you never pitch a product the user already owns.

| Tag                      | Values                                                       | Use                                                                                                                        |
| :----------------------- | :----------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------- |
| `has_checking`           | `1` (set when active)                                        | Foundation product — most cross-sell flows assume this is set.                                                             |
| `has_savings`            | `1` (set when active)                                        | Cross-sell anchor for higher-tier savings, money-market, or CD products.                                                   |
| `has_credit_card`        | `1` (set when active)                                        | Excludes user from credit-card promotion Journeys; enables card-specific campaigns (rewards, statement reminders).         |
| `has_investment_account` | `1` (set when active)                                        | Cross-sell from cash to brokerage, robo-advisor, or self-directed investing.                                               |
| `has_loan`               | `1` (set when active)                                        | Eligibility for loan-management messaging and refi offers.                                                                 |
| `direct_deposit_active`  | `1` (set when an incoming payroll-class deposit is detected) | Strongest engagement signal in banking. Powers "set up direct deposit" Journey audiences and primary-bank retention flows. |

#### Personalization

| Tag                  | Values                                      | Use                                                        |
| :------------------- | :------------------------------------------ | :--------------------------------------------------------- |
| `first_name`         | string                                      | Personalize message content (e.g., `Hi {{ first_name }}`). |
| `acquisition_source` | `referral` / `organic` / `paid` / `partner` | Tailor onboarding messaging to where the user came from.   |

<Card title="Add user data tags" icon="tags" href="./add-user-data-tags">
  Add key-value pairs to user profiles for segmentation and personalization.
</Card>

### Custom Events

Send a Custom Event for each moment you want to react to. Events are stored shorter-term than Tags but can carry properties (transaction amount, currency, transaction type), making them ideal for Journey entry triggers, Wait Until conditions, and Liquid personalization. Use lowercase `snake_case` for event names and keep them consistent across your app and backend.

| Event                               | Use case                                                                                                                                                                                                                                                                                                                               |
| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `signup_completed`                  | Welcome and verification Journey entry. Carry `acquisition_source` if you Tag it so onboarding copy can vary by channel (paid vs organic vs referral).                                                                                                                                                                                 |
| `verification_started`              | Wait Until anchor — branch on whether the user finishes KYC inside an expiration window.                                                                                                                                                                                                                                               |
| `verification_completed`            | Exit verification Journey; thank-you and next-step message.                                                                                                                                                                                                                                                                            |
| `2fa_enabled`                       | Exit 2FA setup Journey; security-confirmation message.                                                                                                                                                                                                                                                                                 |
| `first_transaction_completed`       | Exit onboarding promotion Journey; first-action celebration. Carry `type` (e.g., `deposit` / `trade` / `payment`) and `amount` as properties so the celebration message can reference the specific action the user took.                                                                                                               |
| `transaction_completed`             | Transactional receipt push and email. Carry `amount`, `currency`, `transaction_type`, and `is_first` as properties so receipt copy renders with the right values and first-transaction Journeys branch on the same event.                                                                                                              |
| `transaction_failed`                | Trigger a recovery message with a clear retry path. Carry `failure_reason` (`insufficient_funds`, `card_declined`, `compliance_hold`, etc.) and `retry_url` so the message can deep-link the user to the right resolution.                                                                                                             |
| `large_transaction`                 | Optional fraud-aware confirmation — "Was this you?" with a quick deny path. Carry `amount`, `currency`, and `merchant` (or counterparty) as properties; threshold the trigger by `risk_tier` if you have it.                                                                                                                           |
| `device_added` / `password_changed` | Security event confirmations. Required by many regulators. Carry `device_name` / `ip_country` (for `device_added`) or `change_method` (for `password_changed`) so the confirmation message can describe what happened.                                                                                                                 |
| `application_started`               | User opened an application for a new product (credit card, loan, additional account). Wait Until anchor — branch on completion vs abandonment with a 7-day expiration. Carry `product` (e.g., `credit_card`, `loan`, `savings`) as a property.                                                                                         |
| `feature_enrolled`                  | User signed up for or activated a new product or feature. Exit cross-sell Journey; trigger a thank-you and next-step message. Carry `feature` (e.g., `credit_card`, `direct_deposit`, `auto_invest`) as a property. After firing, also set the corresponding `has_*` Tag so the user is excluded from future pitches for that product. |
| `promotion_redeemed`                | User claimed a promotional offer (signup bonus, referral reward, seasonal promo). Carry `promo_code` and `value_cents` as properties.                                                                                                                                                                                                  |

<Card title="Custom Events" icon="bolt" href="./custom-events">
  Capture user actions and use them to trigger Journeys or Wait Until steps.
</Card>

### Segments

Combine Tags and Custom Events into segments. Start with these eleven:

| Segment                          | Definition                                                                                                                                          |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| Unverified Users                 | `kyc_completed` does not exist. Highest-priority compliance segment.                                                                                |
| Pending verification             | `account_status = "pending"`. In-flight KYC submissions awaiting review.                                                                            |
| 2FA disabled                     | `2fa_enabled` does not exist AND `account_status = "verified"`. Security uplift segment.                                                            |
| New Users — first action pending | `account_status = "verified"` AND `first_transaction_completed` does not exist. Onboarding promotion target.                                        |
| Active Traders                   | `transaction_completed` in the last 7 days, with N+ events. Engaged core.                                                                           |
| Cross-sell — credit card         | `has_checking = "1"` AND `has_credit_card` does not exist AND `Last Session < 30 days`. Active customers eligible for credit-card promotion.        |
| Direct-deposit candidates        | `has_checking = "1"` AND `direct_deposit_active` does not exist. Highest-leverage engagement and primary-bank uplift in retail banking.             |
| Dormant Accounts                 | `Last Session > 30 days` AND `account_status = "verified"`. Re-engagement target.                                                                   |
| High-Value Customers             | `customer_tier = "premium"` OR `total_balance_cents > 5000000`. Premium offer audience.                                                             |
| High-Risk Users                  | `risk_tier = "high"`. Tighter security cadence — faster `device_added` / `password_changed` confirmations and lower `large_transaction` thresholds. |
| Suspended                        | `account_status = "suspended"`. Restrict to account-recovery and required regulatory messages only.                                                 |

<Note>
  Mature fintech setups run 20+ segments split by jurisdiction, product holdings, and regulatory classification. Start with the eleven above, then add depth (additional product-holding combinations, market-data permissions, accredited-investor flags) as your Journeys grow.
</Note>

<Card title="Segmentation" icon="users" href="./segmentation">
  Group users by shared characteristics to target Journeys and campaigns.
</Card>

## Journey examples

With Tags, Custom Events, and segments in place, build Journeys against them. Fintech Journeys mix channels by intent — push and in-app for in-the-moment nudges, email for receipts, statements, and longer-form content, and SMS for high-trust moments like verification, 2FA codes, and large-transaction confirmations. The lifecycle has six core flows:

<Columns cols={2}>
  <Card title="New user verification" icon="id-card" href="./event-driven-journeys">
    Multi-channel KYC reminders across push, email, and SMS in the first 48 hours, entered on `signup_completed` and exited on `verification_completed`.
  </Card>

  <Card title="2FA setup" icon="lock" href="./event-driven-journeys">
    Identify users without `2fa_enabled` and run a security-uplift Journey before their first transaction.
  </Card>

  <Card title="First transaction promotion" icon="circle-dollar-to-slot" href="./mobile-first-journeys#welcome-journeys">
    Day 1 / 2 / 4 / 6 onboarding cadence to drive the first deposit, trade, or payment.
  </Card>

  <Card title="Feature adoption / cross-sell" icon="layer-group" href="./event-driven-journeys">
    Identify customers with product-holding gaps (e.g., checking but no card) and run targeted cross-sell Journeys, exited on `feature_enrolled` or `application_started`.
  </Card>

  <Card title="Transactional alerts" icon="bell" href="./transactional-messages">
    Real-time receipts, balance updates, and security confirmations.
  </Card>

  <Card title="Re-engagement (Dormant Accounts)" icon="rotate-left" href="./mobile-first-journeys#retention-journeys">
    Catch users with no activity in 30+ days before they fully disengage.
  </Card>
</Columns>

<Frame caption="Video: Multi-channel new user verification">
  <iframe width="560" height="315" src="https://www.youtube.com/embed/lp0eY99IjCE?si=ODnjmTiGPSSfIc5q" title="Multi-channel new user verification for fintech" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen />
</Frame>

### Common fintech patterns

* **Multi-channel verification.** Don't rely on email alone for KYC reminders — bounce rates and inbox placement vary, and verification has a hard time window. A push + email + SMS cadence across the first 48 hours measurably lifts completion. Trigger from `signup_completed` and exit on `verification_completed`.
* **2FA setup uplift.** Identify users with `2fa_enabled` absent and run a 7-day Journey of in-app messages and emails framing 2FA as account protection, not friction. Pair with a hard gate on high-risk actions (transfers above a threshold) to make the upside concrete.
* **First-action promotion.** A common new-user cadence is **Day 1, Day 2, Day 4, Day 6** following verification, each surfacing a specific first action — deposit, trade, payment — with a small incentive ("\$10 toward your first trade") to clear the activation hurdle. Exit on `first_transaction_completed`.
* **Feature adoption and cross-sell.** Use [Product holdings](#product-holdings) Tags as exclusion segments — never pitch a product the user already owns. Trigger cross-sell Journeys from a lifecycle moment (90 days after `signup_date`, or post-`first_transaction_completed`) and use `application_started` as a Wait Until anchor with a 7-day expiration to branch on whether the user finishes the application. Exit on `feature_enrolled`, and have your backend set the matching `has_*` Tag so the user is permanently excluded from that pitch.
* **Promotional offers.** Pair a `promotion_redeemed` event with a `promo_code` property to measure each campaign's funnel and to attribute downstream activity. Exclude users who already redeemed a promo from re-targeted versions of the same offer to avoid awkward repeat pitches.
* **Transactional alerts.** Status, money received, balance changes, payments, and identity-verification confirmations should all flow as transactional messages. Send these via the [Transactional messages API](./transactional-messages) so they bypass marketing-consent gates and meet delivery-time expectations.
* **Security event confirmations.** `device_added`, `password_changed`, and `large_transaction` events should trigger immediate confirmation messages. Many regulators require these; users expect them as a sign of a trustworthy product.
* **Risk-tier-aware cadence.** Use the `risk_tier` Tag to scale security and disclosure messaging. The High-Risk Users segment gets tighter cadences on `device_added` and `password_changed` confirmations, lower `large_transaction` thresholds, and faster expirations on Wait Until branches that gate sensitive actions.
* **Jurisdiction-aware copy.** Use the `jurisdiction` Tag to vary disclosure language, frequency caps, and channel choice — for example, holding back marketing SMS in TCPA-heavy regions or swapping in EU-specific privacy copy for `eu` users. See [Liquid syntax](./using-liquid-syntax) for how to branch message content on Tag values.
* **Marketing-consent gating.** Filter every marketing Journey on `marketing_consent_email = "1"` (or `marketing_consent_sms = "1"`). Transactional Journeys via the [Transactional messages API](./transactional-messages) are exempt — they aren't marketing messages and shouldn't be gated by consent.

<Frame caption="Video: Driving 2FA setup with messaging">
  <iframe width="560" height="315" src="https://www.youtube.com/embed/WTlQ5fOCySw?si=suAQ6p5Dz9O727hg" title="Driving 2FA setup with messaging in fintech" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen />
</Frame>

Measure success by KYC completion rate (within 48 hours), 2FA enablement rate, time-to-first-transaction, and Active Traders retention — not just opens or CTR.

## FAQ

### How is this different from the Mobile-first strategy?

[Mobile-first](./mobile-first) targets subscription, freemium, and trial-driven apps where success is measured by trial-to-paid conversion. Fintech overlaps on the data foundation (External IDs, Tags, Custom Events, segments) but adds compliance state (`kyc_completed`, `account_status`), security state (`2fa_enabled`), and transactional moments as first-class concepts. The lifecycle is shaped around verification, security, and recurring transactions — not trial conversion.

### Should I send marketing and transactional messages from the same Journey?

No. Keep transactional flows (receipts, security alerts, verification confirmations) separate from marketing flows (promotions, upsells, re-engagement). Mixing them creates compliance risk — marketing-consent revocations should not silence transactional notices, and transactional messages should not be subject to marketing-frequency caps. Use the [Transactional messages API](./transactional-messages) for the former and standard Journeys for the latter.

### How do I handle messaging for suspended or restricted accounts?

Build a **Suspended** segment on `account_status = "suspended"` and use it as an **exclusion** segment on every marketing Journey. Transactional and account-recovery messages can still send — those are typically required regardless of marketing status — but promotional and engagement nudges should never reach users in a restricted state.

### When should I use SMS over push?

SMS is appropriate for high-trust, time-sensitive moments where push delivery is unreliable or the user isn't logged in: verification codes, 2FA codes, suspicious-activity alerts, and large-transaction confirmations. It's also the right channel when the user might be locked out of the app. Avoid SMS for marketing — the cost-per-message is high, opt-out rates are punishing, and many jurisdictions have strict marketing-SMS regulations.

### Do I need data integrations to use these Journeys?

No. You can build basic verification reminders and re-engagement using dashboard-only segments like "First Session" and "Last Session." Custom Events and Tags give you precise compliance-aware triggers and exit conditions, but they are not required to ship the first version.

### What about apps that mix banking with other products (e.g., insurance, lending)?

The data foundation extends naturally. Use the [Product holdings](#product-holdings) Tags as filters and exclusion segments on top of the base lifecycle audiences — and add product-specific Tags (`has_insurance`, `has_mortgage`) and Custom Events as you launch new lines. Each product line typically gets its own Journey set with the shared compliance and security flows running underneath.

## Related pages

<Columns cols={3}>
  <Card title="Mobile-first strategies" icon="mobile" href="./mobile-first">
    Sister hub for subscription, freemium, and trial-driven mobile apps.
  </Card>

  <Card title="Mobile-first lifecycle Journeys" icon="route" href="./mobile-first-journeys">
    Welcome, event-driven, and retention Journey patterns adaptable to fintech onboarding and dormancy.
  </Card>

  <Card title="Transactional messages" icon="paper-plane" href="./transactional-messages">
    Send receipts, balance updates, and security confirmations through the API.
  </Card>

  <Card title="Event-driven Journeys" icon="bolt" href="./event-driven-journeys">
    Trigger Journeys from `transaction_completed`, `verification_completed`, and other lifecycle events.
  </Card>

  <Card title="Magic link and OTP verification" icon="key" href="./example-verification-magic-link-otp">
    Send one-time passwords, magic links, and verification emails for KYC, sign-in, and high-trust actions.
  </Card>

  <Card title="Push fallback to email or SMS" icon="arrows-rotate" href="./push-fallback-method">
    Reach users via email or SMS when push delivery fails for security and high-priority moments.
  </Card>
</Columns>
