Skip to content

Commit

Permalink
Release 5.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
javierpoloe2y committed Mar 15, 2024
1 parent c5a03ee commit 6216c70
Show file tree
Hide file tree
Showing 36 changed files with 416 additions and 102 deletions.
2 changes: 1 addition & 1 deletion buildSrc/src/main/groovy/hmc.lib-conventions.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ bootJar {

dependencies {
api 'com.hyperwallet:sdk:2.4.3'
api 'com.mirakl:mmp-sdk-operator:6.37.0'
api 'com.mirakl:mmp-sdk-operator:7.2.0'
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ a| * `invoice_id`: invoice identifier
* `currency_iso_code`: ISO code for the currency used in the payment.
* `amount`: Amount of the invoice.
* `transaction_date`: Invoice transaction date.
* `confirm_all_linked_manual_documents`: Confirm the payment of each manual accounting document present in the billing cycle.
|===
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ The connector reads the configuration from the following configuration variables
* `PAYPAL_HYPERWALLET_MAX_AMOUNT_OF_NOTIFICATION_RETRIES`, determines the maximum number of attempts allowed for each notification. Set to `5` by default

* `PAYPAL_HYPERWALLET_RETRY_FAILED_NOTIFICATIONS_CRON_EXPRESSION`, used to configure the periodicity of the retry job.

=== Email alerts

The connector sends an email to the operator when all the retries of a notification fails. The email includes the following details:
Expand Down
3 changes: 3 additions & 0 deletions docs/package.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"scripts": {
"build": "antora --fetch --to-dir build antora-playbook.yml"
},
"devDependencies": {
"@antora/cli": "3.0.3",
"@antora/site-generator": "3.0.3"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ hmc.hyperwallet.programs.userTokens = userToken
hmc.hyperwallet.programs.paymentTokens = paymentToken
hmc.hyperwallet.programs.bankAccountTokens = bankAccountToken
hmc.hyperwallet.programs.rootToken = prg-1fb3df0d-787b-4bbd-9eb7-1d9fe8ed6c8e

hmc.webhooks.payments.confirm-linked-manual-documents = true
6 changes: 6 additions & 0 deletions hmc-app/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ hmc.toggle-features.http-capture = ${PAYPAL_HYPERWALLET_HTTP

hmc.webhooks.payments.failure-statuses = FAILED,RECALLED,RETURNED,EXPIRED,UNCLAIMED,CANCELLED
hmc.webhooks.payments.accepted-statuses = COMPLETED
hmc.webhooks.payments.confirm-linked-manual-documents = ${PAYPAL_HYPERWALLET_CONFIRM_LINKED_MANUAL_DOCUMENTS:true}
hmc.webhooks.routing-keys.payments = PAYMENTS
hmc.webhooks.routing-keys.kyc-users = USERS.UPDATED.VERIFICATION_STATUS
hmc.webhooks.routing-keys.kyc-bstk = USERS.BUSINESS_STAKEHOLDERS
Expand All @@ -130,3 +131,8 @@ hmc.startup-checks.exit-on-fail = ${PAYPAL_HMC_STARTUPCHECK
hmc.financial-reports.outputdir = ${PAYPAL_HYPERWALLET_FINANCIAL_REPORTS_OUTPUT_DIR:./financial-reports}
hmc.financial-reports.header = braintreeCommerceOrderId,miraklOrderId,miraklSellerId,miraklTransactionLineId,miraklTransactionTime,TransactionType,braintreeAmount,miraklDebitAmount,miraklCreditAmount,currencyIsoCode,braintreeTransactionId,braintreeTransactionTime
hmc.financial-reports.filename-prefix = financialReport

hmc.hyperwallet.supported.languages = en,bg,zh,hr,cs,nl,fr,de,el,hu,is,id,in,it,ja,ko,lv,mk,ms,mn,pl,pt,ro,ru,sk,sl,es,sv,th,tr,uk,vi
hmc.hyperwallet.default.language = en

hmc.hyperwallet.countries.not.local.tax = BES,CUB,CUW,DJI,ERI,GUM,KOR,LBR,MYX.PRI,SLB,SSD,TLS,TUV,USA,YEM
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,7 @@ public class PaymentNotificationConfig {
@Value("#{'${hmc.webhooks.payments.accepted-statuses}'}")
private Set<String> acceptedStatuses;

@Value("#{'${hmc.webhooks.payments.confirm-linked-manual-documents}'}")
private boolean confirmLinkedManualDocuments;

}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ protected MiraklConfirmAccountingDocumentPaymentRequest createPaymentConfirmatio
miraklAccountingDocumentPaymentConfirmation
.setTransactionDate(DateUtil.convertToDate(paymentNotificationBodyModel.getCreatedOn(),
HyperWalletConstants.HYPERWALLET_DATE_FORMAT, DateUtil.TIME_UTC));
miraklAccountingDocumentPaymentConfirmation
.setConfirmLinkedManualDocuments(paymentNotificationConfig.isConfirmLinkedManualDocuments());

log.info("Creating payment confirmation request for invoice ID {} and amount {}",
miraklAccountingDocumentPaymentConfirmation.getInvoiceId(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,35 @@ void execute_shouldSendConfirmationPaymentToMirakl() {
assertThat(accountingDocuments.get(0).getCurrencyIsoCode()).isEqualTo(MiraklIsoCurrencyCode.EUR);
assertThat(accountingDocuments.get(0).getTransactionDate()).isEqualTo(DateUtil.convertToDate(CREATED_ON,
HyperWalletConstants.HYPERWALLET_DATE_FORMAT, TimeZone.getTimeZone("UTC")));
assertThat(accountingDocuments.get(0).isConfirmLinkedManualDocuments()).isFalse();
}

@Test
void execute_shouldSendConfirmationPaymentToMiraklConfirmingLinkedManualDocuments() {
when(paymentNotificationConfigMock.isConfirmLinkedManualDocuments()).thenReturn(true);

when(paymentNotificationBodyModelMock.getAmount()).thenReturn(AMOUNT);
when(paymentNotificationBodyModelMock.getClientPaymentId()).thenReturn(INVOICE_ID);
when(paymentNotificationBodyModelMock.getCurrency()).thenReturn(CURRENCY_EUR_ISO_CODE);
when(paymentNotificationBodyModelMock.getCreatedOn()).thenReturn(CREATED_ON);

testObj.execute(paymentNotificationBodyModelMock);

verify(miraklClientMock).confirmAccountingDocumentPayment(
miraklConfirmAccountingDocumentPaymentRequestArgumentCaptor.capture());

final MiraklConfirmAccountingDocumentPaymentRequest miraklConfirmAccountingDocumentPaymentRequest = miraklConfirmAccountingDocumentPaymentRequestArgumentCaptor
.getValue();
final List<MiraklAccountingDocumentPaymentConfirmation> accountingDocuments = miraklConfirmAccountingDocumentPaymentRequest
.getAccountingDocuments();

assertThat(miraklConfirmAccountingDocumentPaymentRequest.getAccountingDocuments()).hasSize(1);
assertThat(accountingDocuments.get(0).getAmount()).isEqualTo(AMOUNT);
assertThat(accountingDocuments.get(0).getInvoiceId()).isEqualTo(Long.valueOf(INVOICE_ID));
assertThat(accountingDocuments.get(0).getCurrencyIsoCode()).isEqualTo(MiraklIsoCurrencyCode.EUR);
assertThat(accountingDocuments.get(0).getTransactionDate()).isEqualTo(DateUtil.convertToDate(CREATED_ON,
HyperWalletConstants.HYPERWALLET_DATE_FORMAT, TimeZone.getTimeZone("UTC")));
assertThat(accountingDocuments.get(0).isConfirmLinkedManualDocuments()).isTrue();
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ public NotificationsRepositoryImpl(final UserHyperwalletSDKService userHyperwall
}

@Override
public HyperwalletWebhookNotification getHyperwalletWebhookNotification(final String program, final String token) {
public HyperwalletWebhookNotification getHyperwalletWebhookNotification(final String programToken,
final String token) {
final Hyperwallet hyperwalletInstance = userHyperwalletSDKService
.getHyperwalletInstanceByHyperwalletProgram(program);
.getHyperwalletInstanceByProgramToken(programToken);
try {
return hyperwalletInstance.getWebhookEvent(token);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,9 @@ public NotificationProcessingServiceImpl(final NotificationConverter notificatio
public void processNotification(final HyperwalletWebhookNotification incomingNotificationDTO) {
final NotificationEntity notificationEntity = notificationConverter.convert(incomingNotificationDTO);

notificationStorageService.saveNotification(notificationEntity);

if (notificationEntityEvaluator.isProcessable(notificationEntity)) {
hyperwalletWebhookNotificationSenderStrategyExecutor.execute(incomingNotificationDTO);
notificationStorageService.saveNotification(notificationEntity);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ public IsDuplicated(final NotificationStorageService notificationStorageService)
@Override
public boolean test(final NotificationEntity notificationEntity) {

final boolean isDuplicated = super.notificationStorageService
.getNotificationsByWebHookToken(notificationEntity.getWebHookToken()).size() > 1;
final boolean isDuplicated = !super.notificationStorageService
.getNotificationsByWebHookToken(notificationEntity.getWebHookToken()).isEmpty();

if (isDuplicated) {
log.warn("Duplicated notification: [{}]", notificationEntity.getWebHookToken());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class NotificationsRepositoryImplTest {

private static final String HYPERWALLET_NOTIFICATION_TOKEN = "TEST_TOKEN";

private static final String HYPERWALLET_NOTIFICATION_PROGRAM = "TEST_PROGRAM";
private static final String HYPERWALLET_NOTIFICATION_PROGRAM_TOKEN = "TEST_PROGRAM_TOKE";

private static final String MSG_ERROR = "An error has occurred";

Expand All @@ -44,38 +44,38 @@ class NotificationsRepositoryImplTest {

@Test
void getHyperwalletWebhookNotification_shouldReturnAnHyperwalletNotification_WhenTokenExists() {
when(userHyperwalletSDKService.getHyperwalletInstanceByHyperwalletProgram(HYPERWALLET_NOTIFICATION_PROGRAM))
when(userHyperwalletSDKService.getHyperwalletInstanceByProgramToken(HYPERWALLET_NOTIFICATION_PROGRAM_TOKEN))
.thenReturn(hyperwalletInstanceMock);
when(hyperwalletInstanceMock.getWebhookEvent(HYPERWALLET_NOTIFICATION_TOKEN))
.thenReturn(hyperwalletWebhookNotificationMock);

final HyperwalletWebhookNotification result = testObj
.getHyperwalletWebhookNotification(HYPERWALLET_NOTIFICATION_PROGRAM, HYPERWALLET_NOTIFICATION_TOKEN);
final HyperwalletWebhookNotification result = testObj.getHyperwalletWebhookNotification(
HYPERWALLET_NOTIFICATION_PROGRAM_TOKEN, HYPERWALLET_NOTIFICATION_TOKEN);

assertThat(result).isEqualTo(hyperwalletWebhookNotificationMock);
}

@Test
void getHyperwalletWebhookNotification_shouldReturnNull_WhenTokenNotExists() {
when(userHyperwalletSDKService.getHyperwalletInstanceByHyperwalletProgram(HYPERWALLET_NOTIFICATION_PROGRAM))
when(userHyperwalletSDKService.getHyperwalletInstanceByProgramToken(HYPERWALLET_NOTIFICATION_PROGRAM_TOKEN))
.thenReturn(hyperwalletInstanceMock);
when(hyperwalletInstanceMock.getWebhookEvent(HYPERWALLET_NOTIFICATION_TOKEN)).thenReturn(null);

final HyperwalletWebhookNotification result = testObj
.getHyperwalletWebhookNotification(HYPERWALLET_NOTIFICATION_PROGRAM, HYPERWALLET_NOTIFICATION_TOKEN);
final HyperwalletWebhookNotification result = testObj.getHyperwalletWebhookNotification(
HYPERWALLET_NOTIFICATION_PROGRAM_TOKEN, HYPERWALLET_NOTIFICATION_TOKEN);

assertThat(result).isNull();
}

@Test
void getHyperwalletWebhookNotification_shouldReturnNull_andLogException_WhenExceptionIsThrown() {
when(userHyperwalletSDKService.getHyperwalletInstanceByHyperwalletProgram(HYPERWALLET_NOTIFICATION_PROGRAM))
when(userHyperwalletSDKService.getHyperwalletInstanceByProgramToken(HYPERWALLET_NOTIFICATION_PROGRAM_TOKEN))
.thenReturn(hyperwalletInstanceMock);
final HyperwalletException hyperwalletException = new HyperwalletException(MSG_ERROR);
when(hyperwalletInstanceMock.getWebhookEvent(HYPERWALLET_NOTIFICATION_TOKEN)).thenThrow(hyperwalletException);

final HyperwalletWebhookNotification result = testObj
.getHyperwalletWebhookNotification(HYPERWALLET_NOTIFICATION_PROGRAM, HYPERWALLET_NOTIFICATION_TOKEN);
final HyperwalletWebhookNotification result = testObj.getHyperwalletWebhookNotification(
HYPERWALLET_NOTIFICATION_PROGRAM_TOKEN, HYPERWALLET_NOTIFICATION_TOKEN);

assertThat(result).isNull();
assertThat(logTrackerStub.contains("Could not fetch notification [%s] due to reason:%n%s".formatted(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,13 @@ void processNotification_shouldSaveAndProcessIncomingNotificationAndReturnsOK_Wh
hyperwalletWebhookNotificationSenderStrategyExecutorMock);

inOrder.verify(notificationConverterMock).convert(hyperwalletWebhookNotification1Mock);
inOrder.verify(hyperwalletWebhookNotificationSenderStrategyExecutorMock)
.execute(hyperwalletWebhookNotification1Mock);
inOrder.verify(notificationStorageServiceMock).saveNotification(notificationEntityMock);
verify(hyperwalletWebhookNotificationSenderStrategyExecutorMock).execute(hyperwalletWebhookNotification1Mock);
}

@Test
void processNotification_shouldSaveAndNotProcessIncomingNotificationAndReturnsOK_WhenNotificationIsNotProcessable() {
void processNotification_shouldNotSaveAndNotProcessIncomingNotificationAndReturnsOK_WhenNotificationIsNotProcessable() {
when(notificationEntityEvaluatorMock.isProcessable(notificationEntityMock)).thenReturn(false);
when(notificationConverterMock.convert(hyperwalletWebhookNotification1Mock)).thenReturn(notificationEntityMock);

Expand All @@ -64,9 +65,9 @@ void processNotification_shouldSaveAndNotProcessIncomingNotificationAndReturnsOK
hyperwalletWebhookNotificationSenderStrategyExecutorMock);

inOrder.verify(notificationConverterMock).convert(hyperwalletWebhookNotification1Mock);
inOrder.verify(notificationStorageServiceMock).saveNotification(notificationEntityMock);
verify(hyperwalletWebhookNotificationSenderStrategyExecutorMock, never())
.execute(hyperwalletWebhookNotification1Mock);
verify(notificationStorageServiceMock, never()).saveNotification(notificationEntityMock);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ void test_ShouldReturnFalse_WhenThereAreNotNotificationWithTheSameWebHookToken()
}

@Test
void test_ShouldReturnFalse_WhenThereIsOneNotificationWithTheSameWebHookToken() {
void test_ShouldReturnTrue_WhenThereIsOneNotificationWithTheSameWebHookToken() {

when(notificationStorageService.getNotificationsByWebHookToken(WEB_HOOK_TOKEN))
.thenReturn(List.of(new NotificationEntity()));

final boolean result = testObj.test(notificationEntityMock);

assertThat(result).isFalse();
assertThat(result).isTrue();
}

@Test
Expand Down
2 changes: 1 addition & 1 deletion hmc-observability/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ dependencies {

inpath 'org.apache.httpcomponents:httpclient'
inpath 'com.hyperwallet:sdk:2.4.3'
inpath 'com.mirakl:mmp-sdk-operator:6.37.0'
inpath 'com.mirakl:mmp-sdk-operator:7.2.0'

testImplementation project(":hmc-testsupport")
}
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,14 @@ private Map<String, String> getQueryParameters(final HttpRequest request) {
}

private String getUrl(final HttpRequest request) {
return request.getRequestLine().getUri();
String uri = request.getRequestLine().getUri();
final Header host = Arrays.stream(request.getHeaders("Host")).findFirst().orElse(null);

if (null != host && !host.getValue().isEmpty()) {
uri = "https://" + host.getValue() + uri;
}

return uri;
}

@SneakyThrows
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.paypal.sellers.bankaccountextraction.services.converters.mirakl;

import com.mirakl.client.mmp.domain.shop.MiraklContactInformation;
import com.mirakl.client.mmp.domain.shop.MiraklProfessionalInformation;
import com.mirakl.client.mmp.domain.shop.MiraklShop;
import com.mirakl.client.mmp.domain.shop.bank.MiraklAbaBankAccountInformation;
import com.mirakl.client.mmp.domain.shop.bank.MiraklPaymentInformation;
import com.mirakl.client.mmp.domain.shop.billing.MiraklDefaultBillingInformation;
import com.paypal.infrastructure.support.strategy.Strategy;
import com.paypal.sellers.bankaccountextraction.model.ABABankAccountModel;
import com.paypal.sellers.bankaccountextraction.model.BankAccountModel;
Expand Down Expand Up @@ -58,8 +58,9 @@ public ABABankAccountModel execute(@NonNull final MiraklShop source) {
.transferType(hyperwalletBankAccountCurrencyInfo.getTransferType())
.type(BankAccountType.ABA)
.bankAccountNumber(miraklAbaBankAccountInformation.getBankAccountNumber())
.businessName(Optional.ofNullable(source.getProfessionalInformation())
.map(MiraklProfessionalInformation::getCorporateName)
.businessName(Optional.ofNullable(source.getDefaultBillingInformation())
.map(MiraklDefaultBillingInformation::getCorporateInformation)
.map(MiraklDefaultBillingInformation.CorporateInformation::getCompanyRegistrationName)
.orElse(null))
.firstName(contactInformation.getFirstname())
.lastName(contactInformation.getLastname())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.paypal.sellers.bankaccountextraction.services.converters.mirakl;

import com.mirakl.client.mmp.domain.shop.MiraklContactInformation;
import com.mirakl.client.mmp.domain.shop.MiraklProfessionalInformation;
import com.mirakl.client.mmp.domain.shop.MiraklShop;
import com.mirakl.client.mmp.domain.shop.bank.MiraklCanadianBankAccountInformation;
import com.mirakl.client.mmp.domain.shop.bank.MiraklPaymentInformation;
import com.mirakl.client.mmp.domain.shop.billing.MiraklDefaultBillingInformation;
import com.paypal.infrastructure.support.strategy.Strategy;
import com.paypal.sellers.bankaccountextraction.model.BankAccountModel;
import com.paypal.sellers.bankaccountextraction.model.BankAccountType;
Expand Down Expand Up @@ -55,8 +55,9 @@ public BankAccountModel execute(final MiraklShop source) {
.transferType(hyperwalletBankAccountCurrencyInfo.getTransferType())
.type(BankAccountType.CANADIAN)
.bankAccountNumber(miraklCanadianBankAccountInformation.getBankAccountNumber())
.businessName(Optional.ofNullable(source.getProfessionalInformation())
.map(MiraklProfessionalInformation::getCorporateName)
.businessName(Optional.ofNullable(source.getDefaultBillingInformation())
.map(MiraklDefaultBillingInformation::getCorporateInformation)
.map(MiraklDefaultBillingInformation.CorporateInformation::getCompanyRegistrationName)
.orElse(null))
.firstName(contactInformation.getFirstname())
.lastName(contactInformation.getLastname())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.paypal.sellers.bankaccountextraction.services.converters.mirakl;

import com.mirakl.client.mmp.domain.shop.MiraklContactInformation;
import com.mirakl.client.mmp.domain.shop.MiraklProfessionalInformation;
import com.mirakl.client.mmp.domain.shop.MiraklShop;
import com.mirakl.client.mmp.domain.shop.bank.MiraklIbanBankAccountInformation;
import com.mirakl.client.mmp.domain.shop.bank.MiraklPaymentInformation;
import com.mirakl.client.mmp.domain.shop.billing.MiraklDefaultBillingInformation;
import com.paypal.infrastructure.support.strategy.Strategy;
import com.paypal.sellers.bankaccountextraction.model.BankAccountModel;
import com.paypal.sellers.bankaccountextraction.model.BankAccountType;
Expand Down Expand Up @@ -57,8 +57,9 @@ public IBANBankAccountModel execute(@NonNull final MiraklShop source) {
.type(BankAccountType.IBAN)
.bankBic(miraklIbanBankAccountInformation.getBic())
.bankAccountNumber(miraklIbanBankAccountInformation.getIban())
.businessName(Optional.ofNullable(source.getProfessionalInformation())
.map(MiraklProfessionalInformation::getCorporateName)
.businessName(Optional.ofNullable(source.getDefaultBillingInformation())
.map(MiraklDefaultBillingInformation::getCorporateInformation)
.map(MiraklDefaultBillingInformation.CorporateInformation::getCompanyRegistrationName)
.orElse(null))
.firstName(contactInformation.getFirstname())
.lastName(contactInformation.getLastname())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.paypal.sellers.bankaccountextraction.services.converters.mirakl;

import com.mirakl.client.mmp.domain.shop.MiraklContactInformation;
import com.mirakl.client.mmp.domain.shop.MiraklProfessionalInformation;
import com.mirakl.client.mmp.domain.shop.MiraklShop;
import com.mirakl.client.mmp.domain.shop.bank.MiraklPaymentInformation;
import com.mirakl.client.mmp.domain.shop.bank.MiraklUkBankAccountInformation;
import com.mirakl.client.mmp.domain.shop.billing.MiraklDefaultBillingInformation;
import com.paypal.infrastructure.support.strategy.Strategy;
import com.paypal.sellers.bankaccountextraction.model.BankAccountModel;
import com.paypal.sellers.bankaccountextraction.model.BankAccountType;
Expand Down Expand Up @@ -52,8 +52,9 @@ public BankAccountModel execute(final MiraklShop source) {
.type(BankAccountType.UK)
.bankAccountNumber(miraklUkBankAccountInformation.getBankAccountNumber())
.bankAccountId(miraklUkBankAccountInformation.getBankSortCode())
.businessName(Optional.ofNullable(source.getProfessionalInformation())
.map(MiraklProfessionalInformation::getCorporateName)
.businessName(Optional.ofNullable(source.getDefaultBillingInformation())
.map(MiraklDefaultBillingInformation::getCorporateInformation)
.map(MiraklDefaultBillingInformation.CorporateInformation::getCompanyRegistrationName)
.orElse(null))
.firstName(contactInformation.getFirstname())
.lastName(contactInformation.getLastname())
Expand Down
Loading

0 comments on commit 6216c70

Please sign in to comment.