Milkyway — overview¶
Milkyway is a cross-border transfer platform. Sending banks integrate with the platform once and gain access to every connected receiving bank (partner) through a single interface: Milkyway talks to the chosen partner itself and normalizes the response to a common format.
The list of partners, services and their terms is in the Services section.
Authentication¶
Access to Milkyway is protected with OAuth 2.0. The sending bank obtains an access
token from Planet9's Keycloak (via the client credentials issued at onboarding),
then passes it on every request to Milkyway in the Authorization: Bearer <token>
header.
How to obtain a token in the stage and production environments (realms, token endpoint, request examples) — see the Authentication section.
Transfer lifecycle¶
Every transfer goes through: Precheck (recipient validation and rate calculation) and Pay (execution). The status can then be polled (Postcheck) or delivered via a webhook from Milkyway — pick whichever suits you.
sequenceDiagram
autonumber
participant S as Sending bank
participant O as Keycloak
participant M as Milkyway
Note over S,O: Authentication
S->>O: Token request (client credentials)
O-->>S: Access token
Note over S,M: Precheck — recipient validation and rate calculation
S->>M: Precheck + Bearer token
M-->>S: amount_debit, currency_debit, rate
Note over S,M: Pay — transfer execution
S->>M: Pay (+ data)
M-->>S: Accepted for processing
Getting the status¶
The transfer status — two ways, your choice:
Option 1 — polling (Postcheck)
sequenceDiagram
participant S as Sending bank
participant M as Milkyway
S->>M: GET postcheck + Bearer token
M-->>S: transaction_id, status, error
Option 2 — webhook (push from Milkyway)
sequenceDiagram
participant M as Milkyway
participant S as Sending bank
M->>S: POST callback (transaction_id, status, error)
S-->>M: 200 OK
Both ways carry the same payload — the one returned by
GET /payments/v1/postcheck:
{
"transaction_id": 42,
"status": 1,
"error": ""
}
Statuses: 0 — processing, 1 — done, 2 — cancelled, 3 — failed,
4 — cancellation in progress.
The webhook removes the need to poll: on a status change Milkyway sends this POST
to the callback URL agreed at onboarding; a 2xx response is expected, otherwise it
retries with exponential backoff. If the webhook is unavailable, polling via
Postcheck always remains.
Feature status
Polling (Postcheck) is available now. The webhook is planned; the payload contract is shown above and will match Postcheck.
Unified interface¶
Requests and responses are the same for every partner and service; the full schema
is in the milkyway core OpenAPI spec (branch dev) and is not duplicated here. Key
fields:
- Precheck:
recipient_id,amount_credit,currency_credit→amount_debit,currency_debit,rate. - Partner-specific fields are passed in the
dataobject — see the Services section.