Wires the cab_hailing ride-hailing example (see
docs/example_implementations/ride_hailing)
to a runnable local BAP/BPP adapter stack, so the full ride-hailing lifecycle can be
driven with Postman and actually observed end to end — not just read as static JSON.
Modelled on beckn-onix's generic-devkit,
reusing its shared bap.example.com / bpp.example.com testnet sandbox credentials,
with a sandbox-bpp payload mount (pattern borrowed from local-retail's
retail-devkit) so responses are realistic ride-hailing content instead of generic stubs.
Scope note: this devkit only wires up the
cab_hailinguse case. Theride-hailing-examplesbranch also has metro fare, bike rental, driver hire, car rental, and multimodal itinerary examples — none of those are wired here yet.Known content caveats (inherited from the source example set, not fixed by this devkit): the flow never reaches a
COMPLETEcontract status (onlyACTIVE, postupdate, orCANCELLED, viacancel),on_cancel's settlements have a duplicateid, andrate/supportdon't fully match theRatingInput/SupportRequestcore schemas. See the review this devkit was scoped from for detail. Once the source example-jsons are fixed, re-runscripts/resolve_sandbox_payloads.pyandscripts/build_postman_collections.pyto refresh this devkit's fixtures/collections.
- Docker Desktop — installed and running
- Git — on your system path
- Postman — for sending API calls
mobility-devkit/
├── config/ # ONIX adapter configs (keys, schema validator, routing)
├── install/ # docker-compose stack, Caddy reverse proxy, ngrok tunnel config
├── postman/ # BAP and BPP Postman collections for the full ride-hailing lifecycle
└── scripts/ # generator scripts that (re)build postman/ and sandbox-payloads/
# from docs/example_implementations/ride_hailing/example-jsons/
The mock BPP's canned response fixtures live outside this folder, at
sandbox-payloads/nfh.global/testnet-mobility/response/
(repo root), mirroring the local-retail convention of keeping sandbox fixtures
alongside — not inside — the devkit directory.
1. Start the adapter stack
cd testnet/mobility-devkit/install
docker compose -f docker-compose-mobility.yml up -d
docker psYou should see six containers: beckn-router, redis, onix-bap,
onix-bpp, sandbox-bap, sandbox-bpp.
These container/network names match
generic-devkitandretail-devkitexactly. Only one of these devkit stacks can run at a time on this machine — stop any other running Beckn devkit first (docker compose downin itsinstall/folder), since container names and ports (8081/8082/3001/3002/6379/9000) would otherwise collide.
2. Import the Postman collections
Import both files from postman/:
- BAP — Beckn Mobility Ride-Hailing Devkit — the 10 outbound requests a rider's app sends
- BPP — Beckn Mobility Ride-Hailing Devkit — the 10
on_*callbacks, for testing the BAP receiver directly with unsolicited pushes (e.g. a driver-arriving push mid-trip)
3. Run the flow
Use the BAP collection, in order:
| # | Action | Folder |
|---|---|---|
| 1 | discover |
1 — Discovery |
| 2 | select → init → confirm |
2 — Transaction |
| 3 | status → track → update → cancel |
3 — Fulfillment |
| 4 | rate → support |
4 — Post-Fulfillment |
Each request returns a synchronous ACK. The matching on_* callback (served from the
sandbox-bpp fixture) arrives back at onix-bap's receiver and is
forwarded to sandbox-bap, where it can be seen in logs:
docker logs -f onix-bap
docker logs -f sandbox-bapcancel and update in this set are illustrative alternate endings from the same
contract (see the scope note above) rather than one continuous story — run them as
separate demonstrations, not back-to-back on the same "trip."
| Variable | Default value | Notes |
|---|---|---|
version |
2.0.0 |
Beckn protocol version |
networkId |
nfh.global/testnet-mobility |
Matches context.networkId |
bap_id |
bap.example.com |
BAP subscriber ID (shared testnet sandbox credential) |
bap_uri |
{{public_url}}/bap/receiver |
BAP callback URL, routed via beckn-router |
bpp_id |
bpp.example.com |
BPP subscriber ID (shared testnet sandbox credential) |
bpp_uri |
{{public_url}}/bpp/receiver |
BPP endpoint URL, routed via beckn-router |
bap_adapter_url |
http://localhost:8081/bap/caller |
BAP collection target |
bpp_adapter_url |
http://localhost:8082/bpp/caller |
BPP collection target |
transaction_id |
fixed UUID | Shared across the full flow; change for a new session |
messageId and timestamp are auto-generated per request via Postman's {{$guid}}
and {{$isoTimestamp}}.
Unlike generic-devkit (which routes select/init/confirm/... to targetType: bpp,
resolved via the live DeDi registry), every routing rule here uses targetType: url
pointing directly at the other adapter's container (onix-bap:8081 /
onix-bpp:8082). The shared bap.example.com/bpp.example.com sandbox
credentials are registered under beckn.one/testnet in the DeDi registry, not under
this devkit's own nfh.global/testnet-mobility network ID, so a registry-resolved
route wouldn't resolve here. Fixed URLs keep the devkit fully self-contained (no
external registry dependency) while still exercising both adapters' full pipeline —
sign, schema validation, ack — rather than skipping straight to the mock.
For the same reason, discover is also routed through onix-bpp rather than
to a live Discover Service URL (as generic-devkit does) — there's no registered
mobility discovery service to point at yet.
| Adapter | Path | Purpose |
|---|---|---|
| BAP | http://localhost:8081/bap/caller/ |
Send outbound action requests (Postman target) |
| BAP | http://localhost:8081/bap/receiver/ |
Receive inbound on_* callbacks |
| BPP | http://localhost:8082/bpp/caller/ |
Send outbound on_* callbacks (Postman target) |
| BPP | http://localhost:8082/bpp/receiver/ |
Receive inbound action requests |
Ships with the same testnet sandbox credentials as beckn-onix's generic-devkit
(bap.example.com / bpp.example.com, pre-registered on beckn.one/testnet via the
DeDi registry). To register your own subscriber IDs and keys, follow the
DeDi registration guide and update the
keyManager block in config/mobility-bap.yaml / config/mobility-bpp.yaml.
Both adapters validate all payloads against the canonical Beckn v2.0.0 OpenAPI spec,
with extended (domain-specific) schema validation enabled against schema.beckn.io
and raw.githubusercontent.com (needed for the mobility *Attributes schema types
used throughout these examples — RideOption, FareEstimate, SurgeMultiplier,
Driver, Passenger, etc.).
cp install/ngrok.yml.example install/ngrok.yml # fill in authtoken (+ static domain)
ngrok start --all --config install/ngrok.ymlThen point public_url (used to derive bap_uri/bpp_uri) at the tunnel URL instead
of http://beckn-router:9000.
Postman (BAP coll.) ──POST /bap/caller/<action>──► onix-bap:8081
│ signs, routes by fixed URL
▼
onix-bpp:8082
│ forwards to sandbox-bpp
▼
sandbox-bpp:3002
│ returns canned on_<action> fixture
▼
onix-bpp:8082 ──POST /bpp/caller/on_<action>──►
│ signs, routes by fixed URL onix-bap:8081
▼ │ forwards to sandbox-bap
▼
sandbox-bap:3001
(view response in logs)
If the cab_hailing content under docs/example_implementations/ride_hailing/example-jsons/
changes (e.g. once the known content caveats above are fixed):
python3 scripts/resolve_sandbox_payloads.py # refreshes sandbox-payloads/.../response/*.json
python3 scripts/build_postman_collections.py # refreshes postman/*.postman_collection.jsonBoth scripts only read from example-jsons/ and write to sandbox-payloads/ /
postman/ — they never modify the source example files.
docker compose -f docker-compose-mobility.yml downContainer fails to start
docker pull fidedocker/onix-adapter
docker pull fidedocker/sandbox-2.0:latestSchema validation error — verify the payload matches the v2.0.0 spec:
docker logs onix-bap 2>&1 | grep -i "schema\|error"on_* callback not received — check BAP receiver logs:
docker logs -f onix-bapSandbox health check fails — allow 10–15 seconds for sandbox containers to initialise:
docker logs sandbox-bap
docker logs sandbox-bpp