pub struct Paygate { /* private fields */ }server only.Expand description
V2-only payment gate for enforcing x402 payments.
Handles the full payment lifecycle: header extraction, verification, settlement, and 402 response generation using the V2 wire format.
Construct via PaygateBuilder (obtained from Paygate::builder).
To add lifecycle hooks (before/after verify and settle), wrap your
facilitator with HookedFacilitator
before passing it to the payment gate.
Implementations§
Source§impl Paygate
impl Paygate
Sourcepub fn builder(facilitator: impl Facilitator + 'static) -> PaygateBuilder
pub fn builder(facilitator: impl Facilitator + 'static) -> PaygateBuilder
Returns a new builder seeded with the given facilitator.
Sourcepub fn builder_from_dyn(facilitator: Arc<dyn DynFacilitator>) -> PaygateBuilder
pub fn builder_from_dyn(facilitator: Arc<dyn DynFacilitator>) -> PaygateBuilder
Returns a new builder over an already-erased facilitator handle.
Sourcepub fn builder_from_server(server: ResourceServer) -> PaygateBuilder
pub fn builder_from_server(server: ResourceServer) -> PaygateBuilder
Returns a new builder from an existing ResourceServer (hooks included).
Sourcepub const fn resource_server(&self) -> &ResourceServer
pub const fn resource_server(&self) -> &ResourceServer
Returns a reference to the resource server (facilitator + hooks).
Sourcepub fn facilitator(&self) -> Arc<dyn DynFacilitator> ⓘ
pub fn facilitator(&self) -> Arc<dyn DynFacilitator> ⓘ
Returns a clone of the erased facilitator handle.
Sourcepub const fn settlement_tracker(&self) -> Option<&BackgroundSettlementTracker>
pub const fn settlement_tracker(&self) -> Option<&BackgroundSettlementTracker>
Returns the in-flight settlement tracker, if one was attached at construction time.
The handle is shareable; clone it and pass to a shutdown task to
await the in-flight drain via
BackgroundSettlementTracker::wait_for_drain:
if let Some(tracker) = paygate.settlement_tracker().cloned() {
tokio::spawn(async move {
match tracker.wait_for_drain(Duration::from_secs(30)).await {
Ok(()) => tracing::info!("settle drain complete"),
Err(remaining) => tracing::warn!(remaining, "drain timeout"),
}
});
}Sourcepub const fn resource(&self) -> &ResourceInfo
pub const fn resource(&self) -> &ResourceInfo
Returns a reference to the resource information.
Sourcepub fn hooks(&self) -> Option<&Arc<dyn DynPaygateHooks>>
pub fn hooks(&self) -> Option<&Arc<dyn DynPaygateHooks>>
Returns the attached paygate hooks, if any.
The middleware layer uses this accessor to dispatch
DynPaygateHooks::on_protected_request and
DynPaygateHooks::on_payment_verified around the payment check.
Sourcepub fn error_response(&self, err: PaygateError) -> Response
pub fn error_response(&self, err: PaygateError) -> Response
Converts a PaygateError into a proper HTTP response.
Verification errors produce a 402 with the Payment-Required header
and a JSON body. Settlement errors produce a 402 with error details.
§Panics
Panics if the payment-required response cannot be serialized to JSON or if the HTTP response builder fails. These indicate a bug.
Source§impl Paygate
impl Paygate
Sourcepub async fn enrich_accepts(&mut self)
pub async fn enrich_accepts(&mut self)
Enriches price tags with facilitator capabilities (e.g., fee payer address).
Sourcepub async fn verify_only(
&self,
headers: &HeaderMap,
) -> Result<VerifiedPayment, PaygateError>
pub async fn verify_only( &self, headers: &HeaderMap, ) -> Result<VerifiedPayment, PaygateError>
Verifies the payment from request headers without executing the inner service or settling on-chain.
Runs ResourceServer lifecycle hooks (before/after verify, failure
recovery). Returns a VerifiedPayment token on success.
§Errors
Returns a verification PaygateError if the payment header is missing,
malformed, or rejected by the facilitator / hooks.
Sourcepub async fn handle_request<ReqBody, ResBody, S: Service<Request<ReqBody>, Response = Response<ResBody>>>(
&self,
inner: S,
req: Request<ReqBody>,
) -> Result<Response, PaygateError>
pub async fn handle_request<ReqBody, ResBody, S: Service<Request<ReqBody>, Response = Response<ResBody>>>( &self, inner: S, req: Request<ReqBody>, ) -> Result<Response, PaygateError>
Handles an incoming request with sequential settlement.
verify → execute → settle → attach header → returnSettlement only runs if the handler returns a success status (not 4xx/5xx).
§Errors
Returns PaygateError if payment verification or settlement fails.
Source§impl Paygate
impl Paygate
Sourcepub async fn handle_request_concurrent<ReqBody, ResBody, S: Service<Request<ReqBody>, Response = Response<ResBody>>>(
&self,
inner: S,
req: Request<ReqBody>,
) -> Result<Response, PaygateError>where
S::Response: IntoResponse,
S::Error: IntoResponse,
S::Future: Send + 'static,
ReqBody: Send + 'static,
pub async fn handle_request_concurrent<ReqBody, ResBody, S: Service<Request<ReqBody>, Response = Response<ResBody>>>(
&self,
inner: S,
req: Request<ReqBody>,
) -> Result<Response, PaygateError>where
S::Response: IntoResponse,
S::Error: IntoResponse,
S::Future: Send + 'static,
ReqBody: Send + 'static,
Handles an incoming request with concurrent settlement.
verify → (settle ∥ execute) → await settle → attach header → returnSettlement is spawned immediately after verification and runs in parallel with the handler, reducing total latency by one facilitator RTT. On handler error (4xx/5xx), the settlement task is abandoned.
§Errors
Returns PaygateError if payment verification or settlement fails.
Sourcepub async fn handle_request_background<ReqBody, ResBody, S: Service<Request<ReqBody>, Response = Response<ResBody>>>(
&self,
inner: S,
req: Request<ReqBody>,
) -> Result<Response, PaygateError>where
S::Response: IntoResponse,
S::Error: IntoResponse,
S::Future: Send + 'static,
ReqBody: Send + 'static,
pub async fn handle_request_background<ReqBody, ResBody, S: Service<Request<ReqBody>, Response = Response<ResBody>>>(
&self,
inner: S,
req: Request<ReqBody>,
) -> Result<Response, PaygateError>where
S::Response: IntoResponse,
S::Error: IntoResponse,
S::Future: Send + 'static,
ReqBody: Send + 'static,
Handles an incoming request with background (fire-and-forget) settlement.
verify → spawn settle (fire-and-forget) → execute → returnSettlement is spawned immediately after verification but never awaited. The response is returned to the client as soon as the handler completes, without waiting for on-chain settlement.
This is ideal for streaming responses (e.g. SSE / LLM token streams) where the client should start receiving data immediately.
Trade-off: the Payment-Response header is not attached to the
response since settlement may still be in progress.
§Errors
Returns a verification PaygateError if payment verification fails.
Settlement errors are logged but do not propagate.