Repository: juspay/hyperswitch
File: crates/hyperswitch_connectors/src/connectors/adyen.rs (Rust)

Code before:
    ) -> CustomResult<
        Option<api_models::payment_methods::PaymentMethodUpdate>,
        errors::ConnectorError,
    > {
        let notif = get_webhook_object_from_body(request.body)
            .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?;

        let card_expiry_in_parts = notif
            .additional_data
            .expiry_date // expiry_date is of format: "M/YYYY"
            .map(|date| {
                date.expose()
                    .split('/')
                    .map(|s| s.to_string())
                    .collect::<Vec<String>>()
            })
            .ok_or(errors::ConnectorError::ParsingFailed)?;

        if card_expiry_in_parts.len() == 2 {
            // Parse month as integer and format back as 2 digits
            let month = card_expiry_in_parts
                .get(1)
                .ok_or(errors::ConnectorError::ParsingFailed)?
                .parse::<u32>()
                .change_context(errors::ConnectorError::ParsingFailed)?;
            let month_str = Secret::new(format!("{:02}", month));

            // Parse year as integer and take last 2 digits
            let year = card_expiry_in_parts
                .get(2)
                .ok_or(errors::ConnectorError::ParsingFailed)?
                .parse::<u32>()
                .change_context(errors::ConnectorError::ParsingFailed)?;
            let year_str = Secret::new(format!("{:02}", year % 100));
            Ok(Some(api_models::payment_methods::PaymentMethodUpdate {
                card: Some(api_models::payment_methods::CardDetailUpdate {
                    card_exp_month: Some(month_str),
                    card_exp_year: Some(year_str),
                    card_holder_name: None,
                    nick_name: None,
                    issuer_country: notif.additional_data.card_issuing_country.clone(),
                    card_issuer: notif.additional_data.card_issuing_bank.clone(),
                    last4_digits: notif
                        .additional_data
                        .card_summary
                        .map(|last4| last4.expose().to_string()),
                }),
                client_secret: None,
            }))
        } else {
            Ok(None)

Review comment (suggestion):
Is it always 2 characters? Let's make sure we handle all the cases

`M/YY`
`MM/YY`
`M/YYYY`
`MM/YYYY`

Code after:
        // for capture_event, original_reference field will have the authorized payment's PSP reference
        if adyen::is_capture_or_cancel_or_adjust_event(&notif.event_code) {
            return Ok(api_models::webhooks::ObjectReferenceId::PaymentId(
                api_models::payments::PaymentIdType::ConnectorTransactionId(
                    notif
                        .original_reference
                        .ok_or(errors::ConnectorError::WebhookReferenceIdNotFound)?,
                ),
            ));
        }
        if adyen::is_transaction_event(&notif.event_code) {
            return Ok(api_models::webhooks::ObjectReferenceId::PaymentId(
                api_models::payments::PaymentIdType::PaymentAttemptId(notif.merchant_reference),
            ));
        }
        if adyen::is_refund_event(&notif.event_code) {
            return Ok(api_models::webhooks::ObjectReferenceId::RefundId(
                api_models::webhooks::RefundIdType::RefundId(notif.merchant_reference),
            ));
        }
        if adyen::is_chargeback_event(&notif.event_code) {
            return Ok(api_models::webhooks::ObjectReferenceId::PaymentId(
                api_models::payments::PaymentIdType::ConnectorTransactionId(
                    notif
                        .original_reference
                        .ok_or(errors::ConnectorError::WebhookReferenceIdNotFound)?,
                ),
            ));
        }
        #[cfg(feature = "payouts")]
        if adyen::is_payout_event(&notif.event_code) {
            return Ok(api_models::webhooks::ObjectReferenceId::PayoutId(
                api_models::webhooks::PayoutIdType::PayoutAttemptId(notif.merchant_reference),
            ));
        }
        Err(report!(errors::ConnectorError::WebhookReferenceIdNotFound))
    }

    fn get_webhook_event_type(
        &self,
        request: &IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<api_models::webhooks::IncomingWebhookEvent, errors::ConnectorError> {
        let notif = get_webhook_object_from_body(request.body)
            .change_context(errors::ConnectorError::WebhookEventTypeNotFound)?;

        Ok(transformers::get_adyen_webhook_event(
            notif.event_code,
            notif.success,
            notif.additional_data.dispute_status,
        ))
    }