Search in sources :

Example 16 with PaymentAttemptModelDao

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

the class TestInvoicePayment method testWithoutDefaultPaymentMethod.

@Test(groups = "slow")
public void testWithoutDefaultPaymentMethod() throws Exception {
    // 2012-05-01T00:03:42.000Z
    clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0));
    final AccountData accountData = getAccountData(0);
    final Account account = createAccount(accountData);
    accountChecker.checkAccount(account.getId(), accountData, callContext);
    final DefaultEntitlement baseEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
    final Invoice invoice1 = invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
    invoiceChecker.checkChargedThroughDate(baseEntitlement.getId(), new LocalDate(2012, 5, 1), callContext);
    // No invoice payment
    Assert.assertEquals(invoice1.getPayments().size(), 0);
    // There is one dangling payment attempt (not easy to get to...)
    final List<AuditLog> paymentAttemptsAuditLogs1 = new ArrayList<AuditLog>();
    for (final AuditLog auditLog : auditUserApi.getAccountAuditLogs(account.getId(), AuditLevel.FULL, callContext).getAuditLogs()) {
        if (auditLog.getAuditedObjectType() == ObjectType.PAYMENT_ATTEMPT) {
            paymentAttemptsAuditLogs1.add(auditLog);
        }
    }
    // One INSERT and one UPDATE
    Assert.assertEquals(paymentAttemptsAuditLogs1.size(), 2);
    final PaymentAttemptModelDao paymentAttempt1 = paymentDao.getPaymentAttempt(paymentAttemptsAuditLogs1.get(0).getAuditedEntityId(), internalCallContext);
    Assert.assertEquals(paymentAttempt1.getStateName(), "ABORTED");
    // 2012-05-31 => DAY 30 have to get out of trial {I0, P0}
    // Note that there is a INVOICE_PAYMENT_ERROR event in that case, unlike the AUTO_PAY_OFF/MANUAL_PAY usecase
    addDaysAndCheckForCompletion(30, NextEvent.PHASE, NextEvent.INVOICE, NextEvent.INVOICE_PAYMENT_ERROR);
    Invoice invoice2 = invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
    invoiceChecker.checkChargedThroughDate(baseEntitlement.getId(), new LocalDate(2012, 6, 30), callContext);
    // Invoice is not paid
    Assert.assertEquals(paymentApi.getAccountPayments(account.getId(), false, false, ImmutableList.<PluginProperty>of(), callContext).size(), 0);
    Assert.assertEquals(invoice2.getBalance().compareTo(new BigDecimal("249.95")), 0);
    Assert.assertEquals(invoiceUserApi.getAccountBalance(account.getId(), callContext).compareTo(invoice2.getBalance()), 0);
    // There is no invoice payment
    Assert.assertEquals(invoice2.getPayments().size(), 0);
    // There is another dangling payment attempt (not easy to get to...)
    final List<AuditLog> paymentAttemptsAuditLogs2 = new ArrayList<AuditLog>();
    for (final AuditLog auditLog : auditUserApi.getAccountAuditLogs(account.getId(), AuditLevel.FULL, callContext).getAuditLogs()) {
        if (auditLog.getAuditedObjectType() == ObjectType.PAYMENT_ATTEMPT && !paymentAttemptsAuditLogs1.contains(auditLog)) {
            paymentAttemptsAuditLogs2.add(auditLog);
        }
    }
    // One INSERT and one UPDATE
    Assert.assertEquals(paymentAttemptsAuditLogs2.size(), 2);
    final PaymentAttemptModelDao paymentAttempt2 = paymentDao.getPaymentAttempt(paymentAttemptsAuditLogs2.get(0).getAuditedEntityId(), internalCallContext);
    Assert.assertEquals(paymentAttempt2.getStateName(), "ABORTED");
    // Just verify we've found the right one
    Assert.assertNotEquals(paymentAttempt2.getId(), paymentAttempt1.getId());
}
Also used : PaymentAttemptModelDao(org.killbill.billing.payment.dao.PaymentAttemptModelDao) Account(org.killbill.billing.account.api.Account) Invoice(org.killbill.billing.invoice.api.Invoice) AccountData(org.killbill.billing.account.api.AccountData) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) ArrayList(java.util.ArrayList) ExpectedInvoiceItemCheck(org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) AuditLog(org.killbill.billing.util.audit.AuditLog) Test(org.testng.annotations.Test)

