mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-10-31 18:17:13 +08:00 
			
		
		
		
	refactor(connector): [BraintreeGraphQl] Enhance currency Mapping with ConnectorCurrencyCommon Trait (#2143)
This commit is contained in:
		| @ -70,6 +70,13 @@ impl ConnectorCommon for {{project-name | downcase | pascal_case}} { | |||||||
|         "{{project-name | downcase}}" |         "{{project-name | downcase}}" | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     fn get_currency_unit(&self) -> api::CurrencyUnit { | ||||||
|  |         todo!() | ||||||
|  |     //    TODO! Check connector documentation, on which unit they are processing the currency.  | ||||||
|  |     //    If the connector accepts amount in lower unit ( i.e cents for USD) then return api::CurrencyUnit::Minor,  | ||||||
|  |     //    if connector accepts amount in base unit (i.e dollars for USD) then return api::CurrencyUnit::Base | ||||||
|  |     } | ||||||
|  |  | ||||||
|     fn common_get_content_type(&self) -> &'static str { |     fn common_get_content_type(&self) -> &'static str { | ||||||
|         "application/json" |         "application/json" | ||||||
|     } |     } | ||||||
| @ -150,7 +157,14 @@ impl | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     fn get_request_body(&self, req: &types::PaymentsAuthorizeRouterData) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> { |     fn get_request_body(&self, req: &types::PaymentsAuthorizeRouterData) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> { | ||||||
|         let req_obj = {{project-name | downcase}}::{{project-name | downcase | pascal_case}}PaymentsRequest::try_from(req)?; |         let connector_router_data = | ||||||
|  |             {{project-name | downcase}}::{{project-name | downcase | pascal_case}}RouterData::try_from(( | ||||||
|  |                 &self.get_currency_unit(), | ||||||
|  |                 req.request.currency, | ||||||
|  |                 req.request.amount, | ||||||
|  |                 req, | ||||||
|  |             ))?; | ||||||
|  |         let req_obj = {{project-name | downcase}}::{{project-name | downcase | pascal_case}}PaymentsRequest::try_from(&connector_router_data)?; | ||||||
|         let {{project-name | downcase}}_req = types::RequestBody::log_and_get_request_body(&req_obj, utils::Encode::<{{project-name | downcase}}::{{project-name | downcase | pascal_case}}PaymentsRequest>::encode_to_string_of_json) |         let {{project-name | downcase}}_req = types::RequestBody::log_and_get_request_body(&req_obj, utils::Encode::<{{project-name | downcase}}::{{project-name | downcase | pascal_case}}PaymentsRequest>::encode_to_string_of_json) | ||||||
|             .change_context(errors::ConnectorError::RequestEncodingFailed)?; |             .change_context(errors::ConnectorError::RequestEncodingFailed)?; | ||||||
|         Ok(Some({{project-name | downcase}}_req)) |         Ok(Some({{project-name | downcase}}_req)) | ||||||
| @ -361,7 +375,14 @@ impl | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     fn get_request_body(&self, req: &types::RefundsRouterData<api::Execute>) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> { |     fn get_request_body(&self, req: &types::RefundsRouterData<api::Execute>) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> { | ||||||
|         let req_obj = {{project-name | downcase}}::{{project-name | downcase | pascal_case}}RefundRequest::try_from(req)?; |         let connector_router_data = | ||||||
|  |             {{project-name | downcase}}::{{project-name | downcase | pascal_case}}RouterData::try_from(( | ||||||
|  |                 &self.get_currency_unit(), | ||||||
|  |                 req.request.currency, | ||||||
|  |                 req.request.refund_amount, | ||||||
|  |                 req, | ||||||
|  |             ))?; | ||||||
|  |         let req_obj = {{project-name | downcase}}::{{project-name | downcase | pascal_case}}RefundRequest::try_from(&connector_router_data)?; | ||||||
|         let {{project-name | downcase}}_req = types::RequestBody::log_and_get_request_body(&req_obj, utils::Encode::<{{project-name | downcase}}::{{project-name | downcase | pascal_case}}RefundRequest>::encode_to_string_of_json) |         let {{project-name | downcase}}_req = types::RequestBody::log_and_get_request_body(&req_obj, utils::Encode::<{{project-name | downcase}}::{{project-name | downcase | pascal_case}}RefundRequest>::encode_to_string_of_json) | ||||||
|             .change_context(errors::ConnectorError::RequestEncodingFailed)?; |             .change_context(errors::ConnectorError::RequestEncodingFailed)?; | ||||||
|         Ok(Some({{project-name | downcase}}_req)) |         Ok(Some({{project-name | downcase}}_req)) | ||||||
|  | |||||||
| @ -1,6 +1,37 @@ | |||||||
| use serde::{Deserialize, Serialize}; | use serde::{Deserialize, Serialize}; | ||||||
| use masking::Secret; | use masking::Secret; | ||||||
| use crate::{connector::utils::PaymentsAuthorizeRequestData,core::errors,types::{self,api, storage::enums}}; | use crate::{connector::utils::{PaymentsAuthorizeRequestData},core::errors,types::{self,api, storage::enums}}; | ||||||
|  |  | ||||||
|  | //TODO: Fill the struct with respective fields | ||||||
|  | pub struct {{project-name | downcase | pascal_case}}RouterData<T> { | ||||||
|  |     pub amount: i64, // The type of amount that a connector accepts, for example, String, i64, f64, etc. | ||||||
|  |     pub router_data: T, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl<T> | ||||||
|  |     TryFrom<( | ||||||
|  |         &types::api::CurrencyUnit, | ||||||
|  |         types::storage::enums::Currency, | ||||||
|  |         i64, | ||||||
|  |         T, | ||||||
|  |     )> for {{project-name | downcase | pascal_case}}RouterData<T> | ||||||
|  | { | ||||||
|  |     type Error = error_stack::Report<errors::ConnectorError>; | ||||||
|  |     fn try_from( | ||||||
|  |         (_currency_unit, _currency, amount, item): ( | ||||||
|  |             &types::api::CurrencyUnit, | ||||||
|  |             types::storage::enums::Currency, | ||||||
|  |             i64, | ||||||
|  |             T, | ||||||
|  |         ), | ||||||
|  |     ) -> Result<Self, Self::Error> { | ||||||
|  |          //Todo :  use utils to convert the amount to the type of amount that a connector accepts | ||||||
|  |         Ok(Self { | ||||||
|  |             amount, | ||||||
|  |             router_data: item, | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| //TODO: Fill the struct with respective fields | //TODO: Fill the struct with respective fields | ||||||
| #[derive(Default, Debug, Serialize, Eq, PartialEq)] | #[derive(Default, Debug, Serialize, Eq, PartialEq)] | ||||||
| @ -19,10 +50,10 @@ pub struct {{project-name | downcase | pascal_case}}Card { | |||||||
|     complete: bool, |     complete: bool, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl TryFrom<&types::PaymentsAuthorizeRouterData> for {{project-name | downcase | pascal_case}}PaymentsRequest  { | impl TryFrom<&{{project-name | downcase | pascal_case}}RouterData<&types::PaymentsAuthorizeRouterData>> for {{project-name | downcase | pascal_case}}PaymentsRequest  { | ||||||
|     type Error = error_stack::Report<errors::ConnectorError>; |     type Error = error_stack::Report<errors::ConnectorError>; | ||||||
|     fn try_from(item: &types::PaymentsAuthorizeRouterData) -> Result<Self,Self::Error> { |     fn try_from(item: &{{project-name | downcase | pascal_case}}RouterData<&types::PaymentsAuthorizeRouterData>) -> Result<Self,Self::Error> { | ||||||
|         match item.request.payment_method_data.clone() { |         match item.router_data.request.payment_method_data.clone() { | ||||||
|             api::PaymentMethodData::Card(req_card) => { |             api::PaymentMethodData::Card(req_card) => { | ||||||
|                 let card = {{project-name | downcase | pascal_case}}Card { |                 let card = {{project-name | downcase | pascal_case}}Card { | ||||||
|                     name: req_card.card_holder_name, |                     name: req_card.card_holder_name, | ||||||
| @ -30,10 +61,10 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for {{project-name | downcase | |||||||
|                     expiry_month: req_card.card_exp_month, |                     expiry_month: req_card.card_exp_month, | ||||||
|                     expiry_year: req_card.card_exp_year, |                     expiry_year: req_card.card_exp_year, | ||||||
|                     cvc: req_card.card_cvc, |                     cvc: req_card.card_cvc, | ||||||
|                     complete: item.request.is_auto_capture()?, |                     complete: item.router_data.request.is_auto_capture()?, | ||||||
|                 }; |                 }; | ||||||
|                 Ok(Self { |                 Ok(Self { | ||||||
|                     amount: item.request.amount, |                     amount: item.amount.to_owned(), | ||||||
|                     card, |                     card, | ||||||
|                 }) |                 }) | ||||||
|             } |             } | ||||||
| @ -113,11 +144,11 @@ pub struct {{project-name | downcase | pascal_case}}RefundRequest { | |||||||
|     pub amount: i64 |     pub amount: i64 | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<F> TryFrom<&types::RefundsRouterData<F>> for {{project-name | downcase | pascal_case}}RefundRequest { | impl<F> TryFrom<&{{project-name | downcase | pascal_case}}RouterData<&types::RefundsRouterData<F>>> for {{project-name | downcase | pascal_case}}RefundRequest { | ||||||
|     type Error = error_stack::Report<errors::ConnectorError>; |     type Error = error_stack::Report<errors::ConnectorError>; | ||||||
|     fn try_from(item: &types::RefundsRouterData<F>) -> Result<Self,Self::Error> { |     fn try_from(item: &{{project-name | downcase | pascal_case}}RouterData<&types::RefundsRouterData<F>>) -> Result<Self,Self::Error> { | ||||||
|         Ok(Self { |         Ok(Self { | ||||||
|             amount: item.request.refund_amount, |             amount: item.amount.to_owned(), | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -74,6 +74,10 @@ impl ConnectorCommon for Braintree { | |||||||
|         "braintree" |         "braintree" | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     fn get_currency_unit(&self) -> api::CurrencyUnit { | ||||||
|  |         api::CurrencyUnit::Base | ||||||
|  |     } | ||||||
|  |  | ||||||
|     fn base_url<'a>(&self, connectors: &'a settings::Connectors) -> &'a str { |     fn base_url<'a>(&self, connectors: &'a settings::Connectors) -> &'a str { | ||||||
|         connectors.braintree.base_url.as_ref() |         connectors.braintree.base_url.as_ref() | ||||||
|     } |     } | ||||||
| @ -425,10 +429,19 @@ impl ConnectorIntegration<api::Capture, types::PaymentsCaptureData, types::Payme | |||||||
|         req: &types::PaymentsCaptureRouterData, |         req: &types::PaymentsCaptureRouterData, | ||||||
|     ) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> { |     ) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> { | ||||||
|         let connector_api_version = &req.connector_api_version.clone(); |         let connector_api_version = &req.connector_api_version.clone(); | ||||||
|  |         let connector_router_data = | ||||||
|  |             braintree_graphql_transformers::BraintreeRouterData::try_from(( | ||||||
|  |                 &self.get_currency_unit(), | ||||||
|  |                 req.request.currency, | ||||||
|  |                 req.request.amount_to_capture, | ||||||
|  |                 req, | ||||||
|  |             ))?; | ||||||
|         match self.is_braintree_graphql_version(connector_api_version) { |         match self.is_braintree_graphql_version(connector_api_version) { | ||||||
|             true => { |             true => { | ||||||
|                 let connector_request = |                 let connector_request = | ||||||
|                     braintree_graphql_transformers::BraintreeCaptureRequest::try_from(req)?; |                     braintree_graphql_transformers::BraintreeCaptureRequest::try_from( | ||||||
|  |                         &connector_router_data, | ||||||
|  |                     )?; | ||||||
|  |  | ||||||
|                 let braintree_req = types::RequestBody::log_and_get_request_body( |                 let braintree_req = types::RequestBody::log_and_get_request_body( | ||||||
|             &connector_request, |             &connector_request, | ||||||
| @ -736,10 +749,19 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P | |||||||
|         req: &types::PaymentsAuthorizeRouterData, |         req: &types::PaymentsAuthorizeRouterData, | ||||||
|     ) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> { |     ) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> { | ||||||
|         let connector_api_version = &req.connector_api_version; |         let connector_api_version = &req.connector_api_version; | ||||||
|  |         let connector_router_data = | ||||||
|  |             braintree_graphql_transformers::BraintreeRouterData::try_from(( | ||||||
|  |                 &self.get_currency_unit(), | ||||||
|  |                 req.request.currency, | ||||||
|  |                 req.request.amount, | ||||||
|  |                 req, | ||||||
|  |             ))?; | ||||||
|         match self.is_braintree_graphql_version(connector_api_version) { |         match self.is_braintree_graphql_version(connector_api_version) { | ||||||
|             true => { |             true => { | ||||||
|                 let connector_request = |                 let connector_request = | ||||||
|                     braintree_graphql_transformers::BraintreePaymentsRequest::try_from(req)?; |                     braintree_graphql_transformers::BraintreePaymentsRequest::try_from( | ||||||
|  |                         &connector_router_data, | ||||||
|  |                     )?; | ||||||
|                 let braintree_payment_request = types::RequestBody::log_and_get_request_body( |                 let braintree_payment_request = types::RequestBody::log_and_get_request_body( | ||||||
|                     &connector_request, |                     &connector_request, | ||||||
|                     utils::Encode::<braintree_graphql_transformers::BraintreePaymentsRequest>::encode_to_string_of_json, |                     utils::Encode::<braintree_graphql_transformers::BraintreePaymentsRequest>::encode_to_string_of_json, | ||||||
| @ -1026,10 +1048,19 @@ impl ConnectorIntegration<api::Execute, types::RefundsData, types::RefundsRespon | |||||||
|         req: &types::RefundsRouterData<api::Execute>, |         req: &types::RefundsRouterData<api::Execute>, | ||||||
|     ) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> { |     ) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> { | ||||||
|         let connector_api_version = &req.connector_api_version; |         let connector_api_version = &req.connector_api_version; | ||||||
|  |         let connector_router_data = | ||||||
|  |             braintree_graphql_transformers::BraintreeRouterData::try_from(( | ||||||
|  |                 &self.get_currency_unit(), | ||||||
|  |                 req.request.currency, | ||||||
|  |                 req.request.refund_amount, | ||||||
|  |                 req, | ||||||
|  |             ))?; | ||||||
|         match self.is_braintree_graphql_version(connector_api_version) { |         match self.is_braintree_graphql_version(connector_api_version) { | ||||||
|             true => { |             true => { | ||||||
|                 let connector_request = |                 let connector_request = | ||||||
|                     braintree_graphql_transformers::BraintreeRefundRequest::try_from(req)?; |                     braintree_graphql_transformers::BraintreeRefundRequest::try_from( | ||||||
|  |                         connector_router_data, | ||||||
|  |                     )?; | ||||||
|                 let braintree_refund_request = types::RequestBody::log_and_get_request_body( |                 let braintree_refund_request = types::RequestBody::log_and_get_request_body( | ||||||
|             &connector_request, |             &connector_request, | ||||||
|             utils::Encode::<braintree_graphql_transformers::BraintreeRefundRequest>::encode_to_string_of_json, |             utils::Encode::<braintree_graphql_transformers::BraintreeRefundRequest>::encode_to_string_of_json, | ||||||
| @ -1310,11 +1341,20 @@ impl | |||||||
|         &self, |         &self, | ||||||
|         req: &types::PaymentsCompleteAuthorizeRouterData, |         req: &types::PaymentsCompleteAuthorizeRouterData, | ||||||
|     ) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> { |     ) -> CustomResult<Option<types::RequestBody>, errors::ConnectorError> { | ||||||
|  |         let connector_router_data = | ||||||
|  |             braintree_graphql_transformers::BraintreeRouterData::try_from(( | ||||||
|  |                 &self.get_currency_unit(), | ||||||
|  |                 req.request.currency, | ||||||
|  |                 req.request.amount, | ||||||
|  |                 req, | ||||||
|  |             ))?; | ||||||
|         let connector_api_version = &req.connector_api_version; |         let connector_api_version = &req.connector_api_version; | ||||||
|         match self.is_braintree_graphql_version(connector_api_version) { |         match self.is_braintree_graphql_version(connector_api_version) { | ||||||
|             true => { |             true => { | ||||||
|                 let connector_request = |                 let connector_request = | ||||||
|                     braintree_graphql_transformers::BraintreePaymentsRequest::try_from(req)?; |                     braintree_graphql_transformers::BraintreePaymentsRequest::try_from( | ||||||
|  |                         &connector_router_data, | ||||||
|  |                     )?; | ||||||
|                 let braintree_payment_request = types::RequestBody::log_and_get_request_body( |                 let braintree_payment_request = types::RequestBody::log_and_get_request_body( | ||||||
|                     &connector_request, |                     &connector_request, | ||||||
|                     utils::Encode::<braintree_graphql_transformers::BraintreePaymentsRequest>::encode_to_string_of_json, |                     utils::Encode::<braintree_graphql_transformers::BraintreePaymentsRequest>::encode_to_string_of_json, | ||||||
|  | |||||||
| @ -18,6 +18,37 @@ pub const CAPTURE_TRANSACTION_MUTATION: &str = "mutation captureTransaction($inp | |||||||
| pub const VOID_TRANSACTION_MUTATION: &str = "mutation voidTransaction($input:  ReverseTransactionInput!) { reverseTransaction(input: $input) { clientMutationId reversal { ...  on Transaction { id legacyId amount { value currencyCode } status } } } }"; | pub const VOID_TRANSACTION_MUTATION: &str = "mutation voidTransaction($input:  ReverseTransactionInput!) { reverseTransaction(input: $input) { clientMutationId reversal { ...  on Transaction { id legacyId amount { value currencyCode } status } } } }"; | ||||||
| pub const REFUND_TRANSACTION_MUTATION: &str = "mutation refundTransaction($input:  RefundTransactionInput!) { refundTransaction(input: $input) {clientMutationId refund { id legacyId amount { value currencyCode } status } } }"; | pub const REFUND_TRANSACTION_MUTATION: &str = "mutation refundTransaction($input:  RefundTransactionInput!) { refundTransaction(input: $input) {clientMutationId refund { id legacyId amount { value currencyCode } status } } }"; | ||||||
|  |  | ||||||
|  | #[derive(Debug, Serialize)] | ||||||
|  | pub struct BraintreeRouterData<T> { | ||||||
|  |     pub amount: String, | ||||||
|  |     pub router_data: T, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl<T> | ||||||
|  |     TryFrom<( | ||||||
|  |         &types::api::CurrencyUnit, | ||||||
|  |         types::storage::enums::Currency, | ||||||
|  |         i64, | ||||||
|  |         T, | ||||||
|  |     )> for BraintreeRouterData<T> | ||||||
|  | { | ||||||
|  |     type Error = error_stack::Report<errors::ConnectorError>; | ||||||
|  |     fn try_from( | ||||||
|  |         (currency_unit, currency, amount, item): ( | ||||||
|  |             &types::api::CurrencyUnit, | ||||||
|  |             types::storage::enums::Currency, | ||||||
|  |             i64, | ||||||
|  |             T, | ||||||
|  |         ), | ||||||
|  |     ) -> Result<Self, Self::Error> { | ||||||
|  |         let amount = utils::get_amount_as_string(currency_unit, amount, currency)?; | ||||||
|  |         Ok(Self { | ||||||
|  |             amount, | ||||||
|  |             router_data: item, | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| #[derive(Debug, Serialize)] | #[derive(Debug, Serialize)] | ||||||
| #[serde(rename_all = "camelCase")] | #[serde(rename_all = "camelCase")] | ||||||
| pub struct PaymentInput { | pub struct PaymentInput { | ||||||
| @ -56,16 +87,23 @@ pub struct TransactionBody { | |||||||
|     merchant_account_id: Secret<String>, |     merchant_account_id: Secret<String>, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl TryFrom<&types::PaymentsAuthorizeRouterData> for BraintreePaymentsRequest { | impl TryFrom<&BraintreeRouterData<&types::PaymentsAuthorizeRouterData>> | ||||||
|  |     for BraintreePaymentsRequest | ||||||
|  | { | ||||||
|     type Error = error_stack::Report<errors::ConnectorError>; |     type Error = error_stack::Report<errors::ConnectorError>; | ||||||
|     fn try_from(item: &types::PaymentsAuthorizeRouterData) -> Result<Self, Self::Error> { |     fn try_from( | ||||||
|  |         item: &BraintreeRouterData<&types::PaymentsAuthorizeRouterData>, | ||||||
|  |     ) -> Result<Self, Self::Error> { | ||||||
|         let metadata: BraintreeMeta = |         let metadata: BraintreeMeta = | ||||||
|             utils::to_connector_meta_from_secret(item.connector_meta_data.clone())?; |             utils::to_connector_meta_from_secret(item.router_data.connector_meta_data.clone())?; | ||||||
|         utils::validate_currency(item.request.currency, metadata.merchant_config_currency)?; |         utils::validate_currency( | ||||||
|  |             item.router_data.request.currency, | ||||||
|  |             metadata.merchant_config_currency, | ||||||
|  |         )?; | ||||||
|  |  | ||||||
|         match item.request.payment_method_data.clone() { |         match item.router_data.request.payment_method_data.clone() { | ||||||
|             api::PaymentMethodData::Card(_) => { |             api::PaymentMethodData::Card(_) => { | ||||||
|                 if item.is_three_ds() { |                 if item.router_data.is_three_ds() { | ||||||
|                     Ok(Self::CardThreeDs(BraintreeClientTokenRequest::try_from( |                     Ok(Self::CardThreeDs(BraintreeClientTokenRequest::try_from( | ||||||
|                         metadata, |                         metadata, | ||||||
|                     )?)) |                     )?)) | ||||||
| @ -94,10 +132,14 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for BraintreePaymentsRequest { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| impl TryFrom<&types::PaymentsCompleteAuthorizeRouterData> for BraintreePaymentsRequest { | impl TryFrom<&BraintreeRouterData<&types::PaymentsCompleteAuthorizeRouterData>> | ||||||
|  |     for BraintreePaymentsRequest | ||||||
|  | { | ||||||
|     type Error = error_stack::Report<errors::ConnectorError>; |     type Error = error_stack::Report<errors::ConnectorError>; | ||||||
|     fn try_from(item: &types::PaymentsCompleteAuthorizeRouterData) -> Result<Self, Self::Error> { |     fn try_from( | ||||||
|         match item.request.payment_method_data.clone() { |         item: &BraintreeRouterData<&types::PaymentsCompleteAuthorizeRouterData>, | ||||||
|  |     ) -> Result<Self, Self::Error> { | ||||||
|  |         match item.router_data.request.payment_method_data.clone() { | ||||||
|             Some(api::PaymentMethodData::Card(_)) => { |             Some(api::PaymentMethodData::Card(_)) => { | ||||||
|                 Ok(Self::Card(CardPaymentRequest::try_from(item)?)) |                 Ok(Self::Card(CardPaymentRequest::try_from(item)?)) | ||||||
|             } |             } | ||||||
| @ -537,22 +579,24 @@ pub struct BraintreeRefundRequest { | |||||||
|     variables: BraintreeRefundVariables, |     variables: BraintreeRefundVariables, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<F> TryFrom<&types::RefundsRouterData<F>> for BraintreeRefundRequest { | impl<F> TryFrom<BraintreeRouterData<&types::RefundsRouterData<F>>> for BraintreeRefundRequest { | ||||||
|     type Error = error_stack::Report<errors::ConnectorError>; |     type Error = error_stack::Report<errors::ConnectorError>; | ||||||
|     fn try_from(item: &types::RefundsRouterData<F>) -> Result<Self, Self::Error> { |     fn try_from( | ||||||
|  |         item: BraintreeRouterData<&types::RefundsRouterData<F>>, | ||||||
|  |     ) -> Result<Self, Self::Error> { | ||||||
|         let metadata: BraintreeMeta = |         let metadata: BraintreeMeta = | ||||||
|             utils::to_connector_meta_from_secret(item.connector_meta_data.clone())?; |             utils::to_connector_meta_from_secret(item.router_data.connector_meta_data.clone())?; | ||||||
|  |  | ||||||
|         utils::validate_currency(item.request.currency, metadata.merchant_config_currency)?; |         utils::validate_currency( | ||||||
|  |             item.router_data.request.currency, | ||||||
|  |             metadata.merchant_config_currency, | ||||||
|  |         )?; | ||||||
|         let query = REFUND_TRANSACTION_MUTATION.to_string(); |         let query = REFUND_TRANSACTION_MUTATION.to_string(); | ||||||
|         let variables = BraintreeRefundVariables { |         let variables = BraintreeRefundVariables { | ||||||
|             input: BraintreeRefundInput { |             input: BraintreeRefundInput { | ||||||
|                 transaction_id: item.request.connector_transaction_id.clone(), |                 transaction_id: item.router_data.request.connector_transaction_id.clone(), | ||||||
|                 refund: RefundInputData { |                 refund: RefundInputData { | ||||||
|                     amount: utils::to_currency_base_unit( |                     amount: item.amount, | ||||||
|                         item.request.refund_amount, |  | ||||||
|                         item.request.currency, |  | ||||||
|                     )?, |  | ||||||
|                     merchant_account_id: metadata.merchant_account_id.ok_or( |                     merchant_account_id: metadata.merchant_account_id.ok_or( | ||||||
|                         errors::ConnectorError::MissingRequiredField { |                         errors::ConnectorError::MissingRequiredField { | ||||||
|                             field_name: "merchant_account_id", |                             field_name: "merchant_account_id", | ||||||
| @ -928,18 +972,17 @@ pub struct BraintreeCaptureRequest { | |||||||
|     variables: VariableCaptureInput, |     variables: VariableCaptureInput, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl TryFrom<&types::PaymentsCaptureRouterData> for BraintreeCaptureRequest { | impl TryFrom<&BraintreeRouterData<&types::PaymentsCaptureRouterData>> for BraintreeCaptureRequest { | ||||||
|     type Error = error_stack::Report<errors::ConnectorError>; |     type Error = error_stack::Report<errors::ConnectorError>; | ||||||
|     fn try_from(item: &types::PaymentsCaptureRouterData) -> Result<Self, Self::Error> { |     fn try_from( | ||||||
|  |         item: &BraintreeRouterData<&types::PaymentsCaptureRouterData>, | ||||||
|  |     ) -> Result<Self, Self::Error> { | ||||||
|         let query = CAPTURE_TRANSACTION_MUTATION.to_string(); |         let query = CAPTURE_TRANSACTION_MUTATION.to_string(); | ||||||
|         let variables = VariableCaptureInput { |         let variables = VariableCaptureInput { | ||||||
|             input: CaptureInputData { |             input: CaptureInputData { | ||||||
|                 transaction_id: item.request.connector_transaction_id.clone(), |                 transaction_id: item.router_data.request.connector_transaction_id.clone(), | ||||||
|                 transaction: CaptureTransactionBody { |                 transaction: CaptureTransactionBody { | ||||||
|                     amount: utils::to_currency_base_unit( |                     amount: item.amount.to_owned(), | ||||||
|                         item.request.amount_to_capture, |  | ||||||
|                         item.request.currency, |  | ||||||
|                     )?, |  | ||||||
|                 }, |                 }, | ||||||
|             }, |             }, | ||||||
|         }; |         }; | ||||||
| @ -1231,14 +1274,20 @@ impl TryFrom<BraintreeMeta> for BraintreeClientTokenRequest { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| impl TryFrom<(&types::PaymentsAuthorizeRouterData, BraintreeMeta)> for CardPaymentRequest { | impl | ||||||
|  |     TryFrom<( | ||||||
|  |         &BraintreeRouterData<&types::PaymentsAuthorizeRouterData>, | ||||||
|  |         BraintreeMeta, | ||||||
|  |     )> for CardPaymentRequest | ||||||
|  | { | ||||||
|     type Error = error_stack::Report<errors::ConnectorError>; |     type Error = error_stack::Report<errors::ConnectorError>; | ||||||
|     fn try_from( |     fn try_from( | ||||||
|         payment_info: (&types::PaymentsAuthorizeRouterData, BraintreeMeta), |         (item, metadata): ( | ||||||
|  |             &BraintreeRouterData<&types::PaymentsAuthorizeRouterData>, | ||||||
|  |             BraintreeMeta, | ||||||
|  |         ), | ||||||
|     ) -> Result<Self, Self::Error> { |     ) -> Result<Self, Self::Error> { | ||||||
|         let item = payment_info.0; |         let query = match item.router_data.request.is_auto_capture()? { | ||||||
|         let metadata = payment_info.1; |  | ||||||
|         let query = match item.request.is_auto_capture()? { |  | ||||||
|             true => CHARGE_CREDIT_CARD_MUTATION.to_string(), |             true => CHARGE_CREDIT_CARD_MUTATION.to_string(), | ||||||
|             false => AUTHORIZE_CREDIT_CARD_MUTATION.to_string(), |             false => AUTHORIZE_CREDIT_CARD_MUTATION.to_string(), | ||||||
|         }; |         }; | ||||||
| @ -1246,17 +1295,14 @@ impl TryFrom<(&types::PaymentsAuthorizeRouterData, BraintreeMeta)> for CardPayme | |||||||
|             query, |             query, | ||||||
|             variables: VariablePaymentInput { |             variables: VariablePaymentInput { | ||||||
|                 input: PaymentInput { |                 input: PaymentInput { | ||||||
|                     payment_method_id: match item.get_payment_method_token()? { |                     payment_method_id: match item.router_data.get_payment_method_token()? { | ||||||
|                         types::PaymentMethodToken::Token(token) => token, |                         types::PaymentMethodToken::Token(token) => token, | ||||||
|                         types::PaymentMethodToken::ApplePayDecrypt(_) => { |                         types::PaymentMethodToken::ApplePayDecrypt(_) => { | ||||||
|                             Err(errors::ConnectorError::InvalidWalletToken)? |                             Err(errors::ConnectorError::InvalidWalletToken)? | ||||||
|                         } |                         } | ||||||
|                     }, |                     }, | ||||||
|                     transaction: TransactionBody { |                     transaction: TransactionBody { | ||||||
|                         amount: utils::to_currency_base_unit( |                         amount: item.amount.to_owned(), | ||||||
|                             item.request.amount, |  | ||||||
|                             item.request.currency, |  | ||||||
|                         )?, |  | ||||||
|                         merchant_account_id: metadata.merchant_account_id.ok_or( |                         merchant_account_id: metadata.merchant_account_id.ok_or( | ||||||
|                             errors::ConnectorError::MissingRequiredField { |                             errors::ConnectorError::MissingRequiredField { | ||||||
|                                 field_name: "merchant_account_id", |                                 field_name: "merchant_account_id", | ||||||
| @ -1269,15 +1315,22 @@ impl TryFrom<(&types::PaymentsAuthorizeRouterData, BraintreeMeta)> for CardPayme | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| impl TryFrom<&types::PaymentsCompleteAuthorizeRouterData> for CardPaymentRequest { | impl TryFrom<&BraintreeRouterData<&types::PaymentsCompleteAuthorizeRouterData>> | ||||||
|  |     for CardPaymentRequest | ||||||
|  | { | ||||||
|     type Error = error_stack::Report<errors::ConnectorError>; |     type Error = error_stack::Report<errors::ConnectorError>; | ||||||
|     fn try_from(item: &types::PaymentsCompleteAuthorizeRouterData) -> Result<Self, Self::Error> { |     fn try_from( | ||||||
|  |         item: &BraintreeRouterData<&types::PaymentsCompleteAuthorizeRouterData>, | ||||||
|  |     ) -> Result<Self, Self::Error> { | ||||||
|         let metadata: BraintreeMeta = |         let metadata: BraintreeMeta = | ||||||
|             utils::to_connector_meta_from_secret(item.connector_meta_data.clone())?; |             utils::to_connector_meta_from_secret(item.router_data.connector_meta_data.clone())?; | ||||||
|         utils::validate_currency(item.request.currency, metadata.merchant_config_currency)?; |         utils::validate_currency( | ||||||
|  |             item.router_data.request.currency, | ||||||
|  |             metadata.merchant_config_currency, | ||||||
|  |         )?; | ||||||
|         let payload_data = |         let payload_data = | ||||||
|             utils::PaymentsCompleteAuthorizeRequestData::get_redirect_response_payload( |             utils::PaymentsCompleteAuthorizeRequestData::get_redirect_response_payload( | ||||||
|                 &item.request, |                 &item.router_data.request, | ||||||
|             )? |             )? | ||||||
|             .expose(); |             .expose(); | ||||||
|         let redirection_response: BraintreeRedirectionResponse = |         let redirection_response: BraintreeRedirectionResponse = | ||||||
| @ -1293,8 +1346,9 @@ impl TryFrom<&types::PaymentsCompleteAuthorizeRouterData> for CardPaymentRequest | |||||||
|         .change_context(errors::ConnectorError::MissingConnectorRedirectionPayload { |         .change_context(errors::ConnectorError::MissingConnectorRedirectionPayload { | ||||||
|             field_name: "three_ds_data", |             field_name: "three_ds_data", | ||||||
|         })?; |         })?; | ||||||
|         let query = |         let query = match utils::PaymentsCompleteAuthorizeRequestData::is_auto_capture( | ||||||
|             match utils::PaymentsCompleteAuthorizeRequestData::is_auto_capture(&item.request)? { |             &item.router_data.request, | ||||||
|  |         )? { | ||||||
|             true => CHARGE_CREDIT_CARD_MUTATION.to_string(), |             true => CHARGE_CREDIT_CARD_MUTATION.to_string(), | ||||||
|             false => AUTHORIZE_CREDIT_CARD_MUTATION.to_string(), |             false => AUTHORIZE_CREDIT_CARD_MUTATION.to_string(), | ||||||
|         }; |         }; | ||||||
| @ -1304,10 +1358,7 @@ impl TryFrom<&types::PaymentsCompleteAuthorizeRouterData> for CardPaymentRequest | |||||||
|                 input: PaymentInput { |                 input: PaymentInput { | ||||||
|                     payment_method_id: three_ds_data.nonce, |                     payment_method_id: three_ds_data.nonce, | ||||||
|                     transaction: TransactionBody { |                     transaction: TransactionBody { | ||||||
|                         amount: utils::to_currency_base_unit( |                         amount: item.amount.to_owned(), | ||||||
|                             item.request.amount, |  | ||||||
|                             item.request.currency, |  | ||||||
|                         )?, |  | ||||||
|                         merchant_account_id: metadata.merchant_account_id.ok_or( |                         merchant_account_id: metadata.merchant_account_id.ok_or( | ||||||
|                             errors::ConnectorError::MissingRequiredField { |                             errors::ConnectorError::MissingRequiredField { | ||||||
|                                 field_name: "merchant_account_id", |                                 field_name: "merchant_account_id", | ||||||
|  | |||||||
| @ -994,6 +994,33 @@ pub fn to_currency_base_unit_from_optional_amount( | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | pub fn get_amount_as_string( | ||||||
|  |     currency_unit: &types::api::CurrencyUnit, | ||||||
|  |     amount: i64, | ||||||
|  |     currency: diesel_models::enums::Currency, | ||||||
|  | ) -> Result<String, error_stack::Report<errors::ConnectorError>> { | ||||||
|  |     let amount = match currency_unit { | ||||||
|  |         types::api::CurrencyUnit::Minor => amount.to_string(), | ||||||
|  |         types::api::CurrencyUnit::Base => to_currency_base_unit(amount, currency)?, | ||||||
|  |     }; | ||||||
|  |     Ok(amount) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pub fn get_amount_as_f64( | ||||||
|  |     currency_unit: &types::api::CurrencyUnit, | ||||||
|  |     amount: i64, | ||||||
|  |     currency: diesel_models::enums::Currency, | ||||||
|  | ) -> Result<f64, error_stack::Report<errors::ConnectorError>> { | ||||||
|  |     let amount = match currency_unit { | ||||||
|  |         types::api::CurrencyUnit::Base => to_currency_base_unit_asf64(amount, currency)?, | ||||||
|  |         types::api::CurrencyUnit::Minor => u32::try_from(amount) | ||||||
|  |             .into_report() | ||||||
|  |             .change_context(errors::ConnectorError::ParsingFailed)? | ||||||
|  |             .into(), | ||||||
|  |     }; | ||||||
|  |     Ok(amount) | ||||||
|  | } | ||||||
|  |  | ||||||
| pub fn to_currency_base_unit( | pub fn to_currency_base_unit( | ||||||
|     amount: i64, |     amount: i64, | ||||||
|     currency: diesel_models::enums::Currency, |     currency: diesel_models::enums::Currency, | ||||||
| @ -1001,7 +1028,7 @@ pub fn to_currency_base_unit( | |||||||
|     currency |     currency | ||||||
|         .to_currency_base_unit(amount) |         .to_currency_base_unit(amount) | ||||||
|         .into_report() |         .into_report() | ||||||
|         .change_context(errors::ConnectorError::RequestEncodingFailed) |         .change_context(errors::ConnectorError::ParsingFailed) | ||||||
| } | } | ||||||
|  |  | ||||||
| pub fn to_currency_lower_unit( | pub fn to_currency_lower_unit( | ||||||
| @ -1050,7 +1077,7 @@ pub fn to_currency_base_unit_asf64( | |||||||
|     currency |     currency | ||||||
|         .to_currency_base_unit_asf64(amount) |         .to_currency_base_unit_asf64(amount) | ||||||
|         .into_report() |         .into_report() | ||||||
|         .change_context(errors::ConnectorError::RequestEncodingFailed) |         .change_context(errors::ConnectorError::ParsingFailed) | ||||||
| } | } | ||||||
|  |  | ||||||
| pub fn str_to_f32<S>(value: &str, serializer: S) -> Result<S::Ok, S::Error> | pub fn str_to_f32<S>(value: &str, serializer: S) -> Result<S::Ok, S::Error> | ||||||
|  | |||||||
| @ -47,10 +47,20 @@ pub trait ConnectorTransactionId: ConnectorCommon + Sync { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | pub enum CurrencyUnit { | ||||||
|  |     Base, | ||||||
|  |     Minor, | ||||||
|  | } | ||||||
|  |  | ||||||
| pub trait ConnectorCommon { | pub trait ConnectorCommon { | ||||||
|     /// Name of the connector (in lowercase). |     /// Name of the connector (in lowercase). | ||||||
|     fn id(&self) -> &'static str; |     fn id(&self) -> &'static str; | ||||||
|  |  | ||||||
|  |     /// Connector accepted currency unit as either "Base" or "Minor" | ||||||
|  |     fn get_currency_unit(&self) -> CurrencyUnit { | ||||||
|  |         CurrencyUnit::Minor // Default implementation should be remove once it is implemented in all connectors | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /// HTTP header used for authorization. |     /// HTTP header used for authorization. | ||||||
|     fn get_auth_header( |     fn get_auth_header( | ||||||
|         &self, |         &self, | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 chikke srujan
					chikke srujan