filter payment methods based on obtainment type

This commit is contained in:
Djkáťo 2024-04-10 16:59:10 +02:00
parent 31eac1d7ab
commit b257d18c95
4 changed files with 116 additions and 12 deletions

View file

@ -1,4 +1,3 @@
[toolchain] [toolchain]
channel = "nightly" channel = "nightly-2024-03-23"
targets = ["x86_64-unknown-linux-gnu"] targets = ["x86_64-unknown-linux-gnu"]
components = ["clippy"]

View file

@ -11,7 +11,7 @@ use tracing_subscriber::EnvFilter;
use saleor_app_sdk::{config::Config, locales::LocaleCode, manifest::AppManifest, SaleorApp}; use saleor_app_sdk::{config::Config, locales::LocaleCode, manifest::AppManifest, SaleorApp};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
// Make our own error that wraps `anyhow::Error`. // Make our own error that wraps `anyhow::Error`.
pub struct AppError(anyhow::Error); pub struct AppError(pub anyhow::Error);
// Tell axum how to convert `AppError` into a response. // Tell axum how to convert `AppError` into a response.
impl IntoResponse for AppError { impl IntoResponse for AppError {
@ -49,7 +49,7 @@ pub fn trace_to_std(config: &Config) -> anyhow::Result<()> {
Ok(()) Ok(())
} }
#[derive(Debug, Clone, Sequence, Serialize, Deserialize)] #[derive(Debug, Clone, Sequence, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")] #[serde(rename_all = "lowercase")]
pub enum PaymentMethodType { pub enum PaymentMethodType {
Accreditation, Accreditation,

View file

@ -2,6 +2,23 @@ use const_format::concatcp;
#[cynic::schema("saleor")] #[cynic::schema("saleor")]
mod schema {} mod schema {}
pub const fragment_checkout_details: &str = r#"
fragment CheckoutDetails on Checkout {
id
isShippingRequired
deliveryMethod {
... on Warehouse {
name
id
}
... on ShippingMethod {
id
name
}
}
}
"#;
pub const fragment_transaction_details: &str = r#" pub const fragment_transaction_details: &str = r#"
fragment TransactionDetails on TransactionItem { fragment TransactionDetails on TransactionItem {
id id
@ -48,6 +65,8 @@ fragment OrderDetails on Order {
paymentStatus paymentStatus
chargeStatus chargeStatus
canFinalize canFinalize
shippingMethodName
collectionPointName
totalBalance { totalBalance {
currency currency
amount amount
@ -75,14 +94,20 @@ subscription PaymentGatewayInitializeSession {
data data
amount amount
sourceObject { sourceObject {
... on Checkout {
...CheckoutDetails
}
... on Order {
...OrderDetails ...OrderDetails
} }
}
amount amount
} }
} }
} }
"#, "#,
fragment_order_details fragment_order_details,
fragment_checkout_details
); );
pub const sub_transaction_initialize_session: &str = concatcp!( pub const sub_transaction_initialize_session: &str = concatcp!(
@ -92,8 +117,13 @@ subscription transactionInitializeSession {
... on TransactionInitializeSession { ... on TransactionInitializeSession {
data data
sourceObject { sourceObject {
... on Checkout {
...CheckoutDetails
}
... on Order {
...OrderDetails ...OrderDetails
} }
}
transaction { transaction {
...TransactionDetails ...TransactionDetails
} }
@ -107,7 +137,8 @@ subscription transactionInitializeSession {
} }
"#, "#,
fragment_order_details, fragment_order_details,
fragment_transaction_details fragment_transaction_details,
fragment_checkout_details
); );
pub const sub_transaction_process_session: &str = concatcp!( pub const sub_transaction_process_session: &str = concatcp!(
@ -120,8 +151,13 @@ subscription transactionProcessSession {
actionType actionType
} }
sourceObject { sourceObject {
... on Checkout {
...CheckoutDetails
}
... on Order {
...OrderDetails ...OrderDetails
} }
}
transaction { transaction {
...TransactionDetails ...TransactionDetails
} }
@ -131,7 +167,8 @@ subscription transactionProcessSession {
} }
"#, "#,
fragment_order_details, fragment_order_details,
fragment_transaction_details fragment_transaction_details,
fragment_checkout_details,
); );
pub const sub_transaction_charge_requested: &str = concatcp!( pub const sub_transaction_charge_requested: &str = concatcp!(
@ -191,6 +228,12 @@ subscription transactionCancelationRequested {
fragment_transaction_details fragment_transaction_details
); );
#[derive(cynic::QueryFragment, Debug)]
pub struct Warehouse {
pub name: String,
pub id: cynic::Id,
}
#[derive(cynic::QueryFragment, Debug)] #[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "TransactionRefundRequested")] #[cynic(graphql_type = "TransactionRefundRequested")]
pub struct TransactionRefundRequested2 { pub struct TransactionRefundRequested2 {
@ -301,6 +344,12 @@ pub struct PaymentGatewayInitializeSession {
pub event: Option<Event6>, pub event: Option<Event6>,
} }
#[derive(cynic::QueryFragment, Debug)]
pub struct ShippingMethod {
pub id: cynic::Id,
pub name: String,
}
#[derive(cynic::QueryFragment, Debug)] #[derive(cynic::QueryFragment, Debug)]
#[cynic(graphql_type = "PaymentGatewayInitializeSession")] #[cynic(graphql_type = "PaymentGatewayInitializeSession")]
pub struct PaymentGatewayInitializeSession2 { pub struct PaymentGatewayInitializeSession2 {
@ -318,6 +367,8 @@ pub struct Order {
pub payment_status: PaymentChargeStatusEnum, pub payment_status: PaymentChargeStatusEnum,
pub charge_status: OrderChargeStatusEnum, pub charge_status: OrderChargeStatusEnum,
pub can_finalize: bool, pub can_finalize: bool,
pub shipping_method_name: Option<String>,
pub collection_point_name: Option<String>,
pub total_balance: Money, pub total_balance: Money,
} }
@ -327,6 +378,13 @@ pub struct Money {
pub amount: f64, pub amount: f64,
} }
#[derive(cynic::QueryFragment, Debug)]
pub struct Checkout {
pub id: cynic::Id,
pub is_shipping_required: bool,
pub delivery_method: Option<DeliveryMethod>,
}
#[derive(cynic::InlineFragments, Debug)] #[derive(cynic::InlineFragments, Debug)]
#[cynic(graphql_type = "Event")] #[cynic(graphql_type = "Event")]
pub enum Event6 { pub enum Event6 {
@ -374,8 +432,17 @@ pub enum Event {
Unknown, Unknown,
} }
#[derive(cynic::InlineFragments, Debug)]
pub enum DeliveryMethod {
Warehouse(Warehouse),
ShippingMethod(ShippingMethod),
#[cynic(fallback)]
Unknown,
}
#[derive(cynic::InlineFragments, Debug)] #[derive(cynic::InlineFragments, Debug)]
pub enum OrderOrCheckout { pub enum OrderOrCheckout {
Checkout(Checkout),
Order(Order), Order(Order),
#[cynic(fallback)] #[cynic(fallback)]
Unknown, Unknown,

View file

@ -22,10 +22,12 @@ use tracing::{debug, error, info};
use crate::{ use crate::{
app::{ app::{
AppError, AppState, PaymentGatewayInitializeSessionData, TransactionInitializeSessionData, AppError, AppState, PaymentGatewayInitializeSessionData, PaymentMethodType,
TransactionInitializeSessionData,
}, },
queries::{ queries::{
event_transactions::{ event_transactions::{
DeliveryMethod, OrderOrCheckout, PaymentGatewayInitializeSession2,
TransactionCancelationRequested2, TransactionChargeRequested2, TransactionCancelationRequested2, TransactionChargeRequested2,
TransactionFlowStrategyEnum, TransactionInitializeSession2, TransactionProcessSession2, TransactionFlowStrategyEnum, TransactionInitializeSession2, TransactionProcessSession2,
TransactionRefundRequested2, TransactionRefundRequested2,
@ -63,8 +65,44 @@ pub async fn webhooks(
// Json::from(serde_json::to_value(PaymentListGatewaysResponse(gateways))?) // Json::from(serde_json::to_value(PaymentListGatewaysResponse(gateways))?)
// } // }
SyncWebhookEventType::PaymentGatewayInitializeSession => { SyncWebhookEventType::PaymentGatewayInitializeSession => {
let session_data = serde_json::from_str::<PaymentGatewayInitializeSession2>(&body)?;
let mut filtered_payment_methods = state.active_payment_methods.clone();
//If obtainment method is via some sort of shipping, remove PaymentMethodType::Cash
//If obtainment method is collection in person at warehouse, remove PaymentMethodType::CODv
match session_data.source_object {
OrderOrCheckout::Order(o) => {
if o.shipping_method_name.is_some() {
filtered_payment_methods.retain(|p| p.typ != PaymentMethodType::Cash)
} else if o.collection_point_name.is_some() {
filtered_payment_methods.retain(|p| p.typ != PaymentMethodType::COD)
} else {
error!("Order has neither shipping_method_name or collection_point_name, how is it being payed for?");
}
}
OrderOrCheckout::Checkout(c) => {
if let Some(d) = c.delivery_method {
match d {
DeliveryMethod::Warehouse(_) => {
filtered_payment_methods
.retain(|p| p.typ != PaymentMethodType::COD);
}
DeliveryMethod::ShippingMethod(_) => {
filtered_payment_methods
.retain(|p| p.typ != PaymentMethodType::Cash);
}
DeliveryMethod::Unknown => {
error!("DeliveryMethod is neither");
}
}
}
}
OrderOrCheckout::Unknown => {
error!("OrderOrCheckout is neither");
}
}
let data = serde_json::to_value(PaymentGatewayInitializeSessionData { let data = serde_json::to_value(PaymentGatewayInitializeSessionData {
payment_methods: state.active_payment_methods, payment_methods: filtered_payment_methods,
})?; })?;
Json::from(serde_json::to_value( Json::from(serde_json::to_value(
PaymentGatewayInitializeSessionResponse::<Value> { data: Some(data) }, PaymentGatewayInitializeSessionResponse::<Value> { data: Some(data) },