use of uk.gov.pay.connector.fee.model.Fee in project pay-connector by alphagov.
the class StripeCaptureHandler method capture.
@Override
public CaptureResponse capture(CaptureGatewayRequest request) {
String transactionId = request.getTransactionId();
try {
StripeCharge capturedCharge;
capturedCharge = captureWithPaymentIntentAPI(request);
List<Fee> feeList = generateFeeList(request.getCreatedDate(), request, capturedCharge.getFee().orElse(0L));
Long processingFee = StripeFeeCalculator.getTotalFeeAmount(feeList);
Long netTransferAmount = request.getAmount() - processingFee;
transferToConnectAccount(request, netTransferAmount, capturedCharge.getId());
return new CaptureResponse(transactionId, COMPLETE, feeList);
} catch (GatewayErrorException e) {
if (e.getFamily() == CLIENT_ERROR) {
var stripeErrorResponse = jsonObjectMapper.getObject(e.getResponseFromGateway(), StripeErrorResponse.class);
String errorCode = stripeErrorResponse.getError().getCode();
String errorMessage = stripeErrorResponse.getError().getMessage();
LOGGER.warn("Capture failed for transaction id {}. Failure code from Stripe: {}, failure message from " + "Stripe: {}. External Charge id: {}. Response code from Stripe: {}", transactionId, errorCode, errorMessage, request.getExternalId(), e.getStatus());
return fromBaseCaptureResponse(new StripeCaptureResponse(transactionId, errorCode, errorMessage), null);
}
if (e.getFamily() == SERVER_ERROR) {
LOGGER.warn("Capture failed for transaction id {}. Reason: {}. Status code from Stripe: {}. Charge External Id: {}", transactionId, e.getMessage(), e.getStatus(), request.getExternalId());
GatewayError gatewayError = gatewayConnectionError("An internal server error occurred when capturing charge_external_id: " + request.getExternalId());
return CaptureResponse.fromGatewayError(gatewayError);
}
LOGGER.error("Unrecognised response status during capture. charge_external_id={}, status={}, response={}", request.getExternalId(), e.getStatus(), e.getResponseFromGateway());
throw new RuntimeException("Unrecognised response status during capture.");
} catch (GatewayException e) {
return CaptureResponse.fromGatewayError(e.toGatewayError());
}
}
use of uk.gov.pay.connector.fee.model.Fee in project pay-connector by alphagov.
the class CollectFeesForFailedPaymentsTaskHandlerTest method shouldPersistFeesAndEmitEvent.
@Test
void shouldPersistFeesAndEmitEvent() throws Exception {
var paymentTaskData = new PaymentTaskData(chargeExternalId);
List<Fee> fees = List.of(Fee.of(RADAR, 6L), Fee.of(THREE_D_S, 7L));
when(stripePaymentProvider.calculateAndTransferFeesForFailedPayments(charge)).thenReturn(fees);
collectFeesForFailedPaymentsTaskHandler.collectAndPersistFees(paymentTaskData);
assertThat(charge.getFees(), hasSize(2));
assertThat(charge.getFees(), containsInAnyOrder(allOf(hasProperty("amountCollected", is(6L)), hasProperty("feeType", is(RADAR)), hasProperty("createdDate", is(clock.instant()))), allOf(hasProperty("amountCollected", is(7L)), hasProperty("feeType", is(THREE_D_S)), hasProperty("createdDate", is(clock.instant())))));
assertThat(charge.getNetAmount(), is(Optional.of(-13L)));
verify(eventService).emitAndRecordEvent(feeIncurredEventArgumentCaptor.capture());
FeeIncurredEventDetails eventDetails = (FeeIncurredEventDetails) feeIncurredEventArgumentCaptor.getValue().getEventDetails();
assertThat(eventDetails.getFee(), is(13L));
assertThat(eventDetails.getNetAmount(), is(-13L));
assertThat(eventDetails.getFeeBreakdown(), is(fees));
}
use of uk.gov.pay.connector.fee.model.Fee in project pay-connector by alphagov.
the class CardCaptureServiceIT method shouldPersistFeesForStripeV2Charge.
@Test
public void shouldPersistFeesForStripeV2Charge() {
long chargeId = nextInt();
String externalChargeId = RandomIdGenerator.newId();
databaseTestHelper.addCharge(anAddChargeParams().withChargeId(chargeId).withExternalChargeId(externalChargeId).withPaymentProvider(STRIPE.getName()).withGatewayAccountId(accountId).withAmount(10000).withStatus(ChargeStatus.CAPTURE_READY).build());
String oldChargeStatus = ChargeStatus.CAPTURE_READY.getValue();
String transactionId = "transactionId";
List<Fee> feeList = List.of(Fee.of(RADAR, 10L), Fee.of(THREE_D_S, 20L), Fee.of(TRANSACTION, 480L));
CaptureResponse captureResponse = new CaptureResponse(transactionId, CaptureResponse.ChargeState.COMPLETE, feeList);
// Trigger the post gateway capture response programmatically which normally would be invoked by the scheduler.
testContext.getInstanceFromGuiceContainer(CardCaptureService.class).processGatewayCaptureResponse(externalChargeId, oldChargeStatus, captureResponse);
List<Map<String, Object>> listOfFees = databaseTestHelper.getFeesByChargeId(chargeId);
assertThat(listOfFees, hasSize(3));
assertThat(listOfFees, containsInAnyOrder(allOf(hasEntry("fee_type", (Object) "radar"), hasEntry("amount_collected", 10L)), allOf(hasEntry("fee_type", (Object) "three_ds"), hasEntry("amount_collected", 20L)), allOf(hasEntry("fee_type", (Object) "transaction"), hasEntry("amount_collected", 480L))));
}
use of uk.gov.pay.connector.fee.model.Fee in project pay-connector by alphagov.
the class CollectFeesForFailedPaymentsTaskHandler method collectAndPersistFees.
@Transactional
public void collectAndPersistFees(PaymentTaskData paymentTaskData) throws GatewayException {
ChargeEntity charge = chargeService.findChargeByExternalId(paymentTaskData.getPaymentExternalId());
List<Fee> fees = stripePaymentProvider.calculateAndTransferFeesForFailedPayments(charge);
Instant now = clock.instant();
fees.stream().map(fee -> new FeeEntity(charge, now, fee)).forEach(charge::addFee);
emitFeeEvent(charge);
}
use of uk.gov.pay.connector.fee.model.Fee in project pay-connector by alphagov.
the class StripeCaptureHandlerTest method shouldCaptureWithV2RadarAnd3dsFeesAndTransferCorrectAmountToConnectAccount.
@Test
public void shouldCaptureWithV2RadarAnd3dsFeesAndTransferCorrectAmountToConnectAccount() throws Exception {
mockStripeCaptureAndTransfer();
// 26Aug2021
int chargeCreatedDate = 1629936000;
// 25Aug2021
int feeV2DateAfterChargeCreatedDate = 1629849600;
when(stripeGatewayConfig.getFeePercentageV2Date()).thenReturn(Instant.ofEpochSecond(feeV2DateAfterChargeCreatedDate));
when(stripeGatewayConfig.getFeePercentageV2()).thenReturn(0.50);
when(stripeGatewayConfig.getRadarFeeInPence()).thenReturn(5);
when(stripeGatewayConfig.getThreeDsFeeInPence()).thenReturn(10);
ChargeEntity chargeEntity = aValidChargeEntity().withGatewayAccountEntity(gatewayAccount).withTransactionId(transactionId).withAmount(10000L).withCreatedDate(Instant.ofEpochSecond(chargeCreatedDate)).withGatewayAccountCredentialsEntity(aGatewayAccountCredentialsEntity().withCredentials(Map.of("stripe_account_id", "stripe_account_id")).withPaymentProvider(STRIPE.getName()).build()).withEvents(List.of(aChargeEventEntity().withStatus(AUTHORISATION_3DS_REQUIRED).build(), aChargeEventEntity().withStatus(CREATED).build())).build();
captureGatewayRequest = CaptureGatewayRequest.valueOf(chargeEntity);
CaptureResponse captureResponse = stripeCaptureHandler.capture(captureGatewayRequest);
ArgumentCaptor<StripeTransferOutRequest> transferRequestCaptor = ArgumentCaptor.forClass(StripeTransferOutRequest.class);
verify(gatewayClient, times(2)).postRequestFor(transferRequestCaptor.capture());
assertThat(transferRequestCaptor.getValue().getGatewayOrder().getPayload(), containsString("amount=9885"));
assertTrue(captureResponse.isSuccessful());
List<Fee> feeList = captureResponse.getFeeList();
assertThat(feeList.size(), is(3));
assertThat(captureResponse.getFeeList(), containsInAnyOrder(Fee.of(FeeType.TRANSACTION, 100L), Fee.of(FeeType.RADAR, 5L), Fee.of(FeeType.THREE_D_S, 10L)));
}
Aggregations