Search in sources :

Example 1 with Refund

use of uk.gov.pay.connector.refund.model.domain.Refund in project pay-connector by alphagov.

the class RefundNotificationProcessor method invoke.

public void invoke(PaymentGatewayName gatewayName, RefundStatus newStatus, GatewayAccountEntity gatewayAccountEntity, String gatewayTransactionId, String transactionId, Charge charge) {
    if (isBlank(gatewayTransactionId)) {
        logger.warn("{} refund notification could not be used to update charge [{}] (missing reference)", gatewayName, charge.getExternalId());
        return;
    }
    Optional<RefundEntity> optionalRefundEntity = refundService.findByChargeExternalIdAndGatewayTransactionId(charge.getExternalId(), gatewayTransactionId);
    if (optionalRefundEntity.isEmpty()) {
        Optional<Refund> mayBeHistoricRefund = refundService.findHistoricRefundByChargeExternalIdAndGatewayTransactionId(charge, gatewayTransactionId);
        mayBeHistoricRefund.ifPresentOrElse(refund -> logger.warn("{} notification could not be processed as refund [{}] has been expunged from connector", gatewayName, refund.getExternalId(), kv(REFUND_EXTERNAL_ID, refund.getExternalId()), kv(PAYMENT_EXTERNAL_ID, charge.getExternalId()), kv(PROVIDER, gatewayName)), () -> logger.warn("{} notification '{}' could not be used to update refund (associated refund entity not found) for charge [{}]", gatewayName, gatewayTransactionId, charge.getExternalId(), kv(PAYMENT_EXTERNAL_ID, charge.getExternalId()), kv(PROVIDER, gatewayName), kv("provider_refund_id", gatewayTransactionId)));
        return;
    }
    RefundEntity refundEntity = optionalRefundEntity.get();
    RefundStatus oldStatus = refundEntity.getStatus();
    refundService.transitionRefundState(refundEntity, gatewayAccountEntity, newStatus, charge);
    if (RefundStatus.REFUNDED.equals(newStatus)) {
        userNotificationService.sendRefundIssuedEmail(refundEntity, charge, gatewayAccountEntity);
    }
    logger.info("Notification received for refund. Updating refund - charge_external_id={}, refund_reference={}, transaction_id={}, status={}, " + "status_to={}, account_id={}, provider={}, provider_type={}", refundEntity.getChargeExternalId(), gatewayTransactionId, transactionId, oldStatus, newStatus, gatewayAccountEntity.getId(), charge.getPaymentGatewayName(), gatewayAccountEntity.getType());
}
Also used : Refund(uk.gov.pay.connector.refund.model.domain.Refund) RefundStatus(uk.gov.pay.connector.refund.model.domain.RefundStatus) RefundEntity(uk.gov.pay.connector.refund.model.domain.RefundEntity)

Example 2 with Refund

use of uk.gov.pay.connector.refund.model.domain.Refund in project pay-connector by alphagov.

the class RefundService method validateRefundAndGetAvailableAmount.

private long validateRefundAndGetAvailableAmount(Charge charge, GatewayAccountEntity gatewayAccountEntity, RefundRequest refundRequest, List<Refund> refundList) {
    ExternalChargeRefundAvailability refundAvailability;
    refundAvailability = providers.byName(PaymentGatewayName.valueFrom(charge.getPaymentGatewayName())).getExternalChargeRefundAvailability(charge, refundList);
    checkIfChargeIsRefundableOrTerminate(charge, refundAvailability, gatewayAccountEntity);
    // We re-check the database for any newly created refunds that could have been made when we were making the
    // network request to find the external refund-ability
    List<Refund> updatedRefunds = checkForNewRefunds(charge, refundList);
    long availableToBeRefunded = getTotalAmountAvailableToBeRefunded(charge, updatedRefunds);
    checkIfRefundRequestIsInConflictOrTerminate(refundRequest, charge, availableToBeRefunded);
    checkIfRefundAmountWithinLimitOrTerminate(refundRequest, charge, refundAvailability, gatewayAccountEntity, availableToBeRefunded);
    return availableToBeRefunded;
}
Also used : Refund(uk.gov.pay.connector.refund.model.domain.Refund) ExternalChargeRefundAvailability(uk.gov.pay.connector.common.model.api.ExternalChargeRefundAvailability)

Example 3 with Refund

use of uk.gov.pay.connector.refund.model.domain.Refund in project pay-connector by alphagov.

the class RefundService method createRefund.

