English Bahasa Melayu

How to Make PayPing Understand Your Bank

PayPing Lite runs completely offline. It never connects to the internet and never sends your notifications to any cloud server. To turn incoming bank and e-wallet notifications into instant spoken ringgit announcements, PayPing uses deterministic regular expression parsers.

You have two ways to add support for a new bank or e-wallet:

  1. In-app visual generator (recommended): Tap a notification on your phone and let PayPing generate the rule automatically.
  2. JSON definition (power users & community contributors): Write portable regex rules that can be shared in the library.

1. The In-App Guided Flow

Whenever PayPing Lite receives a notification from a banking app that it doesn't recognize yet, it places it safely in the Needs Review queue without guessing or making mistakes.

  1. Open PayPing Lite and switch to the Needs Review tab.
  2. Tap the notification you want PayPing to learn.
  3. Select "Create parser from this notification".
  4. Highlight the amount: The app displays the notification text. Simply tap or drag across the amount (e.g. RM 45.20). PayPing automatically generates the corresponding extraction pattern.
  5. Choose the direction:
    • Money In: DuitNow transfers received, QR payments received, salary or cash deposits.
    • Money Out: Debit card transactions, QR payments sent, bill payments.
    • Info (Ignore): OTP codes, promotional alerts, login notices.
  6. Test against recent history: PayPing tests the generated rule against other recent notifications from the same app to verify that it matches accurately without false positives.
  7. Tap Save Parser. The app immediately parses matching future notifications and speaks them aloud.

2. The Parser JSON Schema

Every parser in the library is a single self-contained JSON document conforming to schemaVersion: 1.

{
  "schemaVersion": 1,
  "id": "mybank",
  "name": "My Bank Malaysia",
  "version": 1,
  "author": "Community Contributor",
  "description": "Parser for My Bank transfer received and card charge notifications.",
  "androidPackages": ["com.mybank.app"],
  "iosAppNames": ["My Bank Mobile"],
  "rules": [
    {
      "id": "mybank.received.v1",
      "priority": 200,
      "match": {
        "title": "money received|duitnow received",
        "body": "transferred to your account"
      },
      "direction": "in",
      "confidence": "high",
      "extract": {
        "amount": "(?:RM|MYR)\s*(?[\d,]+\.?\d{0,2})",
        "counterparty": "from\s+(?.+?)(?:\s+on|\.|$)",
        "reference": "ref(?:erence)?:?\s*(?[A-Z0-9]+)"
      }
    }
  ]
}

Key Rule Fields

3. Strict Rules for Safe Regular Expressions

Because PayPing Lite runs in the background on mobile devices (Android Hermes/V8 and iOS JavaScriptCore/Swift), regex execution must be 100% predictable, cross-platform, and fast:

Engine Safety Guardrails

  • NO Lookbehind (Forbidden): Positive lookbehind (?<=...) and negative lookbehind (?<!...) are strictly prohibited. Different regex engines handle lookbehinds inconsistently and can cause fatal crashes on older mobile runtimes. Use non-capturing prefix groups (?:prefix) with named capture groups instead.
  • NO Nested Quantifiers (Catastrophic Backtracking): Never nest quantifiers like (a+)+ or (.*)*. In hostile or unexpected inputs, this causes exponential backtracking (ReDoS) that freezes the app.
  • 50ms Execution Budget: Any regex evaluation that exceeds 50 milliseconds is terminated automatically by the PayPing parser runtime.
  • 4,000 Character Cap: Input notification titles and bodies longer than 4,000 characters are safely truncated before parsing.
  • Named Capture Syntax: Always use standard (?<name>...) named group syntax.

4. Real Worked Examples

Example A: Money In (DuitNow Funds Received)

Notification Body: You've received RM 120.00 in your A/C from AHMAD BIN ALI on 24/10/2026.

{
  "id": "sample.duitnow-in.v1",
  "priority": 200,
  "match": {
    "body": "You've received .* in your A/C"
  },
  "direction": "in",
  "confidence": "high",
  "extract": {
    "amount": "You've received\s+(?RM|MYR)?\s*(?[\d,]+\.?\d{0,2})",
    "counterparty": "from\s+(?.+?)(?:\s+on|\.|$)"
  }
}

Result: Direction is in, amount is 12000 minor units (RM 120.00), counterparty is AHMAD BIN ALI.

Example B: Money Out (Credit Card Purchase)

Notification Body: MYR950.00 was charged to your credit card ending 1681 at MYDIN MART on 21/09/25.

{
  "id": "hsbc.card-charged.v1",
  "priority": 200,
  "match": {
    "body": "was charged to your (?:supp )?credit card"
  },
  "direction": "out",
  "confidence": "high",
  "extract": {
    "amount": "(?RM|MYR)\s*(?[\d,]+\.?\d{0,2})",
    "counterparty": "at (?.+?) on \d"
  }
}

Result: Direction is out, amount is 95000 minor units (RM 950.00), counterparty is MYDIN MART.

Example C: Negative Filter (Ignore Promotional Alerts)

Notification Body: Special Offer! Enjoy RM 20.00 cashback with our partners when you spend today.

{
  "id": "sample.promo-filter.v1",
  "priority": 300,
  "match": {
    "body": "cashback with our partners|discount voucher|enjoy up to"
  },
  "direction": "info",
  "confidence": "none"
}

Result: Direction is info with confidence none. PayPing Lite ignores this notification completely and avoids announcing marketing text.

5. How to Submit New Parsers or Real Samples

Help expand the community library! We welcome parser additions and real notification samples:

  1. Anonymise everything: Replace personal names with fake names (e.g. "SITI AMINAH"), mask account numbers (e.g. "ending 1234"), and jitter transaction amounts.
  2. Open our GitHub Parser Submission Template.
  3. Fill out the bank name, package ID, and sample notification text.
  4. Our maintainers will review, write tests in parser-library/fixtures-real, and publish the update in the next library release.