From 08a79e48bc8cb2d1ac2b758e4db9a9a0a9416484 Mon Sep 17 00:00:00 2001 From: Steven Date: Tue, 21 Jul 2020 21:37:26 +0100 Subject: [PATCH 1/2] PP-6758: use flat refund in csv consumer Currently the flat refund projection puts data in a `payment_details` object. Where this data is pulled from may change. --- .../model/CsvTransactionFactory.java | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/main/java/uk/gov/pay/ledger/transaction/model/CsvTransactionFactory.java b/src/main/java/uk/gov/pay/ledger/transaction/model/CsvTransactionFactory.java index 37f525dfa..c26fc90ae 100644 --- a/src/main/java/uk/gov/pay/ledger/transaction/model/CsvTransactionFactory.java +++ b/src/main/java/uk/gov/pay/ledger/transaction/model/CsvTransactionFactory.java @@ -81,7 +81,7 @@ public Map toMap(TransactionEntity transactionEntity) { if (TransactionType.PAYMENT.toString().equals(transactionEntity.getTransactionType())) { result.putAll( - getPaymentTransactionAttributes(transactionEntity) + getPaymentTransactionAttributes(transactionEntity, transactionDetails) ); result.put(FIELD_AMOUNT, penceToCurrency(transactionEntity.getAmount())); @@ -93,7 +93,7 @@ public Map toMap(TransactionEntity transactionEntity) { if (TransactionType.REFUND.toString().equals(transactionEntity.getTransactionType())) { if (transactionEntity.getParentTransactionEntity() != null) { result.putAll( - getPaymentTransactionAttributes(transactionEntity.getParentTransactionEntity()) + getPaymentTransactionAttributes(transactionEntity, transactionDetails.get("payment_details")) ); } @@ -130,12 +130,9 @@ public Map toMap(TransactionEntity transactionEntity) { return result; } - private Map getPaymentTransactionAttributes(TransactionEntity transactionEntity) throws IOException { + private Map getPaymentTransactionAttributes(TransactionEntity transactionEntity, JsonNode details) throws IOException { Map result = new HashMap<>(); - JsonNode transactionDetails = objectMapper.readTree( - Optional.ofNullable(transactionEntity.getTransactionDetails()).orElse("{}")); - result.put(FIELD_REFERENCE, sanitiseAgainstSpreadsheetFormulaInjection(transactionEntity.getReference())); result.put(FIELD_DESC, sanitiseAgainstSpreadsheetFormulaInjection(transactionEntity.getDescription())); result.put(FIELD_EMAIL, sanitiseAgainstSpreadsheetFormulaInjection(transactionEntity.getEmail())); @@ -143,14 +140,14 @@ private Map getPaymentTransactionAttributes(TransactionEntity tr result.put(FIELD_CARD_NUMBER, transactionEntity.getLastDigitsCardNumber()); result.put(FIELD_GOVUK_PAYMENT_ID, transactionEntity.getExternalId()); - result.put(FIELD_CARD_BRAND, safeGetAsString(transactionDetails, "card_brand_label")); - result.put(FIELD_CARD_EXPIRY_DATE, safeGetAsString(transactionDetails, "expiry_date")); - result.put(FIELD_PROVIDER_ID, safeGetAsString(transactionDetails, "gateway_transaction_id")); - result.put(FIELD_CARD_TYPE, StringUtils.lowerCase(safeGetAsString(transactionDetails, "card_type"))); + result.put(FIELD_CARD_BRAND, safeGetAsString(details, "card_brand_label")); + result.put(FIELD_CARD_EXPIRY_DATE, safeGetAsString(details, "expiry_date")); + result.put(FIELD_PROVIDER_ID, sanitiseAgainstSpreadsheetFormulaInjection(transactionEntity.getGatewayTransactionId())); + result.put(FIELD_CARD_TYPE, StringUtils.lowerCase(safeGetAsString(details, "card_type"))); result.put(FIELD_MOTO, transactionEntity.isMoto()); result.put(FIELD_WALLET_TYPE, capitalizeFully( - replaceChars(safeGetAsString(transactionDetails, "wallet"), '_', ' ')) + replaceChars(safeGetAsString(details, "wallet"), '_', ' ')) ); return result; From e328172762a1ae3320a78429d012d2abb9f1a7b1 Mon Sep 17 00:00:00 2001 From: Steven Date: Wed, 22 Jul 2020 19:22:34 +0100 Subject: [PATCH 2/2] PP-6578: update csv cursor query to use TransactionMapper Remove parent logic from CSV query and directly map results to entities using `TransactionMapper`. --- .../transaction/dao/TransactionDao.java | 4 +- .../model/CsvTransactionFactory.java | 35 ++++++------- .../model/CsvTransactionFactoryTest.java | 50 +++++++++---------- .../resource/TransactionResourceCsvIT.java | 23 +++++---- .../util/fixture/TransactionFixture.java | 38 ++++++++++++-- 5 files changed, 92 insertions(+), 58 deletions(-) diff --git a/src/main/java/uk/gov/pay/ledger/transaction/dao/TransactionDao.java b/src/main/java/uk/gov/pay/ledger/transaction/dao/TransactionDao.java index 39e2d1853..c85f2abfc 100644 --- a/src/main/java/uk/gov/pay/ledger/transaction/dao/TransactionDao.java +++ b/src/main/java/uk/gov/pay/ledger/transaction/dao/TransactionDao.java @@ -71,7 +71,7 @@ public class TransactionDao { "ORDER BY t.created_date DESC OFFSET :offset LIMIT :limit"; private static final String SEARCH_TRANSACTIONS_CURSOR = - SEARCH_TRANSACTIONS_WITH_PARENT_BASE + + "SELECT * FROM transaction t " + ":searchExtraFields " + ":cursorFields " + "ORDER BY t.created_date DESC, t.id DESC LIMIT :limit"; @@ -295,7 +295,7 @@ public List cursorTransactionSearch(TransactionSearchParams s query.bind("startingAfterId", startingAfterId); query.bind("limit", cursorPageSize); - return query.map(new TransactionWithParentMapper()).list(); + return query.map(new TransactionMapper()).list(); }); } diff --git a/src/main/java/uk/gov/pay/ledger/transaction/model/CsvTransactionFactory.java b/src/main/java/uk/gov/pay/ledger/transaction/model/CsvTransactionFactory.java index c26fc90ae..1c8cded37 100644 --- a/src/main/java/uk/gov/pay/ledger/transaction/model/CsvTransactionFactory.java +++ b/src/main/java/uk/gov/pay/ledger/transaction/model/CsvTransactionFactory.java @@ -24,6 +24,7 @@ import static java.math.BigDecimal.valueOf; import static org.apache.commons.lang3.StringUtils.isBlank; +import static org.apache.commons.lang3.StringUtils.lowerCase; import static org.apache.commons.lang3.StringUtils.replaceChars; import static org.apache.commons.text.WordUtils.capitalizeFully; import static uk.gov.pay.ledger.util.JsonParser.safeGetAsLong; @@ -84,19 +85,19 @@ public Map toMap(TransactionEntity transactionEntity) { getPaymentTransactionAttributes(transactionEntity, transactionDetails) ); + result.put(FIELD_GOVUK_PAYMENT_ID, transactionEntity.getExternalId()); result.put(FIELD_AMOUNT, penceToCurrency(transactionEntity.getAmount())); result.put(FIELD_TOTAL_AMOUNT, penceToCurrency(totalAmount)); result.put(FIELD_NET, penceToCurrency(netAmount)); result.put(FIELD_FEE, penceToCurrency(transactionEntity.getFee())); result.put(FIELD_STATE, PaymentState.getDisplayName(transactionEntity.getState())); + result.put(FIELD_MOTO, transactionEntity.isMoto()); } if (TransactionType.REFUND.toString().equals(transactionEntity.getTransactionType())) { - if (transactionEntity.getParentTransactionEntity() != null) { - result.putAll( - getPaymentTransactionAttributes(transactionEntity, transactionDetails.get("payment_details")) - ); - } - + result.putAll( + getPaymentTransactionAttributes(transactionEntity, transactionDetails.get("payment_details")) + ); + result.put(FIELD_GOVUK_PAYMENT_ID, transactionEntity.getParentExternalId()); result.put(FIELD_AMOUNT, penceToCurrency(transactionEntity.getAmount() * -1)); result.put(FIELD_NET, penceToCurrency(netAmount * -1)); result.put(FIELD_TOTAL_AMOUNT, penceToCurrency(totalAmount * -1)); @@ -104,6 +105,7 @@ public Map toMap(TransactionEntity transactionEntity) { result.put(FIELD_STATE, RefundState.getDisplayName(transactionEntity.getState())); } + result.put(FIELD_PROVIDER_ID, sanitiseAgainstSpreadsheetFormulaInjection(transactionEntity.getGatewayTransactionId())); result.put(FIELD_DATE_CREATED, dateCreated); result.put(FIELD_TIME_CREATED, timeCreated); result.put(FIELD_CORPORATE_CARD_SURCHARGE, penceToCurrency( @@ -130,7 +132,8 @@ public Map toMap(TransactionEntity transactionEntity) { return result; } - private Map getPaymentTransactionAttributes(TransactionEntity transactionEntity, JsonNode details) throws IOException { + private Map getPaymentTransactionAttributes(TransactionEntity transactionEntity, JsonNode details) { + Map result = new HashMap<>(); result.put(FIELD_REFERENCE, sanitiseAgainstSpreadsheetFormulaInjection(transactionEntity.getReference())); @@ -138,17 +141,15 @@ private Map getPaymentTransactionAttributes(TransactionEntity tr result.put(FIELD_EMAIL, sanitiseAgainstSpreadsheetFormulaInjection(transactionEntity.getEmail())); result.put(FIELD_CARDHOLDER_NAME, sanitiseAgainstSpreadsheetFormulaInjection(transactionEntity.getCardholderName())); result.put(FIELD_CARD_NUMBER, transactionEntity.getLastDigitsCardNumber()); - result.put(FIELD_GOVUK_PAYMENT_ID, transactionEntity.getExternalId()); - - result.put(FIELD_CARD_BRAND, safeGetAsString(details, "card_brand_label")); - result.put(FIELD_CARD_EXPIRY_DATE, safeGetAsString(details, "expiry_date")); - result.put(FIELD_PROVIDER_ID, sanitiseAgainstSpreadsheetFormulaInjection(transactionEntity.getGatewayTransactionId())); - result.put(FIELD_CARD_TYPE, StringUtils.lowerCase(safeGetAsString(details, "card_type"))); - result.put(FIELD_MOTO, transactionEntity.isMoto()); - result.put(FIELD_WALLET_TYPE, capitalizeFully( - replaceChars(safeGetAsString(details, "wallet"), '_', ' ')) - ); + if (details != null) { + result.put(FIELD_CARD_BRAND, safeGetAsString(details, "card_brand_label")); + result.put(FIELD_CARD_EXPIRY_DATE, safeGetAsString(details, "expiry_date")); + result.put(FIELD_CARD_TYPE, lowerCase(safeGetAsString(details, "card_type"))); + result.put(FIELD_WALLET_TYPE, capitalizeFully( + replaceChars(safeGetAsString(details, "wallet"), '_', ' ')) + ); + } return result; } diff --git a/src/test/java/uk/gov/pay/ledger/transaction/model/CsvTransactionFactoryTest.java b/src/test/java/uk/gov/pay/ledger/transaction/model/CsvTransactionFactoryTest.java index c4cc79a92..abc1bea92 100644 --- a/src/test/java/uk/gov/pay/ledger/transaction/model/CsvTransactionFactoryTest.java +++ b/src/test/java/uk/gov/pay/ledger/transaction/model/CsvTransactionFactoryTest.java @@ -33,19 +33,14 @@ public void setUp() { .withState(TransactionState.FAILED_REJECTED) .withTransactionType(TransactionType.PAYMENT.name()) .withAmount(100L) + .withGatewayTransactionId("gateway-transaction-id") .withCreatedDate(ZonedDateTime.parse("2018-03-12T16:25:01.123456Z")) .withTotalAmount(123L) - .withTransactionDetails( - new GsonBuilder().create() - .toJson(ImmutableMap.builder() - .put("expiry_date", "10/24") - .put("user_email", "refundedbyuser@example.org") - .put("corporate_surcharge", 23) - .put("wallet", "APPLE_PAY") - .put("card_type", "DEBIT") - .put("card_brand_label", "Visa") - .build()) - ); + .withMoto(true) + .withCorporateCardSurcharge(23) + .withCardBrandLabel("Visa") + .withDefaultCardDetails() + .withDefaultTransactionDetails(); } @Test @@ -58,6 +53,8 @@ public void toMapShouldReturnMapWithCorrectCsvDataForPaymentTransaction() { assertPaymentDetails(csvDataMap, transactionEntity); assertThat(csvDataMap.get("Amount"), is("1.00")); + assertThat(csvDataMap.get("GOV.UK Payment ID"), is(transactionEntity.getExternalId())); + assertThat(csvDataMap.get("Provider ID"), is(transactionEntity.getGatewayTransactionId())); assertThat(csvDataMap.get("State"), is("Declined")); assertThat(csvDataMap.get("Finished"), is(true)); assertThat(csvDataMap.get("Error Code"), is("P0010")); @@ -66,27 +63,30 @@ public void toMapShouldReturnMapWithCorrectCsvDataForPaymentTransaction() { assertThat(csvDataMap.get("Time Created"), is("16:25:01")); assertThat(csvDataMap.get("Corporate Card Surcharge"), is("0.23")); assertThat(csvDataMap.get("Total Amount"), is("1.23")); + assertThat(csvDataMap.get("MOTO"), is(true)); } @Test public void toMapShouldReturnMapWithCorrectCsvDataForRefundTransaction() { - TransactionEntity transactionEntity = transactionFixture - .withMoto(true) - .toEntity(); - TransactionEntity refundTransactionEntity = transactionFixture.withTransactionType("REFUND") + TransactionFixture refundTransactionFixture = aTransactionFixture() + .withCreatedDate(ZonedDateTime.parse("2018-03-12T16:25:01.123456Z")) + .withTransactionType("REFUND") .withAmount(99L) .withTotalAmount(99L) .withState(TransactionState.ERROR) - .withParentTransactionEntity(transactionEntity) - .withTransactionDetails(new GsonBuilder().create() - .toJson(ImmutableMap.builder().put("user_email", "refundedbyuser@example.org").build())) - .toEntity(); + .withGatewayTransactionId("refund-gateway-transaction-id") + .withRefundedByUserEmail("refundedbyuser@example.org") + .withParentExternalId("parent-external-id") + .withDefaultPaymentDetails() + .withDefaultTransactionDetails(); - Map csvDataMap = csvTransactionFactory.toMap(refundTransactionEntity); + Map csvDataMap = csvTransactionFactory.toMap(refundTransactionFixture.toEntity()); - assertPaymentDetails(csvDataMap, refundTransactionEntity.getParentTransactionEntity()); + assertPaymentDetails(csvDataMap, refundTransactionFixture.toEntity()); assertThat(csvDataMap.get("Amount"), is("-0.99")); + assertThat(csvDataMap.get("Provider ID"), is(refundTransactionFixture.getGatewayTransactionId())); + assertThat(csvDataMap.get("GOV.UK Payment ID"), is(refundTransactionFixture.getParentExternalId())); assertThat(csvDataMap.get("State"), is("Refund error")); assertThat(csvDataMap.get("Finished"), is(true)); assertThat(csvDataMap.get("Error Code"), is("P0050")); @@ -96,7 +96,7 @@ public void toMapShouldReturnMapWithCorrectCsvDataForRefundTransaction() { assertThat(csvDataMap.get("Corporate Card Surcharge"), is("0.00")); assertThat(csvDataMap.get("Total Amount"), is("-0.99")); assertThat(csvDataMap.get("Net"), is("-0.99")); - assertThat(csvDataMap.get("MOTO"), is(true)); + assertThat(csvDataMap.get("MOTO"), is(nullValue())); } @Test @@ -206,11 +206,9 @@ private void assertPaymentDetails(Map csvDataMap, TransactionEnt assertThat(csvDataMap.get("Email"), is(transactionEntity.getEmail())); assertThat(csvDataMap.get("Card Brand"), is("Visa")); assertThat(csvDataMap.get("Cardholder Name"), is(transactionEntity.getCardholderName())); - assertThat(csvDataMap.get("Card Expiry Date"), is("10/24")); + assertThat(csvDataMap.get("Card Expiry Date"), is("10/21")); assertThat(csvDataMap.get("Card Number"), is(transactionEntity.getLastDigitsCardNumber())); - assertThat(csvDataMap.get("Provider ID"), is(transactionEntity.getGatewayTransactionId())); - assertThat(csvDataMap.get("GOV.UK Payment ID"), is(transactionEntity.getExternalId())); - assertThat(csvDataMap.get("Card Type"), is("debit")); + assertThat(csvDataMap.get("Card Type"), is("credit")); assertThat(csvDataMap.get("Wallet Type"), is("Apple Pay")); } } \ No newline at end of file diff --git a/src/test/java/uk/gov/pay/ledger/transaction/resource/TransactionResourceCsvIT.java b/src/test/java/uk/gov/pay/ledger/transaction/resource/TransactionResourceCsvIT.java index 9f586a41e..c721a8d75 100644 --- a/src/test/java/uk/gov/pay/ledger/transaction/resource/TransactionResourceCsvIT.java +++ b/src/test/java/uk/gov/pay/ledger/transaction/resource/TransactionResourceCsvIT.java @@ -1,12 +1,10 @@ package uk.gov.pay.ledger.transaction.resource; import com.google.common.collect.ImmutableMap; -import io.dropwizard.testing.junit5.DropwizardExtensionsSupport; import org.apache.commons.csv.CSVParser; import org.apache.commons.csv.CSVRecord; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.RegisterExtension; import uk.gov.pay.ledger.extension.AppWithPostgresAndSqsExtension; import uk.gov.pay.ledger.metadatakey.dao.MetadataKeyDao; @@ -75,7 +73,7 @@ public void shouldGetAllTransactionsAsCSVWithAcceptType() throws IOException { .withGatewayAccountId(otherGatewayAccountId) .insert(rule.getJdbi()); - aTransactionFixture() + TransactionFixture refundTransactionFixture = aTransactionFixture() .withTransactionType("REFUND") .withParentExternalId(transactionFixture.getExternalId()) .withGatewayAccountId(transactionFixture.getGatewayAccountId()) @@ -84,6 +82,8 @@ public void shouldGetAllTransactionsAsCSVWithAcceptType() throws IOException { .withAmount(100L) .withTotalAmount(100L) .withState(TransactionState.ERROR_GATEWAY) + .withGatewayTransactionId("refund-gateway-transaction-id") + .withDefaultPaymentDetails() .withDefaultTransactionDetails() .insert(rule.getJdbi()); @@ -110,8 +110,10 @@ public void shouldGetAllTransactionsAsCSVWithAcceptType() throws IOException { CSVRecord paymentRecord = csvRecords.get(0); assertThat(paymentRecord.size(), is(22)); - assertPaymentTransactionDetails(paymentRecord, transactionFixture); + assertCommonPaymentFields(paymentRecord, transactionFixture); assertThat(paymentRecord.get("Amount"), is("1.23")); + assertThat(paymentRecord.get("GOV.UK Payment ID"), is(transactionFixture.getExternalId())); + assertThat(paymentRecord.get("Provider ID"), is(transactionFixture.getGatewayTransactionId())); assertThat(paymentRecord.get("State"), is("Error")); assertThat(paymentRecord.get("Finished"), is("true")); assertThat(paymentRecord.get("Error Code"), is("P0050")); @@ -127,8 +129,10 @@ public void shouldGetAllTransactionsAsCSVWithAcceptType() throws IOException { assertThat(paymentRecord.isMapped("MOTO"), is(false)); CSVRecord refundRecord = csvRecords.get(1); - assertPaymentTransactionDetails(refundRecord, transactionFixture); + assertCommonPaymentFields(refundRecord, refundTransactionFixture); assertThat(refundRecord.get("Amount"), is("-1.00")); + assertThat(refundRecord.get("GOV.UK Payment ID"), is(refundTransactionFixture.getParentExternalId())); + assertThat(refundRecord.get("Provider ID"), is(refundTransactionFixture.getGatewayTransactionId())); assertThat(refundRecord.get("State"), is("Refund error")); assertThat(refundRecord.get("Finished"), is("true")); assertThat(refundRecord.get("Error Code"), is("P0050")); @@ -139,6 +143,7 @@ public void shouldGetAllTransactionsAsCSVWithAcceptType() throws IOException { assertThat(refundRecord.get("Total Amount"), is("-1.00")); assertThat(refundRecord.get("Wallet Type"), is("Apple Pay")); assertThat(refundRecord.get("Issued By"), is("refund-by-user-email@example.org")); + assertThat(refundRecord.isMapped("MOTO"), is(false)); } @Test @@ -364,16 +369,14 @@ public void shouldGetAllTransactionsForAGivenGatewayPayoutId() throws IOExceptio assertThat(paymentRecord.get("GOV.UK Payment ID"), is(transactionFixture.getExternalId())); } - private void assertPaymentTransactionDetails(CSVRecord csvRecord, TransactionFixture transactionFixture) { + private void assertCommonPaymentFields(CSVRecord csvRecord, TransactionFixture transactionFixture) { assertThat(csvRecord.get("Reference"), is(transactionFixture.getReference())); assertThat(csvRecord.get("Description"), is(transactionFixture.getDescription())); assertThat(csvRecord.get("Email"), is("someone@example.org")); - assertThat(csvRecord.get("Card Brand"), is("Diners Club")); - assertThat(csvRecord.get("Cardholder Name"), is("J Doe")); + assertThat(csvRecord.get("Card Brand"), is(transactionFixture.getCardBrandLabel())); + assertThat(csvRecord.get("Cardholder Name"), is(transactionFixture.getCardholderName())); assertThat(csvRecord.get("Card Expiry Date"), is("10/21")); assertThat(csvRecord.get("Card Number"), is("1234")); - assertThat(csvRecord.get("Provider ID"), is("gateway-transaction-id")); - assertThat(csvRecord.get("GOV.UK Payment ID"), is(transactionFixture.getExternalId())); assertThat(csvRecord.get("Card Type"), is("credit")); } } \ No newline at end of file diff --git a/src/test/java/uk/gov/pay/ledger/util/fixture/TransactionFixture.java b/src/test/java/uk/gov/pay/ledger/util/fixture/TransactionFixture.java index 332e31c17..5df26d430 100644 --- a/src/test/java/uk/gov/pay/ledger/util/fixture/TransactionFixture.java +++ b/src/test/java/uk/gov/pay/ledger/util/fixture/TransactionFixture.java @@ -120,6 +120,10 @@ public Long getId() { return id; } + public String getCardExpiryDate() { + return cardExpiryDate; + } + public TransactionFixture withId(Long id) { this.id = id; return this; @@ -221,12 +225,18 @@ public String getCardBrand() { return cardBrand; } + public String getCardBrandLabel() { + return cardBrandLabel; + } + public TransactionFixture withCardBrand(String cardBrand) { this.cardBrand = cardBrand; return this; } - public boolean isMoto() { return moto;} + public boolean isMoto() { + return moto; + } public TransactionFixture withMoto(boolean moto) { this.moto = moto; @@ -378,6 +388,10 @@ public TransactionFixture insert(Jdbi jdbi) { @NotNull private JsonObject getTransactionDetail() { JsonObject transactionDetails = new JsonObject(); + JsonObject refundPaymentDetails = new JsonObject(); + + String defaultCardType = String.valueOf(CREDIT); + String defaultWalletType = "APPLE_PAY"; transactionDetails.addProperty("language", language); transactionDetails.addProperty("return_url", returnUrl); @@ -387,8 +401,17 @@ private JsonObject getTransactionDetail() { transactionDetails.addProperty("corporate_surcharge", corporateCardSurcharge); transactionDetails.addProperty("refunded_by", refundedById); transactionDetails.addProperty("user_email", refundedByUserEmail); - transactionDetails.addProperty("card_type", String.valueOf(CREDIT)); - transactionDetails.addProperty("wallet", "APPLE_PAY"); + transactionDetails.addProperty("card_type", defaultCardType); + transactionDetails.addProperty("wallet", defaultWalletType); + + if ("REFUND".equals(transactionType)) { + refundPaymentDetails.addProperty("card_brand_label", cardBrandLabel); + refundPaymentDetails.addProperty("expiry_date", cardExpiryDate); + refundPaymentDetails.addProperty("card_type", defaultCardType); + refundPaymentDetails.addProperty("wallet", defaultWalletType); + transactionDetails.add("payment_details", refundPaymentDetails); + } + Optional.ofNullable(cardBrandLabel) .ifPresent(cardBrandLabel -> transactionDetails.addProperty("card_brand_label", cardBrandLabel)); Optional.ofNullable(externalMetadata) @@ -593,4 +616,13 @@ public TransactionFixture withRefundedByUserEmail(String refundedByUserEmail) { this.refundedByUserEmail = refundedByUserEmail; return this; } + + public TransactionFixture withDefaultPaymentDetails() { + // default values are already assigned for cardBrand, cardholderName, reference, description, email + + this.firstDigitsCardNumber = "123456"; + this.lastDigitsCardNumber = "1234"; + this.cardBrandLabel = "Visa"; + return this; + } }