Skip to content

Commit a3266e7

Browse files
committed
Merge branch 'feat/acp-837' of github.com:Virtual-Protocol/acp-x402-server into feat/acp-837
2 parents 1dd5bd7 + 8bf12c4 commit a3266e7

File tree

1 file changed

+53
-4
lines changed

1 file changed

+53
-4
lines changed

python/x402/src/x402/fastapi/middleware.py

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,17 @@
2020
PaymentPayload,
2121
PaymentRequirements,
2222
Price,
23+
SettleResponse,
2324
x402PaymentRequiredResponse,
2425
PaywallConfig,
2526
SupportedNetworks,
2627
HTTPInputSchema,
2728
)
2829

30+
import os
31+
import httpx
32+
33+
2934
logger = logging.getLogger(__name__)
3035

3136

@@ -206,10 +211,54 @@ def x402_response(error: str):
206211

207212
# Settle the payment
208213
try:
209-
210-
settle_response = await facilitator.settle(
211-
payment, selected_payment_requirements
212-
)
214+
custom_facilitator_url = os.getenv("CUSTOM_FACILITATOR_API_URL", "")
215+
custom_facilitator_succeeded = False
216+
custom_facilitator_response = None
217+
218+
if custom_facilitator_url:
219+
try:
220+
url = f"{custom_facilitator_url.rstrip('/')}/api/x402/facilitators/settle"
221+
headers = {"x-payment": payment_header}
222+
async with httpx.AsyncClient(timeout=60.0) as client:
223+
custom_facilitator_response = await client.post(url, headers=headers)
224+
custom_facilitator_response.raise_for_status()
225+
custom_facilitator_succeeded = True
226+
logger.info(f"Custom facilitator settle succeeded")
227+
except Exception as e:
228+
logger.warning(f"Custom facilitator settle POST failed: {e}, falling back to default facilitator")
229+
custom_facilitator_succeeded = False
230+
231+
# Fallback to default facilitator if custom facilitator wasn't used or failed
232+
if not custom_facilitator_succeeded:
233+
settle_response = await facilitator.settle(
234+
payment, selected_payment_requirements
235+
)
236+
else:
237+
# If custom facilitator succeeded, we still need a settle_response for the response headers
238+
# Create a minimal success response
239+
try:
240+
payer = payment.payload.authorization.from_
241+
except (AttributeError, KeyError):
242+
payer = ""
243+
244+
# Extract transaction hash from custom facilitator response
245+
transaction_hash = ""
246+
try:
247+
if custom_facilitator_response:
248+
response_data = custom_facilitator_response.json()
249+
if isinstance(response_data, dict) and "data" in response_data:
250+
data = response_data["data"]
251+
if isinstance(data, dict) and "transactionHash" in data:
252+
transaction_hash = data["transactionHash"]
253+
except (AttributeError, KeyError, ValueError, httpx.DecodeError) as e:
254+
logger.warning(f"Failed to extract transactionHash from custom facilitator response: {e}")
255+
256+
settle_response = SettleResponse(
257+
success=True,
258+
transaction=transaction_hash,
259+
network=selected_payment_requirements.network,
260+
payer=payer,
261+
)
213262

214263
if settle_response.success:
215264
response.headers["X-PAYMENT-RESPONSE"] = base64.b64encode(

0 commit comments

Comments
 (0)