Example 17 with PaymentAttemptModelDao

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

the class TestInvoicePayment method testAUTO_PAY_OFFThenPartialPayment.

@Test(groups = "slow")
public void testAUTO_PAY_OFFThenPartialPayment() throws Exception {
    // 2012-05-01T00:03:42.000Z
    clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0));
    final AccountData accountData = getAccountData(0);
    final Account account = createAccountWithNonOsgiPaymentMethod(accountData);
    accountChecker.checkAccount(account.getId(), accountData, callContext);
    final DefaultEntitlement baseEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
    final Invoice invoice1 = invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
    invoiceChecker.checkChargedThroughDate(baseEntitlement.getId(), new LocalDate(2012, 5, 1), callContext);
    // No invoice payment
    Assert.assertEquals(invoice1.getPayments().size(), 0);
    // There is one dangling payment attempt (not easy to get to...)
    final List<AuditLog> paymentAttemptsAuditLogs1 = new ArrayList<AuditLog>();
    for (final AuditLog auditLog : auditUserApi.getAccountAuditLogs(account.getId(), AuditLevel.FULL, callContext).getAuditLogs()) {
        if (auditLog.getAuditedObjectType() == ObjectType.PAYMENT_ATTEMPT) {
            paymentAttemptsAuditLogs1.add(auditLog);
        }
    }
    // One INSERT and one UPDATE
    Assert.assertEquals(paymentAttemptsAuditLogs1.size(), 2);
    final PaymentAttemptModelDao paymentAttempt1 = paymentDao.getPaymentAttempt(paymentAttemptsAuditLogs1.get(0).getAuditedEntityId(), internalCallContext);
    Assert.assertEquals(paymentAttempt1.getStateName(), "ABORTED");
    // Put the account in AUTO_PAY_OFF to make sure payment system does not try to pay the initial invoice
    add_AUTO_PAY_OFF_Tag(account.getId(), ObjectType.ACCOUNT);
    // 2012-05-31 => DAY 30 have to get out of trial {I0, P0}
    addDaysAndCheckForCompletion(30, NextEvent.PHASE, NextEvent.INVOICE);
    Invoice invoice2 = invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2012, 6, 30), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
    invoiceChecker.checkChargedThroughDate(baseEntitlement.getId(), new LocalDate(2012, 6, 30), callContext);
    // Invoice is not paid
    Assert.assertEquals(paymentApi.getAccountPayments(account.getId(), false, false, ImmutableList.<PluginProperty>of(), callContext).size(), 0);
    Assert.assertEquals(invoice2.getBalance().compareTo(new BigDecimal("249.95")), 0);
    Assert.assertEquals(invoiceUserApi.getAccountBalance(account.getId(), callContext).compareTo(invoice2.getBalance()), 0);
    // No invoice payment
    Assert.assertEquals(invoice2.getPayments().size(), 0);
    // There is another dangling payment attempt (not easy to get to...)
    final List<AuditLog> paymentAttemptsAuditLogs2 = new ArrayList<AuditLog>();
    for (final AuditLog auditLog : auditUserApi.getAccountAuditLogs(account.getId(), AuditLevel.FULL, callContext).getAuditLogs()) {
        if (auditLog.getAuditedObjectType() == ObjectType.PAYMENT_ATTEMPT && !paymentAttemptsAuditLogs1.contains(auditLog)) {
            paymentAttemptsAuditLogs2.add(auditLog);
        }
    }
    // One INSERT and one UPDATE
    Assert.assertEquals(paymentAttemptsAuditLogs2.size(), 2);
    final PaymentAttemptModelDao paymentAttempt2 = paymentDao.getPaymentAttempt(paymentAttemptsAuditLogs2.get(0).getAuditedEntityId(), internalCallContext);
    Assert.assertEquals(paymentAttempt2.getStateName(), "ABORTED");
    // Just verify we've found the right one
    Assert.assertNotEquals(paymentAttempt2.getId(), paymentAttempt1.getId());
    // Trigger partial payment
    final Payment payment1 = createPaymentAndCheckForCompletion(account, invoice2, BigDecimal.TEN, account.getCurrency(), NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    paymentChecker.checkPayment(account.getId(), 1, callContext, new ExpectedPaymentCheck(new LocalDate(2012, 5, 31), BigDecimal.TEN, TransactionStatus.SUCCESS, invoice2.getId(), Currency.USD));
    Assert.assertEquals(payment1.getTransactions().size(), 1);
    Assert.assertEquals(payment1.getPurchasedAmount().compareTo(BigDecimal.TEN), 0);
    Assert.assertEquals(payment1.getTransactions().get(0).getProcessedAmount().compareTo(BigDecimal.TEN), 0);
    invoice2 = invoiceUserApi.getInvoice(invoice2.getId(), callContext);
    Assert.assertEquals(invoice2.getBalance().compareTo(new BigDecimal("239.95")), 0);
    Assert.assertEquals(invoiceUserApi.getAccountBalance(account.getId(), callContext).compareTo(invoice2.getBalance()), 0);
    // Remove AUTO_PAY_OFF and verify the invoice is fully paid
    remove_AUTO_PAY_OFF_Tag(account.getId(), ObjectType.ACCOUNT, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
    final Payment payment2 = paymentChecker.checkPayment(account.getId(), 2, callContext, new ExpectedPaymentCheck(new LocalDate(2012, 5, 31), new BigDecimal("239.95"), TransactionStatus.SUCCESS, invoice2.getId(), Currency.USD));
    Assert.assertEquals(payment2.getTransactions().size(), 1);
    Assert.assertEquals(payment2.getPurchasedAmount().compareTo(new BigDecimal("239.95")), 0);
    Assert.assertEquals(payment2.getTransactions().get(0).getProcessedAmount().compareTo(new BigDecimal("239.95")), 0);
    invoice2 = invoiceUserApi.getInvoice(invoice2.getId(), callContext);
    Assert.assertEquals(invoice2.getBalance().compareTo(BigDecimal.ZERO), 0);
    Assert.assertEquals(invoiceUserApi.getAccountBalance(account.getId(), callContext).compareTo(invoice2.getBalance()), 0);
}
Also used : PaymentAttemptModelDao(org.killbill.billing.payment.dao.PaymentAttemptModelDao) Account(org.killbill.billing.account.api.Account) Invoice(org.killbill.billing.invoice.api.Invoice) ArrayList(java.util.ArrayList) ExpectedInvoiceItemCheck(org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime) BigDecimal(java.math.BigDecimal) AuditLog(org.killbill.billing.util.audit.AuditLog) ExpectedPaymentCheck(org.killbill.billing.beatrix.util.PaymentChecker.ExpectedPaymentCheck) Payment(org.killbill.billing.payment.api.Payment) AccountData(org.killbill.billing.account.api.AccountData) DefaultEntitlement(org.killbill.billing.entitlement.api.DefaultEntitlement) Test(org.testng.annotations.Test)

Example 18 with PaymentAttemptModelDao

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

the class PaymentRefresher method getPaymentAttempts.

private List<PaymentAttempt> getPaymentAttempts(final List<PaymentAttemptModelDao> pastPaymentAttempts, final InternalTenantContext internalTenantContext) {
    final List<PaymentAttempt> paymentAttempts = new ArrayList<PaymentAttempt>();
    // Add Past Payment Attempts
    for (final PaymentAttemptModelDao pastPaymentAttempt : pastPaymentAttempts) {
        final PaymentAttempt paymentAttempt = new DefaultPaymentAttempt(pastPaymentAttempt.getAccountId(), pastPaymentAttempt.getPaymentMethodId(), pastPaymentAttempt.getId(), pastPaymentAttempt.getCreatedDate(), pastPaymentAttempt.getUpdatedDate(), pastPaymentAttempt.getCreatedDate(), pastPaymentAttempt.getPaymentExternalKey(), pastPaymentAttempt.getTransactionId(), pastPaymentAttempt.getTransactionExternalKey(), pastPaymentAttempt.getTransactionType(), pastPaymentAttempt.getStateName(), pastPaymentAttempt.getAmount(), pastPaymentAttempt.getCurrency(), pastPaymentAttempt.getPluginName(), buildPluginProperties(pastPaymentAttempt));
        paymentAttempts.add(paymentAttempt);
    }
    // Get Future Payment Attempts from Notification Queue and add them to the list
    try {
        final NotificationQueue retryQueue = notificationQueueService.getNotificationQueue(KILLBILL_SERVICES.PAYMENT_SERVICE.getServiceName(), DefaultRetryService.QUEUE_NAME);
        final Iterable<NotificationEventWithMetadata<NotificationEvent>> notificationEventWithMetadatas = retryQueue.getFutureNotificationForSearchKeys(internalTenantContext.getAccountRecordId(), internalTenantContext.getTenantRecordId());
        for (final NotificationEventWithMetadata<NotificationEvent> notificationEvent : notificationEventWithMetadatas) {
            // Last Attempt
            final PaymentAttemptModelDao lastPaymentAttempt = getLastPaymentAttempt(pastPaymentAttempts, ((PaymentRetryNotificationKey) notificationEvent.getEvent()).getAttemptId());
            if (lastPaymentAttempt != null) {
                final PaymentAttempt futurePaymentAttempt = new // accountId
                DefaultPaymentAttempt(// accountId
                lastPaymentAttempt.getAccountId(), // paymentMethodId
                lastPaymentAttempt.getPaymentMethodId(), // id
                ((PaymentRetryNotificationKey) notificationEvent.getEvent()).getAttemptId(), // createdDate
                null, // updatedDate
                null, // effectiveDate
                notificationEvent.getEffectiveDate(), // paymentExternalKey
                lastPaymentAttempt.getPaymentExternalKey(), // transactionId
                null, // transactionExternalKey
                lastPaymentAttempt.getTransactionExternalKey(), // transactionType
                lastPaymentAttempt.getTransactionType(), // stateName
                SCHEDULED, // amount
                lastPaymentAttempt.getAmount(), // currency
                lastPaymentAttempt.getCurrency(), // pluginName,
                ((PaymentRetryNotificationKey) notificationEvent.getEvent()).getPaymentControlPluginNames().get(0), // pluginProperties
                buildPluginProperties(lastPaymentAttempt));
                paymentAttempts.add(futurePaymentAttempt);
            }
        }
    } catch (final NoSuchNotificationQueue noSuchNotificationQueue) {
        log.error("ERROR Loading Notification Queue - " + noSuchNotificationQueue.getMessage());
    }
    return paymentAttempts;
}
Also used : PaymentAttemptModelDao(org.killbill.billing.payment.dao.PaymentAttemptModelDao) NoSuchNotificationQueue(org.killbill.notificationq.api.NotificationQueueService.NoSuchNotificationQueue) DefaultPaymentAttempt(org.killbill.billing.payment.api.DefaultPaymentAttempt) ArrayList(java.util.ArrayList) PaymentRetryNotificationKey(org.killbill.billing.payment.retry.PaymentRetryNotificationKey) DefaultPaymentAttempt(org.killbill.billing.payment.api.DefaultPaymentAttempt) PaymentAttempt(org.killbill.billing.payment.api.PaymentAttempt) NotificationEventWithMetadata(org.killbill.notificationq.api.NotificationEventWithMetadata) NotificationEvent(org.killbill.notificationq.api.NotificationEvent) NotificationQueue(org.killbill.notificationq.api.NotificationQueue) NoSuchNotificationQueue(org.killbill.notificationq.api.NotificationQueueService.NoSuchNotificationQueue)

Example 19 with PaymentAttemptModelDao

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

the class IncompletePaymentAttemptTask method updatePaymentAndTransactionIfNeeded.

private boolean updatePaymentAndTransactionIfNeeded(final UUID accountId, final UUID paymentTransactionId, @Nullable final TransactionStatus currentTransactionStatus, @Nullable final PaymentTransactionInfoPlugin paymentTransactionInfoPlugin, @Nullable final Integer attemptNumber, @Nullable final UUID userToken, final boolean isApiPayment, final InternalTenantContext internalTenantContext) throws LockFailedException {
    // First, fix the transaction itself
    final TransactionStatus latestTransactionStatus = incompletePaymentTransactionTask.updatePaymentAndTransactionIfNeeded2(accountId, paymentTransactionId, currentTransactionStatus, paymentTransactionInfoPlugin, isApiPayment, internalTenantContext);
    final boolean hasTransactionChanged = latestTransactionStatus == null;
    // Don't insert a notification for the on-the-fly Janitor
    final boolean shouldInsertNotification = attemptNumber != null;
    if (!hasTransactionChanged && shouldInsertNotification) {
        insertNewNotificationForUnresolvedTransactionIfNeeded(paymentTransactionId, latestTransactionStatus, attemptNumber, userToken, isApiPayment, internalTenantContext.getAccountRecordId(), internalTenantContext.getTenantRecordId());
    }
    // If there is a payment attempt associated with that transaction, we need to update it as well
    boolean hasAttemptChanged = false;
    final PaymentTransactionModelDao paymentTransactionModelDao = paymentDao.getPaymentTransaction(paymentTransactionId, internalTenantContext);
    if (paymentTransactionModelDao.getAttemptId() != null) {
        final PaymentAttemptModelDao paymentAttemptModelDao = paymentDao.getPaymentAttempt(paymentTransactionModelDao.getAttemptId(), internalTenantContext);
        if (paymentAttemptModelDao != null) {
            if (hasTransactionChanged || retrySMHelper.getInitialState().getName().equals(paymentAttemptModelDao.getStateName())) {
                // Run the completion part of the state machine to call the plugins and update the attempt in the right terminal state)
                hasAttemptChanged = doIteration(paymentAttemptModelDao, isApiPayment);
            }
        }
    }
    return hasTransactionChanged || hasAttemptChanged;
}
Also used : PaymentAttemptModelDao(org.killbill.billing.payment.dao.PaymentAttemptModelDao) PaymentTransactionModelDao(org.killbill.billing.payment.dao.PaymentTransactionModelDao) TransactionStatus(org.killbill.billing.payment.api.TransactionStatus)

Example 20 with PaymentAttemptModelDao

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

the class DefaultAdminPaymentApi method fixPaymentTransactionState.

// Very similar implementation as the Janitor (see IncompletePaymentTransactionTask / IncompletePaymentAttemptTask)
// The code is different enough to make it difficult to share unfortunately
@Override
public void fixPaymentTransactionState(final Payment payment, final PaymentTransaction paymentTransaction, @Nullable final TransactionStatus transactionStatusOrNull, @Nullable final String lastSuccessPaymentStateOrNull, @Nullable final String currentPaymentStateNameOrNull, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentApiException {
    final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(payment.getAccountId(), callContext);
    TransactionStatus transactionStatus = transactionStatusOrNull;
    if (transactionStatusOrNull == null) {
        checkNotNullParameter(paymentTransaction.getPaymentInfoPlugin(), "PaymentTransactionInfoPlugin");
        transactionStatus = PaymentTransactionInfoPluginConverter.toTransactionStatus(paymentTransaction.getPaymentInfoPlugin());
    }
    String currentPaymentStateName = currentPaymentStateNameOrNull;
    if (currentPaymentStateName == null) {
        switch(transactionStatus) {
            case PENDING:
                currentPaymentStateName = paymentSMHelper.getPendingStateForTransaction(paymentTransaction.getTransactionType());
                break;
            case SUCCESS:
                currentPaymentStateName = paymentSMHelper.getSuccessfulStateForTransaction(paymentTransaction.getTransactionType());
                break;
            case PAYMENT_FAILURE:
                currentPaymentStateName = paymentSMHelper.getFailureStateForTransaction(paymentTransaction.getTransactionType());
                break;
            case PLUGIN_FAILURE:
            case UNKNOWN:
            default:
                currentPaymentStateName = paymentSMHelper.getErroredStateForTransaction(paymentTransaction.getTransactionType());
                break;
        }
    }
    String lastSuccessPaymentState = lastSuccessPaymentStateOrNull;
    if (lastSuccessPaymentState == null && // Verify we are not updating an older transaction (only the last one has an impact on lastSuccessPaymentState)
    paymentTransaction.getId().equals(payment.getTransactions().get(payment.getTransactions().size() - 1).getId())) {
        if (paymentSMHelper.isSuccessState(currentPaymentStateName)) {
            lastSuccessPaymentState = currentPaymentStateName;
        } else {
            for (int i = payment.getTransactions().size() - 2; i >= 0; i--) {
                final PaymentTransaction transaction = payment.getTransactions().get(i);
                if (TransactionStatus.SUCCESS.equals(transaction.getTransactionStatus())) {
                    lastSuccessPaymentState = paymentSMHelper.getSuccessfulStateForTransaction(transaction.getTransactionType());
                    break;
                }
            }
        }
    }
    final PaymentAutomatonDAOHelper paymentAutomatonDAOHelper = new PaymentAutomatonDAOHelper(paymentDao, internalCallContext, paymentSMHelper);
    paymentAutomatonDAOHelper.processPaymentInfoPlugin(transactionStatus, paymentTransaction.getPaymentInfoPlugin(), currentPaymentStateName, lastSuccessPaymentState, // See https://github.com/killbill/killbill/issues/1061#issuecomment-521911301
    paymentTransaction.getAmount(), paymentTransaction.getCurrency(), payment.getAccountId(), null, payment.getId(), paymentTransaction.getId(), paymentTransaction.getTransactionType(), true, true);
    // If there is a payment attempt associated with that transaction, we need to update it as well
    final List<PaymentAttemptModelDao> paymentAttemptsModelDao = paymentDao.getPaymentAttemptByTransactionExternalKey(paymentTransaction.getExternalKey(), internalCallContext);
    final PaymentAttemptModelDao paymentAttemptModelDao = Iterables.<PaymentAttemptModelDao>tryFind(paymentAttemptsModelDao, new Predicate<PaymentAttemptModelDao>() {

        @Override
        public boolean apply(final PaymentAttemptModelDao input) {
            return paymentTransaction.getId().equals(input.getTransactionId());
        }
    }).orNull();
    if (paymentAttemptModelDao != null) {
        // We can re-use the logic from IncompletePaymentAttemptTask as it is doing very similar work (i.e. run the completion part of
        // the state machine to call the plugins and update the attempt in the right terminal state)
        incompletePaymentAttemptTask.doIteration(paymentAttemptModelDao, true);
    }
}
Also used : PaymentAttemptModelDao(org.killbill.billing.payment.dao.PaymentAttemptModelDao) PaymentAutomatonDAOHelper(org.killbill.billing.payment.core.sm.PaymentAutomatonDAOHelper) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) Predicate(com.google.common.base.Predicate)

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