Search in sources :

Example 26 with PaymentAttemptModelDao

use of org.killbill.billing.payment.dao.PaymentAttemptModelDao in project killbill by killbill.

the class TestRetryService method testFailedPaymentWithOneSuccessfulRetry.

@Test(groups = "fast")
public void testFailedPaymentWithOneSuccessfulRetry() throws Exception {
    final Account account = testHelper.createTestAccount("yiyi.gmail.com", true);
    final Invoice invoice = testHelper.createTestInvoice(account, clock.getUTCToday(), Currency.USD);
    final BigDecimal amount = new BigDecimal("10.00");
    final UUID subscriptionId = UUID.randomUUID();
    final UUID bundleId = UUID.randomUUID();
    final LocalDate startDate = clock.getUTCToday();
    final LocalDate endDate = startDate.plusMonths(1);
    invoice.addInvoiceItem(new MockRecurringInvoiceItem(invoice.getId(), account.getId(), subscriptionId, bundleId, "test plan", "test phase", null, startDate, endDate, amount, new BigDecimal("1.0"), Currency.USD));
    setPaymentFailure(FailureType.PAYMENT_FAILURE);
    final String paymentExternalKey = UUID.randomUUID().toString();
    final String transactionExternalKey = UUID.randomUUID().toString();
    invoicePaymentInternalApi.createPurchaseForInvoicePayment(false, account, invoice.getId(), account.getPaymentMethodId(), null, amount, Currency.USD, null, paymentExternalKey, transactionExternalKey, NO_PROPERTIES, PAYMENT_OPTIONS, internalCallContext);
    Payment payment = getPaymentForExternalKey(paymentExternalKey);
    List<PaymentAttemptModelDao> attempts = paymentDao.getPaymentAttempts(paymentExternalKey, internalCallContext);
    assertEquals(attempts.size(), 1);
    final List<PaymentTransactionModelDao> transactions = paymentDao.getTransactionsForPayment(payment.getId(), internalCallContext);
    assertEquals(transactions.size(), 1);
    moveClockForFailureType(FailureType.PAYMENT_FAILURE, 0);
    await().atMost(TIMEOUT, SECONDS).until(new Callable<Boolean>() {

        @Override
        public Boolean call() throws Exception {
            final List<PaymentAttemptModelDao> attempts = paymentDao.getPaymentAttempts(paymentExternalKey, internalCallContext);
            final List<PaymentAttemptModelDao> filteredAttempts = ImmutableList.copyOf(Iterables.filter(attempts, new Predicate<PaymentAttemptModelDao>() {

                @Override
                public boolean apply(final PaymentAttemptModelDao input) {
                    return input.getStateName().equals("SUCCESS") || input.getStateName().equals("RETRIED") || input.getStateName().equals("ABORTED");
                }
            }));
            return filteredAttempts.size() == 2;
        }
    });
    attempts = paymentDao.getPaymentAttempts(payment.getExternalKey(), internalCallContext);
    final int expectedAttempts = 2;
    assertEquals(attempts.size(), expectedAttempts);
    Collections.sort(attempts, new Comparator<PaymentAttemptModelDao>() {

        @Override
        public int compare(final PaymentAttemptModelDao o1, final PaymentAttemptModelDao o2) {
            return o1.getCreatedDate().compareTo(o2.getCreatedDate());
        }
    });
    for (int i = 0; i < attempts.size(); i++) {
        final PaymentAttemptModelDao cur = attempts.get(i);
        if (i < attempts.size() - 1) {
            assertEquals(cur.getStateName(), "RETRIED");
        } else {
            assertEquals(cur.getStateName(), "SUCCESS");
        }
    }
}
Also used : PaymentAttemptModelDao(org.killbill.billing.payment.dao.PaymentAttemptModelDao) Account(org.killbill.billing.account.api.Account) Invoice(org.killbill.billing.invoice.api.Invoice) LocalDate(org.joda.time.LocalDate) BigDecimal(java.math.BigDecimal) PaymentApiException(org.killbill.billing.payment.api.PaymentApiException) Payment(org.killbill.billing.payment.api.Payment) PaymentTransactionModelDao(org.killbill.billing.payment.dao.PaymentTransactionModelDao) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) UUID(java.util.UUID) Test(org.testng.annotations.Test)

