Skip to content

Commit 8818a9b

Browse files
feat(connector): [AUTHORIZEDOTNET] create connector customer flow added (#8774)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
1 parent 58a9c9f commit 8818a9b

File tree

12 files changed

+471
-209
lines changed

12 files changed

+471
-209
lines changed

config/config.example.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -887,7 +887,7 @@ pix = { country = "BR", currency = "BRL" }
887887
bluecode = { country = "AT,BE,BG,HR,CY,CZ,DK,EE,FI,FR,DE,GR,HU,IE,IT,LV,LT,LU,MT,NL,PL,PT,RO,SK,SI,ES,SE,IS,LI,NO", currency = "EUR" }
888888

889889
[connector_customer]
890-
connector_list = "adyen,facilitapay,gocardless,hyperswitch_vault,stax,stripe"
890+
connector_list = "adyen,authorizedotnet,facilitapay,gocardless,hyperswitch_vault,stax,stripe"
891891
payout_connector_list = "nomupay,stripe,wise"
892892

893893
[bank_config.online_banking_fpx]

config/deployments/integration_test.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ force_cookies = true
191191
enabled = true
192192

193193
[connector_customer]
194-
connector_list = "adyen,facilitapay,gocardless,hyperswitch_vault,stax,stripe"
194+
connector_list = "adyen,authorizedotnet,facilitapay,gocardless,hyperswitch_vault,stax,stripe"
195195
payout_connector_list = "nomupay,stripe,wise"
196196

197197
[delayed_session_response]

config/deployments/production.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ open_banking_uk.adyen.banks = "aib,bank_of_scotland,danske_bank,first_direct,fir
1515
przelewy24.stripe.banks = "alior_bank,bank_millennium,bank_nowy_bfg_sa,bank_pekao_sa,banki_spbdzielcze,blik,bnp_paribas,boz,citi,credit_agricole,e_transfer_pocztowy24,getin_bank,idea_bank,inteligo,mbank_mtransfer,nest_przelew,noble_pay,pbac_z_ipko,plus_bank,santander_przelew24,toyota_bank,volkswagen_bank"
1616

1717
[connector_customer]
18-
connector_list = "adyen,facilitapay,gocardless,hyperswitch_vault,stax,stripe"
18+
connector_list = "adyen,authorizedotnet,facilitapay,gocardless,hyperswitch_vault,stax,stripe"
1919
payout_connector_list = "nomupay,stripe,wise"
2020

2121
# Connector configuration, provided attributes will be used to fulfill API requests.

config/deployments/sandbox.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ open_banking_uk.adyen.banks = "aib,bank_of_scotland,danske_bank,first_direct,fir
1515
przelewy24.stripe.banks = "alior_bank,bank_millennium,bank_nowy_bfg_sa,bank_pekao_sa,banki_spbdzielcze,blik,bnp_paribas,boz,citi,credit_agricole,e_transfer_pocztowy24,getin_bank,idea_bank,inteligo,mbank_mtransfer,nest_przelew,noble_pay,pbac_z_ipko,plus_bank,santander_przelew24,toyota_bank,volkswagen_bank"
1616

1717
[connector_customer]
18-
connector_list = "adyen,facilitapay,gocardless,hyperswitch_vault,stax,stripe"
18+
connector_list = "adyen,authorizedotnet,facilitapay,gocardless,hyperswitch_vault,stax,stripe"
1919
payout_connector_list = "nomupay,stripe,wise"
2020

2121
# Connector configuration, provided attributes will be used to fulfill API requests.

config/development.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -942,7 +942,7 @@ nexixpay = { payment_method = "card" }
942942
redsys = { payment_method = "card" }
943943

944944
[connector_customer]
945-
connector_list = "adyen,facilitapay,gocardless,hyperswitch_vault,stax,stripe"
945+
connector_list = "adyen,authorizedotnet,facilitapay,gocardless,hyperswitch_vault,stax,stripe"
946946
payout_connector_list = "nomupay,stripe,wise"
947947

948948
[dummy_connector]

config/docker_compose.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -946,7 +946,7 @@ card.debit = { connector_list = "cybersource" }
946946
connector_list = "adyen,archipel,cybersource,novalnet,stripe,worldpay,worldpayvantiv"
947947

948948
[connector_customer]
949-
connector_list = "adyen,facilitapay,gocardless,hyperswitch_vault,stax,stripe"
949+
connector_list = "adyen,authorizedotnet,facilitapay,gocardless,hyperswitch_vault,stax,stripe"
950950
payout_connector_list = "nomupay,stripe,wise"
951951

952952

crates/hyperswitch_connectors/src/connectors/authorizedotnet.rs

Lines changed: 134 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,22 @@ use hyperswitch_domain_models::{
1616
access_token_auth::AccessTokenAuth,
1717
payments::{Authorize, Capture, PSync, PaymentMethodToken, Session, SetupMandate, Void},
1818
refunds::{Execute, RSync},
19-
CompleteAuthorize,
19+
CompleteAuthorize, CreateConnectorCustomer,
2020
},
2121
router_request_types::{
22-
AccessTokenRequestData, CompleteAuthorizeData, PaymentMethodTokenizationData,
23-
PaymentsAuthorizeData, PaymentsCancelData, PaymentsCaptureData, PaymentsSessionData,
24-
PaymentsSyncData, RefundsData, SetupMandateRequestData,
22+
AccessTokenRequestData, CompleteAuthorizeData, ConnectorCustomerData,
23+
PaymentMethodTokenizationData, PaymentsAuthorizeData, PaymentsCancelData,
24+
PaymentsCaptureData, PaymentsSessionData, PaymentsSyncData, RefundsData,
25+
SetupMandateRequestData,
2526
},
2627
router_response_types::{
2728
ConnectorInfo, PaymentMethodDetails, PaymentsResponseData, RefundsResponseData,
2829
SupportedPaymentMethods, SupportedPaymentMethodsExt,
2930
},
3031
types::{
31-
PaymentsAuthorizeRouterData, PaymentsCancelRouterData, PaymentsCaptureRouterData,
32-
PaymentsCompleteAuthorizeRouterData, PaymentsSyncRouterData, RefundsRouterData,
33-
SetupMandateRouterData,
32+
ConnectorCustomerRouterData, PaymentsAuthorizeRouterData, PaymentsCancelRouterData,
33+
PaymentsCaptureRouterData, PaymentsCompleteAuthorizeRouterData, PaymentsSyncRouterData,
34+
RefundsRouterData, SetupMandateRouterData,
3435
},
3536
};
3637
use hyperswitch_interfaces::{
@@ -42,9 +43,9 @@ use hyperswitch_interfaces::{
4243
consts, errors,
4344
events::connector_api_logs::ConnectorEvent,
4445
types::{
45-
PaymentsAuthorizeType, PaymentsCaptureType, PaymentsCompleteAuthorizeType,
46-
PaymentsSyncType, PaymentsVoidType, RefundExecuteType, RefundSyncType, Response,
47-
SetupMandateType,
46+
ConnectorCustomerType, PaymentsAuthorizeType, PaymentsCaptureType,
47+
PaymentsCompleteAuthorizeType, PaymentsSyncType, PaymentsVoidType, RefundExecuteType,
48+
RefundSyncType, Response, SetupMandateType,
4849
},
4950
webhooks,
5051
};
@@ -137,6 +138,128 @@ impl ConnectorIntegration<AccessTokenAuth, AccessTokenRequestData, AccessToken>
137138
// Not Implemented (R)
138139
}
139140

