diff --git a/src/main/java/com/adyen/enums/VatCategory.java b/src/main/java/com/adyen/enums/VatCategory.java new file mode 100644 index 000000000..ed2eb5f2d --- /dev/null +++ b/src/main/java/com/adyen/enums/VatCategory.java @@ -0,0 +1,19 @@ +package com.adyen.enums; + +public enum VatCategory { + HIGH { + public String toString(){ + return "High"; + } + }, + LOW { + public String toString(){ + return "Low"; + } + }, + NONE { + public String toString(){ + return "None"; + } + } +} diff --git a/src/main/java/com/adyen/model/PaymentRequest.java b/src/main/java/com/adyen/model/PaymentRequest.java index 5710dc161..eb54fc7f6 100644 --- a/src/main/java/com/adyen/model/PaymentRequest.java +++ b/src/main/java/com/adyen/model/PaymentRequest.java @@ -15,8 +15,10 @@ import com.adyen.Util.Util; import com.adyen.constants.ApiConstants; +import com.adyen.model.additionalData.InvoiceLine; import com.google.gson.annotations.SerializedName; +import java.util.List; import java.util.Objects; /** @@ -35,6 +37,8 @@ public class PaymentRequest extends AbstractPaymentRequest { @SerializedName("bankAccount") private BankAccount bankAccount = null; + private List invoiceLines = null; + public PaymentRequest setAmountData(String amount, String currency) { Amount amountData = Util.createAmount(amount, currency); this.setAmount(amountData); @@ -62,6 +66,57 @@ public PaymentRequest setCardData(String cardNumber, return this; } + /** + * Set invoiceLines in addtionalData + * + * @param invoiceLines + * @return + */ + public PaymentRequest setInvoiceLines(List invoiceLines) { + + Integer count = 1; + for (InvoiceLine invoiceLine : invoiceLines) { + + StringBuilder sb = new StringBuilder(); + sb.append("openinvoicedata.line"); + sb.append(Integer.toString(count)); + String lineNumber = sb.toString(); + + this.getOrCreateAdditionalData().put( + new StringBuilder().append(lineNumber).append(".currencyCode").toString(), + invoiceLine.getCurrencyCode()); + + this.getOrCreateAdditionalData().put( + new StringBuilder().append(lineNumber).append(".description").toString(), + invoiceLine.getDescription()); + + this.getOrCreateAdditionalData().put( + new StringBuilder().append(lineNumber).append(".itemAmount").toString(), + invoiceLine.getItemAmount().toString()); + + this.getOrCreateAdditionalData().put( + new StringBuilder().append(lineNumber).append(".itemVatAmount").toString(), + invoiceLine.getItemVATAmount().toString()); + + this.getOrCreateAdditionalData().put( + new StringBuilder().append(lineNumber).append(".itemVatPercentage").toString(), + invoiceLine.getItemVatPercentage().toString()); + + this.getOrCreateAdditionalData().put( + new StringBuilder().append(lineNumber).append(".numberOfItems").toString(), + Integer.toString(invoiceLine.getNumberOfItems())); + + this.getOrCreateAdditionalData().put( + new StringBuilder().append(lineNumber).append(".vatCategory").toString(), + invoiceLine.getVatCategory().toString()); + + count++; + } + + this.getOrCreateAdditionalData().put("openinvoicedata.numberOfLines", Integer.toString(invoiceLines.size())); + return this; + } + public PaymentRequest card(Card card) { this.card = card; return this; diff --git a/src/main/java/com/adyen/model/additionalData/InvoiceLine.java b/src/main/java/com/adyen/model/additionalData/InvoiceLine.java new file mode 100644 index 000000000..0a4ce7456 --- /dev/null +++ b/src/main/java/com/adyen/model/additionalData/InvoiceLine.java @@ -0,0 +1,70 @@ +package com.adyen.model.additionalData; + +import com.adyen.enums.VatCategory; + +public class InvoiceLine { + + private String currencyCode = null; + private String description = null; + private Long itemAmount = null; + private Long itemVATAmount = null; + private Long itemVatPercentage = null; + private Integer numberOfItems = null; + private VatCategory vatCategory = null; + + public String getCurrencyCode() { + return currencyCode; + } + + public void setCurrencyCode(String currencyCode) { + this.currencyCode = currencyCode; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Long getItemAmount() { + return itemAmount; + } + + public void setItemAmount(Long itemAmount) { + this.itemAmount = itemAmount; + } + + public Long getItemVATAmount() { + return itemVATAmount; + } + + public void setItemVATAmount(Long itemVATAmount) { + this.itemVATAmount = itemVATAmount; + } + + public Long getItemVatPercentage() { + return itemVatPercentage; + } + + public void setItemVatPercentage(Long itemVatPercentage) { + this.itemVatPercentage = itemVatPercentage; + } + + public Integer getNumberOfItems() { + return numberOfItems; + } + + public void setNumberOfItems(Integer numberOfItems) { + this.numberOfItems = numberOfItems; + } + + public VatCategory getVatCategory() { + return vatCategory; + } + + public void setVatCategory(VatCategory vatCategory) { + this.vatCategory = vatCategory; + } +} diff --git a/src/test/java/com/adyen/BaseTest.java b/src/test/java/com/adyen/BaseTest.java index 9ea9d6d88..50eb61a69 100644 --- a/src/test/java/com/adyen/BaseTest.java +++ b/src/test/java/com/adyen/BaseTest.java @@ -1,18 +1,17 @@ package com.adyen; +import com.adyen.enums.VatCategory; import com.adyen.httpclient.HTTPClientException; import com.adyen.httpclient.HttpURLConnectionClient; -import com.adyen.model.AbstractPaymentRequest; -import com.adyen.model.PaymentRequest; -import com.adyen.model.PaymentRequest3d; +import com.adyen.model.*; +import com.adyen.model.additionalData.InvoiceLine; import com.adyen.model.modification.AbstractModificationRequest; import com.adyen.model.modification.CaptureRequest; import org.apache.commons.io.IOUtils; import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.text.SimpleDateFormat; +import java.util.*; import static org.mockito.Mockito.*; @@ -119,6 +118,88 @@ protected PaymentRequest createFullCardPaymentRequest() { return paymentRequest; } + /** + * Returns a sample PaymentRequest opbject with full OpenInvoice request + * + * @return + */ + protected PaymentRequest createOpenInvoicePaymentRequest() { + + Date dateOfBirth = null; + try { + SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd"); + dateOfBirth = fmt.parse("1970-07-10"); + } catch (Exception e) { + } + + PaymentRequest paymentRequest = createBasePaymentRequest(new PaymentRequest()) + .reference("123456") + .setAmountData( + "200", + "EUR" + ); + + // Set Shopper Data + paymentRequest.setShopperEmail("youremail@email.com"); + paymentRequest.setDateOfBirth(dateOfBirth); + paymentRequest.setTelephoneNumber("0612345678"); + paymentRequest.setShopperReference("4"); + + // Set Shopper Info + Name shopperName = new Name(); + shopperName.setFirstName("Testperson-nl"); + shopperName.setLastName("Approved"); + shopperName.gender(Name.GenderEnum.MALE); + paymentRequest.setShopperName(shopperName); + + // Set Billing and Delivery address + Address address = new Address(); + address.setCity("Gravenhage"); + address.setCountry("NL"); + address.setHouseNumberOrName("1"); + address.setPostalCode("2521VA"); + address.setStateOrProvince("Zuid-Holland"); + address.setStreet("Neherkade"); + paymentRequest.setDeliveryAddress(address); + paymentRequest.setBillingAddress(address); + + // Use OpenInvoice Provider (klarna, ratepay) + paymentRequest.selectedBrand("klarna"); + + Long itemAmount = new Long("9000"); + Long itemVatAmount = new Long("1000"); + Long itemVatPercentage = new Long("1000"); + + List invoiceLines = new ArrayList(); + + // invoiceLine1 + InvoiceLine invoiceLine = new InvoiceLine(); + invoiceLine.setCurrencyCode("EUR"); + invoiceLine.setDescription("Test product"); + invoiceLine.setItemAmount(itemAmount); + invoiceLine.setItemVATAmount(itemVatAmount); + invoiceLine.setItemVatPercentage(itemVatPercentage); + invoiceLine.setVatCategory(VatCategory.NONE); + invoiceLine.setNumberOfItems(1); + + // invoiceLine2 + InvoiceLine invoiceLine2 = new InvoiceLine(); + invoiceLine2.setCurrencyCode("EUR"); + invoiceLine2.setDescription("Test product 2"); + invoiceLine2.setItemAmount(itemAmount); + invoiceLine2.setItemVATAmount(itemVatAmount); + invoiceLine2.setItemVatPercentage(itemVatPercentage); + invoiceLine2.setVatCategory(VatCategory.NONE); + invoiceLine2.setNumberOfItems(1); + + invoiceLines.add(invoiceLine); + invoiceLines.add(invoiceLine2); + + paymentRequest.setInvoiceLines(invoiceLines); + + return paymentRequest; + } + /** * Returns a sample PaymentRequest object with CSE data * diff --git a/src/test/java/com/adyen/PaymentRequestBuilderTest.java b/src/test/java/com/adyen/PaymentRequestBuilderTest.java index 7bda96903..a0ec782e1 100644 --- a/src/test/java/com/adyen/PaymentRequestBuilderTest.java +++ b/src/test/java/com/adyen/PaymentRequestBuilderTest.java @@ -1,6 +1,5 @@ package com.adyen; -import com.adyen.BaseTest; import com.adyen.model.PaymentRequest; import com.adyen.model.PaymentRequest3d; import com.google.gson.Gson; diff --git a/src/test/java/com/adyen/PaymentRequestTest.java b/src/test/java/com/adyen/PaymentRequestTest.java new file mode 100644 index 000000000..2f7fa030a --- /dev/null +++ b/src/test/java/com/adyen/PaymentRequestTest.java @@ -0,0 +1,33 @@ +package com.adyen; + + +import com.adyen.enums.VatCategory; +import com.adyen.model.PaymentRequest; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class PaymentRequestTest extends BaseTest { + + @Test + public void TestOpenInvoiceRequest() { + PaymentRequest paymentRequestOpenInvoice = createOpenInvoicePaymentRequest(); + assertEquals("2", paymentRequestOpenInvoice.getAdditionalData().get("openinvoicedata.numberOfLines")); + + assertEquals("EUR", paymentRequestOpenInvoice.getAdditionalData().get("openinvoicedata.line1.currencyCode")); + assertEquals("Test product", paymentRequestOpenInvoice.getAdditionalData().get("openinvoicedata.line1.description")); + assertEquals("9000", paymentRequestOpenInvoice.getAdditionalData().get("openinvoicedata.line1.itemAmount")); + assertEquals("1000", paymentRequestOpenInvoice.getAdditionalData().get("openinvoicedata.line1.itemVatAmount")); + assertEquals("1000", paymentRequestOpenInvoice.getAdditionalData().get("openinvoicedata.line1.itemVatPercentage")); + assertEquals("1", paymentRequestOpenInvoice.getAdditionalData().get("openinvoicedata.line1.numberOfItems")); + assertEquals(VatCategory.NONE.toString(), paymentRequestOpenInvoice.getAdditionalData().get("openinvoicedata.line1.vatCategory")); + + assertEquals("EUR", paymentRequestOpenInvoice.getAdditionalData().get("openinvoicedata.line2.currencyCode")); + assertEquals("Test product 2", paymentRequestOpenInvoice.getAdditionalData().get("openinvoicedata.line2.description")); + assertEquals("9000", paymentRequestOpenInvoice.getAdditionalData().get("openinvoicedata.line2.itemAmount")); + assertEquals("1000", paymentRequestOpenInvoice.getAdditionalData().get("openinvoicedata.line2.itemVatAmount")); + assertEquals("1000", paymentRequestOpenInvoice.getAdditionalData().get("openinvoicedata.line2.itemVatPercentage")); + assertEquals("1", paymentRequestOpenInvoice.getAdditionalData().get("openinvoicedata.line2.numberOfItems")); + assertEquals(VatCategory.NONE.toString(), paymentRequestOpenInvoice.getAdditionalData().get("openinvoicedata.line2.vatCategory")); + } +} \ No newline at end of file diff --git a/src/test/java/com/adyen/PaymentTest.java b/src/test/java/com/adyen/PaymentTest.java index 7ebf1207e..652e73623 100644 --- a/src/test/java/com/adyen/PaymentTest.java +++ b/src/test/java/com/adyen/PaymentTest.java @@ -198,4 +198,22 @@ public void TestError401Mocked() throws Exception { assertNull(e.getError()); } } + + /** + * Test OpenInvoice API flow for klarna + * + * @throws Exception + */ + @Test + public void TestOpenInvoice() throws Exception { + + Client client = createMockClientFromFile("mocks/authorise-success-klarna.json"); + Payment payment = new Payment(client); + + PaymentRequest paymentRequest = this.createOpenInvoicePaymentRequest(); + PaymentResult paymentResult = payment.authorise(paymentRequest); + assertEquals("2374421290", paymentResult.getAdditionalData().get("additionalData.acquirerReference")); + assertEquals("klarna", paymentResult.getAdditionalData().get("paymentMethodVariant")); + assertTrue(paymentResult.isAuthorised()); + } } diff --git a/src/test/resources/mocks/authorise-success-klarna.json b/src/test/resources/mocks/authorise-success-klarna.json new file mode 100644 index 000000000..fe3520ffe --- /dev/null +++ b/src/test/resources/mocks/authorise-success-klarna.json @@ -0,0 +1,8 @@ +{ + "additionalData": { + "additionalData.acquirerReference": "2374421290", + "paymentMethodVariant": "klarna" + }, + "pspReference": "8814906011087689", + "resultCode": "Authorised" +} \ No newline at end of file