use serde::{Deserialize, Serialize};
use crate::typed_id::PaymentAttemptId;
#[cfg(feature = "openapi")]
use utoipa::ToSchema;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[cfg_attr(feature = "openapi", derive(ToSchema))]
#[serde(rename_all = "snake_case")]
pub enum PaymentRail {
MppTempo,
X402Base,
}
impl PaymentRail {
pub fn as_wire(&self) -> &'static str {
match self {
PaymentRail::MppTempo => "mpp_tempo",
PaymentRail::X402Base => "x402_base",
}
}
}
impl std::fmt::Display for PaymentRail {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_wire())
}
}
impl std::str::FromStr for PaymentRail {
type Err = String;
fn from_str(value: &str) -> Result<Self, Self::Err> {
match value {
"mpp_tempo" => Ok(PaymentRail::MppTempo),
"x402_base" => Ok(PaymentRail::X402Base),
_ => Err(format!("Invalid payment rail: {value}")),
}
}
}
impl From<&str> for PaymentRail {
fn from(value: &str) -> Self {
match value {
"x402_base" => PaymentRail::X402Base,
_ => PaymentRail::MppTempo,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "UPPERCASE")]
pub enum PaymentMethod {
Get,
Post,
}
impl PaymentMethod {
pub fn as_wire(&self) -> &'static str {
match self {
PaymentMethod::Get => "GET",
PaymentMethod::Post => "POST",
}
}
}
impl std::fmt::Display for PaymentMethod {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_wire())
}
}
impl std::str::FromStr for PaymentMethod {
type Err = String;
fn from_str(value: &str) -> Result<Self, Self::Err> {
match value {
"GET" => Ok(PaymentMethod::Get),
"POST" => Ok(PaymentMethod::Post),
_ => Err(format!("Invalid payment method: {value}")),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MachinePaymentRequest {
pub capability: String,
pub operation: String,
pub method: PaymentMethod,
pub url: String,
pub body: Option<serde_json::Value>,
pub max_amount_usd: f64,
pub rail_preference: Vec<PaymentRail>,
pub metadata: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MachinePaymentResponse {
pub attempt_id: Option<PaymentAttemptId>,
pub amount_usd: f64,
pub rail: Option<PaymentRail>,
pub response: serde_json::Value,
pub receipt: serde_json::Value,
}