mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-04 05:59:48 +08:00
feat(connector): [Nexixpay] add mandates flow for cards (#6259)
Co-authored-by: Mrudul Vajpayee <mrudul.vajpayee@mrudulvajpayee-XJWXCWP7HF.local>
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
pub mod transformers;
|
||||
use std::collections::HashSet;
|
||||
|
||||
use common_enums::enums;
|
||||
use common_utils::{
|
||||
@ -9,6 +10,7 @@ use common_utils::{
|
||||
};
|
||||
use error_stack::{report, ResultExt};
|
||||
use hyperswitch_domain_models::{
|
||||
payment_method_data::PaymentMethodData,
|
||||
router_data::{AccessToken, ConnectorAuthType, ErrorResponse, RouterData},
|
||||
router_flow_types::{
|
||||
access_token_auth::AccessTokenAuth,
|
||||
@ -46,7 +48,7 @@ use uuid::Uuid;
|
||||
use crate::{
|
||||
constants::headers,
|
||||
types::ResponseRouterData,
|
||||
utils::{self, RefundsRequestData},
|
||||
utils::{self, PaymentMethodDataType, RefundsRequestData},
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -212,6 +214,15 @@ impl ConnectorValidation for Nexixpay {
|
||||
),
|
||||
}
|
||||
}
|
||||
fn validate_mandate_payment(
|
||||
&self,
|
||||
pm_type: Option<enums::PaymentMethodType>,
|
||||
pm_data: PaymentMethodData,
|
||||
) -> CustomResult<(), errors::ConnectorError> {
|
||||
let mandate_supported_pmd: HashSet<PaymentMethodDataType> =
|
||||
HashSet::from([PaymentMethodDataType::Card]);
|
||||
utils::is_mandate_supported(pm_data, pm_type, mandate_supported_pmd, self.id())
|
||||
}
|
||||
}
|
||||
|
||||
impl ConnectorIntegration<Session, PaymentsSessionData, PaymentsResponseData> for Nexixpay {}
|
||||
@ -415,11 +426,15 @@ impl ConnectorIntegration<Authorize, PaymentsAuthorizeData, PaymentsResponseData
|
||||
|
||||
fn get_url(
|
||||
&self,
|
||||
_req: &PaymentsAuthorizeRouterData,
|
||||
req: &PaymentsAuthorizeRouterData,
|
||||
connectors: &Connectors,
|
||||
) -> CustomResult<String, errors::ConnectorError> {
|
||||
if req.request.off_session == Some(true) {
|
||||
Ok(format!("{}/orders/mit", self.base_url(connectors)))
|
||||
} else {
|
||||
Ok(format!("{}/orders/3steps/init", self.base_url(connectors)))
|
||||
}
|
||||
}
|
||||
|
||||
fn get_request_body(
|
||||
&self,
|
||||
|
||||
@ -14,7 +14,9 @@ use hyperswitch_domain_models::{
|
||||
CompleteAuthorizeData, PaymentsAuthorizeData, PaymentsCancelData, PaymentsCaptureData,
|
||||
PaymentsPreProcessingData, PaymentsSyncData, ResponseId,
|
||||
},
|
||||
router_response_types::{PaymentsResponseData, RedirectForm, RefundsResponseData},
|
||||
router_response_types::{
|
||||
MandateReference, PaymentsResponseData, RedirectForm, RefundsResponseData,
|
||||
},
|
||||
types::{
|
||||
PaymentsAuthorizeRouterData, PaymentsCancelRouterData, PaymentsCaptureRouterData,
|
||||
PaymentsCompleteAuthorizeRouterData, PaymentsPreProcessingRouterData, RefundsRouterData,
|
||||
@ -47,11 +49,58 @@ impl<T> From<(StringMinorUnit, T)> for NexixpayRouterData<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||
pub enum NexixpayRecurringAction {
|
||||
NoRecurring,
|
||||
SubsequentPayment,
|
||||
ContractCreation,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||
pub enum ContractType {
|
||||
MitUnscheduled,
|
||||
MitScheduled,
|
||||
Cit,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct RecurrenceRequest {
|
||||
action: NexixpayRecurringAction,
|
||||
contract_id: Secret<String>,
|
||||
contract_type: ContractType,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct NexixpayNonMandatePaymentRequest {
|
||||
card: NexixpayCard,
|
||||
recurrence: Option<RecurrenceRequest>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct NexixpayMandatePaymentRequest {
|
||||
contract_id: Secret<String>,
|
||||
capture_type: Option<NexixpayCaptureType>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(untagged)]
|
||||
pub enum NexixpayPaymentsRequestData {
|
||||
NexixpayNonMandatePaymentRequest(Box<NexixpayNonMandatePaymentRequest>),
|
||||
NexixpayMandatePaymentRequest(Box<NexixpayMandatePaymentRequest>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct NexixpayPaymentsRequest {
|
||||
order: Order,
|
||||
card: NexixpayCard,
|
||||
#[serde(flatten)]
|
||||
payment_data: NexixpayPaymentsRequestData,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
@ -69,6 +118,7 @@ pub struct NexixpayCompleteAuthorizeRequest {
|
||||
operation_id: String,
|
||||
capture_type: Option<NexixpayCaptureType>,
|
||||
three_d_s_auth_data: ThreeDSAuthData,
|
||||
recurrence: Option<RecurrenceRequest>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
@ -108,13 +158,13 @@ pub struct Order {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CustomerInfo {
|
||||
card_holder_name: Secret<String>,
|
||||
billing_address: Address,
|
||||
shipping_address: Option<Address>,
|
||||
billing_address: BillingAddress,
|
||||
shipping_address: Option<ShippingAddress>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Address {
|
||||
pub struct BillingAddress {
|
||||
name: Secret<String>,
|
||||
street: Secret<String>,
|
||||
city: String,
|
||||
@ -122,6 +172,16 @@ pub struct Address {
|
||||
country: enums::CountryAlpha2,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ShippingAddress {
|
||||
name: Option<Secret<String>>,
|
||||
street: Option<Secret<String>>,
|
||||
city: Option<String>,
|
||||
post_code: Option<Secret<String>>,
|
||||
country: Option<enums::CountryAlpha2>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct NexixpayCard {
|
||||
@ -137,12 +197,26 @@ struct Recurrence {
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct NexixpayPaymentsResponse {
|
||||
pub struct PaymentsResponse {
|
||||
operation: Operation,
|
||||
three_d_s_auth_request: String,
|
||||
three_d_s_auth_url: Secret<url::Url>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct NexixpayMandateResponse {
|
||||
operation: Operation,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(untagged)]
|
||||
pub enum NexixpayPaymentsResponse {
|
||||
PaymentResponse(Box<PaymentsResponse>),
|
||||
MandateResponse(Box<NexixpayMandateResponse>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ThreeDSAuthResult {
|
||||
@ -371,23 +445,47 @@ impl TryFrom<&NexixpayRouterData<&PaymentsAuthorizeRouterData>> for NexixpayPaym
|
||||
fn try_from(
|
||||
item: &NexixpayRouterData<&PaymentsAuthorizeRouterData>,
|
||||
) -> Result<Self, Self::Error> {
|
||||
match item.router_data.request.payment_method_data {
|
||||
PaymentMethodData::Card(ref req_card) => {
|
||||
let card = NexixpayCard {
|
||||
pan: req_card.card_number.clone(),
|
||||
expiry_date: req_card.get_expiry_date_as_mmyy()?,
|
||||
};
|
||||
let billing_address = Address {
|
||||
let billing_address_street = format!(
|
||||
"{}, {}",
|
||||
item.router_data.get_billing_line1()?.expose(),
|
||||
item.router_data.get_billing_line2()?.expose()
|
||||
);
|
||||
|
||||
let billing_address = BillingAddress {
|
||||
name: item.router_data.get_billing_full_name()?,
|
||||
street: item.router_data.get_billing_line1()?,
|
||||
street: Secret::new(billing_address_street),
|
||||
city: item.router_data.get_billing_city()?,
|
||||
post_code: item.router_data.get_billing_zip()?,
|
||||
country: item.router_data.get_billing_country()?,
|
||||
};
|
||||
let shipping_address_street = match (
|
||||
item.router_data.get_optional_shipping_line1(),
|
||||
item.router_data.get_optional_shipping_line2(),
|
||||
) {
|
||||
(Some(line1), Some(line2)) => Some(Secret::new(format!(
|
||||
"{}, {}",
|
||||
line1.expose(),
|
||||
line2.expose()
|
||||
))),
|
||||
(Some(line1), None) => Some(Secret::new(line1.expose())),
|
||||
(None, Some(line2)) => Some(Secret::new(line2.expose())),
|
||||
(None, None) => None,
|
||||
};
|
||||
|
||||
let shipping_address = item
|
||||
.router_data
|
||||
.get_optional_billing()
|
||||
.map(|_| ShippingAddress {
|
||||
name: item.router_data.get_optional_shipping_full_name(),
|
||||
street: shipping_address_street,
|
||||
city: item.router_data.get_optional_shipping_city(),
|
||||
post_code: item.router_data.get_optional_shipping_zip(),
|
||||
country: item.router_data.get_optional_shipping_country(),
|
||||
});
|
||||
let customer_info = CustomerInfo {
|
||||
card_holder_name: item.router_data.get_billing_full_name()?,
|
||||
billing_address: billing_address.clone(),
|
||||
shipping_address: Some(billing_address),
|
||||
shipping_address: shipping_address.clone(),
|
||||
};
|
||||
let order = Order {
|
||||
order_id: item.router_data.connector_request_reference_id.clone(),
|
||||
@ -396,7 +494,63 @@ impl TryFrom<&NexixpayRouterData<&PaymentsAuthorizeRouterData>> for NexixpayPaym
|
||||
description: item.router_data.description.clone(),
|
||||
customer_info,
|
||||
};
|
||||
Ok(Self { order, card })
|
||||
let payment_data = NexixpayPaymentsRequestData::try_from(item)?;
|
||||
Ok(Self {
|
||||
order,
|
||||
payment_data,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&NexixpayRouterData<&PaymentsAuthorizeRouterData>> for NexixpayPaymentsRequestData {
|
||||
type Error = error_stack::Report<errors::ConnectorError>;
|
||||
fn try_from(
|
||||
item: &NexixpayRouterData<&PaymentsAuthorizeRouterData>,
|
||||
) -> Result<Self, Self::Error> {
|
||||
match item
|
||||
.router_data
|
||||
.request
|
||||
.mandate_id
|
||||
.clone()
|
||||
.and_then(|mandate_id| mandate_id.mandate_reference_id)
|
||||
{
|
||||
None => {
|
||||
let recurrence_request_obj = if item.router_data.request.is_mandate_payment() {
|
||||
let contract_id = item
|
||||
.router_data
|
||||
.connector_mandate_request_reference_id
|
||||
.clone()
|
||||
.ok_or_else(|| errors::ConnectorError::MissingRequiredField {
|
||||
field_name: "connector_mandate_request_reference_id",
|
||||
})?;
|
||||
Some(RecurrenceRequest {
|
||||
action: NexixpayRecurringAction::ContractCreation,
|
||||
contract_id: Secret::new(contract_id),
|
||||
contract_type: ContractType::MitUnscheduled,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
match item.router_data.request.payment_method_data {
|
||||
PaymentMethodData::Card(ref req_card) => {
|
||||
if item.router_data.is_three_ds() {
|
||||
Ok(Self::NexixpayNonMandatePaymentRequest(Box::new(
|
||||
NexixpayNonMandatePaymentRequest {
|
||||
card: NexixpayCard {
|
||||
pan: req_card.card_number.clone(),
|
||||
expiry_date: req_card.get_expiry_date_as_mmyy()?,
|
||||
},
|
||||
recurrence: recurrence_request_obj,
|
||||
},
|
||||
)))
|
||||
} else {
|
||||
Err(errors::ConnectorError::NotSupported {
|
||||
message: "No threeds is not supported".to_string(),
|
||||
connector: "nexixpay",
|
||||
}
|
||||
.into())
|
||||
}
|
||||
}
|
||||
PaymentMethodData::CardRedirect(_)
|
||||
| PaymentMethodData::Wallet(_)
|
||||
@ -408,20 +562,44 @@ impl TryFrom<&NexixpayRouterData<&PaymentsAuthorizeRouterData>> for NexixpayPaym
|
||||
| PaymentMethodData::MandatePayment
|
||||
| PaymentMethodData::Reward
|
||||
| PaymentMethodData::RealTimePayment(_)
|
||||
| PaymentMethodData::MobilePayment(_)
|
||||
| PaymentMethodData::Upi(_)
|
||||
| PaymentMethodData::MobilePayment(_)
|
||||
| PaymentMethodData::Voucher(_)
|
||||
| PaymentMethodData::GiftCard(_)
|
||||
| PaymentMethodData::OpenBanking(_)
|
||||
| PaymentMethodData::CardToken(_)
|
||||
| PaymentMethodData::NetworkToken(_)
|
||||
| PaymentMethodData::CardDetailsForNetworkTransactionId(_) => {
|
||||
| PaymentMethodData::CardDetailsForNetworkTransactionId(_)
|
||||
| PaymentMethodData::NetworkToken(_) => {
|
||||
Err(errors::ConnectorError::NotImplemented(
|
||||
get_unimplemented_payment_method_error_message("nexixpay"),
|
||||
))?
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(api_models::payments::MandateReferenceId::ConnectorMandateId(mandate_data)) => {
|
||||
let contract_id = Secret::new(
|
||||
mandate_data
|
||||
.get_connector_mandate_request_reference_id()
|
||||
.ok_or(errors::ConnectorError::MissingConnectorMandateID)?,
|
||||
);
|
||||
let capture_type =
|
||||
get_nexixpay_capture_type(item.router_data.request.capture_method)?;
|
||||
Ok(Self::NexixpayMandatePaymentRequest(Box::new(
|
||||
NexixpayMandatePaymentRequest {
|
||||
contract_id,
|
||||
capture_type,
|
||||
},
|
||||
)))
|
||||
}
|
||||
Some(api_models::payments::MandateReferenceId::NetworkTokenWithNTI(_))
|
||||
| Some(api_models::payments::MandateReferenceId::NetworkMandateId(_)) => {
|
||||
Err(errors::ConnectorError::NotImplemented(
|
||||
get_unimplemented_payment_method_error_message("nexixpay"),
|
||||
)
|
||||
.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct NexixpayAuthType {
|
||||
@ -598,11 +776,17 @@ impl<F>
|
||||
PaymentsResponseData,
|
||||
>,
|
||||
) -> Result<Self, Self::Error> {
|
||||
match item.response {
|
||||
NexixpayPaymentsResponse::PaymentResponse(ref response_body) => {
|
||||
let complete_authorize_url = item.data.request.get_complete_authorize_url()?;
|
||||
let operation_id: String = item.response.operation.operation_id;
|
||||
let operation_id: String = response_body.operation.operation_id.clone();
|
||||
let redirection_form = nexixpay_threeds_link(NexixpayRedirectionRequest {
|
||||
three_d_s_auth_url: item.response.three_d_s_auth_url.expose().to_string(),
|
||||
three_ds_request: item.response.three_d_s_auth_request.clone(),
|
||||
three_d_s_auth_url: response_body
|
||||
.three_d_s_auth_url
|
||||
.clone()
|
||||
.expose()
|
||||
.to_string(),
|
||||
three_ds_request: response_body.three_d_s_auth_request.clone(),
|
||||
return_url: complete_authorize_url.clone(),
|
||||
transaction_id: operation_id.clone(),
|
||||
})?;
|
||||
@ -622,22 +806,52 @@ impl<F>
|
||||
psync_flow: NexixpayPaymentIntent::Authorize
|
||||
}));
|
||||
Ok(Self {
|
||||
status: AttemptStatus::from(item.response.operation.operation_result),
|
||||
status: AttemptStatus::from(response_body.operation.operation_result.clone()),
|
||||
response: Ok(PaymentsResponseData::TransactionResponse {
|
||||
resource_id: ResponseId::ConnectorTransactionId(
|
||||
item.response.operation.order_id.clone(),
|
||||
response_body.operation.order_id.clone(),
|
||||
),
|
||||
redirection_data: Box::new(Some(redirection_form.clone())),
|
||||
mandate_reference: Box::new(None),
|
||||
mandate_reference: Box::new(Some(MandateReference {
|
||||
connector_mandate_id: item
|
||||
.data
|
||||
.connector_mandate_request_reference_id
|
||||
.clone(),
|
||||
payment_method_id: None,
|
||||
mandate_metadata: None,
|
||||
connector_mandate_request_reference_id: None,
|
||||
})),
|
||||
connector_metadata,
|
||||
network_txn_id: None,
|
||||
connector_response_reference_id: Some(item.response.operation.order_id),
|
||||
connector_response_reference_id: Some(
|
||||
response_body.operation.order_id.clone(),
|
||||
),
|
||||
incremental_authorization_allowed: None,
|
||||
charge_id: None,
|
||||
}),
|
||||
..item.data
|
||||
})
|
||||
}
|
||||
NexixpayPaymentsResponse::MandateResponse(ref mandate_response) => Ok(Self {
|
||||
status: AttemptStatus::from(mandate_response.operation.operation_result.clone()),
|
||||
response: Ok(PaymentsResponseData::TransactionResponse {
|
||||
resource_id: ResponseId::ConnectorTransactionId(
|
||||
mandate_response.operation.order_id.clone(),
|
||||
),
|
||||
redirection_data: Box::new(None),
|
||||
mandate_reference: Box::new(None),
|
||||
connector_metadata: None,
|
||||
network_txn_id: None,
|
||||
connector_response_reference_id: Some(
|
||||
mandate_response.operation.order_id.clone(),
|
||||
),
|
||||
incremental_authorization_allowed: None,
|
||||
charge_id: None,
|
||||
}),
|
||||
..item.data
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn nexixpay_threeds_link(
|
||||
@ -738,7 +952,6 @@ impl<F>
|
||||
meta_data,
|
||||
is_auto_capture,
|
||||
})?);
|
||||
|
||||
Ok(Self {
|
||||
status: AttemptStatus::from(item.response.operation.operation_result),
|
||||
response: Ok(PaymentsResponseData::TransactionResponse {
|
||||
@ -746,7 +959,12 @@ impl<F>
|
||||
item.response.operation.order_id.clone(),
|
||||
),
|
||||
redirection_data: Box::new(None),
|
||||
mandate_reference: Box::new(None),
|
||||
mandate_reference: Box::new(Some(MandateReference {
|
||||
connector_mandate_id: item.data.connector_mandate_request_reference_id.clone(),
|
||||
payment_method_id: None,
|
||||
mandate_metadata: None,
|
||||
connector_mandate_request_reference_id: None,
|
||||
})),
|
||||
connector_metadata,
|
||||
network_txn_id: None,
|
||||
connector_response_reference_id: Some(item.response.operation.order_id),
|
||||
@ -775,17 +993,47 @@ impl TryFrom<&NexixpayRouterData<&PaymentsCompleteAuthorizeRouterData>>
|
||||
|
||||
let order_id = item.router_data.connector_request_reference_id.clone();
|
||||
let amount = item.amount.clone();
|
||||
let billing_address = Address {
|
||||
let billing_address_street = format!(
|
||||
"{}, {}",
|
||||
item.router_data.get_billing_line1()?.expose(),
|
||||
item.router_data.get_billing_line2()?.expose()
|
||||
);
|
||||
|
||||
let billing_address = BillingAddress {
|
||||
name: item.router_data.get_billing_full_name()?,
|
||||
street: item.router_data.get_billing_line1()?,
|
||||
street: Secret::new(billing_address_street),
|
||||
city: item.router_data.get_billing_city()?,
|
||||
post_code: item.router_data.get_billing_zip()?,
|
||||
country: item.router_data.get_billing_country()?,
|
||||
};
|
||||
let shipping_address_street = match (
|
||||
item.router_data.get_optional_shipping_line1(),
|
||||
item.router_data.get_optional_shipping_line2(),
|
||||
) {
|
||||
(Some(line1), Some(line2)) => Some(Secret::new(format!(
|
||||
"{}, {}",
|
||||
line1.expose(),
|
||||
line2.expose()
|
||||
))),
|
||||
(Some(line1), None) => Some(Secret::new(line1.expose())),
|
||||
(None, Some(line2)) => Some(Secret::new(line2.expose())),
|
||||
(None, None) => None,
|
||||
};
|
||||
|
||||
let shipping_address = item
|
||||
.router_data
|
||||
.get_optional_billing()
|
||||
.map(|_| ShippingAddress {
|
||||
name: item.router_data.get_optional_shipping_full_name(),
|
||||
street: shipping_address_street,
|
||||
city: item.router_data.get_optional_shipping_city(),
|
||||
post_code: item.router_data.get_optional_shipping_zip(),
|
||||
country: item.router_data.get_optional_shipping_country(),
|
||||
});
|
||||
let customer_info = CustomerInfo {
|
||||
card_holder_name: item.router_data.get_billing_full_name()?,
|
||||
billing_address: billing_address.clone(),
|
||||
shipping_address: Some(billing_address),
|
||||
shipping_address: shipping_address.clone(),
|
||||
};
|
||||
let order_data = Order {
|
||||
order_id,
|
||||
@ -841,12 +1089,25 @@ impl TryFrom<&NexixpayRouterData<&PaymentsCompleteAuthorizeRouterData>>
|
||||
.into())
|
||||
}
|
||||
};
|
||||
let contract_id = Secret::new(
|
||||
item.router_data
|
||||
.connector_mandate_request_reference_id
|
||||
.clone()
|
||||
.ok_or_else(|| errors::ConnectorError::MissingRequiredField {
|
||||
field_name: "connector_mandate_request_reference_id",
|
||||
})?,
|
||||
);
|
||||
Ok(Self {
|
||||
order: order_data,
|
||||
card: card?,
|
||||
operation_id,
|
||||
capture_type,
|
||||
three_d_s_auth_data,
|
||||
recurrence: Some(RecurrenceRequest {
|
||||
action: NexixpayRecurringAction::ContractCreation,
|
||||
contract_id,
|
||||
contract_type: ContractType::MitUnscheduled,
|
||||
}),
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -870,7 +1131,12 @@ impl<F>
|
||||
response: Ok(PaymentsResponseData::TransactionResponse {
|
||||
resource_id: ResponseId::ConnectorTransactionId(item.response.order_id.clone()),
|
||||
redirection_data: Box::new(None),
|
||||
mandate_reference: Box::new(None),
|
||||
mandate_reference: Box::new(Some(MandateReference {
|
||||
connector_mandate_id: item.data.connector_mandate_request_reference_id.clone(),
|
||||
payment_method_id: None,
|
||||
mandate_metadata: None,
|
||||
connector_mandate_request_reference_id: None,
|
||||
})),
|
||||
connector_metadata: item.data.request.connector_meta.clone(),
|
||||
network_txn_id: None,
|
||||
connector_response_reference_id: Some(item.response.order_id.clone()),
|
||||
|
||||
@ -300,6 +300,7 @@ pub trait RouterData {
|
||||
fn get_optional_shipping_state(&self) -> Option<Secret<String>>;
|
||||
fn get_optional_shipping_first_name(&self) -> Option<Secret<String>>;
|
||||
fn get_optional_shipping_last_name(&self) -> Option<Secret<String>>;
|
||||
fn get_optional_shipping_full_name(&self) -> Option<Secret<String>>;
|
||||
fn get_optional_shipping_phone_number(&self) -> Option<Secret<String>>;
|
||||
fn get_optional_shipping_email(&self) -> Option<Email>;
|
||||
|
||||
@ -369,6 +370,12 @@ impl<Flow, Request, Response> RouterData
|
||||
})
|
||||
}
|
||||
|
||||
fn get_optional_shipping_full_name(&self) -> Option<Secret<String>> {
|
||||
self.get_optional_shipping()
|
||||
.and_then(|shipping_details| shipping_details.address.as_ref())
|
||||
.and_then(|shipping_address| shipping_address.get_optional_full_name())
|
||||
}
|
||||
|
||||
fn get_optional_shipping_line1(&self) -> Option<Secret<String>> {
|
||||
self.address.get_shipping().and_then(|shipping_address| {
|
||||
shipping_address
|
||||
@ -1177,6 +1184,7 @@ pub trait PaymentsAuthorizeRequestData {
|
||||
fn get_card_holder_name_from_additional_payment_method_data(
|
||||
&self,
|
||||
) -> Result<Secret<String>, Error>;
|
||||
fn get_connector_mandate_request_reference_id(&self) -> Result<String, Error>;
|
||||
}
|
||||
|
||||
impl PaymentsAuthorizeRequestData for PaymentsAuthorizeData {
|
||||
@ -1355,6 +1363,20 @@ impl PaymentsAuthorizeRequestData for PaymentsAuthorizeData {
|
||||
.into()),
|
||||
}
|
||||
}
|
||||
/// Attempts to retrieve the connector mandate reference ID as a `Result<String, Error>`.
|
||||
fn get_connector_mandate_request_reference_id(&self) -> Result<String, Error> {
|
||||
self.mandate_id
|
||||
.as_ref()
|
||||
.and_then(|mandate_ids| match &mandate_ids.mandate_reference_id {
|
||||
Some(payments::MandateReferenceId::ConnectorMandateId(connector_mandate_ids)) => {
|
||||
connector_mandate_ids.get_connector_mandate_request_reference_id()
|
||||
}
|
||||
Some(payments::MandateReferenceId::NetworkMandateId(_))
|
||||
| None
|
||||
| Some(payments::MandateReferenceId::NetworkTokenWithNTI(_)) => None,
|
||||
})
|
||||
.ok_or_else(missing_field_err("connector_mandate_request_reference_id"))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait PaymentsCaptureRequestData {
|
||||
@ -1514,6 +1536,7 @@ pub trait PaymentsCompleteAuthorizeRequestData {
|
||||
fn get_redirect_response_payload(&self) -> Result<pii::SecretSerdeValue, Error>;
|
||||
fn get_complete_authorize_url(&self) -> Result<String, Error>;
|
||||
fn is_mandate_payment(&self) -> bool;
|
||||
fn get_connector_mandate_request_reference_id(&self) -> Result<String, Error>;
|
||||
}
|
||||
|
||||
impl PaymentsCompleteAuthorizeRequestData for CompleteAuthorizeData {
|
||||
@ -1554,6 +1577,20 @@ impl PaymentsCompleteAuthorizeRequestData for CompleteAuthorizeData {
|
||||
.and_then(|mandate_ids| mandate_ids.mandate_reference_id.as_ref())
|
||||
.is_some()
|
||||
}
|
||||
/// Attempts to retrieve the connector mandate reference ID as a `Result<String, Error>`.
|
||||
fn get_connector_mandate_request_reference_id(&self) -> Result<String, Error> {
|
||||
self.mandate_id
|
||||
.as_ref()
|
||||
.and_then(|mandate_ids| match &mandate_ids.mandate_reference_id {
|
||||
Some(payments::MandateReferenceId::ConnectorMandateId(connector_mandate_ids)) => {
|
||||
connector_mandate_ids.get_connector_mandate_request_reference_id()
|
||||
}
|
||||
Some(payments::MandateReferenceId::NetworkMandateId(_))
|
||||
| None
|
||||
| Some(payments::MandateReferenceId::NetworkTokenWithNTI(_)) => None,
|
||||
})
|
||||
.ok_or_else(missing_field_err("connector_mandate_request_reference_id"))
|
||||
}
|
||||
}
|
||||
pub trait AddressData {
|
||||
fn get_optional_full_name(&self) -> Option<Secret<String>>;
|
||||
|
||||
@ -1952,6 +1952,98 @@ impl Default for settings::RequiredFields {
|
||||
),
|
||||
}
|
||||
),
|
||||
(
|
||||
enums::Connector::Nexixpay,
|
||||
RequiredFieldFinal {
|
||||
mandate: HashMap::new(),
|
||||
non_mandate: HashMap::new(),
|
||||
common: HashMap::from(
|
||||
[
|
||||
(
|
||||
"payment_method_data.card.card_number".to_string(),
|
||||
RequiredFieldInfo {
|
||||
required_field: "payment_method_data.card.card_number".to_string(),
|
||||
display_name: "card_number".to_string(),
|
||||
field_type: enums::FieldType::UserCardNumber,
|
||||
value: None,
|
||||
}
|
||||
),
|
||||
(
|
||||
"payment_method_data.card.card_exp_month".to_string(),
|
||||
RequiredFieldInfo {
|
||||
required_field: "payment_method_data.card.card_exp_month".to_string(),
|
||||
display_name: "card_exp_month".to_string(),
|
||||
field_type: enums::FieldType::UserCardExpiryMonth,
|
||||
value: None,
|
||||
}
|
||||
),
|
||||
(
|
||||
"payment_method_data.card.card_exp_year".to_string(),
|
||||
RequiredFieldInfo {
|
||||
required_field: "payment_method_data.card.card_exp_year".to_string(),
|
||||
display_name: "card_exp_year".to_string(),
|
||||
field_type: enums::FieldType::UserCardExpiryYear,
|
||||
value: None,
|
||||
}
|
||||
),
|
||||
(
|
||||
"billing.address.line1".to_string(),
|
||||
RequiredFieldInfo {
|
||||
required_field: "payment_method_data.billing.address.line1".to_string(),
|
||||
display_name: "line1".to_string(),
|
||||
field_type: enums::FieldType::UserAddressLine1,
|
||||
value: None,
|
||||
}
|
||||
),
|
||||
(
|
||||
"billing.address.line2".to_string(),
|
||||
RequiredFieldInfo {
|
||||
required_field: "payment_method_data.billing.address.line2".to_string(),
|
||||
display_name: "line1".to_string(),
|
||||
field_type: enums::FieldType::UserAddressLine2,
|
||||
value: None,
|
||||
}
|
||||
),
|
||||
(
|
||||
"billing.address.city".to_string(),
|
||||
RequiredFieldInfo {
|
||||
required_field: "payment_method_data.billing.address.city".to_string(),
|
||||
display_name: "city".to_string(),
|
||||
field_type: enums::FieldType::UserAddressCity,
|
||||
value: None,
|
||||
}
|
||||
),
|
||||
(
|
||||
"billing.address.zip".to_string(),
|
||||
RequiredFieldInfo {
|
||||
required_field: "payment_method_data.billing.address.zip".to_string(),
|
||||
display_name: "zip".to_string(),
|
||||
field_type: enums::FieldType::UserAddressPincode,
|
||||
value: None,
|
||||
}
|
||||
),
|
||||
(
|
||||
"billing.address.first_name".to_string(),
|
||||
RequiredFieldInfo {
|
||||
required_field: "payment_method_data.billing.address.first_name".to_string(),
|
||||
display_name: "first_name".to_string(),
|
||||
field_type: enums::FieldType::UserFullName,
|
||||
value: None,
|
||||
}
|
||||
),
|
||||
(
|
||||
"billing.address.last_name".to_string(),
|
||||
RequiredFieldInfo {
|
||||
required_field: "payment_method_data.billing.address.last_name".to_string(),
|
||||
display_name: "last_name".to_string(),
|
||||
field_type: enums::FieldType::UserFullName,
|
||||
value: None,
|
||||
}
|
||||
)
|
||||
]
|
||||
),
|
||||
}
|
||||
),
|
||||
(
|
||||
enums::Connector::Nmi,
|
||||
RequiredFieldFinal {
|
||||
|
||||
@ -1,19 +1,84 @@
|
||||
const successfulNo3DSCardDetails = {
|
||||
card_number: "4111111111111111",
|
||||
card_exp_month: "08",
|
||||
card_exp_year: "35",
|
||||
card_holder_name: "joseph Doe",
|
||||
card_cvc: "999",
|
||||
};
|
||||
|
||||
const successfulThreeDSTestCardDetails = {
|
||||
card_number: "4349940199004549",
|
||||
card_exp_month: "12",
|
||||
card_exp_year: "30",
|
||||
card_exp_year: "35",
|
||||
card_holder_name: "joseph Doe",
|
||||
card_cvc: "396",
|
||||
};
|
||||
|
||||
const customerAcceptance = {
|
||||
acceptance_type: "offline",
|
||||
accepted_at: "1963-05-03T04:07:52.723Z",
|
||||
online: {
|
||||
ip_address: "125.0.0.1",
|
||||
user_agent: "amet irure esse",
|
||||
},
|
||||
};
|
||||
|
||||
const multiUseMandateData = {
|
||||
customer_acceptance: customerAcceptance,
|
||||
mandate_type: {
|
||||
multi_use: {
|
||||
amount: 8000,
|
||||
currency: "EUR",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const singleUseMandateData = {
|
||||
customer_acceptance: customerAcceptance,
|
||||
mandate_type: {
|
||||
multi_use: {
|
||||
amount: 8000,
|
||||
currency: "EUR",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const billingAddress = {
|
||||
address: {
|
||||
line1: "1467",
|
||||
line2: "Harrison Street",
|
||||
line3: "Harrison Street",
|
||||
city: "San Fransico",
|
||||
state: "California",
|
||||
zip: "94122",
|
||||
country: "IT",
|
||||
first_name: "joseph",
|
||||
last_name: "Doe",
|
||||
},
|
||||
email: "mauro.morandi@nexi.it",
|
||||
phone: {
|
||||
number: "9123456789",
|
||||
country_code: "+91",
|
||||
},
|
||||
};
|
||||
|
||||
const no3DSNotSupportedResponseBody = {
|
||||
error: {
|
||||
type: "invalid_request",
|
||||
message: "No threeds is not supported",
|
||||
code: "IR_00",
|
||||
},
|
||||
};
|
||||
|
||||
export const connectorDetails = {
|
||||
card_pm: {
|
||||
PaymentIntent: {
|
||||
Request: {
|
||||
currency: "EUR",
|
||||
amount: 3545,
|
||||
amount: 6500,
|
||||
customer_acceptance: null,
|
||||
setup_future_usage: "on_session",
|
||||
billing: billingAddress,
|
||||
},
|
||||
Response: {
|
||||
status: 200,
|
||||
@ -22,61 +87,29 @@ export const connectorDetails = {
|
||||
},
|
||||
},
|
||||
},
|
||||
"3DSManualCapture": {
|
||||
PaymentIntentOffSession: {
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
billing: {
|
||||
address: {
|
||||
line1: "1467",
|
||||
line2: "CA",
|
||||
line3: "CA",
|
||||
city: "Florence",
|
||||
state: "Tuscany",
|
||||
zip: "12345",
|
||||
country: "IT",
|
||||
first_name: "Max",
|
||||
last_name: "Mustermann",
|
||||
},
|
||||
email: "mauro.morandi@nexi.it",
|
||||
phone: {
|
||||
number: "9123456789",
|
||||
country_code: "+91",
|
||||
},
|
||||
},
|
||||
payment_method_data: {
|
||||
card: successfulThreeDSTestCardDetails,
|
||||
},
|
||||
currency: "EUR",
|
||||
amount: 6500,
|
||||
authentication_type: "no_three_ds",
|
||||
customer_acceptance: null,
|
||||
setup_future_usage: "on_session",
|
||||
setup_future_usage: "off_session",
|
||||
},
|
||||
Response: {
|
||||
status: 200,
|
||||
body: {
|
||||
status: "requires_capture",
|
||||
status: "requires_payment_method",
|
||||
setup_future_usage: "off_session",
|
||||
},
|
||||
},
|
||||
},
|
||||
"3DSAutoCapture": {
|
||||
"3DSManualCapture": {
|
||||
Configs: {
|
||||
TRIGGER_SKIP: true,
|
||||
},
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
billing: {
|
||||
address: {
|
||||
line1: "1467",
|
||||
line2: "CA",
|
||||
line3: "CA",
|
||||
city: "Florence",
|
||||
state: "Tuscany",
|
||||
zip: "12345",
|
||||
country: "IT",
|
||||
first_name: "Max",
|
||||
last_name: "Mustermann",
|
||||
},
|
||||
email: "mauro.morandi@nexi.it",
|
||||
phone: {
|
||||
number: "9123456789",
|
||||
country_code: "+91",
|
||||
},
|
||||
},
|
||||
billing: billingAddress,
|
||||
payment_method_data: {
|
||||
card: successfulThreeDSTestCardDetails,
|
||||
},
|
||||
@ -90,7 +123,62 @@ export const connectorDetails = {
|
||||
},
|
||||
},
|
||||
},
|
||||
"3DSAutoCapture": {
|
||||
Configs: {
|
||||
TRIGGER_SKIP: true,
|
||||
},
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
billing: billingAddress,
|
||||
payment_method_data: {
|
||||
card: successfulThreeDSTestCardDetails,
|
||||
},
|
||||
customer_acceptance: null,
|
||||
setup_future_usage: "on_session",
|
||||
},
|
||||
Response: {
|
||||
status: 200,
|
||||
body: {
|
||||
status: "requires_customer_action",
|
||||
},
|
||||
},
|
||||
},
|
||||
No3DSManualCapture: {
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
payment_method_data: {
|
||||
card: successfulNo3DSCardDetails,
|
||||
},
|
||||
currency: "EUR",
|
||||
customer_acceptance: null,
|
||||
setup_future_usage: "on_session",
|
||||
billing: billingAddress,
|
||||
},
|
||||
Response: {
|
||||
status: 400,
|
||||
body: no3DSNotSupportedResponseBody,
|
||||
},
|
||||
},
|
||||
No3DSAutoCapture: {
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
payment_method_data: {
|
||||
card: successfulNo3DSCardDetails,
|
||||
},
|
||||
currency: "EUR",
|
||||
customer_acceptance: null,
|
||||
setup_future_usage: "on_session",
|
||||
billing: billingAddress,
|
||||
},
|
||||
Response: {
|
||||
status: 400,
|
||||
body: no3DSNotSupportedResponseBody,
|
||||
},
|
||||
},
|
||||
Capture: {
|
||||
Configs: {
|
||||
TRIGGER_SKIP: true,
|
||||
},
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
payment_method_data: {
|
||||
@ -102,20 +190,23 @@ export const connectorDetails = {
|
||||
status: 200,
|
||||
body: {
|
||||
status: "processing",
|
||||
amount: 3545,
|
||||
amount_capturable: 0,
|
||||
amount_received: 3545,
|
||||
amount: 6500,
|
||||
amount_capturable: 6500,
|
||||
amount_received: null,
|
||||
},
|
||||
},
|
||||
},
|
||||
PartialCapture: {
|
||||
Configs: {
|
||||
TRIGGER_SKIP: true,
|
||||
},
|
||||
Request: {},
|
||||
Response: {
|
||||
status: 200,
|
||||
body: {
|
||||
status: "processing",
|
||||
amount: 3545,
|
||||
amount_capturable: 0,
|
||||
amount: 6500,
|
||||
amount_capturable: 6500,
|
||||
amount_received: 100,
|
||||
},
|
||||
},
|
||||
@ -130,6 +221,9 @@ export const connectorDetails = {
|
||||
},
|
||||
},
|
||||
Refund: {
|
||||
Configs: {
|
||||
TRIGGER_SKIP: true,
|
||||
},
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
payment_method_data: {
|
||||
@ -140,11 +234,14 @@ export const connectorDetails = {
|
||||
Response: {
|
||||
status: 200,
|
||||
body: {
|
||||
status: "processing",
|
||||
status: "pending",
|
||||
},
|
||||
},
|
||||
},
|
||||
PartialRefund: {
|
||||
Configs: {
|
||||
TRIGGER_SKIP: true,
|
||||
},
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
payment_method_data: {
|
||||
@ -155,7 +252,7 @@ export const connectorDetails = {
|
||||
Response: {
|
||||
status: 200,
|
||||
body: {
|
||||
status: "processing",
|
||||
status: "pending",
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -174,5 +271,329 @@ export const connectorDetails = {
|
||||
},
|
||||
},
|
||||
},
|
||||
MandateMultiUse3DSAutoCapture: {
|
||||
Configs: {
|
||||
TRIGGER_SKIP: true,
|
||||
},
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
payment_method_data: {
|
||||
card: successfulThreeDSTestCardDetails,
|
||||
},
|
||||
currency: "EUR",
|
||||
mandate_data: multiUseMandateData,
|
||||
billing: billingAddress,
|
||||
},
|
||||
Response: {
|
||||
status: 200,
|
||||
body: {
|
||||
status: "requires_customer_action",
|
||||
},
|
||||
},
|
||||
},
|
||||
MandateMultiUse3DSManualCapture: {
|
||||
Configs: {
|
||||
TRIGGER_SKIP: true,
|
||||
},
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
payment_method_data: {
|
||||
card: successfulThreeDSTestCardDetails,
|
||||
},
|
||||
currency: "EUR",
|
||||
mandate_data: multiUseMandateData,
|
||||
billing: billingAddress,
|
||||
},
|
||||
Response: {
|
||||
status: 200,
|
||||
body: {
|
||||
status: "requires_customer_action",
|
||||
},
|
||||
},
|
||||
},
|
||||
MandateMultiUseNo3DSAutoCapture: {
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
payment_method_data: {
|
||||
card: successfulNo3DSCardDetails,
|
||||
},
|
||||
currency: "EUR",
|
||||
mandate_data: multiUseMandateData,
|
||||
billing: billingAddress,
|
||||
},
|
||||
Response: {
|
||||
status: 400,
|
||||
body: no3DSNotSupportedResponseBody,
|
||||
},
|
||||
},
|
||||
MandateMultiUseNo3DSManualCapture: {
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
payment_method_data: {
|
||||
card: successfulNo3DSCardDetails,
|
||||
},
|
||||
currency: "EUR",
|
||||
mandate_data: multiUseMandateData,
|
||||
billing: billingAddress,
|
||||
},
|
||||
Response: {
|
||||
status: 400,
|
||||
body: no3DSNotSupportedResponseBody,
|
||||
},
|
||||
},
|
||||
MandateSingleUse3DSAutoCapture: {
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
payment_method_data: {
|
||||
card: successfulThreeDSTestCardDetails,
|
||||
},
|
||||
currency: "EUR",
|
||||
mandate_data: singleUseMandateData,
|
||||
billing: billingAddress,
|
||||
},
|
||||
Response: {
|
||||
status: 200,
|
||||
body: {
|
||||
status: "requires_customer_action",
|
||||
},
|
||||
},
|
||||
},
|
||||
MandateSingleUse3DSManualCapture: {
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
payment_method_data: {
|
||||
card: successfulThreeDSTestCardDetails,
|
||||
},
|
||||
currency: "EUR",
|
||||
mandate_data: singleUseMandateData,
|
||||
billing: billingAddress,
|
||||
},
|
||||
Response: {
|
||||
status: 200,
|
||||
body: {
|
||||
status: "requires_customer_action",
|
||||
},
|
||||
},
|
||||
},
|
||||
MandateSingleUseNo3DSAutoCapture: {
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
payment_method_data: {
|
||||
card: successfulNo3DSCardDetails,
|
||||
},
|
||||
currency: "EUR",
|
||||
mandate_data: singleUseMandateData,
|
||||
billing: billingAddress,
|
||||
},
|
||||
Response: {
|
||||
status: 400,
|
||||
body: no3DSNotSupportedResponseBody,
|
||||
},
|
||||
},
|
||||
MandateSingleUseNo3DSManualCapture: {
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
payment_method_data: {
|
||||
card: successfulNo3DSCardDetails,
|
||||
},
|
||||
currency: "EUR",
|
||||
mandate_data: singleUseMandateData,
|
||||
billing: billingAddress,
|
||||
},
|
||||
Response: {
|
||||
status: 400,
|
||||
body: no3DSNotSupportedResponseBody,
|
||||
},
|
||||
},
|
||||
manualPaymentRefund: {
|
||||
Configs: {
|
||||
TRIGGER_SKIP: true,
|
||||
},
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
payment_method_data: {
|
||||
card: successfulThreeDSTestCardDetails,
|
||||
},
|
||||
currency: "EUR",
|
||||
customer_acceptance: null,
|
||||
},
|
||||
Response: {
|
||||
status: 200,
|
||||
body: {
|
||||
status: "pending",
|
||||
},
|
||||
},
|
||||
},
|
||||
ZeroAuthMandate: {
|
||||
Configs: {
|
||||
TRIGGER_SKIP: true,
|
||||
},
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
payment_method_data: {
|
||||
card: successfulThreeDSTestCardDetails,
|
||||
},
|
||||
currency: "EUR",
|
||||
mandate_data: singleUseMandateData,
|
||||
},
|
||||
Response: {
|
||||
status: 200,
|
||||
body: {
|
||||
status: "processing",
|
||||
},
|
||||
},
|
||||
},
|
||||
PaymentMethodIdMandateNo3DSAutoCapture: {
|
||||
Configs: {
|
||||
TRIGGER_SKIP: true,
|
||||
},
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
payment_method_data: {
|
||||
card: successfulThreeDSTestCardDetails,
|
||||
},
|
||||
currency: "EUR",
|
||||
amount: 6500,
|
||||
mandate_data: null,
|
||||
customer_acceptance: customerAcceptance,
|
||||
},
|
||||
Response: {
|
||||
status: 200,
|
||||
body: {
|
||||
status: "requires_customer_action",
|
||||
},
|
||||
},
|
||||
},
|
||||
PaymentMethodIdMandateNo3DSManualCapture: {
|
||||
Configs: {
|
||||
TRIGGER_SKIP: true,
|
||||
},
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
payment_method_data: {
|
||||
card: successfulThreeDSTestCardDetails,
|
||||
},
|
||||
currency: "EUR",
|
||||
amount: 6500,
|
||||
mandate_data: null,
|
||||
customer_acceptance: customerAcceptance,
|
||||
},
|
||||
Response: {
|
||||
status: 200,
|
||||
body: {
|
||||
status: "requires_customer_action",
|
||||
},
|
||||
},
|
||||
},
|
||||
PaymentMethodIdMandate3DSAutoCapture: {
|
||||
Configs: {
|
||||
TRIGGER_SKIP: true,
|
||||
},
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
payment_method_data: {
|
||||
card: successfulThreeDSTestCardDetails,
|
||||
},
|
||||
currency: "EUR",
|
||||
amount: 6500,
|
||||
mandate_data: null,
|
||||
authentication_type: "three_ds",
|
||||
customer_acceptance: customerAcceptance,
|
||||
},
|
||||
Response: {
|
||||
status: 200,
|
||||
body: {
|
||||
status: "requires_customer_action",
|
||||
},
|
||||
},
|
||||
},
|
||||
PaymentMethodIdMandate3DSManualCapture: {
|
||||
Configs: {
|
||||
TRIGGER_SKIP: true,
|
||||
},
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
payment_method_data: {
|
||||
card: successfulThreeDSTestCardDetails,
|
||||
},
|
||||
currency: "EUR",
|
||||
amount: 6500,
|
||||
mandate_data: null,
|
||||
authentication_type: "three_ds",
|
||||
customer_acceptance: customerAcceptance,
|
||||
},
|
||||
Response: {
|
||||
status: 200,
|
||||
body: {
|
||||
status: "requires_customer_action",
|
||||
},
|
||||
},
|
||||
},
|
||||
SaveCardUseNo3DSAutoCapture: {
|
||||
Configs: {
|
||||
TRIGGER_SKIP: true,
|
||||
},
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
payment_method_type: "debit",
|
||||
payment_method_data: {
|
||||
card: successfulNo3DSCardDetails,
|
||||
},
|
||||
currency: "EUR",
|
||||
billing: billingAddress,
|
||||
setup_future_usage: "on_session",
|
||||
customer_acceptance: customerAcceptance,
|
||||
},
|
||||
Response: {
|
||||
status: 200,
|
||||
body: {
|
||||
status: "requires_customer_action",
|
||||
},
|
||||
},
|
||||
},
|
||||
SaveCardUseNo3DSAutoCaptureOffSession: {
|
||||
Configs: {
|
||||
TRIGGER_SKIP: true,
|
||||
},
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
currency: "EUR",
|
||||
billing: billingAddress,
|
||||
payment_method_type: "debit",
|
||||
payment_method_data: {
|
||||
card: successfulNo3DSCardDetails,
|
||||
},
|
||||
setup_future_usage: "off_session",
|
||||
customer_acceptance: customerAcceptance,
|
||||
},
|
||||
Response: {
|
||||
status: 200,
|
||||
body: {
|
||||
status: "requires_customer_action",
|
||||
},
|
||||
},
|
||||
},
|
||||
SaveCardUseNo3DSManualCaptureOffSession: {
|
||||
Configs: {
|
||||
TRIGGER_SKIP: true,
|
||||
},
|
||||
Request: {
|
||||
payment_method: "card",
|
||||
currency: "EUR",
|
||||
billing: billingAddress,
|
||||
payment_method_type: "debit",
|
||||
payment_method_data: {
|
||||
card: successfulNo3DSCardDetails,
|
||||
},
|
||||
setup_future_usage: "off_session",
|
||||
customer_acceptance: customerAcceptance,
|
||||
},
|
||||
Response: {
|
||||
status: 200,
|
||||
body: {
|
||||
status: "requires_customer_action",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user