1use serde::{Deserialize, Serialize};
2
3use crate::{
4 transport::{PaymentPayload, PaymentRequirements, SettlementResponse},
5 types::{AnyJson, ExtensionIdentifier, Record, X402Version},
6};
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct PaymentRequest {
10 pub payment_payload: PaymentPayload,
11 pub payment_requirements: PaymentRequirements,
12}
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub enum VerifyResult {
16 Valid(VerifyValid),
17 Invalid(VerifyInvalid),
18}
19
20impl VerifyResult {
21 pub fn is_valid(&self) -> bool {
22 matches!(self, VerifyResult::Valid(_))
23 }
24
25 pub fn valid(valid: VerifyValid) -> Self {
26 VerifyResult::Valid(valid)
27 }
28
29 pub fn invalid(invalid: VerifyInvalid) -> Self {
30 VerifyResult::Invalid(invalid)
31 }
32
33 pub fn as_valid(&self) -> Option<&VerifyValid> {
34 match self {
35 VerifyResult::Valid(v) => Some(v),
36 _ => None,
37 }
38 }
39
40 pub fn as_invalid(&self) -> Option<&VerifyInvalid> {
41 match self {
42 VerifyResult::Invalid(v) => Some(v),
43 _ => None,
44 }
45 }
46}
47
48#[derive(Debug, Clone, Serialize, Deserialize)]
49pub struct VerifyValid {
50 pub payer: String,
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct VerifyInvalid {
55 pub invalid_reason: String,
56 pub payer: Option<String>,
57}
58
59#[derive(Debug, Clone, Serialize, Deserialize)]
60pub enum SettleResult {
61 Success(SettleSuccess),
62 Failed(SettleFailed),
63}
64
65impl SettleResult {
66 pub fn is_success(&self) -> bool {
67 matches!(self, SettleResult::Success(_))
68 }
69
70 pub fn success(success: SettleSuccess) -> Self {
71 SettleResult::Success(success)
72 }
73
74 pub fn failed(failed: SettleFailed) -> Self {
75 SettleResult::Failed(failed)
76 }
77
78 pub fn as_success(&self) -> Option<&SettleSuccess> {
79 match self {
80 SettleResult::Success(v) => Some(v),
81 _ => None,
82 }
83 }
84
85 pub fn as_failed(&self) -> Option<&SettleFailed> {
86 match self {
87 SettleResult::Failed(v) => Some(v),
88 _ => None,
89 }
90 }
91}
92
93#[derive(Debug, Clone, Serialize, Deserialize)]
94pub struct SettleSuccess {
95 pub payer: String,
96 pub transaction: String,
97 pub network: String,
98}
99
100#[derive(Debug, Clone, Serialize, Deserialize)]
101pub struct SettleFailed {
102 pub error_reason: String,
103 pub payer: Option<String>,
104}
105
106#[derive(Debug, Clone, Serialize, Deserialize)]
107#[serde(rename_all = "camelCase")]
108pub struct SupportedKinds {
109 pub x402_version: X402Version,
110 pub scheme: String,
111 pub network: String,
112 pub extra: Option<AnyJson>,
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize)]
116#[serde(rename_all = "camelCase")]
117pub struct SupportedResponse {
118 pub kinds: Vec<SupportedKinds>,
119
120 pub extensions: Vec<ExtensionIdentifier>,
123 pub signers: Record<Vec<String>>,
125}
126
127impl From<SettleSuccess> for SettlementResponse {
128 fn from(success: SettleSuccess) -> Self {
129 SettlementResponse {
130 success: true,
131 transaction: success.transaction,
132 network: success.network,
133 payer: success.payer,
134 }
135 }
136}
137
138pub trait Facilitator {
140 type Error: std::error::Error;
141
142 fn supported(&self) -> impl Future<Output = Result<SupportedResponse, Self::Error>>;
143
144 fn verify(
145 &self,
146 request: PaymentRequest,
147 ) -> impl Future<Output = Result<VerifyResult, Self::Error>>;
148
149 fn settle(
150 &self,
151 request: PaymentRequest,
152 ) -> impl Future<Output = Result<SettleResult, Self::Error>>;
153}