Android payment gateway

Payment received.
Webhook sent.

NotifyPay turns a spare Android phone into a payment gateway. It reads e-wallet payment notifications and delivers them to your backend as structured, secure webhooks, with no merchant API needed.

  • No provider API
  • Offline queue
  • API-key secured

9:41

G
GCash

You have received PHP 250.00 of GCash from +63 9•• ••• 4821.

NotifyPay gateway running
POST /api/notification-receiversending…
{
  "source": "gcash",
  "amount": 250.00,
  "sender_masked": "+63 9•• ••• 4821",
  "created_at": "2026-10-03T09:41:00.000Z"
}

x-api-key: ••••••••

Features

Everything between “ding” and “order confirmed”.

01

Notification listener

A system-level listener catches incoming GCash payment notifications the moment they land.

02

Smart parsing

Amount, masked sender, mobile number and timestamp are extracted into clean fields.

03

Secure webhooks

Every payment is POSTed to your endpoint with an API key header your backend verifies.

04

Never loses a payment

Offline? Events queue on the device and retry automatically in the background.

05

Always on

A foreground service keeps the gateway alive, with a live log of everything it sent.

06

Drop-in receiver

A ready-made API route stores payments in Supabase and normalizes PH mobile numbers.

How it works

Live in three steps.

  1. 1

    Install on a spare phone

    Sign in to your e-wallet and grant NotifyPay notification access.

  2. 2

    Point it at your API

    Set your webhook URL and API key in the app.

  3. 3

    Get paid, get notified

    Each payment reaches your backend in seconds, ready to confirm orders.

Developers

One endpoint. Clean JSON.

Your backend receives a simple POST for every payment. Verify the API key, match the amount to an order, and you're done.

  • Kotlin Android app (notification listener + WorkManager retries)
  • Node.js receiver route with Supabase storage
  • Philippine mobile number normalization built in
// verify + store a payment
export default async function handler(req, res) {
  if (req.headers["x-api-key"] !== process.env.NOTIFYPAY_API_KEY)
    return res.status(401).json({ error: "Unauthorized" });

  const { source, amount, sender_masked, created_at } = req.body;
  await db.payments.insert({ source, amount, sender_masked, created_at });
  res.json({ ok: true });
}