@Transactional
@SuppressWarnings("WeakerAccess")
public RefundEntity createRefund(Charge charge, GatewayAccountEntity gatewayAccountEntity, RefundRequest refundRequest) {
    List<Refund> refundList = findRefunds(charge);
    long availableAmount = validateRefundAndGetAvailableAmount(charge, gatewayAccountEntity, refundRequest, refundList);
    RefundEntity refundEntity = createRefundEntity(refundRequest, gatewayAccountEntity, charge);
    logger.info("Card refund request sent - charge_external_id={}, status={}, amount={}, transaction_id={}, account_id={}, operation_type=Refund, amount_available_refund={}, amount_requested_refund={}, provider={}, provider_type={}, user_external_id={}", charge.getExternalId(), charge.getExternalStatus(), charge.getAmount(), charge.getGatewayTransactionId(), gatewayAccountEntity.getId(), availableAmount, refundRequest.getAmount(), charge.getPaymentGatewayName(), gatewayAccountEntity.getType(), refundRequest.getUserExternalId());
    return refundEntity;
}
Also used : Refund(uk.gov.pay.connector.refund.model.domain.Refund) RefundEntity(uk.gov.pay.connector.refund.model.domain.RefundEntity) Transactional(com.google.inject.persist.Transactional)

Example 4 with Refund

use of uk.gov.pay.connector.refund.model.domain.Refund in project pay-connector by alphagov.

the class ChargeParityChecker method matchRefundSummary.

private boolean matchRefundSummary(ChargeEntity chargeEntity, LedgerTransaction transaction) {
    List<Refund> refundList = refundService.findRefunds(Charge.from(chargeEntity));
    ExternalChargeRefundAvailability refundAvailability = providers.byName(chargeEntity.getPaymentGatewayName()).getExternalChargeRefundAvailability(Charge.from(chargeEntity), refundList);
    return isEquals(refundAvailability.getStatus(), ofNullable(transaction.getRefundSummary()).map(ChargeResponse.RefundSummary::getStatus).orElse(null), "refund_summary.status");
}
Also used : Refund(uk.gov.pay.connector.refund.model.domain.Refund) ExternalChargeRefundAvailability(uk.gov.pay.connector.common.model.api.ExternalChargeRefundAvailability)

Example 5 with Refund

use of uk.gov.pay.connector.refund.model.domain.Refund in project pay-connector by alphagov.

the class RefundCalculatorTest method getRefundedAmount_shouldIncludeCreatedSubmittedAndRefundedRefunds.

@Test
void getRefundedAmount_shouldIncludeCreatedSubmittedAndRefundedRefunds() {
    RefundEntity createdRefund = RefundEntityFixture.aValidRefundEntity().withAmount(10L).withStatus(RefundStatus.CREATED).build();
    RefundEntity submittedRefund = RefundEntityFixture.aValidRefundEntity().withAmount(20L).withStatus(RefundStatus.REFUND_SUBMITTED).build();
    RefundEntity refundedRefund = RefundEntityFixture.aValidRefundEntity().withAmount(30L).withStatus(RefundStatus.REFUNDED).build();
    RefundEntity errorRefund = RefundEntityFixture.aValidRefundEntity().withAmount(30L).withStatus(RefundStatus.REFUND_ERROR).build();
    long actualAmount = RefundCalculator.getRefundedAmount(Stream.of(createdRefund, submittedRefund, refundedRefund, errorRefund).map(Refund::from).collect(Collectors.toList()));
    // refunds with status of REFUND_ERROR should not be included in returned amount
    long expectedAmount = createdRefund.getAmount() + submittedRefund.getAmount() + refundedRefund.getAmount();
    assertThat(actualAmount, is(expectedAmount));
}
Also used : Refund(uk.gov.pay.connector.refund.model.domain.Refund) RefundEntity(uk.gov.pay.connector.refund.model.domain.RefundEntity) Test(org.junit.jupiter.api.Test)

Aggregations

Refund (uk.gov.pay.connector.refund.model.domain.Refund)14 RefundEntity (uk.gov.pay.connector.refund.model.domain.RefundEntity)8 Test (org.junit.jupiter.api.Test)7 Charge (uk.gov.pay.connector.charge.model.domain.Charge)6 ChargeEntity (uk.gov.pay.connector.charge.model.domain.ChargeEntity)3 LedgerTransaction (uk.gov.pay.connector.client.ledger.model.LedgerTransaction)3 ExternalChargeRefundAvailability (uk.gov.pay.connector.common.model.api.ExternalChargeRefundAvailability)3 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)2 ChargeResponse (uk.gov.pay.connector.charge.model.ChargeResponse)2 ChargeEventEntity (uk.gov.pay.connector.chargeevent.model.domain.ChargeEventEntity)2 LedgerTransactionFixture.aValidLedgerTransaction (uk.gov.pay.connector.model.domain.LedgerTransactionFixture.aValidLedgerTransaction)2 RefundEntityFixture.aValidRefundEntity (uk.gov.pay.connector.model.domain.RefundEntityFixture.aValidRefundEntity)2 Transactional (com.google.inject.persist.Transactional)1 UTC (java.time.ZoneOffset.UTC)1 ZonedDateTime (java.time.ZonedDateTime)1 List (java.util.List)1 Objects.nonNull (java.util.Objects.nonNull)1 Optional.ofNullable (java.util.Optional.ofNullable)1 Collectors (java.util.stream.Collectors)1 Before (org.junit.Before)1