Connection flow
Program-owned card selection, connect-hint verification, association reads, and final-list submission.
In an environment where the current flow is enabled, Facto opens the card page you registered. The cardholder signs in, chooses cards, and approves the change on that page. Your backend then reads the current card list and submits the complete list the cardholder confirmed.
Use the Engine host and server credential issued for the same enabled environment as the Card Program. Credentials never move between environments.
Prerequisites
| Facto configures | Your team builds |
|---|---|
| An approved Program Connection and a server credential | A cardholder sign-in, card selection, and approval page |
The exact connect_page_url that Facto may open | A backend that verifies the connection hint and calls the Engine API |
Keep the server credential out of the browser. Use provider-only card IDs plus the network, card type, and last four digits for display. PAN and CVV are rejected. There is no Server SDK for the card-list operations.
Connection sequence
Connect handshake
Who calls whom, in order, from the cardholder choosing your program to the window sealing.
Create the connect intent and open the Program page
The cardholder chooses the program in Facto and continues. Facto first opens a
blank popup from that click, then creates the connection request and sends the
popup to connect_page_url. Ask the cardholder to allow popups; the current
interface reports a blocked popup and requires a retry. The URL fragment carries
connect_hint and connect_intent_id, so neither enters server logs or the
Referer header. Read them, then remove the fragment from the address bar.
Verify the connect hint
Pass the hint from your page to your backend and verify it with
/.well-known/facto-card-program-connect/jwks.json. The
verifyFactoCardProgramConnectHint helper from @facto/connect/server performs
this check. This is the only SDK helper for the current flow.
Capture card selection and consent
Explain which cards will be connected and what will be shared. Let the
cardholder add or remove cards, then require explicit approval. Keep an
auditable approval_ref for that decision.
Read current associations
The response includes the current associations and portfolio_revision.
Submit the final desired card set
Send the complete post-update set of cards that should remain connected. An empty
list removes every card this user connected to this program. Include
the connection hint, approval_ref, authorized_changes_digest, and
portfolio_revision in the JSON body, plus Idempotency-Key in the header.
Facto stores the approval reference and digest as the Program's audit record. It checks their format, but does not recompute the digest or independently verify your approval page.
Apply the transaction and track status
Facto saves all card changes in one transaction or saves none. applied means
the list changed; no_change means it already matched. If the cardholder
cancels, report it explicitly:
Send { "connect_hint": "eyJ..." } as the JSON body. An empty body is invalid.
Facto polls the connection status. The status returned by the Engine is authoritative.
If Facto pauses new card connections, a request that adds cards returns
423 binding_admission_closed. A request that only removes cards still works.
Closing the popup without reporting cancellation leaves the request pending
until it expires; a retry needs a new request.
PaymentRoute configuration
Each card retained in the final set has an active card binding. Payment
eligibility also requires the cardholder to associate a PaymentRoute in Facto.
The Card Program cannot read PaymentRoute or payment_readiness. If the
connection result still
requires a funding source, the cardholder returns to Cards, opens the card, and
selects a pipeline with active status. Continue with card bindings and consent
and PaymentRoute and authorization.