Skip to content
ashrafeldawodyPublic

About

Turn a spare Android phone into a self-hosted payment gateway for mobile wallets (Vodafone Cash, e& money): the phone forwards wallet SMS receipts, the server matches them to payment intents and fires signed webhooks. No cloud, your data never leaves your server.

Topics

Resources

Security policy

Stars

18 stars

Watchers

0 watching

Forks

Repository files navigation

Tahweel (تحويل)

Turn a spare Android phone into a payment gateway for your mobile wallet.

Personal wallets such as Vodafone Cash, e& money or Orange Cash have no merchant API, but every transfer you receive arrives as an SMS from the operator. Tahweel makes that SMS usable by software: an Android phone holding the wallet SIM forwards the operator SMS to a server you run, the server checks that the receipt came from a trusted operator sender id, matches it against a payment intent your system registered, and sends your backend a signed webhook.

  • Self-hosted. One container, no cloud, no account, no telemetry. Your data never leaves your server.
  • Gateway-style API. POST /api/v1/intents, receive payment.matched. Swagger UI and a Postman collection included.
  • Dashboard. Devices, every forwarded SMS with its verdict, intents, webhook deliveries, settings, manual matching.
  • Fake SMS protection. Anyone can send an SMS that pretends to come from vf-cash. Optionally, a receipt only matches when its wallet balance adds up, and receipts above an amount you choose wait until you confirm them in the wallet app. See Security.
  • New wallets are one file. A parser plus sample messages.
customer pays 200 EGP ──▶ operator SMS ──▶ Listener phone ──▶ Tahweel server ──▶ webhook ──▶ your system

Quickstart

1. Run the server

export INGEST_TOKEN=$(openssl rand -hex 32) API_KEY=$(openssl rand -hex 32) ADMIN_PASSWORD='choose-a-long-password'
docker run -d --name tahweel --restart unless-stopped \
  -p 3000:3000 -v tahweel-data:/app/data \
  -e INGEST_TOKEN -e API_KEY -e ADMIN_PASSWORD \
  ghcr.io/ashrafeldawody/tahweel:latest
echo "phone token: $INGEST_TOKEN"

Open http://localhost:3000/ and log in with ADMIN_PASSWORD. Swagger is at /docs. Compose, PostgreSQL, HTTPS and every setting: docs/deploy.md.

2. Install the app on the phone

Download tahweel-listener-<version>-release.apk from the latest release, open it, enter your server URL and INGEST_TOKEN, tap Grant everything and Test connection. The phone appears under Devices.

3. Create a payment intent from your backend

curl -X POST http://localhost:3000/api/v1/intents \
  -H "X-Api-Key: $API_KEY" -H "content-type: application/json" \
  -d '{"reference":"order-1001","amount":200,"sender_phone":"01061916846","expires_in_minutes":120}'

When the customer's transfer arrives, Tahweel POSTs payment.matched to your webhook (set it on the dashboard's Settings page). See docs/webhooks.md to verify the signature.

Play Protect blocked the install?

The app needs the RECEIVE_SMS permission, so Google Play Protect often blocks the APK with "App blocked to protect your device". Install it over USB with ADB instead; Play Protect does not scan ADB installs.

  1. Enable Developer options: Settings → About phone (→ Software information on Samsung) → tap Build number 7 times.
  2. Enable USB debugging: Settings → Developer options → USB debugging on. On Samsung (One UI 6+) also turn off Settings → Security and privacy → Auto Blocker.
  3. Install ADB on your computer: winget install Google.PlatformTools (Windows), brew install android-platform-tools (macOS) or sudo apt install adb (Linux).
  4. Connect the phone by USB, run adb devices, and tap Allow on the phone's Allow USB debugging? prompt.
  5. Install:
    adb install -r tahweel-listener-<version>-release.apk

Wireless debugging, troubleshooting and the alternative (pausing Play Protect for a minute) are in docs/listener.md. Afterwards, go through the phone checklist there (battery settings, no screen lock, charger) so the phone never stops forwarding SMS.

Documentation

Guide What's inside
FAQ Paying before the order exists, polling, authentication, transaction numbers, installing the app
How it works Architecture, matching rules, limits, roadmap
API Intents, polling, ingest protocol, admin API
Webhooks Events, headers, retries, signature verification (Node, PHP)
Listener app Building, installing with ADB, phone setup checklist, operating
Deployment Environment variables, Docker, PostgreSQL, reverse proxy, backups, releases
Security Fake SMS protection, where your data goes, credentials
Parsers Adding a new wallet's SMS format
Development Repository layout, tests, CI
Postman Ready-made collection for the API

License

MIT, © Ashraf Eldawody. See LICENSE.

About

Turn a spare Android phone into a self-hosted payment gateway for mobile wallets (Vodafone Cash, e& money): the phone forwards wallet SMS receipts, the server matches them to payment intents and fires signed webhooks. No cloud, your data never leaves your server.

Topics

Resources

Security policy

Stars

18 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages