# MIDDLEWARES
async def settle_with_flow402(
*,
nonce: str,
tx_hash: str,
fee_tx_hash: Optional[str],
intent_id: str,
) -> Dict[str, Any]:
"""
Call Flow402 simplified /settle endpoint.
"""
url = "https://api.flow402.net/settle"
payload = {
"nonce": nonce,
"txHash": tx_hash,
"feeTxHash": fee_tx_hash,
"intentId": intent_id,
}
async with httpx.AsyncClient() as client:
res = await client.post(url, json=payload)
# If 4xx/5xx: raise for debug, you can also handle gracefully
res.raise_for_status()
return res.json()
async def require_payment(body: Dict[str, Any] = Body(...)):
"""
FastAPI dependency that checks payment against Flow402.
It mimics the Express middleware `requirePayment`.
"""
nonce = body.get("nonce")
intent_id = body.get("intentId")
tx_hash = body.get("txHash")
fee_tx_hash = body.get("feeTxHash")
# Return 402 "Payment required" if missing fields
if not nonce or not intent_id or not tx_hash:
raise HTTPException(
status_code=402,
detail={
"error": "payment_required",
"message": "Missing Flow402 payment body.",
"expectedBody": ["nonce", "intentId", "txHash"],
"optionalBody": "feeTxHash",
},
)
# Call Flow402 facilitator
result = await settle_with_flow402(
nonce=nonce,
tx_hash=tx_hash,
fee_tx_hash=fee_tx_hash,
intent_id=intent_id,
)
# Return 402 if payment not settled
if not result.get("settled"):
raise HTTPException(
status_code=402,
detail={
"error": "payment_not_settled",
"message": "Payment not settled on-chain.",
"facilitatorResponse": result,
},
)
# Attach receipt-like info for the endpoint handler
return {
"txHash": result.get("txHash"),
"receipt": result.get("receipt"),
}