diff --git a/Cargo.lock b/Cargo.lock index 8023468..79c742a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4604,6 +4604,7 @@ name = "stripe_adapter" version = "0.1.0" dependencies = [ "async-trait", + "derive_more", "fulfillment_adapter", "payment_adapter", "payup", diff --git a/crates/payment_adapter/src/lib.rs b/crates/payment_adapter/src/lib.rs index aac1e43..8b063df 100644 --- a/crates/payment_adapter/src/lib.rs +++ b/crates/payment_adapter/src/lib.rs @@ -2,7 +2,6 @@ use std::any::Any; use std::collections::HashMap; -use std::ops::DerefMut; pub use config::PaymentProviderConfig; pub use model::v3::*; @@ -32,14 +31,13 @@ pub struct UpdateRequests { pub customer_metadata: Option, } -pub struct PaymentSessionData { - pub id: Option, - pub meta: HashMap, +pub trait PaymentSessionData: Send + Sync { + fn id(&self) -> Option; } pub struct PaymentProcessorSessionResponse { pub update_requests: Option, - pub session_data: PaymentSessionData, + pub session_data: Box, } pub struct PaymentProcessorContext { @@ -50,7 +48,7 @@ pub struct PaymentProcessorContext { pub resource_id: String, pub customer: Option, pub context: PaymentProcessCtx, - pub payment_session_data: PaymentSessionData, + pub payment_session_data: Box, } #[derive(Debug, serde::Serialize, serde::Deserialize)] @@ -129,6 +127,8 @@ pub enum PError { ChargeNotExists(String), #[error("Failed capture charge with id {0:?}")] FailedCapture(String), + #[error("Invalid charge for given payment adapter")] + InvalidType, } pub type PResult = Result; @@ -166,82 +166,68 @@ pub trait PaymentAdapter { */ async fn refund_payment( &mut self, - payment_session_data: PaymentSessionData, + payment_session_data: &mut Box, refund_amount: Amount, - ) -> PResult; + ) -> PResult<()>; /** * Authorize an existing session if it is not already authorized */ async fn authorize_payment( &mut self, - payment_session_data: PaymentSessionData, + payment_session_data: &mut Box, data: PaymentProcessCtx, - ) -> PResult<(PaymentSessionStatus, PaymentSessionData)>; + ) -> PResult<(PaymentSessionStatus, ())>; /** * Capture an existing session */ async fn capture_payment( &mut self, - payment_session_data: PaymentSessionData, - ) -> PResult; + payment_session_data: &mut Box, + ) -> PResult<()>; /** * Delete an existing session */ async fn delete_payment( &mut self, - payment_session_data: PaymentSessionData, - ) -> PResult; + payment_session_data: &mut Box, + ) -> PResult<()>; /** * Retrieve an existing session */ async fn retrieve_payment( &mut self, - payment_session_data: PaymentSessionData, - ) -> PResult; + payment_session_data: &mut Box, + ) -> PResult<()>; /** * Cancel an existing session */ async fn cancel_payment( &mut self, - payment_session_data: PaymentSessionData, - ) -> PResult; + payment_session_data: &mut Box, + ) -> PResult<()>; /** * Return the status of the session */ async fn payment_status( &mut self, - payment_session_data: &PaymentSessionData, + payment_session_data: &mut Box, ) -> PResult; } -// use traitcast::{Traitcast, TraitcastFrom}; - -pub trait APaymentSessionData: Any { - fn id(&self) -> Option; +pub fn session_ref( + session: &Box, +) -> Option<&T> { + ::downcast_ref(session) } -pub struct BPSD(Box); - -impl BPSD { - pub fn as_mut_ref(&mut self) -> Option<&mut T> { - use std::boxed::Box; - - let r = self.0.deref_mut(); - if ::is::<&T>(r) { - Some(unsafe { r as &mut T }) - } else { - None - } - } -} - -async fn f(mut psd: &mut BPSD) { - use std::boxed::Box; - let c = psd.deref_mut(); +pub fn session_mut_ref( + session: &mut Box, +) -> Option<&mut T> { + ::downcast_mut(session) } diff --git a/crates/stripe_adapter/Cargo.toml b/crates/stripe_adapter/Cargo.toml index 3105dbb..a279db4 100644 --- a/crates/stripe_adapter/Cargo.toml +++ b/crates/stripe_adapter/Cargo.toml @@ -17,3 +17,4 @@ payup = { version = "*", features = [] } tracing = { version = "0.1.37" } async-trait = { version = "0.1.68" } serde = { version = "1.0.162", features = ['derive'] } +derive_more = { version = "0.99.17" } diff --git a/crates/stripe_adapter/src/lib.rs b/crates/stripe_adapter/src/lib.rs index b573714..c9b25e7 100644 --- a/crates/stripe_adapter/src/lib.rs +++ b/crates/stripe_adapter/src/lib.rs @@ -1,9 +1,9 @@ #![crate_type = "rlib"] -use std::any::Any; use std::collections::HashMap; use std::ops::DerefMut; +use derive_more::DerefMut; use fulfillment_adapter::*; use payment_adapter::*; use payup::stripe; @@ -105,7 +105,7 @@ impl PaymentAdapter for StripePrzelewy24 { captured: self.config.capture.clone(), currency: Some(currency_code.into()), description: desc, - customer: customer.map(|c| c.id.0.to_string()), + customer: customer.as_ref().map(|c| c.id.0.to_string()), receipt_email: Some(email.0), ..stripe::Charge::new() } @@ -113,11 +113,11 @@ impl PaymentAdapter for StripePrzelewy24 { .await .unwrap(); - let update_requests = match customer { + let update_requests = match customer.as_ref() { Some(c) if !c.has_stripe_id() => Some(UpdateRequests { customer_metadata: Some(CustomerMetadata(HashMap::from([( "id".to_string(), - AnyData(change.customer.unwrap_or_default().into_bytes()), + AnyData(change.customer.clone().unwrap_or_default().into_bytes()), )]))), }), _ => None, @@ -125,7 +125,7 @@ impl PaymentAdapter for StripePrzelewy24 { Ok(PaymentProcessorSessionResponse { update_requests, - session_data: payment_session_data, + session_data: Box::new(Charge(change)), }) } @@ -138,30 +138,30 @@ impl PaymentAdapter for StripePrzelewy24 { async fn refund_payment( &mut self, - payment_session_data: PaymentSessionData, + payment_session_data: &mut Box, refund_amount: Amount, - ) -> PResult { + ) -> PResult<()> { todo!() } async fn authorize_payment( &mut self, - payment_session_data: PaymentSessionData, + payment_session_data: &mut Box, data: PaymentProcessCtx, - ) -> PResult<(PaymentSessionStatus, PaymentSessionData)> { - self.payment_status(&payment_session_data) + ) -> PResult<(PaymentSessionStatus, ())> { + self.payment_status(payment_session_data) .await - .map(|status| (status, payment_session_data)) + .map(|status| (status, ())) } async fn capture_payment( &mut self, - mut payment_session_data: PaymentSessionData, - ) -> PResult { - let id = payment_session_data - .id - .clone() - .ok_or_else(|| PError::NoChargeId)?; + payment_session_data: &mut Box, + ) -> PResult<()> { + let Some(session) = session_mut_ref::(payment_session_data) else { + return Err(PError::InvalidType); + }; + let id = session.id().ok_or_else(|| PError::NoChargeId)?; let charge = stripe::Charge::async_get(self.stripe.clone(), id.clone()) .await .map_err(|_| PError::ChargeNotExists(id.clone()))?; @@ -172,38 +172,40 @@ impl PaymentAdapter for StripePrzelewy24 { tracing::warn!("{e}"); PError::FailedCapture(id) })?; - payment_session_data.id = charge.id; - Ok(payment_session_data) + session.0 = change; + Ok(()) } async fn delete_payment( &mut self, - payment_session_data: PaymentSessionData, - ) -> PResult { + payment_session_data: &mut Box, + ) -> PResult<()> { todo!() } async fn retrieve_payment( &mut self, - payment_session_data: PaymentSessionData, - ) -> PResult { + payment_session_data: &mut Box, + ) -> PResult<()> { todo!() } async fn cancel_payment( &mut self, - payment_session_data: PaymentSessionData, - ) -> PResult { + payment_session_data: &mut Box, + ) -> PResult<()> { todo!() } async fn payment_status( &mut self, - payment_session_data: &PaymentSessionData, + payment_session_data: &mut Box, ) -> PResult { payment_status( self.stripe.clone(), - payment_session_data.id.clone().unwrap_or_default(), + payment_session_data + .id() + .ok_or_else(|| PError::NoChargeId)?, ) .await .map_err(|_| PError::HttpError) @@ -240,3 +242,12 @@ impl StripeCustomerMetadata for Customer { .and_then(|v| String::from_utf8(v.clone()).ok()) } } + +#[derive(Debug, derive_more::Deref, derive_more::DerefMut)] +struct Charge(stripe::Charge); + +impl PaymentSessionData for Charge { + fn id(&self) -> Option { + self.0.id.clone() + } +}