Example 27 with PaymentAttemptModelDao

use of org.killbill.billing.payment.dao.PaymentAttemptModelDao in project killbill by killbill.

the class TestRetryService method testAbortedPayment.

@Test(groups = "fast")
public void testAbortedPayment() throws Exception {
    final Account account = testHelper.createTestAccount("yiyi.gmail.com", true);
    final Invoice invoice = testHelper.createTestInvoice(account, clock.getUTCToday(), Currency.USD);
    final BigDecimal amount = new BigDecimal("10.00");
    final UUID subscriptionId = UUID.randomUUID();
    final UUID bundleId = UUID.randomUUID();
    final LocalDate startDate = clock.getUTCToday();
    final LocalDate endDate = startDate.plusMonths(1);
    invoice.addInvoiceItem(new MockRecurringInvoiceItem(invoice.getId(), account.getId(), subscriptionId, bundleId, "test plan", "test phase", null, startDate, endDate, amount, new BigDecimal("1.0"), Currency.USD));
    setPaymentFailure(FailureType.PAYMENT_FAILURE);
    final String paymentExternalKey = UUID.randomUUID().toString();
    final String transactionExternalKey = UUID.randomUUID().toString();
    invoicePaymentInternalApi.createPurchaseForInvoicePayment(false, account, invoice.getId(), account.getPaymentMethodId(), null, amount, Currency.USD, null, paymentExternalKey, transactionExternalKey, NO_PROPERTIES, PAYMENT_OPTIONS, internalCallContext);
    Payment payment = getPaymentForExternalKey(paymentExternalKey);
    List<PaymentAttemptModelDao> attempts = paymentDao.getPaymentAttempts(paymentExternalKey, internalCallContext);
    assertEquals(attempts.size(), 1);
    final List<PaymentTransactionModelDao> transactions = paymentDao.getTransactionsForPayment(payment.getId(), internalCallContext);
    assertEquals(transactions.size(), 1);
    int maxTries = paymentConfig.getPaymentFailureRetryDays(internalCallContext).size();
    for (int curFailure = 0; curFailure < maxTries; curFailure++) {
        // Set plugin to fail with specific type unless this is the last attempt and we want a success
        setPaymentFailure(FailureType.PAYMENT_FAILURE);
        moveClockForFailureType(FailureType.PAYMENT_FAILURE, curFailure);
        final int curFailureCondition = curFailure;
        await().atMost(TIMEOUT, SECONDS).until(new Callable<Boolean>() {

            @Override
            public Boolean call() throws Exception {
                final List<PaymentAttemptModelDao> attempts = paymentDao.getPaymentAttempts(paymentExternalKey, internalCallContext);
                final List<PaymentAttemptModelDao> filteredAttempts = ImmutableList.copyOf(Iterables.filter(attempts, new Predicate<PaymentAttemptModelDao>() {

                    @Override
                    public boolean apply(final PaymentAttemptModelDao input) {
                        return input.getStateName().equals("SUCCESS") || input.getStateName().equals("RETRIED") || input.getStateName().equals("ABORTED");
                    }
                }));
                return filteredAttempts.size() == curFailureCondition + 2;
            }
        });
    }
    attempts = paymentDao.getPaymentAttempts(payment.getExternalKey(), internalCallContext);
    final int expectedAttempts = maxTries + 1;
    assertEquals(attempts.size(), expectedAttempts);
    Collections.sort(attempts, new Comparator<PaymentAttemptModelDao>() {

        @Override
        public int compare(final PaymentAttemptModelDao o1, final PaymentAttemptModelDao o2) {
            return o1.getCreatedDate().compareTo(o2.getCreatedDate());
        }
    });
    for (int i = 0; i < attempts.size(); i++) {
        final PaymentAttemptModelDao cur = attempts.get(i);
        if (i < attempts.size() - 1) {
            assertEquals(cur.getStateName(), "RETRIED");
        } else {
            assertEquals(cur.getStateName(), "ABORTED");
        }
    }
}
Also used : PaymentAttemptModelDao(org.killbill.billing.payment.dao.PaymentAttemptModelDao) Account(org.killbill.billing.account.api.Account) Invoice(org.killbill.billing.invoice.api.Invoice) LocalDate(org.joda.time.LocalDate) BigDecimal(java.math.BigDecimal) PaymentApiException(org.killbill.billing.payment.api.PaymentApiException) Payment(org.killbill.billing.payment.api.Payment) PaymentTransactionModelDao(org.killbill.billing.payment.dao.PaymentTransactionModelDao) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) UUID(java.util.UUID) Test(org.testng.annotations.Test)

