AgooPay is not licensed by the Bank of Ghana. It is under development, and we are working towards our licence. Nobody can use it to make or receive a payment. Anyone offering you AgooPay payments is not us.
AgooPayUnder Development
Tell Me More
agoopay.com/developers · Planned, Test Keys Only

Code Is the Other Customer.

Keys, code and logs are part of the look, not an afterthought. Code is ink and white, because the only coloured word in a block is where the money is. This is how it will look. There's no API to call yet.

01 · A First Look

Ask, Open, Believe the Message

Three steps: ask for the money from your server, open our screen on your page, and act only on the signed message that reaches your server.

Quickstart

Sample, test keys only
  1. 1. Ask for the money, from your server
    const ask = await agoopay.asks.create({
      amount: "240.00", currency: "GHS",
      reference: "order_2291",
    }, { idempotencyKey: "order_2291" })
  2. 2. Open our screen, on your page
    AgooPay.open({ ask: "ask_test_7F3K" })
  3. 3. Believe the message, not the browser
    app.post("/hooks", (req, res) => {
      const msg = agoopay.verify(req)  // refuses a bad signature
      if (msg.payment.status === "settled") ship(msg.payment.reference)
      res.sendStatus(200)
    })

Keys

There are no real keys. Nothing here can move money.
  • Public test keypk_test_51F3kA2bQ9xZ7w
  • Secret test keysk_test_••••••••••••••

Webhook Inspector

Signature checked with your signing secret1 delivery, last answered 200
{
  "id": "msg_01HF93",
  "type": "payment.settled",
  "created": "2026-11-01T16:30:00Z",
  "payment": {
    "id": "AP-7F3K-20411",
    "status": "settled",
    "thread": { "at": "settled", "step": 4, "of": 5 },
    "who_has_it": "agoopay",
    "amount": "240.00", "currency": "GHS",
    "fee": "4.68", "tax_on_fee": "0.94", "net": "234.38"
  },
  "sample": true
}

A replay would send the same message again, with the same ID. It moves no money, and your server should treat it as already seen.

In Your Terminal
$ agoopay listen --forward localhost:4242/hooks
  Ready. Test messages will arrive here.
14:03:09  payment.said_yes     moving    → 200
14:03:12  payment.captured     moving    → 200
14:03:58  payment.no_answer    unknown   → 200
02 · How It Will Behave

Built Around What Goes Wrong

A timeout doesn't mean a payment failed. So the API won't pretend it does.

Unknown Outcomes

We Don't Know Yet Is a Real Answer

When a network goes quiet, a payment will sit in a state of its own, with who has it and when you'll know. You'll be able to reproduce it in the sandbox and see the exact next action.

  • The same idempotency key can't take money twice
  • Every message has an ID and can be safely replayed
  • Each message says where it is on the thread
A Message Sits on Its Thread
Sample
14:03:09  payment.said_yes     moving
14:03:12  payment.captured     moving
14:03:58  payment.no_answer    unknown
For the People Building It

Read It Once, Then Trust It

Plain names for what's happening: asked, said yes, captured, settled, in the bank. The same words on the screen, in the API and in the logs.

Someone typing code at a desk, with a laptop open beside the keyboard.
Writing the code

The Sandbox, Described

A gated sandbox with test keys and sample data, by invitation. It isn't open, and there's no public checkout, because a public one could be copied by scammers.

SDKs, Planned

iOSAndroidJavaScriptGoNodePythonPHPJavaA command lineMCPWooCommerce

Test Numbers Only

In the demo and the sandbox, card fields will take only published test numbers. A number that looks real will be refused with a plain message, and it won't be stored or logged.

03 · Tell Us

Building Something?

Tell us what you run. We'll write when there's something you can try. This signs you up to nothing.

No Keys Today

There are no real keys and no API to call. The keys and messages above are samples, and they do nothing anywhere.

In your own words, such as a fabric shop, an online store or a fund.

This signs you up to nothing.