Transfer consent
The payer API 0.9 adds optional transfer consent. A quote is a preview. A consent receipt records payer intent. Issuer debit approval is a separate step that this version does not implement.
The payer API runs only in the local sandbox: the hosted sandbox does not serve it yet.
POST /v1/payer/transfer-consents takes quote_id and the required boolean name_unavailable_acknowledged. Use the original DPoP session and an Idempotency-Key UUID. An UNAVAILABLE name requires true; a MATCHED name requires false. The source must stay VERIFIED and the quote CURRENT. Consent never bypasses the currency, amount, fee or limit rules.
Display and verify the exact returned quote before signing. The device challenge uses TRANSFER_CONSENT and binds the original quote, source/destination intent, evidence versions, payer/device/session and acknowledgement. Sign the returned signing_bytes with the enrolled P-256 device key, SHA256 ECDSA DER encoded as unpadded base64url. The generated SDK handles wire serialization; it does not generate device signatures or DPoP. Never collect an issuer PIN, password or OTP.
Each quote has a single challenge. Exact retries of the preparation keep the challenge and its deadline; another key does not create a second challenge. The expiry stays bounded by the quote and the session. A new quote is needed after expiry.
POST /v1/payer/transfer-consents/{id}/complete takes signature. Preserve the exact completion key and signature after an uncertain outcome; use a fresh DPoP proof for each retry. A changed signature under the same key conflicts. Successful concurrent retries produce one immutable consent. Failed attempts are bounded to ten per challenge and fifty per device/minute; preparation is bounded to ten per payer/minute and sixty/hour.
GET /v1/payer/transfer-consents/{id} returns an accepted historical receipt to the original session while it is active. An exact retry can recover that receipt even after the quote expired or the source was later suspended. CONSENT_RECORDED and PAYER_INTENT_ONLY prove neither a debit authorization, nor reserved funds, nor an executed transfer. Another session cannot read this receipt.
These calls do not extend session idle time. Dismissing a confirmation before sending creates no accepted consent. After sending, interruption or timeout is uncertain: retry the original command or read its receipt. Issuer approval and transfer execution follow separate contracts. Android and iOS remain independent native implementations.