2828import com .adyen .model .transferwebhooks .TransferWebhooksHandler ;
2929import com .adyen .util .HMACValidator ;
3030import java .security .SignatureException ;
31+ import java .time .OffsetDateTime ;
3132import java .util .Optional ;
3233import org .junit .jupiter .api .Assertions ;
3334import org .junit .jupiter .api .Test ;
@@ -619,6 +620,11 @@ public void testMandateCreatedNotificationRequest() {
619620 assertEquals (Mandate .StatusEnum .APPROVED , request .getData ().getMandate ().getStatus ());
620621 assertEquals (Mandate .TypeEnum .BACS , request .getData ().getMandate ().getType ());
621622
623+ // createdAt and updatedAt are now deserialized as OffsetDateTime
624+ OffsetDateTime expectedDate = OffsetDateTime .parse ("2025-09-04T13:40:41.581Z" );
625+ assertEquals (expectedDate , request .getData ().getMandate ().getCreatedAt ());
626+ assertEquals (expectedDate , request .getData ().getMandate ().getUpdatedAt ());
627+
622628 assertNotNull (request .getData ().getMandate ().getCounterparty ());
623629 assertNotNull (request .getData ().getMandate ().getCounterparty ().getAccountHolder ());
624630 assertEquals (
@@ -638,4 +644,173 @@ public void testMandateCreatedNotificationRequest() {
638644 assertEquals ("405081" , ukLocalAccountId .getSortCode ());
639645 assertEquals (UKLocalMandateAccountIdentification .TypeEnum .UKLOCAL , ukLocalAccountId .getType ());
640646 }
647+
648+ @ Test
649+ public void testMandateNotificationWithInvalidDates () {
650+ String json =
651+ "{\" data\" :{\" balancePlatform\" :\" YOUR_BALANCE_PLATFORM\" ,\" mandate\" :{"
652+ + "\" id\" :\" MNDT000000000000000000000001\" ,\" status\" :\" approved\" ,\" type\" :\" bacs\" ,"
653+ + "\" createdAt\" :\" not-a-date\" ,\" updatedAt\" :\" not-a-date\" }},"
654+ + "\" environment\" :\" test\" ,\" type\" :\" balancePlatform.mandate.created\" }" ;
655+
656+ ConfigurationWebhooksHandler handler = new ConfigurationWebhooksHandler (json );
657+ // createdAt/updatedAt are now OffsetDateTime, an invalid date fails deserialization
658+ assertFalse (handler .getMandateNotificationRequest ().isPresent ());
659+ }
660+
661+ @ Test
662+ public void testMandateNotificationWithUnknownAccountIdentificationType () {
663+ String json =
664+ "{\" data\" :{\" balancePlatform\" :\" YOUR_BALANCE_PLATFORM\" ,\" mandate\" :{"
665+ + "\" id\" :\" MNDT000000000000000000000001\" ,\" status\" :\" approved\" ,\" type\" :\" bacs\" ,"
666+ + "\" counterparty\" :{\" accountIdentification\" :{\" type\" :\" unknownType\" }}}},"
667+ + "\" environment\" :\" test\" ,\" type\" :\" balancePlatform.mandate.created\" }" ;
668+
669+ ConfigurationWebhooksHandler handler = new ConfigurationWebhooksHandler (json );
670+ // an unknown account identification discriminator type fails deserialization
671+ assertFalse (handler .getMandateNotificationRequest ().isPresent ());
672+ }
673+
674+ @ Test
675+ public void testPaymentInstrumentIbanAdditionalBankAccountIdentification () {
676+ String json =
677+ getFileContents (
678+ "mocks/balancePlatform-webhooks/configuration-paymentInstrument-created.json" );
679+
680+ ConfigurationWebhooksHandler handler = new ConfigurationWebhooksHandler (json );
681+ Optional <PaymentNotificationRequest > optionalRequest = handler .getPaymentNotificationRequest ();
682+ assertTrue (optionalRequest .isPresent ());
683+
684+ PaymentNotificationRequest request = optionalRequest .get ();
685+ assertEquals (
686+ PaymentNotificationRequest .TypeEnum .BALANCEPLATFORM_PAYMENTINSTRUMENT_CREATED ,
687+ request .getType ());
688+ assertEquals ("test" , request .getEnvironment ());
689+
690+ PaymentInstrument paymentInstrument = request .getData ().getPaymentInstrument ();
691+ assertNotNull (paymentInstrument );
692+ assertEquals ("PI00000000000000000001" , paymentInstrument .getId ());
693+ assertNotNull (paymentInstrument .getAdditionalBankAccountIdentifications ());
694+ assertEquals (1 , paymentInstrument .getAdditionalBankAccountIdentifications ().size ());
695+
696+ // the discriminator (type=iban) resolves to IbanAccountIdentification
697+ IbanAccountIdentification ibanAccountIdentification =
698+ paymentInstrument
699+ .getAdditionalBankAccountIdentifications ()
700+ .get (0 )
701+ .getIbanAccountIdentification ();
702+ assertNotNull (ibanAccountIdentification );
703+ assertEquals ("NL11ADYB00000000" , ibanAccountIdentification .getIban ());
704+ assertEquals (IbanAccountIdentification .TypeEnum .IBAN , ibanAccountIdentification .getType ());
705+ }
706+
707+ @ Test
708+ public void testPaymentInstrumentUnknownAdditionalBankAccountIdentificationType () {
709+ String json =
710+ "{\" data\" :{\" balancePlatform\" :\" YOUR_BALANCE_PLATFORM\" ,\" paymentInstrument\" :{"
711+ + "\" id\" :\" PI00000000000000000001\" ,\" balanceAccountId\" :\" BA00000000000000000001\" ,"
712+ + "\" issuingCountryCode\" :\" NL\" ,\" status\" :\" active\" ,\" type\" :\" bankAccount\" ,"
713+ + "\" additionalBankAccountIdentifications\" :[{\" type\" :\" unknownType\" }]}},"
714+ + "\" environment\" :\" test\" ,\" type\" :\" balancePlatform.paymentInstrument.created\" }" ;
715+
716+ ConfigurationWebhooksHandler handler = new ConfigurationWebhooksHandler (json );
717+ // an unknown additional bank account identification discriminator type fails deserialization
718+ assertFalse (handler .getPaymentNotificationRequest ().isPresent ());
719+ }
720+
721+ @ Test
722+ public void testTopUpConfigurationCreatedNotificationRequest () {
723+ String json =
724+ getFileContents (
725+ "mocks/balancePlatform-webhooks/balanceplatform-recurringTopUp-created.json" );
726+
727+ ConfigurationWebhooksHandler handler = new ConfigurationWebhooksHandler (json );
728+ Optional <TopUpConfigurationEventRequest > optionalRequest =
729+ handler .getTopUpConfigurationEventRequest ();
730+ assertTrue (optionalRequest .isPresent ());
731+
732+ TopUpConfigurationEventRequest request = optionalRequest .get ();
733+ assertEquals (
734+ TopUpConfigurationEventRequest .TypeEnum
735+ .BALANCEPLATFORM_BALANCEACCOUNT_RECURRINGTOPUP_CREATED ,
736+ request .getType ());
737+ assertEquals ("test" , request .getEnvironment ());
738+ assertNotNull (request .getTimestamp ());
739+
740+ TopUpWebhookData data = request .getData ();
741+ assertNotNull (data );
742+ assertEquals ("BA00000000000000000001" , data .getAccountId ());
743+ assertEquals ("YOUR_BALANCE_PLATFORM" , data .getBalancePlatform ());
744+ assertNotNull (data .getCreationDate ());
745+
746+ WebhookTopUpConfiguration config = data .getWebhookTopUpConfiguration ();
747+ assertNotNull (config );
748+ assertEquals ("TU4227C224555B5FTD2NT2JV4WN5" , config .getId ());
749+ assertEquals ("Top up when balance is low" , config .getDescription ());
750+ assertEquals ("TopUpFromSavings" , config .getReferenceForBeneficiary ());
751+ assertEquals (WebhookTopUpConfiguration .StatusEnum .ACTIVE , config .getStatus ());
752+
753+ assertNotNull (config .getCounterparty ());
754+ assertEquals ("SE00000000000000000001" , config .getCounterparty ().getTransferInstrumentId ());
755+
756+ assertNotNull (config .getMandate ());
757+ assertEquals ("MND00000000000000000001" , config .getMandate ().getReference ());
758+ assertNotNull (config .getMandate ().getCreationDate ());
759+
760+ assertNotNull (config .getTopUpAmount ());
761+ assertEquals ("EUR" , config .getTopUpAmount ().getFixedAmount ().getCurrency ());
762+ assertEquals (Long .valueOf (10000 ), config .getTopUpAmount ().getFixedAmount ().getValue ());
763+
764+ assertNotNull (config .getTrigger ());
765+ assertEquals (WebhookTopUpTrigger .ScheduleEnum .WEEKLY , config .getTrigger ().getSchedule ());
766+ assertEquals (Long .valueOf (5000 ), config .getTrigger ().getThreshold ().getValue ());
767+ }
768+
769+ @ Test
770+ public void testTopUpConfigurationUpdatedNotificationRequest () {
771+ String json =
772+ getFileContents (
773+ "mocks/balancePlatform-webhooks/balanceplatform-recurringTopUp-updated.json" );
774+
775+ ConfigurationWebhooksHandler handler = new ConfigurationWebhooksHandler (json );
776+ Optional <TopUpConfigurationUpdatedEventRequest > optionalRequest =
777+ handler .getTopUpConfigurationUpdatedEventRequest ();
778+ assertTrue (optionalRequest .isPresent ());
779+
780+ TopUpConfigurationUpdatedEventRequest request = optionalRequest .get ();
781+ assertEquals (
782+ TopUpConfigurationUpdatedEventRequest .TypeEnum
783+ .BALANCEPLATFORM_BALANCEACCOUNT_RECURRINGTOPUP_UPDATED ,
784+ request .getType ());
785+ assertEquals ("test" , request .getEnvironment ());
786+ assertNotNull (request .getTimestamp ());
787+
788+ TopUpUpdatedWebhookData data = request .getData ();
789+ assertNotNull (data );
790+ assertEquals ("BA00000000000000000001" , data .getAccountId ());
791+ assertEquals ("YOUR_BALANCE_PLATFORM" , data .getBalancePlatform ());
792+
793+ WebhookTopUpConfigurationUpdated config = data .getWebhookTopUpConfiguration ();
794+ assertNotNull (config );
795+ assertEquals ("Top up when balance is low - updated" , config .getDescription ());
796+ assertEquals (WebhookTopUpConfigurationUpdated .StatusEnum .INACTIVE , config .getStatus ());
797+ assertEquals ("counterpartyAccountBlocked" , config .getDisabledReason ());
798+ assertEquals ("The counterparty account is blocked." , config .getReasonDetail ());
799+ assertEquals (Long .valueOf (15000 ), config .getTopUpAmount ().getFixedAmount ().getValue ());
800+ assertEquals (WebhookTopUpTrigger .ScheduleEnum .MONTHLY , config .getTrigger ().getSchedule ());
801+ assertEquals (Long .valueOf (3000 ), config .getTrigger ().getThreshold ().getValue ());
802+ }
803+
804+ @ Test
805+ public void testTopUpConfigurationWithUnknownTypeReturnsEmpty () {
806+ String json =
807+ "{\" data\" :{\" balancePlatform\" :\" YOUR_BALANCE_PLATFORM\" },"
808+ + "\" environment\" :\" test\" ,"
809+ + "\" type\" :\" balancePlatform.balanceAccount.recurringTopUp.unknown\" }" ;
810+
811+ ConfigurationWebhooksHandler handler = new ConfigurationWebhooksHandler (json );
812+ // an unknown event type does not match the TopUp created/updated type enums
813+ assertFalse (handler .getTopUpConfigurationEventRequest ().isPresent ());
814+ assertFalse (handler .getTopUpConfigurationUpdatedEventRequest ().isPresent ());
815+ }
641816}
0 commit comments