KeelsonDocs
    Judge Mode

    API reference TEE

    Countersign a cart

    POST/v1/countersign

    Sends the cart to the TEE legs in order and returns the countersignatures only when both agree. A DENY is countersigned too. An app acting for a user (purchases:write) countersigns only under a mandate that user approved for it; under a mandate of Keelson's hosted operator it sends mandateId and Keelson closes the mandate with that operator's key over the request id and this cart, and nothing else. A cart is bought once per mandate: while a purchase of the same cart is in flight, or for ten minutes after it was captured, another request for it is answered 409 purchase-exists with that purchase's id, whatever its request id, evidence or Idempotency-Key. Retrying after a lost answer is therefore safe; to buy the same cart again on purpose, name that purchase in repeatOf.

    Headers

    Content-Typeapplication/jsonRequired
    idempotency-keystringRequired
    Idempotency-KeystringRequired
    1 to 255 characters. A retry with the same key returns the first answer.

    Request body

    application/json

    authorizationIdstring
    The PayPal authorization that holds the mandate's funds, or this request's own hold when the mandate holds each purchase separately; leg A reads it. Absent for a card mandate, whose purchase is paid with a single-use card issued after the ALLOW.
    closedMandatestring
    The open mandate closed by the agent's key binding over the request and cart. Required, except of an app acting for a user under a mandate of Keelson's hosted operator, which sends mandateId instead.
    mandateIdstring
    Only for an app acting for a user (purchases:write) under a mandate of Keelson's hosted operator that the user approved for it: Keelson closes the mandate with the hosted operator's key over requestId and this cart.
    requestIdstring
    With mandateId: the request ULID the closed mandate binds, and the purchase's id; a new one when left out.
    cartobjectRequired
    unitobjectRequired
    The PayPal purchase unit the cart is checked against: {amount}, the checkout total the buyer pays as a PayPal Orders v2 amount, whose breakdown has the item_total of the cart's lines and, when the checkout charges them, tax_total, shipping and discount. Keelson countersigns amount.value, which must be item_total + tax_total + shipping − discount, and checks it against the mandate's budget. handling, insurance and shipping_discount are refused: fold them into shipping.
    evidenceobject
    Evidence sources per field. channel3: sources are refused here: the API adds them from the observation stored in the evidence.
    evidenceRootstringRequired
    The root of the evidence stored with POST /v1/evidence for this mandate.
    liveobject
    Only when the buyer pays at the store's own checkout with their own PayPal account: Keelson countersigns and logs the purchase and issues its Alibi, and neither covers nor captures it. Its Alibi is public once the PayPal transaction is recorded. The agent's pay click waits for an ALLOW; the agent then records PayPal's transaction id with PUT /v1/purchases/{id}/paypal-transaction.
    repeatOfstring
    Only when the user asked to buy the same cart again: the id of the latest purchase of this cart under the mandate. Not needed once that purchase was denied or failed before capture, or was captured more than ten minutes ago. A retry after a lost answer never sends it: the 409 purchase-exists answer names the purchase already made.

    Responses

    • 200The decision and its countersignatures
    • 202Countersigned, and a step of the purchase is still pending; Location is the purchase, which finishes on its own
    • 401A leg refused the agent's authority
    • 404No such mandate of an operator this client linked, or that the user approved for this app
    • 409The mandate is not active, the evidence root is not stored for it or already binds another purchase, the request was already used, or the same cart is already being bought (purchase-exists, with its purchaseId)
    • 413A leg refused the request as too large
    • 422The request is invalid, the purchase unit's amount does not reconcile with the cart (invalid-amount), the authorization is not this purchase's hold, the cart is not the one held for this request, the evidence holds another cart or another checkout amount or reference rates Keelson did not issue, its Channel3 observation is not usable, its WebFact is not this purchase's, or a live store is not the website the mandate allows
    • 429Too many countersigns for this mandate
    • 502The legs disagree, or a signer is not registered
    • 503A leg needed to sign, or PayPal, is unavailable, or the hosted operator's key is not configured

    200 response

    purchaseIdstringRequired
    modestringRequired
    degraded when leg B was unreachable and only leg A signed.One of 2of2degraded
    decisionstringRequired
    One of allowdeny
    countersignobjectRequired
    The EIP-712 Countersign message, as decimal strings.
    digeststringRequired
    signaturesobjectRequired
    signersobjectRequired
    tracevalue
    The keelson.eval/1 trace both legs signed over.
    approvalobject
    On a deny for a cart over the mandate's amount or outside its merchants: the user was asked to approve this cart once. Poll POST /v1/connections/token with its device_code; the answer is a single-purchase mandate for exactly this cart.
    statestring
    CAPTURED once logged, covered and captured; FAILED with failure when a step refused; COUNTERSIGNED, LOGGED or COVERED while a step is pending; DENIED for a DENY.
    logIndexstring
    The leaf's index in the Alibi log.
    coverageobject
    The lockCoverage transaction of the operator's bond.
    captureobject
    The PayPal capture of the countersigned amount.
    failureobject
    The step that failed and why; nothing was captured.
    blockedarray of string
    For a DENIED cart, the mandate fields whose check failed.
    reasonsarray of object
    For a DENIED cart, each failed field with what the mandate allowed and what the cart had, as text.
    checksarray of object
    For a purchase the engine checked, each mandate field with what the mandate allowed, what the cart had and whether it held.
    cardobject
    A card purchase: its single-use card (never its number) and every authorization the card network sent it, with both legs' decision. CAPTURED once the merchant's capture settles.
    liveobject
    A purchase the buyer pays at the store's own checkout: the store's origin and the PayPal transaction id once the agent recorded it. Never covered nor captured.