mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-30 01:27:31 +08:00
feat(connector): [Adyen] Implement Boleto Bancario in Vouchers and Add support for Voucher in Next Action (#1657)
Co-authored-by: Pa1NarK <69745008+pixincreate@users.noreply.github.com>
This commit is contained in:
@ -1187,7 +1187,7 @@ pub struct RewardData {
|
|||||||
pub struct BoletoVoucherData {
|
pub struct BoletoVoucherData {
|
||||||
/// The shopper's social security number
|
/// The shopper's social security number
|
||||||
#[schema(value_type = Option<String>)]
|
#[schema(value_type = Option<String>)]
|
||||||
social_security_number: Option<Secret<String>>,
|
pub social_security_number: Option<Secret<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]
|
#[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]
|
||||||
@ -1371,6 +1371,11 @@ pub enum NextActionData {
|
|||||||
#[schema(value_type = String)]
|
#[schema(value_type = String)]
|
||||||
image_data_url: Url,
|
image_data_url: Url,
|
||||||
},
|
},
|
||||||
|
/// Contains the download url and the reference number for transaction
|
||||||
|
DisplayVoucherInformation {
|
||||||
|
#[schema(value_type = String)]
|
||||||
|
voucher_details: VoucherNextStepData,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]
|
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]
|
||||||
@ -1382,6 +1387,14 @@ pub struct BankTransferNextStepsData {
|
|||||||
pub receiver: ReceiverDetails,
|
pub receiver: ReceiverDetails,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]
|
||||||
|
pub struct VoucherNextStepData {
|
||||||
|
/// Reference number required for the transaction
|
||||||
|
pub reference: String,
|
||||||
|
/// Url to download the payment instruction
|
||||||
|
pub download_url: Option<Url>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||||
pub struct QrCodeNextStepsInstruction {
|
pub struct QrCodeNextStepsInstruction {
|
||||||
pub image_data_url: Url,
|
pub image_data_url: Url,
|
||||||
|
|||||||
@ -770,6 +770,9 @@ pub enum StripeNextAction {
|
|||||||
QrCodeInformation {
|
QrCodeInformation {
|
||||||
image_data_url: url::Url,
|
image_data_url: url::Url,
|
||||||
},
|
},
|
||||||
|
DisplayVoucherInformation {
|
||||||
|
voucher_details: payments::VoucherNextStepData,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn into_stripe_next_action(
|
pub(crate) fn into_stripe_next_action(
|
||||||
@ -796,6 +799,9 @@ pub(crate) fn into_stripe_next_action(
|
|||||||
payments::NextActionData::QrCodeInformation { image_data_url } => {
|
payments::NextActionData::QrCodeInformation { image_data_url } => {
|
||||||
StripeNextAction::QrCodeInformation { image_data_url }
|
StripeNextAction::QrCodeInformation { image_data_url }
|
||||||
}
|
}
|
||||||
|
payments::NextActionData::DisplayVoucherInformation { voucher_details } => {
|
||||||
|
StripeNextAction::DisplayVoucherInformation { voucher_details }
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -371,6 +371,9 @@ pub enum StripeNextAction {
|
|||||||
QrCodeInformation {
|
QrCodeInformation {
|
||||||
image_data_url: url::Url,
|
image_data_url: url::Url,
|
||||||
},
|
},
|
||||||
|
DisplayVoucherInformation {
|
||||||
|
voucher_details: payments::VoucherNextStepData,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn into_stripe_next_action(
|
pub(crate) fn into_stripe_next_action(
|
||||||
@ -397,6 +400,9 @@ pub(crate) fn into_stripe_next_action(
|
|||||||
payments::NextActionData::QrCodeInformation { image_data_url } => {
|
payments::NextActionData::QrCodeInformation { image_data_url } => {
|
||||||
StripeNextAction::QrCodeInformation { image_data_url }
|
StripeNextAction::QrCodeInformation { image_data_url }
|
||||||
}
|
}
|
||||||
|
payments::NextActionData::DisplayVoucherInformation { voucher_details } => {
|
||||||
|
StripeNextAction::DisplayVoucherInformation { voucher_details }
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -122,6 +122,7 @@ pub struct AdyenPaymentRequest<'a> {
|
|||||||
shopper_name: Option<ShopperName>,
|
shopper_name: Option<ShopperName>,
|
||||||
shopper_locale: Option<String>,
|
shopper_locale: Option<String>,
|
||||||
shopper_email: Option<Email>,
|
shopper_email: Option<Email>,
|
||||||
|
social_security_number: Option<Secret<String>>,
|
||||||
telephone_number: Option<Secret<String>>,
|
telephone_number: Option<Secret<String>>,
|
||||||
billing_address: Option<Address>,
|
billing_address: Option<Address>,
|
||||||
delivery_address: Option<Address>,
|
delivery_address: Option<Address>,
|
||||||
@ -155,6 +156,7 @@ pub enum AdyenStatus {
|
|||||||
Received,
|
Received,
|
||||||
RedirectShopper,
|
RedirectShopper,
|
||||||
Refused,
|
Refused,
|
||||||
|
PresentToShopper,
|
||||||
#[cfg(feature = "payouts")]
|
#[cfg(feature = "payouts")]
|
||||||
#[serde(rename = "[payout-confirm-received]")]
|
#[serde(rename = "[payout-confirm-received]")]
|
||||||
PayoutConfirmReceived,
|
PayoutConfirmReceived,
|
||||||
@ -177,7 +179,7 @@ impl ForeignFrom<(bool, AdyenStatus)> for storage_enums::AttemptStatus {
|
|||||||
fn foreign_from((is_manual_capture, adyen_status): (bool, AdyenStatus)) -> Self {
|
fn foreign_from((is_manual_capture, adyen_status): (bool, AdyenStatus)) -> Self {
|
||||||
match adyen_status {
|
match adyen_status {
|
||||||
AdyenStatus::AuthenticationFinished => Self::AuthenticationSuccessful,
|
AdyenStatus::AuthenticationFinished => Self::AuthenticationSuccessful,
|
||||||
AdyenStatus::AuthenticationNotRequired => Self::Pending,
|
AdyenStatus::AuthenticationNotRequired | AdyenStatus::PresentToShopper => Self::Pending,
|
||||||
AdyenStatus::Authorised => match is_manual_capture {
|
AdyenStatus::Authorised => match is_manual_capture {
|
||||||
true => Self::Authorized,
|
true => Self::Authorized,
|
||||||
// In case of Automatic capture Authorized is the final status of the payment
|
// In case of Automatic capture Authorized is the final status of the payment
|
||||||
@ -236,6 +238,7 @@ pub struct AdyenThreeDS {
|
|||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum AdyenPaymentResponse {
|
pub enum AdyenPaymentResponse {
|
||||||
Response(Response),
|
Response(Response),
|
||||||
|
PresentToShopper(AdyenPtsResponse),
|
||||||
NextActionResponse(NextActionResponse),
|
NextActionResponse(NextActionResponse),
|
||||||
RedirectionErrorResponse(RedirectionErrorResponse),
|
RedirectionErrorResponse(RedirectionErrorResponse),
|
||||||
}
|
}
|
||||||
@ -268,6 +271,16 @@ pub struct NextActionResponse {
|
|||||||
refusal_reason_code: Option<String>,
|
refusal_reason_code: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct AdyenPtsResponse {
|
||||||
|
psp_reference: String,
|
||||||
|
result_code: AdyenStatus,
|
||||||
|
action: AdyenPtsAction,
|
||||||
|
refusal_reason: Option<String>,
|
||||||
|
refusal_reason_code: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct AdyenNextAction {
|
pub struct AdyenNextAction {
|
||||||
@ -281,6 +294,20 @@ pub struct AdyenNextAction {
|
|||||||
qr_code_data: Option<String>,
|
qr_code_data: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct AdyenPtsAction {
|
||||||
|
reference: String,
|
||||||
|
download_url: Option<Url>,
|
||||||
|
payment_method_type: Option<String>,
|
||||||
|
expires_at: Option<String>,
|
||||||
|
initial_amount: Option<Amount>,
|
||||||
|
pass_creation_token: Option<String>,
|
||||||
|
total_amount: Option<Amount>,
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
type_of_response: Option<ActionType>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "lowercase")]
|
#[serde(rename_all = "lowercase")]
|
||||||
pub enum ActionType {
|
pub enum ActionType {
|
||||||
@ -288,6 +315,7 @@ pub enum ActionType {
|
|||||||
Await,
|
Await,
|
||||||
#[serde(rename = "qrCode")]
|
#[serde(rename = "qrCode")]
|
||||||
QrCode,
|
QrCode,
|
||||||
|
Voucher,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
|
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
|
||||||
@ -313,6 +341,8 @@ pub enum AdyenPaymentMethod<'a> {
|
|||||||
BancontactCard(Box<BancontactCardData>),
|
BancontactCard(Box<BancontactCardData>),
|
||||||
Bizum(Box<BankRedirectionPMData>),
|
Bizum(Box<BankRedirectionPMData>),
|
||||||
Blik(Box<BlikRedirectionData>),
|
Blik(Box<BlikRedirectionData>),
|
||||||
|
#[serde(rename = "boletobancario")]
|
||||||
|
Boleto,
|
||||||
ClearPay(Box<AdyenPayLaterData>),
|
ClearPay(Box<AdyenPayLaterData>),
|
||||||
Dana(Box<DanaWalletData>),
|
Dana(Box<DanaWalletData>),
|
||||||
Eps(Box<BankRedirectionWithIssuer<'a>>),
|
Eps(Box<BankRedirectionWithIssuer<'a>>),
|
||||||
@ -1047,6 +1077,9 @@ impl<'a> TryFrom<&types::PaymentsAuthorizeRouterData> for AdyenPaymentRequest<'a
|
|||||||
api_models::payments::PaymentMethodData::BankDebit(ref bank_debit) => {
|
api_models::payments::PaymentMethodData::BankDebit(ref bank_debit) => {
|
||||||
AdyenPaymentRequest::try_from((item, bank_debit))
|
AdyenPaymentRequest::try_from((item, bank_debit))
|
||||||
}
|
}
|
||||||
|
api_models::payments::PaymentMethodData::Voucher(ref voucher_data) => {
|
||||||
|
AdyenPaymentRequest::try_from((item, voucher_data))
|
||||||
|
}
|
||||||
_ => Err(errors::ConnectorError::NotSupported {
|
_ => Err(errors::ConnectorError::NotSupported {
|
||||||
message: format!("{:?}", item.request.payment_method_type),
|
message: format!("{:?}", item.request.payment_method_type),
|
||||||
connector: "Adyen",
|
connector: "Adyen",
|
||||||
@ -1230,6 +1263,15 @@ fn get_payout_card_details(payout_method_data: &PayoutMethodData) -> Option<Payo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_social_security_number(
|
||||||
|
voucher_data: &api_models::payments::VoucherData,
|
||||||
|
) -> Option<Secret<String>> {
|
||||||
|
match voucher_data {
|
||||||
|
payments::VoucherData::Boleto(boleto_data) => boleto_data.social_security_number.clone(),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> TryFrom<&api_models::payments::BankDebitData> for AdyenPaymentMethod<'a> {
|
impl<'a> TryFrom<&api_models::payments::BankDebitData> for AdyenPaymentMethod<'a> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
fn try_from(
|
fn try_from(
|
||||||
@ -1289,6 +1331,16 @@ impl<'a> TryFrom<&api_models::payments::BankDebitData> for AdyenPaymentMethod<'a
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> TryFrom<&api_models::payments::VoucherData> for AdyenPaymentMethod<'a> {
|
||||||
|
type Error = Error;
|
||||||
|
fn try_from(voucher_data: &api_models::payments::VoucherData) -> Result<Self, Self::Error> {
|
||||||
|
match voucher_data {
|
||||||
|
payments::VoucherData::Boleto { .. } => Ok(AdyenPaymentMethod::Boleto),
|
||||||
|
_ => Err(errors::ConnectorError::NotImplemented("Payment method".to_string()).into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> TryFrom<&api::Card> for AdyenPaymentMethod<'a> {
|
impl<'a> TryFrom<&api::Card> for AdyenPaymentMethod<'a> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
fn try_from(card: &api::Card) -> Result<Self, Self::Error> {
|
fn try_from(card: &api::Card) -> Result<Self, Self::Error> {
|
||||||
@ -1731,6 +1783,7 @@ impl<'a>
|
|||||||
shopper_name: None,
|
shopper_name: None,
|
||||||
shopper_email: None,
|
shopper_email: None,
|
||||||
shopper_locale: None,
|
shopper_locale: None,
|
||||||
|
social_security_number: None,
|
||||||
billing_address: None,
|
billing_address: None,
|
||||||
delivery_address: None,
|
delivery_address: None,
|
||||||
country_code: None,
|
country_code: None,
|
||||||
@ -1770,6 +1823,7 @@ impl<'a> TryFrom<(&types::PaymentsAuthorizeRouterData, &api::Card)> for AdyenPay
|
|||||||
shopper_name: None,
|
shopper_name: None,
|
||||||
shopper_email: None,
|
shopper_email: None,
|
||||||
shopper_locale: None,
|
shopper_locale: None,
|
||||||
|
social_security_number: None,
|
||||||
billing_address: None,
|
billing_address: None,
|
||||||
delivery_address: None,
|
delivery_address: None,
|
||||||
country_code: None,
|
country_code: None,
|
||||||
@ -1818,6 +1872,7 @@ impl<'a>
|
|||||||
shopper_name: None,
|
shopper_name: None,
|
||||||
shopper_locale: None,
|
shopper_locale: None,
|
||||||
shopper_email: item.request.email.clone(),
|
shopper_email: item.request.email.clone(),
|
||||||
|
social_security_number: None,
|
||||||
telephone_number: None,
|
telephone_number: None,
|
||||||
billing_address: None,
|
billing_address: None,
|
||||||
delivery_address: None,
|
delivery_address: None,
|
||||||
@ -1830,6 +1885,56 @@ impl<'a>
|
|||||||
Ok(request)
|
Ok(request)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl<'a>
|
||||||
|
TryFrom<(
|
||||||
|
&types::PaymentsAuthorizeRouterData,
|
||||||
|
&api_models::payments::VoucherData,
|
||||||
|
)> for AdyenPaymentRequest<'a>
|
||||||
|
{
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn try_from(
|
||||||
|
value: (
|
||||||
|
&types::PaymentsAuthorizeRouterData,
|
||||||
|
&api_models::payments::VoucherData,
|
||||||
|
),
|
||||||
|
) -> Result<Self, Self::Error> {
|
||||||
|
let (item, voucher_data) = value;
|
||||||
|
let amount = get_amount_data(item);
|
||||||
|
let auth_type = AdyenAuthType::try_from(&item.connector_auth_type)?;
|
||||||
|
let shopper_interaction = AdyenShopperInteraction::from(item);
|
||||||
|
let recurring_processing_model = get_recurring_processing_model(item)?.0;
|
||||||
|
let browser_info = get_browser_info(item)?;
|
||||||
|
let additional_data = get_additional_data(item);
|
||||||
|
let payment_method = AdyenPaymentMethod::try_from(voucher_data)?;
|
||||||
|
let return_url = item.request.get_return_url()?;
|
||||||
|
let social_security_number = get_social_security_number(voucher_data);
|
||||||
|
let request = AdyenPaymentRequest {
|
||||||
|
amount,
|
||||||
|
merchant_account: auth_type.merchant_account,
|
||||||
|
payment_method,
|
||||||
|
reference: item.payment_id.to_string(),
|
||||||
|
return_url,
|
||||||
|
browser_info,
|
||||||
|
shopper_interaction,
|
||||||
|
recurring_processing_model,
|
||||||
|
additional_data,
|
||||||
|
shopper_name: None,
|
||||||
|
shopper_locale: None,
|
||||||
|
shopper_email: item.request.email.clone(),
|
||||||
|
social_security_number,
|
||||||
|
telephone_number: None,
|
||||||
|
billing_address: None,
|
||||||
|
delivery_address: None,
|
||||||
|
country_code: None,
|
||||||
|
line_items: None,
|
||||||
|
shopper_reference: None,
|
||||||
|
store_payment_method: None,
|
||||||
|
channel: None,
|
||||||
|
};
|
||||||
|
Ok(request)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a>
|
impl<'a>
|
||||||
TryFrom<(
|
TryFrom<(
|
||||||
@ -1871,6 +1976,7 @@ impl<'a>
|
|||||||
shopper_name: None,
|
shopper_name: None,
|
||||||
shopper_email: item.request.email.clone(),
|
shopper_email: item.request.email.clone(),
|
||||||
shopper_locale,
|
shopper_locale,
|
||||||
|
social_security_number: None,
|
||||||
billing_address: None,
|
billing_address: None,
|
||||||
delivery_address: None,
|
delivery_address: None,
|
||||||
country_code: country,
|
country_code: country,
|
||||||
@ -1956,6 +2062,7 @@ impl<'a> TryFrom<(&types::PaymentsAuthorizeRouterData, &api::WalletData)>
|
|||||||
shopper_name: None,
|
shopper_name: None,
|
||||||
shopper_email,
|
shopper_email,
|
||||||
shopper_locale: None,
|
shopper_locale: None,
|
||||||
|
social_security_number: None,
|
||||||
billing_address: None,
|
billing_address: None,
|
||||||
delivery_address: None,
|
delivery_address: None,
|
||||||
country_code: None,
|
country_code: None,
|
||||||
@ -2005,6 +2112,7 @@ impl<'a> TryFrom<(&types::PaymentsAuthorizeRouterData, &api::PayLaterData)>
|
|||||||
shopper_name,
|
shopper_name,
|
||||||
shopper_email,
|
shopper_email,
|
||||||
shopper_locale: None,
|
shopper_locale: None,
|
||||||
|
social_security_number: None,
|
||||||
billing_address,
|
billing_address,
|
||||||
delivery_address,
|
delivery_address,
|
||||||
country_code,
|
country_code,
|
||||||
@ -2170,6 +2278,58 @@ pub fn get_next_action_response(
|
|||||||
Ok((status, error, payments_response_data))
|
Ok((status, error, payments_response_data))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct AdyenMetaData {
|
||||||
|
download_url: Option<Url>,
|
||||||
|
reference: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_present_to_shopper_response(
|
||||||
|
response: AdyenPtsResponse,
|
||||||
|
is_manual_capture: bool,
|
||||||
|
status_code: u16,
|
||||||
|
) -> errors::CustomResult<
|
||||||
|
(
|
||||||
|
storage_enums::AttemptStatus,
|
||||||
|
Option<types::ErrorResponse>,
|
||||||
|
types::PaymentsResponseData,
|
||||||
|
),
|
||||||
|
errors::ConnectorError,
|
||||||
|
> {
|
||||||
|
let status =
|
||||||
|
storage_enums::AttemptStatus::foreign_from((is_manual_capture, response.result_code));
|
||||||
|
let error = if response.refusal_reason.is_some() || response.refusal_reason_code.is_some() {
|
||||||
|
Some(types::ErrorResponse {
|
||||||
|
code: response
|
||||||
|
.refusal_reason_code
|
||||||
|
.unwrap_or_else(|| consts::NO_ERROR_CODE.to_string()),
|
||||||
|
message: response
|
||||||
|
.refusal_reason
|
||||||
|
.unwrap_or_else(|| consts::NO_ERROR_MESSAGE.to_string()),
|
||||||
|
reason: None,
|
||||||
|
status_code,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let metadata = serde_json::json!(AdyenMetaData {
|
||||||
|
download_url: response.action.download_url,
|
||||||
|
reference: response.action.reference,
|
||||||
|
});
|
||||||
|
|
||||||
|
let payments_response_data = types::PaymentsResponseData::TransactionResponse {
|
||||||
|
resource_id: types::ResponseId::ConnectorTransactionId(response.psp_reference),
|
||||||
|
redirection_data: None,
|
||||||
|
mandate_reference: None,
|
||||||
|
connector_metadata: Some(metadata),
|
||||||
|
network_txn_id: None,
|
||||||
|
connector_response_reference_id: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((status, error, payments_response_data))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_redirection_error_response(
|
pub fn get_redirection_error_response(
|
||||||
response: RedirectionErrorResponse,
|
response: RedirectionErrorResponse,
|
||||||
is_manual_capture: bool,
|
is_manual_capture: bool,
|
||||||
@ -2199,6 +2359,7 @@ pub fn get_redirection_error_response(
|
|||||||
network_txn_id: None,
|
network_txn_id: None,
|
||||||
connector_response_reference_id: None,
|
connector_response_reference_id: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((status, error, payments_response_data))
|
Ok((status, error, payments_response_data))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2257,6 +2418,9 @@ impl<F, Req>
|
|||||||
let item = items.0;
|
let item = items.0;
|
||||||
let is_manual_capture = items.1;
|
let is_manual_capture = items.1;
|
||||||
let (status, error, payment_response_data) = match item.response {
|
let (status, error, payment_response_data) = match item.response {
|
||||||
|
AdyenPaymentResponse::PresentToShopper(response) => {
|
||||||
|
get_present_to_shopper_response(response, is_manual_capture, item.http_code)?
|
||||||
|
}
|
||||||
AdyenPaymentResponse::Response(response) => {
|
AdyenPaymentResponse::Response(response) => {
|
||||||
get_adyen_response(response, is_manual_capture, item.http_code)?
|
get_adyen_response(response, is_manual_capture, item.http_code)?
|
||||||
}
|
}
|
||||||
|
|||||||
@ -429,7 +429,8 @@ impl PaymentRedirectFlow for PaymentRedirectCompleteAuthorize {
|
|||||||
api_models::payments::NextActionData::RedirectToUrl { redirect_to_url } => Some(redirect_to_url),
|
api_models::payments::NextActionData::RedirectToUrl { redirect_to_url } => Some(redirect_to_url),
|
||||||
api_models::payments::NextActionData::DisplayBankTransferInformation { .. } => None,
|
api_models::payments::NextActionData::DisplayBankTransferInformation { .. } => None,
|
||||||
api_models::payments::NextActionData::ThirdPartySdkSessionToken { .. } => None,
|
api_models::payments::NextActionData::ThirdPartySdkSessionToken { .. } => None,
|
||||||
api_models::payments::NextActionData::QrCodeInformation{..} => None
|
api_models::payments::NextActionData::QrCodeInformation{..} => None,
|
||||||
|
api_models::payments::NextActionData::DisplayVoucherInformation{ .. } => None,
|
||||||
})
|
})
|
||||||
.ok_or(errors::ApiErrorResponse::InternalServerError)
|
.ok_or(errors::ApiErrorResponse::InternalServerError)
|
||||||
.into_report()
|
.into_report()
|
||||||
|
|||||||
@ -1442,6 +1442,9 @@ pub(crate) fn validate_payment_method_fields_present(
|
|||||||
) | (
|
) | (
|
||||||
api_enums::PaymentMethod::Upi,
|
api_enums::PaymentMethod::Upi,
|
||||||
api::PaymentMethodData::Upi(..)
|
api::PaymentMethodData::Upi(..)
|
||||||
|
) | (
|
||||||
|
api_enums::PaymentMethod::Voucher,
|
||||||
|
api::PaymentMethodData::Voucher(..)
|
||||||
)
|
)
|
||||||
) | None
|
) | None
|
||||||
),
|
),
|
||||||
|
|||||||
@ -373,11 +373,14 @@ where
|
|||||||
let bank_transfer_next_steps =
|
let bank_transfer_next_steps =
|
||||||
bank_transfer_next_steps_check(payment_attempt.clone())?;
|
bank_transfer_next_steps_check(payment_attempt.clone())?;
|
||||||
|
|
||||||
|
let next_action_voucher = voucher_next_steps_check(payment_attempt.clone())?;
|
||||||
|
|
||||||
let next_action_containing_qr_code =
|
let next_action_containing_qr_code =
|
||||||
qr_code_next_steps_check(payment_attempt.clone())?;
|
qr_code_next_steps_check(payment_attempt.clone())?;
|
||||||
|
|
||||||
if payment_intent.status == enums::IntentStatus::RequiresCustomerAction
|
if payment_intent.status == enums::IntentStatus::RequiresCustomerAction
|
||||||
|| bank_transfer_next_steps.is_some()
|
|| bank_transfer_next_steps.is_some()
|
||||||
|
|| next_action_voucher.is_some()
|
||||||
|| next_action_containing_qr_code.is_some()
|
|| next_action_containing_qr_code.is_some()
|
||||||
{
|
{
|
||||||
next_action_response = bank_transfer_next_steps
|
next_action_response = bank_transfer_next_steps
|
||||||
@ -386,6 +389,11 @@ where
|
|||||||
bank_transfer_steps_and_charges_details: bank_transfer,
|
bank_transfer_steps_and_charges_details: bank_transfer,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.or(next_action_voucher.map(|voucher_data| {
|
||||||
|
api_models::payments::NextActionData::DisplayVoucherInformation {
|
||||||
|
voucher_details: voucher_data,
|
||||||
|
}
|
||||||
|
}))
|
||||||
.or(next_action_containing_qr_code.map(|qr_code_data| {
|
.or(next_action_containing_qr_code.map(|qr_code_data| {
|
||||||
api_models::payments::NextActionData::QrCodeInformation {
|
api_models::payments::NextActionData::QrCodeInformation {
|
||||||
image_data_url: qr_code_data.image_data_url,
|
image_data_url: qr_code_data.image_data_url,
|
||||||
@ -686,6 +694,28 @@ pub fn bank_transfer_next_steps_check(
|
|||||||
Ok(bank_transfer_next_step)
|
Ok(bank_transfer_next_step)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn voucher_next_steps_check(
|
||||||
|
payment_attempt: storage::PaymentAttempt,
|
||||||
|
) -> RouterResult<Option<api_models::payments::VoucherNextStepData>> {
|
||||||
|
let voucher_next_step = if let Some(diesel_models::enums::PaymentMethod::Voucher) =
|
||||||
|
payment_attempt.payment_method
|
||||||
|
{
|
||||||
|
let voucher_next_steps: Option<api_models::payments::VoucherNextStepData> = payment_attempt
|
||||||
|
.connector_metadata
|
||||||
|
.map(|metadata| {
|
||||||
|
metadata
|
||||||
|
.parse_value("NextStepsRequirements")
|
||||||
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
|
.attach_printable("Failed to parse the Value to NextRequirements struct")
|
||||||
|
})
|
||||||
|
.transpose()?;
|
||||||
|
voucher_next_steps
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
Ok(voucher_next_step)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn change_order_details_to_new_type(
|
pub fn change_order_details_to_new_type(
|
||||||
order_amount: i64,
|
order_amount: i64,
|
||||||
order_details: api_models::payments::OrderDetails,
|
order_details: api_models::payments::OrderDetails,
|
||||||
|
|||||||
@ -196,6 +196,7 @@ Never share your secret api keys. Keep them guarded and secure.
|
|||||||
api_models::payments::VoucherData,
|
api_models::payments::VoucherData,
|
||||||
api_models::payments::BoletoVoucherData,
|
api_models::payments::BoletoVoucherData,
|
||||||
api_models::payments::Address,
|
api_models::payments::Address,
|
||||||
|
api_models::payments::VoucherData,
|
||||||
api_models::payments::BankRedirectData,
|
api_models::payments::BankRedirectData,
|
||||||
api_models::payments::BankRedirectBilling,
|
api_models::payments::BankRedirectBilling,
|
||||||
api_models::payments::BankRedirectBilling,
|
api_models::payments::BankRedirectBilling,
|
||||||
|
|||||||
@ -6376,6 +6376,25 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"description": "Contains the download url and the reference number for transaction",
|
||||||
|
"required": [
|
||||||
|
"voucher_details",
|
||||||
|
"type"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"voucher_details": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"display_voucher_information"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"discriminator": {
|
"discriminator": {
|
||||||
|
|||||||
Reference in New Issue
Block a user