feat(connector): [ZSL] add connector template code (#4285)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
Co-authored-by: SamraatBansal <55536657+SamraatBansal@users.noreply.github.com>
This commit is contained in:
AkshayaFoiger
2024-04-10 18:55:33 +05:30
committed by GitHub
parent 3963219e44
commit 086516b7b3
22 changed files with 589 additions and 34 deletions

View File

@ -228,6 +228,7 @@ volt.base_url = "https://api.sandbox.volt.io/"
wise.base_url = "https://api.sandbox.transferwise.tech/"
worldline.base_url = "https://eu.sandbox.api-ingenico.com/"
worldpay.base_url = "https://try.access.worldpay.com/"
zsl.base_url = "https://api.sitoffalb.net/"
zen.base_url = "https://api.zen-test.com/"
zen.secondary_base_url = "https://secure.zen-test.com/"
@ -280,6 +281,7 @@ cards = [
"threedsecureio",
"worldpay",
"zen",
"zsl",
]
# Scheduler settings provides a point to modify the behaviour of scheduler flow.

View File

@ -143,6 +143,7 @@ cards = [
"worldline",
"worldpay",
"zen",
"zsl",
]
[refund]
@ -227,6 +228,7 @@ volt.base_url = "https://api.sandbox.volt.io/"
trustpay.base_url_bank_redirects = "https://aapi.trustpay.eu/"
zen.base_url = "https://api.zen-test.com/"
zen.secondary_base_url = "https://secure.zen-test.com/"
zsl.base_url = "https://api.sitoffalb.net/"
[scheduler]
stream = "SCHEDULER_STREAM"

View File

@ -164,6 +164,7 @@ worldline.base_url = "https://eu.sandbox.api-ingenico.com/"
worldpay.base_url = "https://try.access.worldpay.com/"
zen.base_url = "https://api.zen-test.com/"
zen.secondary_base_url = "https://secure.zen-test.com/"
zsl.base_url = "https://api.sitoffalb.net/"
[pm_filters.default]
@ -225,6 +226,7 @@ cards = [
"worldline",
"worldpay",
"zen",
"zsl"
]
[delayed_session_response]

View File

@ -126,10 +126,11 @@ pub enum Connector {
Wise,
Worldline,
Worldpay,
Zen,
Signifyd,
Plaid,
Riskified,
Zen,
// Zsl, Added as template code for future usage
}
impl Connector {
@ -207,6 +208,7 @@ impl Connector {
| Self::Worldline
| Self::Worldpay
| Self::Zen
// | Self::Zsl Added as template code for future usage
| Self::Signifyd
| Self::Plaid
| Self::Riskified
@ -264,6 +266,7 @@ impl Connector {
| Self::Worldline
| Self::Worldpay
| Self::Zen
// | Self::Zsl, Added as template code for future usage
| Self::Signifyd
| Self::Plaid
| Self::Riskified

View File

@ -167,6 +167,7 @@ pub enum RoutableConnectors {
Worldline,
Worldpay,
Zen,
// Zsl, Added as template code for future usage
}
impl AttemptStatus {

View File

@ -163,12 +163,13 @@ pub struct ConnectorConfig {
pub wise_payout: Option<ConnectorTomlConfig>,
pub worldline: Option<ConnectorTomlConfig>,
pub worldpay: Option<ConnectorTomlConfig>,
pub zen: Option<ConnectorTomlConfig>,
pub square: Option<ConnectorTomlConfig>,
pub stax: Option<ConnectorTomlConfig>,
pub dummy_connector: Option<ConnectorTomlConfig>,
pub stripe_test: Option<ConnectorTomlConfig>,
pub paypal_test: Option<ConnectorTomlConfig>,
pub zen: Option<ConnectorTomlConfig>,
pub zsl: Option<ConnectorTomlConfig>,
}
impl ConnectorConfig {
@ -277,6 +278,7 @@ impl ConnectorConfig {
Connector::Worldline => Ok(connector_data.worldline),
Connector::Worldpay => Ok(connector_data.worldpay),
Connector::Zen => Ok(connector_data.zen),
// Connector::Zsl => Ok(connector_data.zsl), Added as template code for future usage
#[cfg(feature = "dummy_connector")]
Connector::DummyConnector1 => Ok(connector_data.dummy_connector),
#[cfg(feature = "dummy_connector")]

View File

@ -539,6 +539,7 @@ pub struct Connectors {
pub worldline: ConnectorParams,
pub worldpay: ConnectorParams,
pub zen: ConnectorParams,
pub zsl: ConnectorParams,
}
#[derive(Debug, Deserialize, Clone, Default, router_derive::ConfigValidate)]

View File

@ -57,6 +57,7 @@ pub mod wise;
pub mod worldline;
pub mod worldpay;
pub mod zen;
pub mod zsl;
#[cfg(feature = "dummy_connector")]
pub use self::dummyconnector::DummyConnector;
@ -72,5 +73,5 @@ pub use self::{
payu::Payu, placetopay::Placetopay, powertranz::Powertranz, prophetpay::Prophetpay,
rapyd::Rapyd, riskified::Riskified, shift4::Shift4, signifyd::Signifyd, square::Square,
stax::Stax, stripe::Stripe, threedsecureio::Threedsecureio, trustpay::Trustpay, tsys::Tsys,
volt::Volt, wise::Wise, worldline::Worldline, worldpay::Worldpay, zen::Zen,
volt::Volt, wise::Wise, worldline::Worldline, worldpay::Worldpay, zen::Zen, zsl::Zsl,
};

View File

@ -0,0 +1,279 @@
pub mod transformers;
use std::fmt::Debug;
use error_stack::{report, ResultExt};
use masking::ExposeInterface;
use transformers as zsl;
use crate::{
configs::settings,
core::errors::{self, CustomResult},
events::connector_api_logs::ConnectorEvent,
headers,
services::{
self,
request::{self, Mask},
ConnectorIntegration, ConnectorValidation,
},
types::{
self,
api::{self, ConnectorCommon, ConnectorCommonExt},
ErrorResponse, RequestContent, Response,
},
utils::BytesExt,
};
#[derive(Debug, Clone)]
pub struct Zsl;
impl api::Payment for Zsl {}
impl api::PaymentSession for Zsl {}
impl api::ConnectorAccessToken for Zsl {}
impl api::MandateSetup for Zsl {}
impl api::PaymentAuthorize for Zsl {}
impl api::PaymentSync for Zsl {}
impl api::PaymentCapture for Zsl {}
impl api::PaymentVoid for Zsl {}
impl api::Refund for Zsl {}
impl api::RefundExecute for Zsl {}
impl api::RefundSync for Zsl {}
impl api::PaymentToken for Zsl {}
impl
ConnectorIntegration<
api::PaymentMethodToken,
types::PaymentMethodTokenizationData,
types::PaymentsResponseData,
> for Zsl
{
// Not Implemented (R)
}
impl<Flow, Request, Response> ConnectorCommonExt<Flow, Request, Response> for Zsl
where
Self: ConnectorIntegration<Flow, Request, Response>,
{
fn build_headers(
&self,
req: &types::RouterData<Flow, Request, Response>,
_connectors: &settings::Connectors,
) -> CustomResult<Vec<(String, request::Maskable<String>)>, errors::ConnectorError> {
let mut header = vec![(
headers::CONTENT_TYPE.to_string(),
self.get_content_type().to_string().into(),
)];
let mut api_key = self.get_auth_header(&req.connector_auth_type)?;
header.append(&mut api_key);
Ok(header)
}
}
impl ConnectorCommon for Zsl {
fn id(&self) -> &'static str {
"zsl"
}
fn get_currency_unit(&self) -> api::CurrencyUnit {
api::CurrencyUnit::Minor
}
fn common_get_content_type(&self) -> &'static str {
"application/json"
}
fn base_url<'a>(&self, connectors: &'a settings::Connectors) -> &'a str {
connectors.zsl.base_url.as_ref()
}
fn get_auth_header(
&self,
auth_type: &types::ConnectorAuthType,
) -> CustomResult<Vec<(String, request::Maskable<String>)>, errors::ConnectorError> {
let auth = zsl::ZslAuthType::try_from(auth_type)
.change_context(errors::ConnectorError::FailedToObtainAuthType)?;
Ok(vec![(
headers::AUTHORIZATION.to_string(),
format!("{}:{}", auth.api_key.expose(), auth.merchant_id.expose()).into_masked(),
)])
}
fn build_error_response(
&self,
res: Response,
event_builder: Option<&mut ConnectorEvent>,
) -> CustomResult<ErrorResponse, errors::ConnectorError> {
let response: zsl::ZslErrorResponse = res
.response
.parse_struct("ZslErrorResponse")
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
event_builder.map(|i| i.set_response_body(&response));
router_env::logger::info!(connector_response=?response);
Ok(ErrorResponse {
status_code: res.status_code,
code: response.code,
message: response.message,
reason: response.reason,
attempt_status: None,
connector_transaction_id: None,
})
}
}
impl ConnectorValidation for Zsl {
//TODO: implement functions when support enabled
}
impl ConnectorIntegration<api::Session, types::PaymentsSessionData, types::PaymentsResponseData>
for Zsl
{
//TODO: implement sessions flow
}
impl ConnectorIntegration<api::AccessTokenAuth, types::AccessTokenRequestData, types::AccessToken>
for Zsl
{
}
impl
ConnectorIntegration<
api::SetupMandate,
types::SetupMandateRequestData,
types::PaymentsResponseData,
> for Zsl
{
}
impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::PaymentsResponseData>
for Zsl
{
fn get_headers(
&self,
req: &types::PaymentsAuthorizeRouterData,
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::PaymentsAuthorizeRouterData,
_connectors: &settings::Connectors,
) -> CustomResult<String, errors::ConnectorError> {
Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into())
}
fn get_request_body(
&self,
req: &types::PaymentsAuthorizeRouterData,
_connectors: &settings::Connectors,
) -> CustomResult<RequestContent, errors::ConnectorError> {
let connector_router_data = zsl::ZslRouterData::try_from((
&self.get_currency_unit(),
req.request.currency,
req.request.amount,
req,
))?;
let connector_req = zsl::ZslPaymentsRequest::try_from(&connector_router_data)?;
Ok(RequestContent::Json(Box::new(connector_req)))
}
fn build_request(
&self,
req: &types::PaymentsAuthorizeRouterData,
connectors: &settings::Connectors,
) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
Ok(Some(
services::RequestBuilder::new()
.method(services::Method::Post)
.url(&types::PaymentsAuthorizeType::get_url(
self, req, connectors,
)?)
.attach_default_headers()
.headers(types::PaymentsAuthorizeType::get_headers(
self, req, connectors,
)?)
.set_body(types::PaymentsAuthorizeType::get_request_body(
self, req, connectors,
)?)
.build(),
))
}
fn handle_response(
&self,
data: &types::PaymentsAuthorizeRouterData,
event_builder: Option<&mut ConnectorEvent>,
res: Response,
) -> CustomResult<types::PaymentsAuthorizeRouterData, errors::ConnectorError> {
let response: zsl::ZslPaymentsResponse = res
.response
.parse_struct("Zsl PaymentsAuthorizeResponse")
.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 ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsResponseData>
for Zsl
{
}
impl ConnectorIntegration<api::Capture, types::PaymentsCaptureData, types::PaymentsResponseData>
for Zsl
{
}
impl ConnectorIntegration<api::Void, types::PaymentsCancelData, types::PaymentsResponseData>
for Zsl
{
}
impl ConnectorIntegration<api::Execute, types::RefundsData, types::RefundsResponseData> for Zsl {}
impl ConnectorIntegration<api::RSync, types::RefundsData, types::RefundsResponseData> for Zsl {}
#[async_trait::async_trait]
impl api::IncomingWebhook for Zsl {
fn get_webhook_object_reference_id(
&self,
_request: &api::IncomingWebhookRequestDetails<'_>,
) -> CustomResult<api::webhooks::ObjectReferenceId, errors::ConnectorError> {
Err(report!(errors::ConnectorError::WebhooksNotImplemented))
}
fn get_webhook_event_type(
&self,
_request: &api::IncomingWebhookRequestDetails<'_>,
) -> CustomResult<api::IncomingWebhookEvent, errors::ConnectorError> {
Err(report!(errors::ConnectorError::WebhooksNotImplemented))
}
fn get_webhook_resource_object(
&self,
_request: &api::IncomingWebhookRequestDetails<'_>,
) -> CustomResult<Box<dyn masking::ErasedMaskSerialize>, errors::ConnectorError> {
Err(report!(errors::ConnectorError::WebhooksNotImplemented))
}
}

View File

@ -0,0 +1,159 @@
use masking::Secret;
use serde::{Deserialize, Serialize};
use crate::{
connector::utils::PaymentsAuthorizeRequestData,
core::errors,
types::{self, domain, storage::enums},
};
//TODO: Fill the struct with respective fields
pub struct ZslRouterData<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 ZslRouterData<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
#[derive(Default, Debug, Serialize, Eq, PartialEq)]
pub struct ZslPaymentsRequest {
amount: i64,
card: ZslCard,
}
#[derive(Default, Debug, Serialize, Eq, PartialEq)]
pub struct ZslCard {
number: cards::CardNumber,
expiry_month: Secret<String>,
expiry_year: Secret<String>,
cvc: Secret<String>,
complete: bool,
}
impl TryFrom<&ZslRouterData<&types::PaymentsAuthorizeRouterData>> for ZslPaymentsRequest {
type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(
item: &ZslRouterData<&types::PaymentsAuthorizeRouterData>,
) -> Result<Self, Self::Error> {
match item.router_data.request.payment_method_data.clone() {
domain::PaymentMethodData::Card(req_card) => {
let card = ZslCard {
number: req_card.card_number,
expiry_month: req_card.card_exp_month,
expiry_year: req_card.card_exp_year,
cvc: req_card.card_cvc,
complete: item.router_data.request.is_auto_capture()?,
};
Ok(Self {
amount: item.amount.to_owned(),
card,
})
}
_ => Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()),
}
}
}
//TODO: Fill the struct with respective fields
// Auth Struct
pub struct ZslAuthType {
pub(super) api_key: Secret<String>,
pub(super) merchant_id: Secret<String>,
}
impl TryFrom<&types::ConnectorAuthType> for ZslAuthType {
type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(auth_type: &types::ConnectorAuthType) -> Result<Self, Self::Error> {
match auth_type {
types::ConnectorAuthType::BodyKey { api_key, key1 } => Ok(Self {
api_key: api_key.to_owned(),
merchant_id: key1.to_owned(),
}),
_ => Err(errors::ConnectorError::FailedToObtainAuthType.into()),
}
}
}
// PaymentsResponse
//TODO: Append the remaining status flags
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum ZslPaymentStatus {
Succeeded,
Failed,
#[default]
Processing,
}
impl From<ZslPaymentStatus> for enums::AttemptStatus {
fn from(item: ZslPaymentStatus) -> Self {
match item {
ZslPaymentStatus::Succeeded => Self::Charged,
ZslPaymentStatus::Failed => Self::Failure,
ZslPaymentStatus::Processing => Self::Authorizing,
}
}
}
//TODO: Fill the struct with respective fields
#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ZslPaymentsResponse {
status: ZslPaymentStatus,
id: String,
}
impl<F, T>
TryFrom<types::ResponseRouterData<F, ZslPaymentsResponse, T, types::PaymentsResponseData>>
for types::RouterData<F, T, types::PaymentsResponseData>
{
type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(
item: types::ResponseRouterData<F, ZslPaymentsResponse, T, types::PaymentsResponseData>,
) -> Result<Self, Self::Error> {
Ok(Self {
status: enums::AttemptStatus::from(item.response.status),
response: Ok(types::PaymentsResponseData::TransactionResponse {
resource_id: types::ResponseId::ConnectorTransactionId(item.response.id),
redirection_data: None,
mandate_reference: None,
connector_metadata: None,
network_txn_id: None,
connector_response_reference_id: None,
incremental_authorization_allowed: None,
}),
..item.data
})
}
}
//TODO: Fill the struct with respective fields
#[derive(Default, Debug, Serialize, Deserialize, PartialEq)]
pub struct ZslErrorResponse {
pub status_code: u16,
pub code: String,
pub message: String,
pub reason: Option<String>,
}

View File

@ -1916,6 +1916,10 @@ pub(crate) fn validate_auth_and_metadata_type(
zen::transformers::ZenAuthType::try_from(val)?;
Ok(())
}
// api_enums::Connector::Zsl => {
// zsl::transformers::ZslAuthType::try_from(val)?;
// Ok(())
// } Added as template code for future usage
api_enums::Connector::Signifyd => {
signifyd::transformers::SignifydAuthType::try_from(val)?;
Ok(())

View File

@ -185,7 +185,8 @@ default_imp_for_complete_authorize!(
connector::Wise,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
macro_rules! default_imp_for_webhook_source_verification {
($($path:ident::$connector:ident),*) => {
@ -268,7 +269,8 @@ default_imp_for_webhook_source_verification!(
connector::Wise,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
macro_rules! default_imp_for_create_customer {
@ -351,7 +353,8 @@ default_imp_for_create_customer!(
connector::Wise,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
macro_rules! default_imp_for_connector_redirect_response {
@ -423,7 +426,8 @@ default_imp_for_connector_redirect_response!(
connector::Volt,
connector::Wise,
connector::Worldline,
connector::Worldpay
connector::Worldpay,
connector::Zsl
);
macro_rules! default_imp_for_connector_request_id {
@ -438,6 +442,7 @@ macro_rules! default_imp_for_connector_request_id {
impl<const T: u8> api::ConnectorTransactionId for connector::DummyConnector<T> {}
default_imp_for_connector_request_id!(
connector::Zsl,
connector::Aci,
connector::Adyen,
connector::Airwallex,
@ -579,7 +584,8 @@ default_imp_for_accept_dispute!(
connector::Wise,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
macro_rules! default_imp_for_file_upload {
@ -685,7 +691,8 @@ default_imp_for_file_upload!(
connector::Wise,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
macro_rules! default_imp_for_submit_evidence {
@ -769,7 +776,8 @@ default_imp_for_submit_evidence!(
connector::Wise,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
macro_rules! default_imp_for_defend_dispute {
@ -854,7 +862,8 @@ default_imp_for_defend_dispute!(
connector::Wise,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
macro_rules! default_imp_for_pre_processing_steps{
@ -931,7 +940,8 @@ default_imp_for_pre_processing_steps!(
connector::Wise,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
macro_rules! default_imp_for_payouts {
@ -999,7 +1009,8 @@ default_imp_for_payouts!(
connector::Volt,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
#[cfg(feature = "payouts")]
@ -1084,7 +1095,8 @@ default_imp_for_payouts_create!(
connector::Volt,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
#[cfg(feature = "payouts")]
@ -1172,7 +1184,8 @@ default_imp_for_payouts_eligibility!(
connector::Volt,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
#[cfg(feature = "payouts")]
@ -1257,7 +1270,8 @@ default_imp_for_payouts_fulfill!(
connector::Volt,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
#[cfg(feature = "payouts")]
@ -1342,7 +1356,8 @@ default_imp_for_payouts_cancel!(
connector::Volt,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
#[cfg(feature = "payouts")]
@ -1428,7 +1443,8 @@ default_imp_for_payouts_quote!(
connector::Volt,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
#[cfg(feature = "payouts")]
@ -1514,7 +1530,8 @@ default_imp_for_payouts_recipient!(
connector::Volt,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
macro_rules! default_imp_for_approve {
@ -1600,7 +1617,8 @@ default_imp_for_approve!(
connector::Wise,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
macro_rules! default_imp_for_reject {
@ -1686,7 +1704,8 @@ default_imp_for_reject!(
connector::Wise,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
macro_rules! default_imp_for_fraud_check {
@ -1754,7 +1773,8 @@ default_imp_for_fraud_check!(
connector::Wise,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
#[cfg(feature = "frm")]
@ -1840,7 +1860,8 @@ default_imp_for_frm_sale!(
connector::Wise,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
#[cfg(feature = "frm")]
@ -1926,7 +1947,8 @@ default_imp_for_frm_checkout!(
connector::Wise,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
#[cfg(feature = "frm")]
@ -2012,7 +2034,8 @@ default_imp_for_frm_transaction!(
connector::Wise,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
#[cfg(feature = "frm")]
@ -2098,7 +2121,8 @@ default_imp_for_frm_fulfillment!(
connector::Wise,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
#[cfg(feature = "frm")]
@ -2184,7 +2208,8 @@ default_imp_for_frm_record_return!(
connector::Wise,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
macro_rules! default_imp_for_incremental_authorization {
@ -2269,7 +2294,8 @@ default_imp_for_incremental_authorization!(
connector::Wise,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
macro_rules! default_imp_for_revoking_mandates {
@ -2351,7 +2377,8 @@ default_imp_for_revoking_mandates!(
connector::Wise,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);
macro_rules! default_imp_for_connector_authentication {
@ -2476,5 +2503,6 @@ default_imp_for_connector_authentication!(
connector::Wise,
connector::Worldline,
connector::Worldpay,
connector::Zen
connector::Zen,
connector::Zsl
);

View File

@ -385,6 +385,7 @@ impl ConnectorData {
enums::Connector::Tsys => Ok(Box::new(&connector::Tsys)),
enums::Connector::Volt => Ok(Box::new(&connector::Volt)),
enums::Connector::Zen => Ok(Box::new(&connector::Zen)),
// enums::Connector::Zsl => Ok(Box::new(&connector::Zsl)), Added as template code for future usage
enums::Connector::Signifyd
| enums::Connector::Plaid
| enums::Connector::Riskified

View File

@ -247,6 +247,7 @@ impl ForeignTryFrom<api_enums::Connector> for common_enums::RoutableConnectors {
api_enums::Connector::Worldline => Self::Worldline,
api_enums::Connector::Worldpay => Self::Worldpay,
api_enums::Connector::Zen => Self::Zen,
// api_enums::Connector::Zsl => Self::Zsl, Added as template code for future usage
#[cfg(feature = "dummy_connector")]
api_enums::Connector::DummyConnector1 => Self::DummyConnector1,
#[cfg(feature = "dummy_connector")]

View File

@ -306,7 +306,7 @@ async fn should_sync_refund() {
);
}
// Cards Negative scenerios
// Cards Negative scenarios
// Creates a payment with incorrect CVC.
#[actix_web::test]
async fn should_fail_payment_for_incorrect_cvc() {

View File

@ -65,3 +65,4 @@ mod wise;
mod worldline;
mod worldpay;
mod zen;
mod zsl;

View File

@ -206,3 +206,9 @@ api_key="API Key"
[ebanx]
api_key="API Key"
[zsl]
api_key="API Key"
key1= "Merchant id"

View File

@ -0,0 +1,59 @@
use router::types::{self, storage::enums};
use test_utils::connector_auth;
use crate::utils::{self, ConnectorActions};
struct ZslTest;
impl ConnectorActions for ZslTest {}
impl utils::Connector for ZslTest {
fn get_data(&self) -> types::api::ConnectorData {
use router::connector::Zsl;
types::api::ConnectorData {
connector: Box::new(&Zsl),
connector_name: types::Connector::Adyen,
// Added as Dummy connector as template code is added for future usage
get_token: types::api::GetToken::Connector,
merchant_connector_id: None,
}
}
fn get_auth_token(&self) -> types::ConnectorAuthType {
utils::to_connector_auth_type(
connector_auth::ConnectorAuthentication::new()
.zsl
.expect("Missing connector authentication configuration")
.into(),
)
}
fn get_name(&self) -> String {
"zsl".to_string()
}
}
static CONNECTOR: ZslTest = ZslTest {};
fn get_default_payment_info() -> Option<utils::PaymentInfo> {
None
}
fn payment_method_details() -> Option<types::PaymentsAuthorizeData> {
None
}
// Partially captures a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_partially_capture_authorized_payment() {
let response = CONNECTOR
.authorize_and_capture_payment(
payment_method_details(),
Some(types::PaymentsCaptureData {
amount_to_capture: 50,
..utils::PaymentCaptureType::default().0
}),
get_default_payment_info(),
)
.await
.expect("Capture payment response");
assert_eq!(response.status, enums::AttemptStatus::AuthenticationPending);
}

View File

@ -68,6 +68,7 @@ pub struct ConnectorAuthentication {
pub worldpay: Option<BodyKey>,
pub worldline: Option<SignatureKey>,
pub zen: Option<HeaderKey>,
pub zsl: Option<BodyKey>,
pub automation_configs: Option<AutomationConfigs>,
}

View File

@ -131,6 +131,7 @@ worldpay.base_url = "https://try.access.worldpay.com/"
wise.base_url = "https://api.sandbox.transferwise.tech/"
zen.base_url = "https://api.zen-test.com/"
zen.secondary_base_url = "https://secure.zen-test.com/"
zsl.base_url = "https://api.sitoffalb.net/"
[pm_filters.default]
apple_pay = { country = "AU,CN,HK,JP,MO,MY,NZ,SG,TW,AM,AT,AZ,BY,BE,BG,HR,CY,CZ,DK,EE,FO,FI,FR,GE,DE,GR,GL,GG,HU,IS,IE,IM,IT,KZ,JE,LV,LI,LT,LU,MT,MD,MC,ME,NL,NO,PL,PT,RO,SM,RS,SK,SI,ES,SE,CH,UA,GB,AR,CO,CR,BR,MX,PE,BH,IL,JO,KW,PS,QA,SA,AE,CA,UM,US,KR,VN,MA,ZA,VA,CL,SV,GT,HN,PA", currency = "AED,AUD,CHF,CAD,EUR,GBP,HKD,SGD,USD" }
@ -191,6 +192,7 @@ cards = [
"worldline",
"worldpay",
"zen",
"zsl",
]
[pm_filters.volt]

View File

@ -7179,10 +7179,10 @@
"wise",
"worldline",
"worldpay",
"zen",
"signifyd",
"plaid",
"riskified"
"riskified",
"zen"
]
},
"ConnectorMetadata": {

View File

@ -6,7 +6,7 @@ function find_prev_connector() {
git checkout $self
cp $self $self.tmp
# Add new connector to existing list and sort it
connectors=(aci adyen airwallex applepay authorizedotnet bambora bankofamerica billwerk bitpay bluesnap boku braintree cashtocode checkout coinbase cryptopay cybersource dlocal dummyconnector ebanx fiserv forte globalpay globepay gocardless helcim iatapay klarna mollie multisafepay nexinets noon nuvei opayo opennode payeezy payme paypal payu placetopay powertranz prophetpay rapyd shift4 square stax stripe threedsecureio trustpay tsys volt wise worldline worldpay "$1")
connectors=(aci adyen airwallex applepay authorizedotnet bambora bankofamerica billwerk bitpay bluesnap boku braintree cashtocode checkout coinbase cryptopay cybersource dlocal dummyconnector ebanx fiserv forte globalpay globepay gocardless helcim iatapay klarna mollie multisafepay nexinets noon nuvei opayo opennode payeezy payme paypal payu placetopay powertranz prophetpay rapyd shift4 square stax stripe threedsecureio trustpay tsys volt wise worldline worldpay zsl "$1")
IFS=$'\n' sorted=($(sort <<<"${connectors[*]}")); unset IFS
res=`echo ${sorted[@]}`
sed -i'' -e "s/^ connectors=.*/ connectors=($res \"\$1\")/" $self.tmp