141+
impl api::ConnectorCustomer for Authorizedotnet {}
142+
143+
impl ConnectorIntegration<CreateConnectorCustomer, ConnectorCustomerData, PaymentsResponseData>
144+
for Authorizedotnet
145+
{
146+
fn get_headers(
147+
&self,
148+
req: &ConnectorCustomerRouterData,
149+
connectors: &Connectors,
150+
) -> CustomResult<Vec<(String, Maskable<String>)>, errors::ConnectorError> {
151+
self.build_headers(req, connectors)
152+
}
153+
154+
fn get_content_type(&self) -> &'static str {
155+
self.common_get_content_type()
156+
}
157+
158+
fn get_url(
159+
&self,
160+
_req: &ConnectorCustomerRouterData,
161+
connectors: &Connectors,
162+
) -> CustomResult<String, errors::ConnectorError> {
163+
Ok(self.base_url(connectors).to_string())
164+
}
165+
166+
fn get_request_body(
167+
&self,
168+
req: &ConnectorCustomerRouterData,
169+
_connectors: &Connectors,
170+
) -> CustomResult<RequestContent, errors::ConnectorError> {
171+
let connector_req = authorizedotnet::CustomerRequest::try_from(req)?;
172+
Ok(RequestContent::Json(Box::new(connector_req)))
173+
}
174+
175+
fn build_request(
176+
&self,
177+
req: &ConnectorCustomerRouterData,
178+
connectors: &Connectors,
179+
) -> CustomResult<Option<Request>, errors::ConnectorError> {
180+
Ok(Some(
181+
RequestBuilder::new()
182+
.method(Method::Post)
183+
.url(&ConnectorCustomerType::get_url(self, req, connectors)?)
184+
.attach_default_headers()
185+
.headers(ConnectorCustomerType::get_headers(self, req, connectors)?)
186+
.set_body(ConnectorCustomerType::get_request_body(
187+
self, req, connectors,
188+
)?)
189+
.build(),
190+
))
191+
}
192+
193+
fn handle_response(
194+
&self,
195+
data: &ConnectorCustomerRouterData,
196+
event_builder: Option<&mut ConnectorEvent>,
197+
res: Response,
198+
) -> CustomResult<ConnectorCustomerRouterData, errors::ConnectorError>
199+
where
200+
PaymentsResponseData: Clone,
201+
{
202+
use bytes::Buf;
203+
// Handle the case where response bytes contains U+FEFF (BOM) character sent by connector
204+
let encoding = encoding_rs::UTF_8;
205+
let intermediate_response = encoding.decode_with_bom_removal(res.response.chunk());
206+
let intermediate_response =
207+
bytes::Bytes::copy_from_slice(intermediate_response.0.as_bytes());
208+
let response: authorizedotnet::AuthorizedotnetCustomerResponse = intermediate_response
209+
.parse_struct("AuthorizedotnetCustomerResponse")
210+
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
211+
212+
event_builder.map(|i| i.set_response_body(&response));
213+
router_env::logger::info!(connector_response=?response);
214+
215+
RouterData::try_from(ResponseRouterData {
216+
response,
217+
data: data.clone(),
218+
http_code: res.status_code,
219+
})
220+
.change_context(errors::ConnectorError::ResponseHandlingFailed)
221+
}
222+
223+
fn get_error_response(
224+
&self,
225+
res: Response,
226+
event_builder: Option<&mut ConnectorEvent>,
227+
) -> CustomResult<ErrorResponse, errors::ConnectorError> {
228+
use bytes::Buf;
229+
// Handle the case where response bytes contains U+FEFF (BOM) character sent by connector
230+
let encoding = encoding_rs::UTF_8;
231+
let intermediate_response = encoding.decode_with_bom_removal(res.response.chunk());
232+
let intermediate_response =
233+
bytes::Bytes::copy_from_slice(intermediate_response.0.as_bytes());
234+
let response: authorizedotnet::AuthorizedotnetErrorResponse = intermediate_response
235+
.parse_struct("AuthorizedotnetErrorResponse")
236+
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
237+
238+
event_builder.map(|i| i.set_error_response_body(&response));
239+
router_env::logger::info!(connector_response=?response);
240+
241+
Ok(ErrorResponse {
242+
status_code: res.status_code,
243+
code: response
244+
.error
245+
.code
246+
.clone()
247+
.unwrap_or_else(|| consts::NO_ERROR_CODE.to_string()),
248+
message: response
249+
.error
250+
.message
251+
.clone()
252+
.unwrap_or_else(|| consts::NO_ERROR_MESSAGE.to_string()),
253+
reason: response.error.message,
254+
attempt_status: None,
255+
connector_transaction_id: None,
256+
network_advice_code: None,
257+
network_decline_code: None,
258+
network_error_message: None,
259+
})
260+
}
261+
}
262+
140263
impl MandateSetup for Authorizedotnet {}
141264

142265
impl ConnectorIntegration<SetupMandate, SetupMandateRequestData, PaymentsResponseData>
@@ -165,7 +288,7 @@ impl ConnectorIntegration<SetupMandate, SetupMandateRequestData, PaymentsRespons
165288
req: &SetupMandateRouterData,
166289
_connectors: &Connectors,
167290
) -> CustomResult<RequestContent, errors::ConnectorError> {
168-
let connector_req = authorizedotnet::CreateCustomerProfileRequest::try_from(req)?;
291+
let connector_req = authorizedotnet::CreateCustomerPaymentProfileRequest::try_from(req)?;
169292
Ok(RequestContent::Json(Box::new(connector_req)))
170293
}
171294

@@ -192,7 +315,6 @@ impl ConnectorIntegration<SetupMandate, SetupMandateRequestData, PaymentsRespons
192315
res: Response,
193316
) -> CustomResult<SetupMandateRouterData, errors::ConnectorError> {
194317
use bytes::Buf;
195-
196318
// Handle the case where response bytes contains U+FEFF (BOM) character sent by connector
197319
let encoding = encoding_rs::UTF_8;
198320
let intermediate_response = encoding.decode_with_bom_removal(res.response.chunk());

0 commit comments

Comments
 (0)