Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(connector): implement authentication flow for netcetera #4334

Merged
merged 31 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
5300f54
Generate connector template code for netcetera
hrithikesh026 Apr 2, 2024
18a30db
feat(connector): integrate netcetera connector with pre authenticatio…
hrithikesh026 Apr 3, 2024
f508975
docs(openapi): re-generate OpenAPI specification
hyperswitch-bot[bot] Apr 3, 2024
98db511
introduce new connector authentication type
hrithikesh026 Apr 4, 2024
ddac07f
introduce CertificateAuth type to ConnectorAuthType enum
hrithikesh026 Apr 4, 2024
a1bbeb7
feat(connector): implement authentication flow for netcetera
hrithikesh026 Apr 10, 2024
93699d0
Merge branch 'main' into implement-authentication-flow-netcetera
hrithikesh026 Apr 10, 2024
a5004b0
Merge branch 'main' into integrate-netcetera
hrithikesh026 Apr 10, 2024
7caad1f
chore: run formatter
hyperswitch-bot[bot] Apr 10, 2024
200cc6a
Merge branch 'integrate-netcetera' into implement-authentication-flow…
hrithikesh026 Apr 10, 2024
2adf984
chore: run formatter
hyperswitch-bot[bot] Apr 10, 2024
979dd95
address spell check
hrithikesh026 Apr 10, 2024
e72531a
Merge branch 'integrate-netcetera' into implement-authentication-flow…
hrithikesh026 Apr 10, 2024
71fcbb5
address comments
hrithikesh026 Apr 10, 2024
1026996
address comments
hrithikesh026 Apr 10, 2024
4d4be38
docs(openapi): re-generate OpenAPI specification
hyperswitch-bot[bot] Apr 10, 2024
c0a7cd9
docs(openapi): re-generate OpenAPI specification
hyperswitch-bot[bot] Apr 10, 2024
0252d23
Merge branch 'main' into integrate-netcetera
hrithikesh026 Apr 10, 2024
39564e1
chore: update Cargo.lock
hyperswitch-bot[bot] Apr 10, 2024
ba2f475
address comments
hrithikesh026 Apr 10, 2024
dd20349
Merge branch 'integrate-netcetera' into implement-authentication-flow…
hrithikesh026 Apr 12, 2024
2796b62
arrange connector names alphabetically
hrithikesh026 Apr 12, 2024
0ced93b
update netcetera auth type in sample_auth.toml
hrithikesh026 Apr 12, 2024
35ab4e3
Merge branch 'integrate-netcetera' into implement-authentication-flow…
hrithikesh026 Apr 12, 2024
2777b5c
address spell check
hrithikesh026 Apr 15, 2024
026e873
Merge branch 'main' into implement-authentication-flow-netcetera
hrithikesh026 Apr 17, 2024
6ef6d4f
chore: remove todo comments
hrithikesh026 Apr 17, 2024
c24025f
chore: run formatter
hyperswitch-bot[bot] Apr 17, 2024
7af9af0
address comments
hrithikesh026 Apr 18, 2024
16f933b
address spell check
hrithikesh026 Apr 18, 2024
2174ec2
make enum variant untagged
hrithikesh026 Apr 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/deployments/production.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ zen.base_url = "https://api.zen.com/"
zen.secondary_base_url = "https://secure.zen.com/"
zsl.base_url = "https://api.sitoffalb.net/"
threedsecureio.base_url = "https://service.3dsecure.io"
netcetera.base_url = "https://{{merchant_endpoint_prefix}}.3ds-server.prev.netcetera-cloud-payment.ch"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we raise a query, if this would be the same URL prev for PROD too?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If netcetera.base_url is missing in production.toml, it would cause production deployment to fail.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will just be a temporary fix to avoid production deployment failure.


[delayed_session_response]
connectors_with_delayed_session_response = "trustpay,payme"
Expand Down
10 changes: 10 additions & 0 deletions crates/common_enums/src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,16 @@ impl Currency {
| Self::ZMW => false,
}
}

pub fn number_of_digits_after_decimal_point(self) -> u8 {
if self.is_zero_decimal_currency() {
0
} else if self.is_three_decimal_currency() {
3
} else {
2
}
}
}

#[derive(
Expand Down
3 changes: 3 additions & 0 deletions crates/common_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ pub mod date_time {
YYYYMMDDHHmmss,
/// Format the date in 20191105 format
YYYYMMDD,
/// Format the date in 201911050811 format
YYYYMMDDHHmm,
}

/// Create a new [`PrimitiveDateTime`] with the current date and time in UTC.
Expand Down Expand Up @@ -95,6 +97,7 @@ pub mod date_time {
match format {
DateFormat::YYYYMMDDHHmmss => time::macros::format_description!("[year repr:full][month padding:zero repr:numerical][day padding:zero][hour padding:zero repr:24][minute padding:zero][second padding:zero]"),
DateFormat::YYYYMMDD => time::macros::format_description!("[year repr:full][month padding:zero repr:numerical][day padding:zero]"),
DateFormat::YYYYMMDDHHmm => time::macros::format_description!("[year repr:full][month padding:zero repr:numerical][day padding:zero][hour padding:zero repr:24][minute padding:zero]"),
}
}
}
Expand Down
114 changes: 107 additions & 7 deletions crates/router/src/connector/netcetera.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod netcetera_types;
pub mod transformers;

