diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a1248686..b9c788c64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ # CHANGELOG -## Next release +## Next Release +- Fix payment method funding and deletion failures due to undetermined payment method type - Adds `refund` function in Insurance service for requesting a refund for a standalone insurance ## v7.1.1 (2024-03-21) diff --git a/src/main/java/com/easypost/model/PaymentMethodObject.java b/src/main/java/com/easypost/model/PaymentMethodObject.java index b81284a67..f8cfbfa07 100644 --- a/src/main/java/com/easypost/model/PaymentMethodObject.java +++ b/src/main/java/com/easypost/model/PaymentMethodObject.java @@ -59,9 +59,10 @@ public PaymentMethodType getType() { if (getId() == null) { return null; } - if (getId().startsWith("card_")) { + String objectType = getObject(); + if (getId().startsWith("card_") || (objectType != null && objectType.equals("CreditCard"))) { type = PaymentMethodType.CREDIT_CARD; - } else if (getId().startsWith("bank_")) { + } else if (getId().startsWith("bank_") || (objectType != null && objectType.equals("BankAccount"))) { type = PaymentMethodType.BANK_ACCOUNT; } return type; diff --git a/src/test/java/com/easypost/BillingTest.java b/src/test/java/com/easypost/BillingTest.java index 1141bcc52..762264b7c 100644 --- a/src/test/java/com/easypost/BillingTest.java +++ b/src/test/java/com/easypost/BillingTest.java @@ -12,16 +12,29 @@ import org.mockito.Mockito; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; public final class BillingTest { private static TestUtils.VCR vcr; private String jsonResponse = "{\"id\":\"cust_...\",\"object\":\"PaymentMethods\",\"primary_" + - "payment_method\":{\"id\":\"card_...\",\"disabled_at\":null,\"object\":\"CreditCard\",\"na" + + "payment_method\":{\"id\":\"pm_...\",\"disabled_at\":null,\"object\":\"CreditCard\",\"na" + "me\":null,\"last4\":\"4242\",\"exp_month\":1,\"exp_year\":2025,\"brand\":\"Visa\"},\"secondar" + - "y_payment_method\":{\"id\":\"card_...\",\"disabled_at\":null,\"object\":\"CreditCard\",\"name\":nu" + + "y_payment_method\":{\"id\":\"pm_...\",\"disabled_at\":null,\"object\":\"BankAccount\",\"name\":nu" + "ll,\"last4\":\"4444\",\"exp_month\":1,\"exp_year\":2025,\"brand\":\"Mastercard\"}}"; private PaymentMethod paymentMethod = Constants.Http.GSON.fromJson(jsonResponse, PaymentMethod.class); + + private String jsonResponseLegacyPrefixes = "{\"id\":\"cust_...\",\"object\":\"PaymentMethods\",\"primary_" + + "payment_method\":{\"id\":\"card_...\",\"disabled_at\":null,\"object\":null,\"na" + + "me\":null,\"last4\":\"4242\",\"exp_month\":1,\"exp_year\":2025,\"brand\":\"Visa\"},\"secondar" + + "y_payment_method\":{\"id\":\"bank_...\",\"disabled_at\":null,\"object\":null,\"name\":nu" + + "ll,\"last4\":\"4444\",\"exp_month\":1,\"exp_year\":2025,\"brand\":\"Mastercard\"}}"; + + private PaymentMethod paymentMethodLegacyPrefixes = + Constants.Http.GSON.fromJson(jsonResponseLegacyPrefixes, PaymentMethod.class); + private static MockedStatic requestMock = Mockito.mockStatic(Requestor.class); /** @@ -100,4 +113,56 @@ public void testRetrievePaymentMethods() throws EasyPostException { assertNotNull(paymentMethods.getPrimaryPaymentMethod()); assertNotNull(paymentMethods.getSecondaryPaymentMethod()); } + + /** + * Test determining a payment method type by its object type. + * + * @throws EasyPostException when the request fails. + */ + @Test + public void testDeterminePaymentMethodTypeByObjectType() throws EasyPostException { + requestMock.when(() -> Requestor.request( + RequestMethod.GET, "payment_methods", null, PaymentMethod.class, vcr.client)) + .thenReturn(paymentMethod); + + // Should be a credit card with "CreditCard" object type and "pm_" prefix + PaymentMethodObject creditCard = + vcr.client.billing.retrievePaymentMethods().getPrimaryPaymentMethod(); + assertTrue(creditCard.getId().startsWith("pm_")); + assertEquals("CreditCard", creditCard.getObject()); + assertEquals(PaymentMethodObject.PaymentMethodType.CREDIT_CARD, creditCard.getType()); + + // Should be a bank account with "BankAccount" object type and "pm_" prefix + PaymentMethodObject bankAccount = + vcr.client.billing.retrievePaymentMethods().getSecondaryPaymentMethod(); + assertTrue(bankAccount.getId().startsWith("pm_")); + assertEquals("BankAccount", bankAccount.getObject()); + assertEquals(PaymentMethodObject.PaymentMethodType.BANK_ACCOUNT, bankAccount.getType()); + } + + /** + * Test determining a payment method type by its legacy prefix. + * + * @throws EasyPostException when the request fails. + */ + @Test + public void testDeterminePaymentMethodTypeByLegacyPrefix() throws EasyPostException { + requestMock.when(() -> Requestor.request( + RequestMethod.GET, "payment_methods", null, PaymentMethod.class, vcr.client)) + .thenReturn(paymentMethodLegacyPrefixes); + + // Should be a credit card with null object type and "card_" prefix + PaymentMethodObject creditCard = + vcr.client.billing.retrievePaymentMethods().getPrimaryPaymentMethod(); + assertTrue(creditCard.getId().startsWith("card_")); + assertNull(creditCard.getObject()); + assertEquals(PaymentMethodObject.PaymentMethodType.CREDIT_CARD, creditCard.getType()); + + // Should be a bank account with null object type and "bank_" prefix + PaymentMethodObject bankAccount = + vcr.client.billing.retrievePaymentMethods().getSecondaryPaymentMethod(); + assertTrue(bankAccount.getId().startsWith("bank_")); + assertNull(bankAccount.getObject()); + assertEquals(PaymentMethodObject.PaymentMethodType.BANK_ACCOUNT, bankAccount.getType()); + } }