diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json index 0505dd498e..275a271616 100644 --- a/api-reference-v2/openapi_spec.json +++ b/api-reference-v2/openapi_spec.json @@ -11712,11 +11712,12 @@ "PaymentsCreateResponseOpenApi": { "type": "object", "required": [ + "payment_id", + "merchant_id", "status", "amount", "net_amount", "amount_capturable", - "amount_received", "currency", "payment_method", "attempt_count" @@ -11726,7 +11727,6 @@ "type": "string", "description": "Unique identifier for the payment. This ensures idempotency for multiple payments\nthat have been done by a single merchant.", "example": "pay_mbabizu24mvu3mela5njyhpit4", - "nullable": true, "maxLength": 30, "minLength": 30 }, @@ -11734,7 +11734,6 @@ "type": "string", "description": "This is an identifier for the merchant account. This is inferred from the API key\nprovided during the request", "example": "merchant_1668273825", - "nullable": true, "maxLength": 255 }, "status": { @@ -11768,7 +11767,8 @@ "type": "integer", "format": "int64", "description": "The amount which is already captured from the payment, this helps in the cases where merchants can't capture all capturable amount at once.", - "example": 6540 + "example": 6540, + "nullable": true }, "connector": { "type": "string", @@ -12765,11 +12765,12 @@ "PaymentsResponse": { "type": "object", "required": [ + "payment_id", + "merchant_id", "status", "amount", "net_amount", "amount_capturable", - "amount_received", "currency", "payment_method", "attempt_count" @@ -12779,7 +12780,6 @@ "type": "string", "description": "Unique identifier for the payment. This ensures idempotency for multiple payments\nthat have been done by a single merchant.", "example": "pay_mbabizu24mvu3mela5njyhpit4", - "nullable": true, "maxLength": 30, "minLength": 30 }, @@ -12787,7 +12787,6 @@ "type": "string", "description": "This is an identifier for the merchant account. This is inferred from the API key\nprovided during the request", "example": "merchant_1668273825", - "nullable": true, "maxLength": 255 }, "status": { @@ -12821,7 +12820,8 @@ "type": "integer", "format": "int64", "description": "The amount which is already captured from the payment, this helps in the cases where merchants can't capture all capturable amount at once.", - "example": 6540 + "example": 6540, + "nullable": true }, "connector": { "type": "string", diff --git a/api-reference/openapi_spec.json b/api-reference/openapi_spec.json index 63dae96511..67254b3609 100644 --- a/api-reference/openapi_spec.json +++ b/api-reference/openapi_spec.json @@ -16292,11 +16292,12 @@ "PaymentsCreateResponseOpenApi": { "type": "object", "required": [ + "payment_id", + "merchant_id", "status", "amount", "net_amount", "amount_capturable", - "amount_received", "currency", "payment_method", "attempt_count" @@ -16306,7 +16307,6 @@ "type": "string", "description": "Unique identifier for the payment. This ensures idempotency for multiple payments\nthat have been done by a single merchant.", "example": "pay_mbabizu24mvu3mela5njyhpit4", - "nullable": true, "maxLength": 30, "minLength": 30 }, @@ -16314,7 +16314,6 @@ "type": "string", "description": "This is an identifier for the merchant account. This is inferred from the API key\nprovided during the request", "example": "merchant_1668273825", - "nullable": true, "maxLength": 255 }, "status": { @@ -16348,7 +16347,8 @@ "type": "integer", "format": "int64", "description": "The amount which is already captured from the payment, this helps in the cases where merchants can't capture all capturable amount at once.", - "example": 6540 + "example": 6540, + "nullable": true }, "connector": { "type": "string", @@ -17345,11 +17345,12 @@ "PaymentsResponse": { "type": "object", "required": [ + "payment_id", + "merchant_id", "status", "amount", "net_amount", "amount_capturable", - "amount_received", "currency", "payment_method", "attempt_count" @@ -17359,7 +17360,6 @@ "type": "string", "description": "Unique identifier for the payment. This ensures idempotency for multiple payments\nthat have been done by a single merchant.", "example": "pay_mbabizu24mvu3mela5njyhpit4", - "nullable": true, "maxLength": 30, "minLength": 30 }, @@ -17367,7 +17367,6 @@ "type": "string", "description": "This is an identifier for the merchant account. This is inferred from the API key\nprovided during the request", "example": "merchant_1668273825", - "nullable": true, "maxLength": 255 }, "status": { @@ -17401,7 +17400,8 @@ "type": "integer", "format": "int64", "description": "The amount which is already captured from the payment, this helps in the cases where merchants can't capture all capturable amount at once.", - "example": 6540 + "example": 6540, + "nullable": true }, "connector": { "type": "string", diff --git a/crates/api_models/src/events/payment.rs b/crates/api_models/src/events/payment.rs index c4459223a5..ba137cd3ba 100644 --- a/crates/api_models/src/events/payment.rs +++ b/crates/api_models/src/events/payment.rs @@ -99,9 +99,9 @@ impl ApiEventMetric for PaymentsRequest { impl ApiEventMetric for PaymentsResponse { fn get_api_event_type(&self) -> Option { - self.payment_id - .clone() - .map(|payment_id| ApiEventsType::Payment { payment_id }) + Some(ApiEventsType::Payment { + payment_id: self.payment_id.clone(), + }) } } diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index b02d44f980..5ccde3e6d7 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -3554,16 +3554,7 @@ pub struct ReceiverDetails { amount_remaining: Option, } -#[derive( - Setter, - Clone, - Default, - Debug, - PartialEq, - serde::Serialize, - ToSchema, - router_derive::PolymorphicSchema, -)] +#[derive(Clone, Debug, PartialEq, serde::Serialize, ToSchema, router_derive::PolymorphicSchema)] #[generate_schemas(PaymentsCreateResponseOpenApi)] pub struct PaymentsResponse { @@ -3574,12 +3565,12 @@ pub struct PaymentsResponse { max_length = 30, example = "pay_mbabizu24mvu3mela5njyhpit4" )] - pub payment_id: Option, + pub payment_id: String, /// This is an identifier for the merchant account. This is inferred from the API key /// provided during the request - #[schema(max_length = 255, example = "merchant_1668273825", value_type = Option)] - pub merchant_id: Option, + #[schema(max_length = 255, example = "merchant_1668273825", value_type = String)] + pub merchant_id: id_type::MerchantId, #[schema(value_type = IntentStatus, example = "failed", default = "requires_confirmation")] pub status: api_enums::IntentStatus, @@ -3595,10 +3586,10 @@ pub struct PaymentsResponse { /// The maximum amount that could be captured from the payment #[schema(value_type = i64, minimum = 100, example = 6540)] - pub amount_capturable: Option, + pub amount_capturable: MinorUnit, /// The amount which is already captured from the payment, this helps in the cases where merchants can't capture all capturable amount at once. - #[schema(value_type = i64, example = 6540)] + #[schema(value_type = Option, example = 6540)] pub amount_received: Option, /// The connector used for the payment @@ -3658,7 +3649,6 @@ pub struct PaymentsResponse { pub mandate_id: Option, /// Provided mandate information for creating a mandate - #[auth_based] pub mandate_data: Option, /// Indicates that you intend to make future payments with this Payment’s payment method. Providing this parameter will attach the payment method to the Customer, if present, after the Payment is confirmed and any required actions from the user are complete. @@ -3682,12 +3672,10 @@ pub struct PaymentsResponse { /// The payment method that is to be used #[schema(value_type = PaymentMethod, example = "bank_transfer")] - #[auth_based] pub payment_method: Option, /// The payment method information provided for making a payment #[schema(value_type = Option, example = "bank_transfer")] - #[auth_based] #[serde(serialize_with = "serialize_payment_method_data_response")] pub payment_method_data: Option, diff --git a/crates/router/src/compatibility/stripe/payment_intents/types.rs b/crates/router/src/compatibility/stripe/payment_intents/types.rs index c061931256..e76ed607b2 100644 --- a/crates/router/src/compatibility/stripe/payment_intents/types.rs +++ b/crates/router/src/compatibility/stripe/payment_intents/types.rs @@ -462,11 +462,11 @@ impl From for payments::PaymentsCancelRequest { #[derive(Default, Eq, PartialEq, Serialize, Debug)] pub struct StripePaymentIntentResponse { - pub id: Option, + pub id: String, pub object: &'static str, pub amount: i64, pub amount_received: Option, - pub amount_capturable: Option, + pub amount_capturable: i64, pub currency: String, pub status: StripePaymentStatus, pub client_secret: Option>, @@ -520,7 +520,7 @@ impl From for StripePaymentIntentResponse { id: resp.payment_id, status: StripePaymentStatus::from(resp.status), amount: resp.amount.get_amount_as_i64(), - amount_capturable: resp.amount_capturable.map(|amt| amt.get_amount_as_i64()), + amount_capturable: resp.amount_capturable.get_amount_as_i64(), amount_received: resp.amount_received.map(|amt| amt.get_amount_as_i64()), connector: resp.connector, client_secret: resp.client_secret, diff --git a/crates/router/src/compatibility/stripe/setup_intents/types.rs b/crates/router/src/compatibility/stripe/setup_intents/types.rs index 66c35637de..8d59ef4031 100644 --- a/crates/router/src/compatibility/stripe/setup_intents/types.rs +++ b/crates/router/src/compatibility/stripe/setup_intents/types.rs @@ -451,7 +451,7 @@ pub(crate) fn into_stripe_next_action( #[derive(Default, Eq, PartialEq, Serialize)] pub struct StripeSetupIntentResponse { - pub id: Option, + pub id: String, pub object: String, pub status: StripeSetupStatus, pub client_secret: Option>, diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index df61b8809a..3a101fe8fc 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -389,7 +389,7 @@ pub fn payments_to_payments_response( payment_data: PaymentData, captures: Option>, customer: Option, - auth_flow: services::AuthFlow, + _auth_flow: services::AuthFlow, base_url: &str, operation: &Op, connector_request_reference_id_config: &ConnectorRequestReferenceIdConfig, @@ -715,7 +715,6 @@ where ) } - let mut response: api::PaymentsResponse = Default::default(); let routed_through = payment_attempt.connector.clone(); let connector_label = routed_through.as_ref().and_then(|connector_name| { @@ -749,163 +748,144 @@ where } }; - services::ApplicationResponse::JsonWithHeaders(( - response - .set_net_amount(payment_attempt.net_amount) - .set_payment_id(Some(payment_attempt.payment_id)) - .set_merchant_id(Some(payment_attempt.merchant_id)) - .set_status(payment_intent.status) - .set_amount(payment_attempt.amount) - .set_amount_capturable(Some(payment_attempt.amount_capturable)) - .set_amount_received(payment_intent.amount_captured) - .set_surcharge_details(surcharge_details) - .set_connector(routed_through) - .set_client_secret(payment_intent.client_secret.map(Secret::new)) - .set_created(Some(payment_intent.created_at)) - .set_currency(currency.to_string()) - .set_customer_id(customer.as_ref().map(|cus| cus.clone().get_customer_id())) - .set_email( - customer - .as_ref() - .and_then(|cus| cus.email.as_ref().map(|s| s.to_owned())), - ) - .set_name( - customer - .as_ref() - .and_then(|cus| cus.name.as_ref().map(|s| s.to_owned())), - ) - .set_phone( - customer - .as_ref() - .and_then(|cus| cus.phone.as_ref().map(|s| s.to_owned())), - ) - .set_mandate_id(mandate_id) - .set_mandate_data( - payment_data.setup_mandate.map(|d| api::MandateData { - customer_acceptance: d.customer_acceptance.map(|d| { - api::CustomerAcceptance { - acceptance_type: match d.acceptance_type { - hyperswitch_domain_models::mandates::AcceptanceType::Online => { - api::AcceptanceType::Online - } - hyperswitch_domain_models::mandates::AcceptanceType::Offline => { - api::AcceptanceType::Offline - } - }, - accepted_at: d.accepted_at, - online: d.online.map(|d| api::OnlineMandate { - ip_address: d.ip_address, - user_agent: d.user_agent, - }), - } - }), - mandate_type: d.mandate_type.map(|d| match d { - hyperswitch_domain_models::mandates::MandateDataType::MultiUse(Some(i)) => { - api::MandateType::MultiUse(Some(api::MandateAmountData { - amount: i.amount, - currency: i.currency, - start_date: i.start_date, - end_date: i.end_date, - metadata: i.metadata, - })) - } - hyperswitch_domain_models::mandates::MandateDataType::SingleUse(i) => { - api::MandateType::SingleUse(api::payments::MandateAmountData { - amount: i.amount, - currency: i.currency, - start_date: i.start_date, - end_date: i.end_date, - metadata: i.metadata, - }) - } - hyperswitch_domain_models::mandates::MandateDataType::MultiUse(None) => { - api::MandateType::MultiUse(None) - } - }), - update_mandate_id: d.update_mandate_id, - }), - auth_flow == services::AuthFlow::Merchant, - ) - .set_description(payment_intent.description) - .set_refunds(refunds_response) // refunds.iter().map(refund_to_refund_response), - .set_disputes(disputes_response) - .set_attempts(attempts_response) - .set_captures(captures_response) - .set_payment_method( - payment_attempt.payment_method, - auth_flow == services::AuthFlow::Merchant, - ) - .set_payment_method_data( - payment_method_data_response, - auth_flow == services::AuthFlow::Merchant, - ) - .set_payment_token(payment_attempt.payment_token) - .set_error_message( - payment_attempt - .error_reason - .or(payment_attempt.error_message), - ) - .set_error_code(payment_attempt.error_code) - .set_shipping(payment_data.address.get_shipping().cloned()) - .set_billing(payment_data.address.get_payment_billing().cloned()) - .set_next_action(next_action_response) - .set_return_url(payment_intent.return_url) - .set_cancellation_reason(payment_attempt.cancellation_reason) - .set_authentication_type(payment_attempt.authentication_type) - .set_statement_descriptor_name(payment_intent.statement_descriptor_name) - .set_statement_descriptor_suffix(payment_intent.statement_descriptor_suffix) - .set_setup_future_usage(payment_intent.setup_future_usage) - .set_capture_method(payment_attempt.capture_method) - .set_payment_experience(payment_attempt.payment_experience) - .set_payment_method_type(payment_attempt.payment_method_type) - .set_metadata(payment_intent.metadata) - .set_order_details(payment_intent.order_details) - .set_connector_label(connector_label) - .set_business_country(payment_intent.business_country) - .set_business_label(payment_intent.business_label) - .set_business_sub_label(payment_attempt.business_sub_label) - .set_allowed_payment_method_types(payment_intent.allowed_payment_method_types) - .set_ephemeral_key(payment_data.ephemeral_key.map(ForeignFrom::foreign_from)) - .set_frm_message(frm_message) - .set_merchant_decision(merchant_decision) - .set_manual_retry_allowed(helpers::is_manual_retry_allowed( - &payment_intent.status, - &payment_attempt.status, - connector_request_reference_id_config, - &merchant_id, - )) - .set_connector_transaction_id(payment_attempt.connector_transaction_id) - .set_feature_metadata(payment_intent.feature_metadata) - .set_connector_metadata(payment_intent.connector_metadata) - .set_reference_id(payment_attempt.connector_response_reference_id) - .set_payment_link(payment_link_data) - .set_profile_id(payment_intent.profile_id) - .set_attempt_count(payment_intent.attempt_count) - .set_merchant_connector_id(payment_attempt.merchant_connector_id) - .set_unified_code(payment_attempt.unified_code) - .set_unified_message(payment_attempt.unified_message) - .set_incremental_authorization_allowed( - payment_intent.incremental_authorization_allowed, - ) - .set_external_authentication_details(external_authentication_details) - .set_fingerprint(payment_intent.fingerprint_id) - .set_authorization_count(payment_intent.authorization_count) - .set_incremental_authorizations(incremental_authorizations_response) - .set_expires_on(payment_intent.session_expiry) - .set_external_3ds_authentication_attempted( - payment_attempt.external_three_ds_authentication_attempted, - ) - .set_payment_method_id(payment_attempt.payment_method_id) - .set_payment_method_status(payment_data.payment_method_info.map(|info| info.status)) - .set_customer(customer_details_response.clone()) - .set_browser_info(payment_attempt.browser_info) - .set_updated(Some(payment_intent.modified_at)) - .set_charges(charges_response) - .set_frm_metadata(payment_intent.frm_metadata) - .set_merchant_order_reference_id(payment_intent.merchant_order_reference_id) - .to_owned(), - headers, - )) + let mandate_data = payment_data.setup_mandate.map(|d| api::MandateData { + customer_acceptance: d.customer_acceptance.map(|d| api::CustomerAcceptance { + acceptance_type: match d.acceptance_type { + hyperswitch_domain_models::mandates::AcceptanceType::Online => { + api::AcceptanceType::Online + } + hyperswitch_domain_models::mandates::AcceptanceType::Offline => { + api::AcceptanceType::Offline + } + }, + accepted_at: d.accepted_at, + online: d.online.map(|d| api::OnlineMandate { + ip_address: d.ip_address, + user_agent: d.user_agent, + }), + }), + mandate_type: d.mandate_type.map(|d| match d { + hyperswitch_domain_models::mandates::MandateDataType::MultiUse(Some(i)) => { + api::MandateType::MultiUse(Some(api::MandateAmountData { + amount: i.amount, + currency: i.currency, + start_date: i.start_date, + end_date: i.end_date, + metadata: i.metadata, + })) + } + hyperswitch_domain_models::mandates::MandateDataType::SingleUse(i) => { + api::MandateType::SingleUse(api::payments::MandateAmountData { + amount: i.amount, + currency: i.currency, + start_date: i.start_date, + end_date: i.end_date, + metadata: i.metadata, + }) + } + hyperswitch_domain_models::mandates::MandateDataType::MultiUse(None) => { + api::MandateType::MultiUse(None) + } + }), + update_mandate_id: d.update_mandate_id, + }); + + let payments_response = api::PaymentsResponse { + payment_id: payment_intent.payment_id, + merchant_id: payment_intent.merchant_id, + status: payment_intent.status, + amount: payment_attempt.amount, + net_amount: payment_attempt.net_amount, + amount_capturable: payment_attempt.amount_capturable, + amount_received: payment_intent.amount_captured, + connector: routed_through, + client_secret: payment_intent.client_secret.map(Secret::new), + created: Some(payment_intent.created_at), + currency: currency.to_string(), + customer_id: customer.as_ref().map(|cus| cus.clone().get_customer_id()), + customer: customer_details_response, + description: payment_intent.description, + refunds: refunds_response, + disputes: disputes_response, + attempts: attempts_response, + captures: captures_response, + mandate_id, + mandate_data, + setup_future_usage: payment_intent.setup_future_usage, + off_session: payment_intent.off_session, + capture_on: None, + capture_method: payment_attempt.capture_method, + payment_method: payment_attempt.payment_method, + payment_method_data: payment_method_data_response, + payment_token: payment_attempt.payment_token, + shipping: payment_data.address.get_shipping().cloned(), + billing: payment_data.address.get_payment_billing().cloned(), + order_details: payment_intent.order_details, + email: customer + .as_ref() + .and_then(|cus| cus.email.as_ref().map(|s| s.to_owned())), + name: customer + .as_ref() + .and_then(|cus| cus.name.as_ref().map(|s| s.to_owned())), + phone: customer + .as_ref() + .and_then(|cus| cus.phone.as_ref().map(|s| s.to_owned())), + return_url: payment_intent.return_url, + authentication_type: payment_attempt.authentication_type, + statement_descriptor_name: payment_intent.statement_descriptor_name, + statement_descriptor_suffix: payment_intent.statement_descriptor_suffix, + next_action: next_action_response, + cancellation_reason: payment_attempt.cancellation_reason, + error_code: payment_attempt.error_code, + error_message: payment_attempt + .error_reason + .or(payment_attempt.error_message), + unified_code: payment_attempt.unified_code, + unified_message: payment_attempt.unified_message, + payment_experience: payment_attempt.payment_experience, + payment_method_type: payment_attempt.payment_method_type, + connector_label, + business_country: payment_intent.business_country, + business_label: payment_intent.business_label, + business_sub_label: payment_attempt.business_sub_label, + allowed_payment_method_types: payment_intent.allowed_payment_method_types, + ephemeral_key: payment_data.ephemeral_key.map(ForeignFrom::foreign_from), + manual_retry_allowed: helpers::is_manual_retry_allowed( + &payment_intent.status, + &payment_attempt.status, + connector_request_reference_id_config, + &merchant_id, + ), + connector_transaction_id: payment_attempt.connector_transaction_id, + frm_message, + metadata: payment_intent.metadata, + connector_metadata: payment_intent.connector_metadata, + feature_metadata: payment_intent.feature_metadata, + reference_id: payment_attempt.connector_response_reference_id, + payment_link: payment_link_data, + profile_id: payment_intent.profile_id, + surcharge_details, + attempt_count: payment_intent.attempt_count, + merchant_decision, + merchant_connector_id: payment_attempt.merchant_connector_id, + incremental_authorization_allowed: payment_intent.incremental_authorization_allowed, + authorization_count: payment_intent.authorization_count, + incremental_authorizations: incremental_authorizations_response, + external_authentication_details, + external_3ds_authentication_attempted: payment_attempt + .external_three_ds_authentication_attempted, + expires_on: payment_intent.session_expiry, + fingerprint: payment_intent.fingerprint_id, + browser_info: payment_attempt.browser_info, + payment_method_id: payment_attempt.payment_method_id, + payment_method_status: payment_data.payment_method_info.map(|info| info.status), + updated: Some(payment_intent.modified_at), + charges: charges_response, + frm_metadata: payment_intent.frm_metadata, + merchant_order_reference_id: payment_intent.merchant_order_reference_id, + }; + + services::ApplicationResponse::JsonWithHeaders((payments_response, headers)) }; metrics::PAYMENT_OPS_COUNT.add( @@ -1034,15 +1014,13 @@ pub fn wait_screen_next_steps_check( } impl ForeignFrom<(storage::PaymentIntent, storage::PaymentAttempt)> for api::PaymentsResponse { - fn foreign_from(item: (storage::PaymentIntent, storage::PaymentAttempt)) -> Self { - let pi = item.0; - let pa = item.1; + fn foreign_from((pi, pa): (storage::PaymentIntent, storage::PaymentAttempt)) -> Self { Self { - payment_id: Some(pi.payment_id), - merchant_id: Some(pi.merchant_id), + payment_id: pi.payment_id, + merchant_id: pi.merchant_id, status: pi.status, amount: pi.amount, - amount_capturable: pi.amount_captured, + amount_capturable: pa.amount_capturable, client_secret: pi.client_secret.map(|s| s.into()), created: Some(pi.created_at), currency: pi.currency.map(|c| c.to_string()).unwrap_or_default(), @@ -1107,7 +1085,55 @@ impl ForeignFrom<(storage::PaymentIntent, storage::PaymentAttempt)> for api::Pay } } ), - ..Default::default() + // TODO: fill in details based on requirement + net_amount: pa.net_amount, + amount_received: None, + refunds: None, + disputes: None, + attempts: None, + captures: None, + mandate_id: None, + mandate_data: None, + off_session: None, + capture_on: None, + payment_token: None, + email: None, + name: None, + phone: None, + return_url: None, + statement_descriptor_name: None, + statement_descriptor_suffix: None, + next_action: None, + cancellation_reason: None, + error_code: None, + error_message: None, + unified_code: None, + unified_message: None, + payment_experience: None, + connector_label: None, + allowed_payment_method_types: None, + ephemeral_key: None, + manual_retry_allowed: None, + frm_message: None, + connector_metadata: None, + feature_metadata: None, + reference_id: None, + payment_link: None, + surcharge_details: None, + merchant_decision: None, + incremental_authorization_allowed: None, + authorization_count: None, + incremental_authorizations: None, + external_authentication_details: None, + external_3ds_authentication_attempted: None, + expires_on: None, + fingerprint: None, + browser_info: None, + payment_method_id: None, + payment_method_status: None, + updated: None, + charges: None, + frm_metadata: None, } } } diff --git a/crates/router/src/core/webhooks/incoming.rs b/crates/router/src/core/webhooks/incoming.rs index 9d16cf62c0..d3e5873e9e 100644 --- a/crates/router/src/core/webhooks/incoming.rs +++ b/crates/router/src/core/webhooks/incoming.rs @@ -46,7 +46,7 @@ use crate::{ storage::{self, enums}, transformers::{ForeignFrom, ForeignInto, ForeignTryFrom}, }, - utils::{self as helper_utils, generate_id, OptionExt}, + utils::{self as helper_utils, generate_id}, }; #[cfg(feature = "payouts")] use crate::{core::payouts, types::storage::PayoutAttemptUpdate}; @@ -596,12 +596,7 @@ async fn payments_incoming_webhook_flow( match payments_response { services::ApplicationResponse::JsonWithHeaders((payments_response, _)) => { - let payment_id = payments_response - .payment_id - .clone() - .get_required_value("payment_id") - .change_context(errors::ApiErrorResponse::WebhookProcessingFailure) - .attach_printable("payment id not received from payments core")?; + let payment_id = payments_response.payment_id.clone(); let status = payments_response.status; @@ -1087,12 +1082,8 @@ async fn external_authentication_incoming_webhook_flow( .await?; match payments_response { services::ApplicationResponse::JsonWithHeaders((payments_response, _)) => { - let payment_id = payments_response - .payment_id - .clone() - .get_required_value("payment_id") - .change_context(errors::ApiErrorResponse::WebhookProcessingFailure) - .attach_printable("payment id not received from payments core")?; + let payment_id = payments_response.payment_id.clone(); + let status = payments_response.status; let event_type: Option = payments_response.status.foreign_into(); @@ -1316,12 +1307,7 @@ async fn frm_incoming_webhook_flow( }; match payment_response { services::ApplicationResponse::JsonWithHeaders((payments_response, _)) => { - let payment_id = payments_response - .payment_id - .clone() - .get_required_value("payment_id") - .change_context(errors::ApiErrorResponse::WebhookProcessingFailure) - .attach_printable("payment id not received from payments core")?; + let payment_id = payments_response.payment_id.clone(); let status = payments_response.status; let event_type: Option = payments_response.status.foreign_into(); if let Some(outgoing_event_type) = event_type { @@ -1480,12 +1466,7 @@ async fn bank_transfer_webhook_flow( match response? { services::ApplicationResponse::JsonWithHeaders((payments_response, _)) => { - let payment_id = payments_response - .payment_id - .clone() - .get_required_value("payment_id") - .change_context(errors::ApiErrorResponse::WebhookProcessingFailure) - .attach_printable("did not receive payment id from payments core response")?; + let payment_id = payments_response.payment_id.clone(); let event_type: Option = payments_response.status.foreign_into(); let status = payments_response.status; diff --git a/crates/router/src/core/webhooks/outgoing.rs b/crates/router/src/core/webhooks/outgoing.rs index 36eadab612..b075b15e7f 100644 --- a/crates/router/src/core/webhooks/outgoing.rs +++ b/crates/router/src/core/webhooks/outgoing.rs @@ -96,7 +96,7 @@ pub(crate) async fn create_event_and_trigger_outgoing_webhook( .change_context(errors::ApiErrorResponse::WebhookProcessingFailure) .attach_printable("Failed to construct outgoing webhook request content")?; - let event_metadata = storage::EventMetadata::foreign_from((&content, &primary_object_id)); + let event_metadata = storage::EventMetadata::foreign_from(&content); let key_manager_state = &(&state).into(); let new_event = domain::Event { event_id: event_id.clone(), @@ -905,14 +905,11 @@ async fn error_response_handler( Err(error) } -impl ForeignFrom<(&api::OutgoingWebhookContent, &str)> for storage::EventMetadata { - fn foreign_from((content, primary_object_id): (&api::OutgoingWebhookContent, &str)) -> Self { +impl ForeignFrom<&api::OutgoingWebhookContent> for storage::EventMetadata { + fn foreign_from(content: &api::OutgoingWebhookContent) -> Self { match content { webhooks::OutgoingWebhookContent::PaymentDetails(payments_response) => Self::Payment { - payment_id: payments_response - .payment_id - .clone() - .unwrap_or_else(|| primary_object_id.to_owned()), + payment_id: payments_response.payment_id.clone(), }, webhooks::OutgoingWebhookContent::RefundDetails(refund_response) => Self::Refund { payment_id: refund_response.payment_id.clone(), @@ -941,7 +938,7 @@ fn get_outgoing_webhook_event_content_from_event_metadata( event_metadata.map(|metadata| match metadata { diesel_models::EventMetadata::Payment { payment_id } => { OutgoingWebhookEventContent::Payment { - payment_id: Some(payment_id), + payment_id, content: serde_json::Value::Null, } } diff --git a/crates/router/src/events/outgoing_webhook_logs.rs b/crates/router/src/events/outgoing_webhook_logs.rs index 2a56f60eca..0f7ca4a234 100644 --- a/crates/router/src/events/outgoing_webhook_logs.rs +++ b/crates/router/src/events/outgoing_webhook_logs.rs @@ -27,7 +27,7 @@ pub struct OutgoingWebhookEvent { #[serde(tag = "outgoing_webhook_event_type", rename_all = "snake_case")] pub enum OutgoingWebhookEventContent { Payment { - payment_id: Option, + payment_id: String, content: Value, }, Payout { diff --git a/crates/router/tests/payments.rs b/crates/router/tests/payments.rs index 8508e3d5cd..66f99dd085 100644 --- a/crates/router/tests/payments.rs +++ b/crates/router/tests/payments.rs @@ -317,7 +317,7 @@ async fn payments_create_core() { payment_id: Some(api::PaymentIdType::PaymentIntentId( "pay_mbabizu24mvu3mela5njyhpit10".to_string(), )), - merchant_id: Some(merchant_id), + merchant_id: Some(merchant_id.clone()), amount: Some(MinorUnit::new(6540).into()), currency: Some(api_enums::Currency::USD), capture_method: Some(api_enums::CaptureMethod::Automatic), @@ -364,10 +364,10 @@ async fn payments_create_core() { }; let expected_response = api::PaymentsResponse { - payment_id: Some("pay_mbabizu24mvu3mela5njyhpit10".to_string()), + payment_id: "pay_mbabizu24mvu3mela5njyhpit10".to_string(), status: api_enums::IntentStatus::Succeeded, amount: MinorUnit::new(6540), - amount_capturable: None, + amount_capturable: MinorUnit::new(0), amount_received: None, client_secret: None, created: None, @@ -376,7 +376,72 @@ async fn payments_create_core() { description: Some("Its my first payment request".to_string()), refunds: None, mandate_id: None, - ..Default::default() + merchant_id, + net_amount: MinorUnit::new(6540), + connector: None, + customer: None, + disputes: None, + attempts: None, + captures: None, + mandate_data: None, + setup_future_usage: None, + off_session: None, + capture_on: None, + capture_method: None, + payment_method: None, + payment_method_data: None, + payment_token: None, + shipping: None, + billing: None, + order_details: None, + email: None, + name: None, + phone: None, + return_url: None, + authentication_type: None, + statement_descriptor_name: None, + statement_descriptor_suffix: None, + next_action: None, + cancellation_reason: None, + error_code: None, + error_message: None, + unified_code: None, + unified_message: None, + payment_experience: None, + payment_method_type: None, + connector_label: None, + business_country: None, + business_label: None, + business_sub_label: None, + allowed_payment_method_types: None, + ephemeral_key: None, + manual_retry_allowed: None, + connector_transaction_id: None, + frm_message: None, + metadata: None, + connector_metadata: None, + feature_metadata: None, + reference_id: None, + payment_link: None, + profile_id: None, + surcharge_details: None, + attempt_count: 1, + merchant_decision: None, + merchant_connector_id: None, + incremental_authorization_allowed: None, + authorization_count: None, + incremental_authorizations: None, + external_authentication_details: None, + external_3ds_authentication_attempted: None, + expires_on: None, + fingerprint: None, + browser_info: None, + payment_method_id: None, + payment_method_status: None, + updated: None, + charges: None, + frm_metadata: None, + merchant_order_reference_id: None, }; let expected_response = services::ApplicationResponse::JsonWithHeaders((expected_response, vec![])); @@ -551,10 +616,10 @@ async fn payments_create_core_adyen_no_redirect() { let expected_response = services::ApplicationResponse::JsonWithHeaders(( api::PaymentsResponse { - payment_id: Some(payment_id.clone()), + payment_id: payment_id.clone(), status: api_enums::IntentStatus::Processing, amount: MinorUnit::new(6540), - amount_capturable: None, + amount_capturable: MinorUnit::new(0), amount_received: None, client_secret: None, created: None, @@ -563,7 +628,72 @@ async fn payments_create_core_adyen_no_redirect() { description: Some("Its my first payment request".to_string()), refunds: None, mandate_id: None, - ..Default::default() + merchant_id, + net_amount: MinorUnit::new(6540), + connector: None, + customer: None, + disputes: None, + attempts: None, + captures: None, + mandate_data: None, + setup_future_usage: None, + off_session: None, + capture_on: None, + capture_method: None, + payment_method: None, + payment_method_data: None, + payment_token: None, + shipping: None, + billing: None, + order_details: None, + email: None, + name: None, + phone: None, + return_url: None, + authentication_type: None, + statement_descriptor_name: None, + statement_descriptor_suffix: None, + next_action: None, + cancellation_reason: None, + error_code: None, + error_message: None, + unified_code: None, + unified_message: None, + payment_experience: None, + payment_method_type: None, + connector_label: None, + business_country: None, + business_label: None, + business_sub_label: None, + allowed_payment_method_types: None, + ephemeral_key: None, + manual_retry_allowed: None, + connector_transaction_id: None, + frm_message: None, + metadata: None, + connector_metadata: None, + feature_metadata: None, + reference_id: None, + payment_link: None, + profile_id: None, + surcharge_details: None, + attempt_count: 1, + merchant_decision: None, + merchant_connector_id: None, + incremental_authorization_allowed: None, + authorization_count: None, + incremental_authorizations: None, + external_authentication_details: None, + external_3ds_authentication_attempted: None, + expires_on: None, + fingerprint: None, + browser_info: None, + payment_method_id: None, + payment_method_status: None, + updated: None, + charges: None, + frm_metadata: None, + merchant_order_reference_id: None, }, vec![], )); diff --git a/crates/router/tests/payments2.rs b/crates/router/tests/payments2.rs index f9a6e4a523..7899abf72a 100644 --- a/crates/router/tests/payments2.rs +++ b/crates/router/tests/payments2.rs @@ -77,7 +77,7 @@ async fn payments_create_core() { payment_id: Some(api::PaymentIdType::PaymentIntentId( "pay_mbabizu24mvu3mela5njyhpit10".to_string(), )), - merchant_id: Some(merchant_id), + merchant_id: Some(merchant_id.clone()), amount: Some(MinorUnit::new(6540).into()), currency: Some(api_enums::Currency::USD), capture_method: Some(api_enums::CaptureMethod::Automatic), @@ -124,10 +124,10 @@ async fn payments_create_core() { }; let expected_response = api::PaymentsResponse { - payment_id: Some("pay_mbabizu24mvu3mela5njyhpit10".to_string()), + payment_id: "pay_mbabizu24mvu3mela5njyhpit10".to_string(), status: api_enums::IntentStatus::Succeeded, amount: MinorUnit::new(6540), - amount_capturable: None, + amount_capturable: MinorUnit::new(0), amount_received: None, client_secret: None, created: None, @@ -136,7 +136,72 @@ async fn payments_create_core() { description: Some("Its my first payment request".to_string()), refunds: None, mandate_id: None, - ..Default::default() + merchant_id, + net_amount: MinorUnit::new(6540), + connector: None, + customer: None, + disputes: None, + attempts: None, + captures: None, + mandate_data: None, + setup_future_usage: None, + off_session: None, + capture_on: None, + capture_method: None, + payment_method: None, + payment_method_data: None, + payment_token: None, + shipping: None, + billing: None, + order_details: None, + email: None, + name: None, + phone: None, + return_url: None, + authentication_type: None, + statement_descriptor_name: None, + statement_descriptor_suffix: None, + next_action: None, + cancellation_reason: None, + error_code: None, + error_message: None, + unified_code: None, + unified_message: None, + payment_experience: None, + payment_method_type: None, + connector_label: None, + business_country: None, + business_label: None, + business_sub_label: None, + allowed_payment_method_types: None, + ephemeral_key: None, + manual_retry_allowed: None, + connector_transaction_id: None, + frm_message: None, + metadata: None, + connector_metadata: None, + feature_metadata: None, + reference_id: None, + payment_link: None, + profile_id: None, + surcharge_details: None, + attempt_count: 1, + merchant_decision: None, + merchant_connector_id: None, + incremental_authorization_allowed: None, + authorization_count: None, + incremental_authorizations: None, + external_authentication_details: None, + external_3ds_authentication_attempted: None, + expires_on: None, + fingerprint: None, + browser_info: None, + payment_method_id: None, + payment_method_status: None, + updated: None, + charges: None, + frm_metadata: None, + merchant_order_reference_id: None, }; let expected_response = services::ApplicationResponse::JsonWithHeaders((expected_response, vec![])); @@ -319,10 +384,10 @@ async fn payments_create_core_adyen_no_redirect() { let expected_response = services::ApplicationResponse::JsonWithHeaders(( api::PaymentsResponse { - payment_id: Some(payment_id.clone()), + payment_id: payment_id.clone(), status: api_enums::IntentStatus::Processing, amount: MinorUnit::new(6540), - amount_capturable: None, + amount_capturable: MinorUnit::new(0), amount_received: None, client_secret: None, created: None, @@ -331,7 +396,72 @@ async fn payments_create_core_adyen_no_redirect() { description: Some("Its my first payment request".to_string()), refunds: None, mandate_id: None, - ..Default::default() + merchant_id, + net_amount: MinorUnit::new(6540), + connector: None, + customer: None, + disputes: None, + attempts: None, + captures: None, + mandate_data: None, + setup_future_usage: None, + off_session: None, + capture_on: None, + capture_method: None, + payment_method: None, + payment_method_data: None, + payment_token: None, + shipping: None, + billing: None, + order_details: None, + email: None, + name: None, + phone: None, + return_url: None, + authentication_type: None, + statement_descriptor_name: None, + statement_descriptor_suffix: None, + next_action: None, + cancellation_reason: None, + error_code: None, + error_message: None, + unified_code: None, + unified_message: None, + payment_experience: None, + payment_method_type: None, + connector_label: None, + business_country: None, + business_label: None, + business_sub_label: None, + allowed_payment_method_types: None, + ephemeral_key: None, + manual_retry_allowed: None, + connector_transaction_id: None, + frm_message: None, + metadata: None, + connector_metadata: None, + feature_metadata: None, + reference_id: None, + payment_link: None, + profile_id: None, + surcharge_details: None, + attempt_count: 1, + merchant_decision: None, + merchant_connector_id: None, + incremental_authorization_allowed: None, + authorization_count: None, + incremental_authorizations: None, + external_authentication_details: None, + external_3ds_authentication_attempted: None, + expires_on: None, + fingerprint: None, + browser_info: None, + payment_method_id: None, + payment_method_status: None, + updated: None, + charges: None, + frm_metadata: None, + merchant_order_reference_id: None, }, vec![], ));