Skip to content

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_creditamount_debit, currency_debit, rate.
  • Partner-specific fields are passed in the data object — see the Services section.