1use serde::{Deserialize, Serialize};
17
18use crate::typed_id::PaymentAttemptId;
19
20#[cfg(feature = "openapi")]
21use utoipa::ToSchema;
22
23#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
25#[cfg_attr(feature = "openapi", derive(ToSchema))]
26#[serde(rename_all = "snake_case")]
27pub enum PaymentRail {
28 MppTempo,
29 X402Base,
30}
31
32impl PaymentRail {
33 pub fn as_wire(&self) -> &'static str {
34 match self {
35 PaymentRail::MppTempo => "mpp_tempo",
36 PaymentRail::X402Base => "x402_base",
37 }
38 }
39}
40
41impl std::fmt::Display for PaymentRail {
42 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43 f.write_str(self.as_wire())
44 }
45}
46
47impl std::str::FromStr for PaymentRail {
48 type Err = String;
49
50 fn from_str(value: &str) -> Result<Self, Self::Err> {
51 match value {
52 "mpp_tempo" => Ok(PaymentRail::MppTempo),
53 "x402_base" => Ok(PaymentRail::X402Base),
54 _ => Err(format!("Invalid payment rail: {value}")),
55 }
56 }
57}
58
59impl From<&str> for PaymentRail {
60 fn from(value: &str) -> Self {
61 match value {
62 "x402_base" => PaymentRail::X402Base,
63 _ => PaymentRail::MppTempo,
64 }
65 }
66}
67
68#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
70#[serde(rename_all = "UPPERCASE")]
71pub enum PaymentMethod {
72 Get,
73 Post,
74}
75
76impl PaymentMethod {
77 pub fn as_wire(&self) -> &'static str {
78 match self {
79 PaymentMethod::Get => "GET",
80 PaymentMethod::Post => "POST",
81 }
82 }
83}
84
85impl std::fmt::Display for PaymentMethod {
86 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87 f.write_str(self.as_wire())
88 }
89}
90
91impl std::str::FromStr for PaymentMethod {
92 type Err = String;
93
94 fn from_str(value: &str) -> Result<Self, Self::Err> {
95 match value {
96 "GET" => Ok(PaymentMethod::Get),
97 "POST" => Ok(PaymentMethod::Post),
98 _ => Err(format!("Invalid payment method: {value}")),
99 }
100 }
101}
102
103#[derive(Debug, Clone, Serialize, Deserialize)]
105pub struct MachinePaymentRequest {
106 pub capability: String,
107 pub operation: String,
108 pub method: PaymentMethod,
109 pub url: String,
110 pub body: Option<serde_json::Value>,
111 pub max_amount_usd: f64,
112 pub rail_preference: Vec<PaymentRail>,
113 pub metadata: serde_json::Value,
114}
115
116#[derive(Debug, Clone, Serialize, Deserialize)]
118pub struct MachinePaymentResponse {
119 pub attempt_id: Option<PaymentAttemptId>,
120 pub amount_usd: f64,
121 pub rail: Option<PaymentRail>,
122 pub response: serde_json::Value,
123 pub receipt: serde_json::Value,
124}