Trigger events
Produce a real sandbox payment, and the events that follow it.
wajub trigger does not fabricate a payload. It calls the sandbox API the way your code would,
with the test number that produces the outcome you asked for, and lets the platform emit the
events on its own. What reaches your handler is therefore identical to what a real payer would
have produced.
$ wajub trigger payment.succeeded
Triggering payment.succeeded …
✓ created payment trx_test_VPRKcDWn0pi29ScaQL9B
✓ dispatched cm.mtn charge (+237670000000)
✓ payment trx_test_VPRKcDWn0pi29ScaQL9B is succeededThe number it dialled is the giveaway: +237670000000 is the sandbox MTN Cameroon prefix followed
by the success suffix. Ask for a failure and it uses the failure suffix instead.
$ wajub trigger payment.failed --amount 2500
Triggering payment.failed …
✓ created payment trx_test_PR8mmBq5bfkxqGcJRtP5
✓ dispatched cm.mtn charge (+237670000002)
✓ payment trx_test_PR8mmBq5bfkxqGcJRtP5 is failedThe eight events
Triggerable events:
customer.created Create a customer
customer.updated Create then update a customer
payment.cancelled Create and cancel a payment (mobile money canceled)
payment.created Create a payment and leave it unpaid
payment.failed Create and fail a payment (mobile money failure)
payment.succeeded Create and complete a payment (mobile money success)
refund.failed Complete a payment whose refund deterministically fails
refund.succeeded Complete a payment then refund it (refund succeeds)Eight arguments, but far more than eight events, because each one drives a real flow.
| You trigger | Your endpoint receives, in order |
|---|---|
payment.created | payment.created |
payment.failed | payment.created, payment.processing, payment.failed |
payment.succeeded | payment.created, payment.processing, payment.succeeded, balance.updated, fee.charged |
refund.succeeded | The five above, then refund.created, refund.succeeded, balance.updated |
The very first trigger on an account also emits customer.created, because the CLI creates the
CLI Trigger customer it reuses afterwards.
The chain is the lesson, not a side effect
A real payment behaves the same way. If your handler only implements payment.succeeded, this is
where you find out that four other types are already arriving and being ignored, and that
fee.charged is the one your ledger was missing.
Shaping what gets created
| Flag | Default | Effect |
|---|---|---|
--amount | 5000 | Amount on the created resource |
--currency | XAF | Currency |
--channel | cm.mtn | Which rail to charge |
--phone | Derived | Override the payer number. Advanced, it decides the outcome |
-d, --data | Extra key=value on the created resource, repeatable | |
--list | Print the list above and exit |
wajub trigger payment.succeeded --amount 250000 --currency XOF --channel ci.orange
wajub trigger customer.created -d name="Boutique Akwa" -d email=contact@example.com
wajub trigger payment.succeeded -d reference=order-4172 -d description="Order #4172"Passing -d reference=order-4172 is the trick that makes the test realistic: your handler can then
look the order up exactly as it would in production, instead of special casing the fake payment.
`--phone` overrides the outcome
The number decides what the sandbox does, so wajub trigger payment.succeeded --phone +237670000002 creates a payment that fails. Use it to reach outcomes the eight arguments do
not cover, such as a timeout, and read
test scenarios for the full suffix table.
What it cannot trigger
The list is short on purpose: an event only appears there when the CLI can produce it without extra setup. Everything else you produce the same way you would in your own code.
| Event | How to produce it |
|---|---|
transfer.* | wajub beneficiaries create, then wajub transfers create |
dispute.* | Disputes are opened by the acquirer, not by you |
invoice.* | wajub invoices create, then send or mark-paid |
link.* | wajub links create |
account.* | wajub accounts create, for Sync platforms |
payment.expired | Let a pending payment reach the end of its window |
payment.split.* | Pass split_count on a sandbox payment |
Use it against sandbox, deliberately
wajub trigger writes through the API using whichever profile is active. Point it at the wrong
one and you have created a real customer on a real account.
wajub config # which profile is default?
wajub trigger payment.succeeded --profile sandboxThe loop
# 1
wajub listen --forward-to localhost:3000/webhooks/wajub
# 2
wajub trigger payment.succeeded
wajub trigger payment.failed
wajub trigger refund.succeededThree commands cover the branches most handlers get wrong: the happy path, the failure that must release the reservation, and the refund that must not be mistaken for a new payment.