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