Example 28 with PaymentAttemptModelDao

use of org.killbill.billing.payment.dao.PaymentAttemptModelDao in project killbill by killbill.

the class TestRetryablePayment method testRetryToSuccessWithPaymentApiExceptionAndNoRetry.

@Test(groups = "fast")
public void testRetryToSuccessWithPaymentApiExceptionAndNoRetry() {
    mockRetryProviderPlugin.setAborted(false).setNextRetryDate(null);
    mockRetryAuthorizeOperationCallback.setResult(null).setException(new PaymentApiException(ErrorCode.__UNKNOWN_ERROR_CODE, "bla"));
    runner.setOperationCallback(mockRetryAuthorizeOperationCallback).setContext(paymentStateContext);
    final State state = retrySMHelper.getRetriedState();
    final UUID transactionId = UUID.randomUUID();
    paymentDao.insertPaymentAttemptWithProperties(new PaymentAttemptModelDao(account.getId(), paymentMethodId, utcNow, utcNow, paymentExternalKey, transactionId, paymentTransactionExternalKey, TransactionType.AUTHORIZE, state.getName(), amount, currency, null, EMPTY_PROPERTIES), internalCallContext);
    try {
        runner.run(state, false, TransactionType.AUTHORIZE, ControlOperation.AUTHORIZE, account, paymentMethodId, null, paymentExternalKey, paymentTransactionExternalKey, amount, currency, null, emptyProperties, null, callContext, internalCallContext);
        fail("Expecting paymentApiException...");
    } catch (final PaymentApiException e) {
        final List<PaymentAttemptModelDao> pas = paymentDao.getPaymentAttemptByTransactionExternalKey(paymentTransactionExternalKey, internalCallContext);
        assertEquals(pas.size(), 2);
        final PaymentAttemptModelDao failedAttempts = Iterables.tryFind(pas, new Predicate<PaymentAttemptModelDao>() {

            @Override
            public boolean apply(final PaymentAttemptModelDao input) {
                return input.getTransactionType() == TransactionType.AUTHORIZE && input.getStateName().equals("ABORTED");
            }
        }).orNull();
        assertNotNull(failedAttempts);
    }
}
Also used : PaymentAttemptModelDao(org.killbill.billing.payment.dao.PaymentAttemptModelDao) State(org.killbill.automaton.State) PaymentApiException(org.killbill.billing.payment.api.PaymentApiException) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) UUID(java.util.UUID) Test(org.testng.annotations.Test)

Example 29 with PaymentAttemptModelDao

use of org.killbill.billing.payment.dao.PaymentAttemptModelDao in project killbill by killbill.

the class TestRetryablePayment method testInitToAborted.

@Test(groups = "fast")
public void testInitToAborted() throws PaymentApiException {
    mockRetryProviderPlugin.setAborted(true).setNextRetryDate(null);
    mockRetryAuthorizeOperationCallback.setResult(OperationResult.SUCCESS).setException(null);
    runner.setOperationCallback(mockRetryAuthorizeOperationCallback).setContext(paymentStateContext);
    try {
        runner.run(true, TransactionType.AUTHORIZE, ControlOperation.AUTHORIZE, account, paymentMethodId, null, paymentExternalKey, paymentTransactionExternalKey, amount, currency, null, emptyProperties, null, callContext, internalCallContext);
        fail();
    } catch (PaymentApiException e) {
        assertEquals(e.getCode(), ErrorCode.PAYMENT_PLUGIN_API_ABORTED.getCode());
    }
    assertFalse(mockRetryProviderPlugin.isOnSuccessCallExecuted(), "OnSuccessCall method should not be called when payment is aborted");
    assertFalse(mockRetryProviderPlugin.isOnFailureCallExecuted(), "onFailureCall method should not be called when payment is aborted");
    final PaymentAttemptModelDao pa = paymentDao.getPaymentAttemptByTransactionExternalKey(paymentTransactionExternalKey, internalCallContext).get(0);
    assertEquals(pa.getTransactionExternalKey(), paymentTransactionExternalKey);
    assertEquals(pa.getStateName(), "ABORTED");
    assertEquals(pa.getTransactionType(), TransactionType.AUTHORIZE);
}
Also used : PaymentAttemptModelDao(org.killbill.billing.payment.dao.PaymentAttemptModelDao) PaymentApiException(org.killbill.billing.payment.api.PaymentApiException) Test(org.testng.annotations.Test)

