Issuer approval status
The payer API 0.11 adds an optional synthetic issuer handoff after a quote, device-signed consent and retained approval request. POST /v1/payer/transfer-approval-requests/{id}/issuer-refresh takes an empty body, an Idempotency-Key UUID and fresh DPoP from the original session. GET /v1/payer/transfer-approval-requests/{id}/issuer-status reads the locally retained status without contacting another service, accepting new evidence or renewing the idle session.
The payer API runs only in the local sandbox: the hosted sandbox does not serve it yet.
For an eligible PENDING request with status: CURRENT, the response may contain approval_url. Open that configured synthetic issuer page for explicit approval or decline. Treat its fragment capability as sensitive: do not send it to analytics, log it, or put it in a notification. A null URL means the app must not offer a handoff from this response. On return, explicitly refresh with a new mutation UUID and fresh DPoP. The browser return itself proves no decision.
The response authority is always APPROVAL_STATUS_ONLY. APPROVED and DECLINED refer to a retained local historical decision; inspect decision.classification and decision.requires_investigation. The decision member is absent until a local classification has been retained. AWAITING_ACCEPTANCE means terminal issuer evidence was saved but the local acceptance step has not completed; only explicit refresh can attempt that step. UNAVAILABLE or CONFLICT must not be treated as an approval. The separate status reports the original time window and source availability. None of these fields authorizes a debit, reserves funds or proves that a recipient was paid.
A historical decision stays historical. A later expiry, revocation or suspension does not rewrite the retained fact and never turns it into an execution authorization. Only the original session, while active, can read this status. A URL is published only for a pending request that is still eligible and not expired. Reads do not extend the session.
If last_refresh is UNKNOWN, preserve the original request and mutation key and retry with a fresh DPoP proof. Each possible dispatch consumes a separately committed attempt. Once a command has a known pending response, retrying that same key is passive; use a new key for the next explicit poll. Terminal recovery is local. Every successful command key, including a cache hit, binds to its original request. The persistent limits are sixty commands and sixty dispatch attempts per request and 120 of each per session per minute. GET remains available without creating either record. A foreign session returns 404; an invalid or revoked session returns 401; first refresh after expiry returns 410; exhausted budgets return 429.
The generated SDK exposes refreshPayerTransferIssuer, readPayerTransferIssuerStatus, TransferIssuerStatus and TransferIssuerDecision. Clients supply device-backed DPoP and enforce their own lifecycle and presentation rules. Android and iOS continue as independent native implementations.
The integration is disabled by default. Identity requires quote and approval admission configuration plus IDENTITY_ISSUER_REFRESH_ENABLED=true, its private switch origin, separate observation service credential and perimeter credential, configured transfer issuer origin, and separate bank/wallet transfer public keys. The switch observation service and isolated synthetic transfer issuer must also be explicitly configured. Linking keys are not transfer approval pins. Live provider integration and monetary execution remain separate work.
For a native issuer return after credentials were cleared on lock, see fresh-proof original-session resumption.