mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-31 01:57:45 +08:00
feat(connector): [Bambora APAC] add mandate flow (#5376)
This commit is contained in:
@ -186,7 +186,7 @@ airwallex.base_url = "https://api-demo.airwallex.com/"
|
|||||||
applepay.base_url = "https://apple-pay-gateway.apple.com/"
|
applepay.base_url = "https://apple-pay-gateway.apple.com/"
|
||||||
authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api"
|
authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api"
|
||||||
bambora.base_url = "https://api.na.bambora.com"
|
bambora.base_url = "https://api.na.bambora.com"
|
||||||
bamboraapac.base_url = "https://demo.bambora.co.nz/interface/api/dts.asmx"
|
bamboraapac.base_url = "https://demo.ippayments.com.au/interface/api"
|
||||||
bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/"
|
bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/"
|
||||||
billwerk.base_url = "https://api.reepay.com/"
|
billwerk.base_url = "https://api.reepay.com/"
|
||||||
billwerk.secondary_base_url = "https://card.reepay.com/"
|
billwerk.secondary_base_url = "https://card.reepay.com/"
|
||||||
|
|||||||
@ -26,7 +26,7 @@ airwallex.base_url = "https://api-demo.airwallex.com/"
|
|||||||
applepay.base_url = "https://apple-pay-gateway.apple.com/"
|
applepay.base_url = "https://apple-pay-gateway.apple.com/"
|
||||||
authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api"
|
authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api"
|
||||||
bambora.base_url = "https://api.na.bambora.com"
|
bambora.base_url = "https://api.na.bambora.com"
|
||||||
bamboraapac.base_url = "https://demo.ippayments.com.au/interface/api/dts.asmx"
|
bamboraapac.base_url = "https://demo.ippayments.com.au/interface/api"
|
||||||
bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/"
|
bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/"
|
||||||
billwerk.base_url = "https://api.reepay.com/"
|
billwerk.base_url = "https://api.reepay.com/"
|
||||||
billwerk.secondary_base_url = "https://card.reepay.com/"
|
billwerk.secondary_base_url = "https://card.reepay.com/"
|
||||||
|
|||||||
@ -30,7 +30,7 @@ airwallex.base_url = "https://api-demo.airwallex.com/"
|
|||||||
applepay.base_url = "https://apple-pay-gateway.apple.com/"
|
applepay.base_url = "https://apple-pay-gateway.apple.com/"
|
||||||
authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api"
|
authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api"
|
||||||
bambora.base_url = "https://api.na.bambora.com"
|
bambora.base_url = "https://api.na.bambora.com"
|
||||||
bamboraapac.base_url = "https://demo.ippayments.com.au/interface/api/dts.asmx"
|
bamboraapac.base_url = "https://demo.ippayments.com.au/interface/api"
|
||||||
bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/"
|
bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/"
|
||||||
billwerk.base_url = "https://api.reepay.com/"
|
billwerk.base_url = "https://api.reepay.com/"
|
||||||
billwerk.secondary_base_url = "https://card.reepay.com/"
|
billwerk.secondary_base_url = "https://card.reepay.com/"
|
||||||
|
|||||||
@ -182,7 +182,7 @@ airwallex.base_url = "https://api-demo.airwallex.com/"
|
|||||||
applepay.base_url = "https://apple-pay-gateway.apple.com/"
|
applepay.base_url = "https://apple-pay-gateway.apple.com/"
|
||||||
authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api"
|
authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api"
|
||||||
bambora.base_url = "https://api.na.bambora.com"
|
bambora.base_url = "https://api.na.bambora.com"
|
||||||
bamboraapac.base_url = "https://demo.ippayments.com.au/interface/api/dts.asmx"
|
bamboraapac.base_url = "https://demo.ippayments.com.au/interface/api"
|
||||||
bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/"
|
bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/"
|
||||||
billwerk.base_url = "https://api.reepay.com/"
|
billwerk.base_url = "https://api.reepay.com/"
|
||||||
billwerk.secondary_base_url = "https://card.reepay.com/"
|
billwerk.secondary_base_url = "https://card.reepay.com/"
|
||||||
|
|||||||
@ -115,7 +115,7 @@ airwallex.base_url = "https://api-demo.airwallex.com/"
|
|||||||
applepay.base_url = "https://apple-pay-gateway.apple.com/"
|
applepay.base_url = "https://apple-pay-gateway.apple.com/"
|
||||||
authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api"
|
authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api"
|
||||||
bambora.base_url = "https://api.na.bambora.com"
|
bambora.base_url = "https://api.na.bambora.com"
|
||||||
bamboraapac.base_url = "https://demo.bambora.co.nz/interface/api/dts.asmx"
|
bamboraapac.base_url = "https://demo.ippayments.com.au/interface/api"
|
||||||
bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/"
|
bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/"
|
||||||
billwerk.base_url = "https://api.reepay.com/"
|
billwerk.base_url = "https://api.reepay.com/"
|
||||||
billwerk.secondary_base_url = "https://card.reepay.com/"
|
billwerk.secondary_base_url = "https://card.reepay.com/"
|
||||||
|
|||||||
@ -92,6 +92,22 @@ impl ConnectorValidation for Bamboraapac {
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn validate_mandate_payment(
|
||||||
|
&self,
|
||||||
|
_pm_type: Option<enums::PaymentMethodType>,
|
||||||
|
pm_data: types::domain::payments::PaymentMethodData,
|
||||||
|
) -> CustomResult<(), errors::ConnectorError> {
|
||||||
|
let connector = self.id();
|
||||||
|
match pm_data {
|
||||||
|
types::domain::payments::PaymentMethodData::Card(_) => Ok(()),
|
||||||
|
_ => Err(errors::ConnectorError::NotSupported {
|
||||||
|
message: "mandate payment".to_string(),
|
||||||
|
connector,
|
||||||
|
}
|
||||||
|
.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConnectorCommon for Bamboraapac {
|
impl ConnectorCommon for Bamboraapac {
|
||||||
@ -167,6 +183,85 @@ impl
|
|||||||
types::PaymentsResponseData,
|
types::PaymentsResponseData,
|
||||||
> for Bamboraapac
|
> for Bamboraapac
|
||||||
{
|
{
|
||||||
|
fn get_headers(
|
||||||
|
&self,
|
||||||
|
req: &types::SetupMandateRouterData,
|
||||||
|
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::SetupMandateRouterData,
|
||||||
|
connectors: &settings::Connectors,
|
||||||
|
) -> CustomResult<String, errors::ConnectorError> {
|
||||||
|
Ok(format!("{}/sipp.asmx", self.base_url(connectors)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_request_body(
|
||||||
|
&self,
|
||||||
|
req: &types::SetupMandateRouterData,
|
||||||
|
_connectors: &settings::Connectors,
|
||||||
|
) -> CustomResult<RequestContent, errors::ConnectorError> {
|
||||||
|
let connector_req = bamboraapac::get_setup_mandate_body(req)?;
|
||||||
|
|
||||||
|
Ok(RequestContent::RawBytes(connector_req))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_request(
|
||||||
|
&self,
|
||||||
|
req: &types::SetupMandateRouterData,
|
||||||
|
connectors: &settings::Connectors,
|
||||||
|
) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
|
||||||
|
Ok(Some(
|
||||||
|
services::RequestBuilder::new()
|
||||||
|
.method(services::Method::Post)
|
||||||
|
.url(&types::SetupMandateType::get_url(self, req, connectors)?)
|
||||||
|
.attach_default_headers()
|
||||||
|
.headers(types::SetupMandateType::get_headers(self, req, connectors)?)
|
||||||
|
.set_body(types::SetupMandateType::get_request_body(
|
||||||
|
self, req, connectors,
|
||||||
|
)?)
|
||||||
|
.build(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_response(
|
||||||
|
&self,
|
||||||
|
data: &types::SetupMandateRouterData,
|
||||||
|
event_builder: Option<&mut ConnectorEvent>,
|
||||||
|
res: Response,
|
||||||
|
) -> CustomResult<types::SetupMandateRouterData, errors::ConnectorError> {
|
||||||
|
let response_data = html_to_xml_string_conversion(
|
||||||
|
String::from_utf8(res.response.to_vec())
|
||||||
|
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?,
|
||||||
|
);
|
||||||
|
|
||||||
|
let response = response_data
|
||||||
|
.parse_xml::<bamboraapac::BamboraapacMandateResponse>()
|
||||||
|
.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::Authorize, types::PaymentsAuthorizeData, types::PaymentsResponseData>
|
impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::PaymentsResponseData>
|
||||||
@ -189,7 +284,7 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P
|
|||||||
_req: &types::PaymentsAuthorizeRouterData,
|
_req: &types::PaymentsAuthorizeRouterData,
|
||||||
connectors: &settings::Connectors,
|
connectors: &settings::Connectors,
|
||||||
) -> CustomResult<String, errors::ConnectorError> {
|
) -> CustomResult<String, errors::ConnectorError> {
|
||||||
Ok(self.base_url(connectors).to_string())
|
Ok(format!("{}/dts.asmx", self.base_url(connectors)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_request_body(
|
fn get_request_body(
|
||||||
@ -284,7 +379,7 @@ impl ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsRe
|
|||||||
_req: &types::PaymentsSyncRouterData,
|
_req: &types::PaymentsSyncRouterData,
|
||||||
connectors: &settings::Connectors,
|
connectors: &settings::Connectors,
|
||||||
) -> CustomResult<String, errors::ConnectorError> {
|
) -> CustomResult<String, errors::ConnectorError> {
|
||||||
Ok(self.base_url(connectors).to_string())
|
Ok(format!("{}/dts.asmx", self.base_url(connectors)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_request_body(
|
fn get_request_body(
|
||||||
@ -368,7 +463,7 @@ impl ConnectorIntegration<api::Capture, types::PaymentsCaptureData, types::Payme
|
|||||||
_req: &types::PaymentsCaptureRouterData,
|
_req: &types::PaymentsCaptureRouterData,
|
||||||
connectors: &settings::Connectors,
|
connectors: &settings::Connectors,
|
||||||
) -> CustomResult<String, errors::ConnectorError> {
|
) -> CustomResult<String, errors::ConnectorError> {
|
||||||
Ok(self.base_url(connectors).to_string())
|
Ok(format!("{}/dts.asmx", self.base_url(connectors)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_request_body(
|
fn get_request_body(
|
||||||
@ -467,7 +562,7 @@ impl ConnectorIntegration<api::Execute, types::RefundsData, types::RefundsRespon
|
|||||||
_req: &types::RefundExecuteRouterData,
|
_req: &types::RefundExecuteRouterData,
|
||||||
connectors: &settings::Connectors,
|
connectors: &settings::Connectors,
|
||||||
) -> CustomResult<String, errors::ConnectorError> {
|
) -> CustomResult<String, errors::ConnectorError> {
|
||||||
Ok(self.base_url(connectors).to_string())
|
Ok(format!("{}/dts.asmx", self.base_url(connectors)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_request_body(
|
fn get_request_body(
|
||||||
@ -560,7 +655,7 @@ impl ConnectorIntegration<api::RSync, types::RefundsData, types::RefundsResponse
|
|||||||
_req: &types::RefundSyncRouterData,
|
_req: &types::RefundSyncRouterData,
|
||||||
connectors: &settings::Connectors,
|
connectors: &settings::Connectors,
|
||||||
) -> CustomResult<String, errors::ConnectorError> {
|
) -> CustomResult<String, errors::ConnectorError> {
|
||||||
Ok(self.base_url(connectors).to_string())
|
Ok(format!("{}/dts.asmx", self.base_url(connectors)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_request_body(
|
fn get_request_body(
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use masking::{PeekInterface, Secret};
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
connector::utils::{self, CardData, RouterData},
|
connector::utils::{self, CardData, PaymentsAuthorizeRequestData, RouterData},
|
||||||
core::errors,
|
core::errors,
|
||||||
types::{self, domain, storage::enums, transformers::ForeignFrom},
|
types::{self, domain, storage::enums, transformers::ForeignFrom},
|
||||||
};
|
};
|
||||||
@ -94,6 +94,25 @@ fn get_card_data(req: &types::PaymentsAuthorizeRouterData) -> Result<String, Err
|
|||||||
let card_holder_name = req.get_billing_full_name()?;
|
let card_holder_name = req.get_billing_full_name()?;
|
||||||
let card_data = match &req.request.payment_method_data {
|
let card_data = match &req.request.payment_method_data {
|
||||||
domain::PaymentMethodData::Card(card) => {
|
domain::PaymentMethodData::Card(card) => {
|
||||||
|
if req.request.setup_future_usage == Some(enums::FutureUsage::OffSession) {
|
||||||
|
format!(
|
||||||
|
r#"
|
||||||
|
<CreditCard Registered="False">
|
||||||
|
<TokeniseAlgorithmID>2</TokeniseAlgorithmID>
|
||||||
|
<CardNumber>{}</CardNumber>
|
||||||
|
<ExpM>{}</ExpM>
|
||||||
|
<ExpY>{}</ExpY>
|
||||||
|
<CVN>{}</CVN>
|
||||||
|
<CardHolderName>{}</CardHolderName>
|
||||||
|
</CreditCard>
|
||||||
|
"#,
|
||||||
|
card.card_number.get_card_no(),
|
||||||
|
card.card_exp_month.peek(),
|
||||||
|
card.get_expiry_year_4_digit().peek(),
|
||||||
|
card.card_cvc.peek(),
|
||||||
|
card_holder_name.peek(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
format!(
|
format!(
|
||||||
r#"
|
r#"
|
||||||
<CreditCard Registered="False">
|
<CreditCard Registered="False">
|
||||||
@ -111,6 +130,18 @@ fn get_card_data(req: &types::PaymentsAuthorizeRouterData) -> Result<String, Err
|
|||||||
card_holder_name.peek(),
|
card_holder_name.peek(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
domain::PaymentMethodData::MandatePayment => {
|
||||||
|
format!(
|
||||||
|
r#"
|
||||||
|
<CreditCard>
|
||||||
|
<TokeniseAlgorithmID>2</TokeniseAlgorithmID>
|
||||||
|
<CardNumber>{}</CardNumber>
|
||||||
|
</CreditCard>
|
||||||
|
"#,
|
||||||
|
req.request.get_connector_mandate_id()?
|
||||||
|
)
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(errors::ConnectorError::NotImplemented(
|
return Err(errors::ConnectorError::NotImplemented(
|
||||||
utils::get_unimplemented_payment_method_error_message("Bambora APAC"),
|
utils::get_unimplemented_payment_method_error_message("Bambora APAC"),
|
||||||
@ -182,6 +213,7 @@ pub struct SubmitSinglePaymentResult {
|
|||||||
pub struct PaymentResponse {
|
pub struct PaymentResponse {
|
||||||
response_code: u8,
|
response_code: u8,
|
||||||
receipt: String,
|
receipt: String,
|
||||||
|
credit_card_token: Option<String>,
|
||||||
declined_code: Option<String>,
|
declined_code: Option<String>,
|
||||||
declined_message: Option<String>,
|
declined_message: Option<String>,
|
||||||
}
|
}
|
||||||
@ -234,6 +266,23 @@ impl<F>
|
|||||||
.submit_single_payment_result
|
.submit_single_payment_result
|
||||||
.response
|
.response
|
||||||
.receipt;
|
.receipt;
|
||||||
|
|
||||||
|
let mandate_reference =
|
||||||
|
if item.data.request.setup_future_usage == Some(enums::FutureUsage::OffSession) {
|
||||||
|
let connector_mandate_id = item
|
||||||
|
.response
|
||||||
|
.body
|
||||||
|
.submit_single_payment_response
|
||||||
|
.submit_single_payment_result
|
||||||
|
.response
|
||||||
|
.credit_card_token;
|
||||||
|
Some(types::MandateReference {
|
||||||
|
connector_mandate_id,
|
||||||
|
payment_method_id: None,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
// transaction approved
|
// transaction approved
|
||||||
if response_code == 0 {
|
if response_code == 0 {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@ -243,7 +292,7 @@ impl<F>
|
|||||||
connector_transaction_id.to_owned(),
|
connector_transaction_id.to_owned(),
|
||||||
),
|
),
|
||||||
redirection_data: None,
|
redirection_data: None,
|
||||||
mandate_reference: None,
|
mandate_reference,
|
||||||
connector_metadata: None,
|
connector_metadata: None,
|
||||||
network_txn_id: None,
|
network_txn_id: None,
|
||||||
connector_response_reference_id: Some(connector_transaction_id),
|
connector_response_reference_id: Some(connector_transaction_id),
|
||||||
@ -288,6 +337,159 @@ impl<F>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_setup_mandate_body(req: &types::SetupMandateRouterData) -> Result<Vec<u8>, Error> {
|
||||||
|
let card_holder_name = req.get_billing_full_name()?;
|
||||||
|
let auth_details = BamboraapacAuthType::try_from(&req.connector_auth_type)?;
|
||||||
|
let body = match &req.request.payment_method_data {
|
||||||
|
domain::PaymentMethodData::Card(card) => {
|
||||||
|
format!(
|
||||||
|
r#"
|
||||||
|
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
|
||||||
|
xmlns:sipp="http://www.ippayments.com.au/interface/api/sipp">
|
||||||
|
<soapenv:Header/>
|
||||||
|
<soapenv:Body>
|
||||||
|
<sipp:TokeniseCreditCard>
|
||||||
|
<sipp:tokeniseCreditCardXML>
|
||||||
|
<![CDATA[
|
||||||
|
<TokeniseCreditCard>
|
||||||
|
<CardNumber>{}</CardNumber>
|
||||||
|
<ExpM>{}</ExpM>
|
||||||
|
<ExpY>{}</ExpY>
|
||||||
|
<CardHolderName>{}</CardHolderName>
|
||||||
|
<TokeniseAlgorithmID>2</TokeniseAlgorithmID>
|
||||||
|
<UserName>{}</UserName>
|
||||||
|
<Password>{}</Password>
|
||||||
|
</TokeniseCreditCard>
|
||||||
|
]]>
|
||||||
|
</sipp:tokeniseCreditCardXML>
|
||||||
|
</sipp:TokeniseCreditCard>
|
||||||
|
</soapenv:Body>
|
||||||
|
</soapenv:Envelope>
|
||||||
|
"#,
|
||||||
|
card.card_number.get_card_no(),
|
||||||
|
card.card_exp_month.peek(),
|
||||||
|
card.get_expiry_year_4_digit().peek(),
|
||||||
|
card_holder_name.peek(),
|
||||||
|
auth_details.username.peek(),
|
||||||
|
auth_details.password.peek(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return Err(errors::ConnectorError::NotImplemented(
|
||||||
|
utils::get_unimplemented_payment_method_error_message("Bambora APAC"),
|
||||||
|
))?;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(body.as_bytes().to_vec())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(rename = "Envelope")]
|
||||||
|
#[serde(rename_all = "PascalCase")]
|
||||||
|
pub struct BamboraapacMandateResponse {
|
||||||
|
body: MandateBodyResponse,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "PascalCase")]
|
||||||
|
pub struct MandateBodyResponse {
|
||||||
|
tokenise_credit_card_response: TokeniseCreditCardResponse,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "PascalCase")]
|
||||||
|
pub struct TokeniseCreditCardResponse {
|
||||||
|
tokenise_credit_card_result: TokeniseCreditCardResult,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "PascalCase")]
|
||||||
|
pub struct TokeniseCreditCardResult {
|
||||||
|
tokenise_credit_card_response: MandateResponseBody,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "PascalCase")]
|
||||||
|
pub struct MandateResponseBody {
|
||||||
|
return_value: u8,
|
||||||
|
token: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F>
|
||||||
|
TryFrom<
|
||||||
|
types::ResponseRouterData<
|
||||||
|
F,
|
||||||
|
BamboraapacMandateResponse,
|
||||||
|
types::SetupMandateRequestData,
|
||||||
|
types::PaymentsResponseData,
|
||||||
|
>,
|
||||||
|
> for types::RouterData<F, types::SetupMandateRequestData, types::PaymentsResponseData>
|
||||||
|
{
|
||||||
|
type Error = error_stack::Report<errors::ConnectorError>;
|
||||||
|
fn try_from(
|
||||||
|
item: types::ResponseRouterData<
|
||||||
|
F,
|
||||||
|
BamboraapacMandateResponse,
|
||||||
|
types::SetupMandateRequestData,
|
||||||
|
types::PaymentsResponseData,
|
||||||
|
>,
|
||||||
|
) -> Result<Self, Self::Error> {
|
||||||
|
let response_code = item
|
||||||
|
.response
|
||||||
|
.body
|
||||||
|
.tokenise_credit_card_response
|
||||||
|
.tokenise_credit_card_result
|
||||||
|
.tokenise_credit_card_response
|
||||||
|
.return_value;
|
||||||
|
|
||||||
|
let connector_mandate_id = item
|
||||||
|
.response
|
||||||
|
.body
|
||||||
|
.tokenise_credit_card_response
|
||||||
|
.tokenise_credit_card_result
|
||||||
|
.tokenise_credit_card_response
|
||||||
|
.token
|
||||||
|
.ok_or(errors::ConnectorError::MissingConnectorMandateID)?;
|
||||||
|
|
||||||
|
// transaction approved
|
||||||
|
if response_code == 0 {
|
||||||
|
Ok(Self {
|
||||||
|
status: enums::AttemptStatus::Charged,
|
||||||
|
response: Ok(types::PaymentsResponseData::TransactionResponse {
|
||||||
|
resource_id: types::ResponseId::NoResponseId,
|
||||||
|
redirection_data: None,
|
||||||
|
mandate_reference: Some(types::MandateReference {
|
||||||
|
connector_mandate_id: Some(connector_mandate_id),
|
||||||
|
payment_method_id: None,
|
||||||
|
}),
|
||||||
|
connector_metadata: None,
|
||||||
|
network_txn_id: None,
|
||||||
|
connector_response_reference_id: None,
|
||||||
|
incremental_authorization_allowed: None,
|
||||||
|
charge_id: None,
|
||||||
|
}),
|
||||||
|
..item.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// transaction failed
|
||||||
|
else {
|
||||||
|
Ok(Self {
|
||||||
|
status: enums::AttemptStatus::Failure,
|
||||||
|
response: Err(types::ErrorResponse {
|
||||||
|
status_code: item.http_code,
|
||||||
|
code: consts::NO_ERROR_CODE.to_string(),
|
||||||
|
message: consts::NO_ERROR_MESSAGE.to_string(),
|
||||||
|
reason: None,
|
||||||
|
attempt_status: None,
|
||||||
|
connector_transaction_id: None,
|
||||||
|
}),
|
||||||
|
..item.data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// capture body in soap format
|
// capture body in soap format
|
||||||
pub fn get_capture_body(
|
pub fn get_capture_body(
|
||||||
req: &BamboraapacRouterData<&types::PaymentsCaptureRouterData>,
|
req: &BamboraapacRouterData<&types::PaymentsCaptureRouterData>,
|
||||||
|
|||||||
@ -80,7 +80,7 @@ airwallex.base_url = "https://api-demo.airwallex.com/"
|
|||||||
applepay.base_url = "https://apple-pay-gateway.apple.com/"
|
applepay.base_url = "https://apple-pay-gateway.apple.com/"
|
||||||
authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api"
|
authorizedotnet.base_url = "https://apitest.authorize.net/xml/v1/request.api"
|
||||||
bambora.base_url = "https://api.na.bambora.com"
|
bambora.base_url = "https://api.na.bambora.com"
|
||||||
bamboraapac.base_url = "https://demo.ippayments.com.au/interface/api/dts.asmx"
|
bamboraapac.base_url = "https://demo.ippayments.com.au/interface/api"
|
||||||
bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/"
|
bankofamerica.base_url = "https://apitest.merchant-services.bankofamerica.com/"
|
||||||
billwerk.base_url = "https://api.reepay.com/"
|
billwerk.base_url = "https://api.reepay.com/"
|
||||||
billwerk.secondary_base_url = "https://card.reepay.com/"
|
billwerk.secondary_base_url = "https://card.reepay.com/"
|
||||||
|
|||||||
Reference in New Issue
Block a user