feat(core): [Paypal] Add session_token flow for Paypal sdk (#4697)

Co-authored-by: swangi-kumari <swangi.12015941@lpu.in>
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
SamraatBansal
2024-05-27 16:35:07 +05:30
committed by GitHub
parent 8d9c7bc45c
commit b3d4d13db8
28 changed files with 525 additions and 101 deletions

View File

@ -1012,6 +1012,7 @@ impl PaymentRedirectFlow for PaymentRedirectCompleteAuthorize {
api_models::payments::NextActionData::DisplayVoucherInformation{ .. } => None,
api_models::payments::NextActionData::WaitScreenInformation{..} => None,
api_models::payments::NextActionData::ThreeDsInvoke{..} => None,
api_models::payments::NextActionData::InvokeSdkClient{..} => None,
})
.ok_or(errors::ApiErrorResponse::InternalServerError)

View File

@ -634,6 +634,42 @@ where
) -> RouterResult<Self>;
}
fn create_paypal_sdk_session_token(
_state: &routes::AppState,
router_data: &types::PaymentsSessionRouterData,
connector: &api::ConnectorData,
_business_profile: &storage::business_profile::BusinessProfile,
) -> RouterResult<types::PaymentsSessionRouterData> {
let connector_metadata = router_data.connector_meta_data.clone();
let paypal_sdk_data = connector_metadata
.clone()
.parse_value::<payment_types::PaypalSdkSessionTokenData>("PaypalSdkSessionTokenData")
.change_context(errors::ConnectorError::NoConnectorMetaData)
.attach_printable(format!(
"cannot parse paypal_sdk metadata from the given value {connector_metadata:?}"
))
.change_context(errors::ApiErrorResponse::InvalidDataFormat {
field_name: "connector_metadata".to_string(),
expected_format: "paypal_sdk_metadata_format".to_string(),
})?;
Ok(types::PaymentsSessionRouterData {
response: Ok(types::PaymentsResponseData::SessionResponse {
session_token: payment_types::SessionToken::Paypal(Box::new(
payment_types::PaypalSessionTokenResponse {
connector: connector.connector_name.to_string(),
session_token: paypal_sdk_data.data.client_id,
sdk_next_action: payment_types::SdkNextAction {
next_action: payment_types::NextActionCall::Confirm,
},
},
)),
}),
..router_data.clone()
})
}
#[async_trait]
impl RouterDataSession for types::PaymentsSessionRouterData {
async fn decide_flow<'a, 'b>(
@ -651,6 +687,9 @@ impl RouterDataSession for types::PaymentsSessionRouterData {
api::GetToken::ApplePayMetadata => {
create_applepay_session_token(state, self, connector, business_profile).await
}
api::GetToken::PaypalSdkMetadata => {
create_paypal_sdk_session_token(state, self, connector, business_profile)
}
api::GetToken::Connector => {
let connector_integration: services::BoxedConnectorIntegration<
'_,

View File

@ -471,6 +471,7 @@ impl From<api_models::enums::PaymentMethodType> for api::GetToken {
match value {
api_models::enums::PaymentMethodType::GooglePay => Self::GpayMetadata,
api_models::enums::PaymentMethodType::ApplePay => Self::ApplePayMetadata,
api_models::enums::PaymentMethodType::Paypal => Self::PaypalSdkMetadata,
_ => Self::Connector,
}
}

View File

@ -539,6 +539,8 @@ where
let next_action_containing_qr_code_url = qr_code_next_steps_check(payment_attempt.clone())?;
let papal_sdk_next_action = paypal_sdk_next_steps_check(payment_attempt.clone())?;
let next_action_containing_wait_screen =
wait_screen_next_steps_check(payment_attempt.clone())?;
@ -547,6 +549,7 @@ where
|| next_action_voucher.is_some()
|| next_action_containing_qr_code_url.is_some()
|| next_action_containing_wait_screen.is_some()
|| papal_sdk_next_action.is_some()
|| payment_data.authentication.is_some()
{
next_action_response = bank_transfer_next_steps
@ -563,6 +566,11 @@ where
.or(next_action_containing_qr_code_url.map(|qr_code_data| {
api_models::payments::NextActionData::foreign_from(qr_code_data)
}))
.or(papal_sdk_next_action.map(|paypal_next_action_data| {
api_models::payments::NextActionData::InvokeSdkClient{
next_action_data: paypal_next_action_data
}
}))
.or(next_action_containing_wait_screen.map(|wait_screen_data| {
api_models::payments::NextActionData::WaitScreenInformation {
display_from_timestamp: wait_screen_data.display_from_timestamp,
@ -875,6 +883,21 @@ pub fn qr_code_next_steps_check(
let qr_code_instructions = qr_code_steps.transpose().ok().flatten();
Ok(qr_code_instructions)
}
pub fn paypal_sdk_next_steps_check(
payment_attempt: storage::PaymentAttempt,
) -> RouterResult<Option<api_models::payments::SdkNextActionData>> {
let paypal_connector_metadata: Option<Result<api_models::payments::SdkNextActionData, _>> =
payment_attempt.connector_metadata.map(|metadata| {
metadata.parse_value("SdkNextActionData").map_err(|_| {
crate::logger::warn!(
"SdkNextActionData parsing failed for paypal_connector_metadata"
)
})
});
let paypal_next_steps = paypal_connector_metadata.transpose().ok().flatten();
Ok(paypal_next_steps)
}
pub fn wait_screen_next_steps_check(
payment_attempt: storage::PaymentAttempt,
@ -1275,6 +1298,7 @@ impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::PaymentsSyncData
},
payment_method_type: payment_data.payment_attempt.payment_method_type,
currency: payment_data.currency,
payment_experience: payment_data.payment_attempt.payment_experience,
})
}
}