Setting up your funding integration

Register the URLs Moov should call, then exchange a signing secret. You host the endpoints; Moov POSTs to them.

Three steps: register URLs, exchange a signing secret, and confirm the request shape.

Register your provider URLs #

Register independent URLs with Moov Money:

URLCalled whenPurpose
AuthorizationURLA user initiates a paymentPlace a hold on their funding source
CaptureURLThe recipient completes a claimSettle (capture) a previously placed hold
HoldReleaseURLA payment is canceled or expiresRelease a hold, returning funds to the sender
CreditURLA request has been paid into your walletBook a deposit to the requester

Moov Money POSTs to each registered URL verbatim, with no path appended. The URLs may live at different hosts, bases, or paths; they are treated as opaque endpoints. Paths in the API reference (authorize, capture, release, credit account) are illustrative only. Register CreditURL before go-live if you collect on requests; it isn’t called until requests are enabled for your program. (Card-funded programs skip all four: an OCT to the requester’s FI-issued card credits them instead.)

There is no API for URL registration: send the URLs to your Moov integration contact, who configures them for your program. Changing a URL later goes through the same channel.

Exchange signing secrets #

Request and response bodies are encrypted JWEs. The wrapping key is a raw 32-byte secret issued via the Moov Money API. Authenticate with your Moov API key (Dashboard → Developers → API keys) as HTTP Basic auth:

curl -X POST "https://api.moov.money/providers/$PROVIDER_ID/signing-secrets" \
  -u "$MOOV_API_KEY_ID:$MOOV_API_KEY_SECRET"

Field-by-field: create signing secret.

See sender authentication for more on this credential. It’s the same API key used to register senders and mint their access tokens.

The secret is returned exactly once, base64url-encoded without padding (RFC 4648 §5). Decode it to recover the raw 32-byte AES key and store it in your secrets manager. It cannot be retrieved again, only rotated.

The cryptographic parameters, both directions:

  • Key management: A256KW (AES-256 key wrap)
  • Content encryption: A256GCM
  • JWE header: {"alg":"A256KW","enc":"A256GCM","typ":"JWT","cty":"JWT"}
  • The inner payload is a JWT with iat and exp at the top level and all Moov claims under a moov object

See Encryption for a worked example of decrypting a request and encrypting a response.

Confirm the transport shape #

Each endpoint accepts HTTPS POST with Content-Type: application/json. The request body is a JSON object with a single request field carrying the compact-serialized JWE; your response is a JSON object with a single response field carrying the JWE reply:

// Request from Moov Money
{ "request": "eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMjU2R0NNIiwidHlwIjoiSldUIiwiY3R5IjoiSldUIn0.…" }

// Your response
{ "response": "eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMjU2R0NNIiwidHlwIjoiSldUIiwiY3R5IjoiSldUIn0.…" }

All business fields (amounts, references, the idempotency key) travel inside the JWE claims, never in the outer JSON.

Next steps #