use std::fmt::Debug;
Expand All @@ -9,7 +10,6 @@ use transformers as netcetera;

use crate::{
configs::settings,
consts,
core::errors::{self, CustomResult},
events::connector_api_logs::ConnectorEvent,
headers,
Expand Down Expand Up @@ -107,11 +107,8 @@ impl ConnectorCommon for Netcetera {
Ok(ErrorResponse {
status_code: res.status_code,
code: response.error_details.error_code,
message: response
.error_details
.error_description
.unwrap_or(consts::NO_ERROR_MESSAGE.into()),
reason: response.error_details.error_detail,
message: response.error_details.error_description,
reason: Some(response.error_details.error_detail),
attempt_status: None,
connector_transaction_id: None,
})
Expand All @@ -123,7 +120,6 @@ impl ConnectorValidation for Netcetera {}
impl ConnectorIntegration<api::Session, types::PaymentsSessionData, types::PaymentsResponseData>
for Netcetera
{
//TODO: implement sessions flow
}

impl ConnectorIntegration<api::AccessTokenAuth, types::AccessTokenRequestData, types::AccessToken>
Expand Down Expand Up @@ -313,6 +309,110 @@ impl
types::authentication::AuthenticationResponseData,
> for Netcetera
{
fn get_headers(
&self,
req: &types::authentication::ConnectorAuthenticationRouterData,
connectors: &settings::Connectors,
) -> CustomResult<Vec<(String, request::Maskable<String>)>, errors::ConnectorError> {
self.build_headers(req, connectors)
}

fn get_content_type(&self) -> &'static str {
self.common_get_content_type()
}

fn get_url(
&self,
req: &types::authentication::ConnectorAuthenticationRouterData,
connectors: &settings::Connectors,
) -> CustomResult<String, errors::ConnectorError> {
let base_url = build_endpoint(self.base_url(connectors), &req.connector_meta_data)?;
SamraatBansal marked this conversation as resolved.
Show resolved Hide resolved
Ok(format!("{}/3ds/authentication", base_url,))
}

fn get_request_body(
&self,
req: &types::authentication::ConnectorAuthenticationRouterData,
_connectors: &settings::Connectors,
) -> CustomResult<RequestContent, errors::ConnectorError> {
let connector_router_data = netcetera::NetceteraRouterData::try_from((
&self.get_currency_unit(),
req.request
.currency
.ok_or(errors::ConnectorError::MissingRequiredField {
field_name: "currency",
})?,
req.request
.amount
.ok_or(errors::ConnectorError::MissingRequiredField {
field_name: "amount",
})?,
req,
))?;
let req_obj = netcetera::NetceteraAuthenticationRequest::try_from(&connector_router_data);
Ok(RequestContent::Json(Box::new(req_obj?)))
}

fn build_request(
&self,
req: &types::authentication::ConnectorAuthenticationRouterData,
connectors: &settings::Connectors,
) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
let netcetera_auth_type = netcetera::NetceteraAuthType::try_from(&req.connector_auth_type)?;
Ok(Some(
services::RequestBuilder::new()
.method(services::Method::Post)
.url(
&types::authentication::ConnectorAuthenticationType::get_url(
self, req, connectors,
)?,
)
.attach_default_headers()
.headers(
types::authentication::ConnectorAuthenticationType::get_headers(
self, req, connectors,
)?,
)
.set_body(
types::authentication::ConnectorAuthenticationType::get_request_body(
self, req, connectors,
)?,
)
.add_certificate(Some(netcetera_auth_type.certificate.expose()))
.add_certificate_key(Some(netcetera_auth_type.private_key.expose()))
.build(),
))
}

fn handle_response(
&self,
data: &types::authentication::ConnectorAuthenticationRouterData,
event_builder: Option<&mut ConnectorEvent>,
res: Response,
) -> CustomResult<
types::authentication::ConnectorAuthenticationRouterData,
errors::ConnectorError,
> {
let response: netcetera::NetceteraAuthenticationResponse = res
.response
.parse_struct("NetceteraAuthenticationResponse")
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
event_builder.map(|i| i.set_response_body(&response));
router_env::logger::info!(connector_response=?response);
types::RouterData::try_from(types::ResponseRouterData {
response,
data: data.clone(),
http_code: res.status_code,
})
}

fn get_error_response(
&self,
res: Response,
event_builder: Option<&mut ConnectorEvent>,
) -> CustomResult<ErrorResponse, errors::ConnectorError> {
self.build_error_response(res, event_builder)
}
}

impl
Expand Down
Loading
Loading