Example 30 with PaymentAttemptModelDao

use of org.killbill.billing.payment.dao.PaymentAttemptModelDao in project killbill by killbill.

the class TestRetryablePayment method testRetryToSuccessWithResSuccess.

@Test(groups = "fast")
public void testRetryToSuccessWithResSuccess() throws PaymentApiException {
    mockRetryProviderPlugin.setAborted(false).setNextRetryDate(null);
    mockRetryAuthorizeOperationCallback.setResult(OperationResult.SUCCESS).setException(null);
    runner.setOperationCallback(mockRetryAuthorizeOperationCallback).setContext(paymentStateContext);
    final State state = retrySMHelper.getRetriedState();
    final UUID transactionId = UUID.randomUUID();
    paymentDao.insertPaymentAttemptWithProperties(new PaymentAttemptModelDao(account.getId(), paymentMethodId, utcNow, utcNow, paymentExternalKey, transactionId, paymentTransactionExternalKey, TransactionType.AUTHORIZE, state.getName(), amount, currency, null, EMPTY_PROPERTIES), internalCallContext);
    runner.run(state, false, TransactionType.AUTHORIZE, ControlOperation.AUTHORIZE, account, paymentMethodId, null, paymentExternalKey, paymentTransactionExternalKey, amount, currency, null, emptyProperties, null, callContext, internalCallContext);
    final List<PaymentAttemptModelDao> pas = paymentDao.getPaymentAttemptByTransactionExternalKey(paymentTransactionExternalKey, internalCallContext);
    assertEquals(pas.size(), 2);
    final PaymentAttemptModelDao successfulAttempt = Iterables.tryFind(pas, new Predicate<PaymentAttemptModelDao>() {

        @Override
        public boolean apply(final PaymentAttemptModelDao input) {
            return input.getTransactionType() == TransactionType.AUTHORIZE && input.getStateName().equals("SUCCESS");
        }
    }).orNull();
    assertNotNull(successfulAttempt);
}
Also used : PaymentAttemptModelDao(org.killbill.billing.payment.dao.PaymentAttemptModelDao) State(org.killbill.automaton.State) UUID(java.util.UUID) Predicate(com.google.common.base.Predicate) Test(org.testng.annotations.Test)

Aggregations

PaymentAttemptModelDao (org.killbill.billing.payment.dao.PaymentAttemptModelDao)33 Test (org.testng.annotations.Test)24 UUID (java.util.UUID)16 PaymentApiException (org.killbill.billing.payment.api.PaymentApiException)15 PaymentTransactionModelDao (org.killbill.billing.payment.dao.PaymentTransactionModelDao)12 BigDecimal (java.math.BigDecimal)10 LocalDate (org.joda.time.LocalDate)10 Invoice (org.killbill.billing.invoice.api.Invoice)10 Account (org.killbill.billing.account.api.Account)8 Payment (org.killbill.billing.payment.api.Payment)8 DateTime (org.joda.time.DateTime)7 State (org.killbill.automaton.State)7 Predicate (com.google.common.base.Predicate)6 ArrayList (java.util.ArrayList)6 PaymentModelDao (org.killbill.billing.payment.dao.PaymentModelDao)6 ImmutableList (com.google.common.collect.ImmutableList)5 List (java.util.List)5 AccountData (org.killbill.billing.account.api.AccountData)3 ExpectedInvoiceItemCheck (org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck)3 InternalCallContext (org.killbill.billing.callcontext.InternalCallContext)3