use std::fmt;
use crate::charge::{Charge, ChargeRequest, IdempotencyKey, OrderRef};
use crate::error::Error;
use crate::id::PaymentId;
use crate::instrument::Instrument;
use crate::money::Money;
use crate::refund::{Refund, RefundRequest};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct ProviderId(&'static str);
impl ProviderId {
pub const STRIPE: Self = Self("stripe");
pub const IYZICO: Self = Self("iyzico");
#[must_use]
pub const fn new(name: &'static str) -> Self {
Self(name)
}
#[must_use]
pub const fn as_str(self) -> &'static str {
self.0
}
}
impl fmt::Display for ProviderId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
#[expect(
clippy::struct_excessive_bools,
reason = "each is an independent yes or no about one provider; a state machine would invent an order between them that does not exist"
)]
pub struct Capabilities {
pub separate_capture: bool,
pub partial_capture: bool,
pub partial_refund: bool,
pub repeated_refund: bool,
pub lookup_by_order: bool,
pub saved_instruments: bool,
}
pub use async_trait::async_trait;
#[async_trait]
pub trait Provider: fmt::Debug + Send + Sync {
fn id(&self) -> ProviderId;
async fn charge(&self, request: &ChargeRequest) -> Result<Charge, Error>;
async fn charge_status(&self, id: &PaymentId) -> Result<Charge, Error>;
async fn capture(
&self,
id: &PaymentId,
amount: Option<Money>,
idempotency: Option<&IdempotencyKey>,
) -> Result<Charge, Error>;
async fn cancel(&self, id: &PaymentId) -> Result<Charge, Error>;
async fn refund(&self, request: &RefundRequest) -> Result<Refund, Error>;
async fn lookup(&self, order: &OrderRef) -> Result<Option<Charge>, Error>;
async fn instruments(&self, customer: &str) -> Result<Vec<Instrument>, Error>;
fn capabilities(&self) -> Capabilities;
}