Search in sources :

Example 16 with PaymentTransactionModelDao

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

the class TestRetryablePayment method testRetryLogicFromRetriedStateWithLockFailure.

@Test(groups = "fast")
public void testRetryLogicFromRetriedStateWithLockFailure() throws LockFailedException {
    GlobalLock lock = null;
    try {
        // Grab lock so that operation later will fail...
        lock = locker.lockWithNumberOfTries(LockerType.ACCNT_INV_PAY.toString(), account.getId().toString(), 1);
        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();
        final UUID paymentId = UUID.randomUUID();
        final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(account.getId(), paymentMethodId, utcNow, utcNow, paymentExternalKey, transactionId, paymentTransactionExternalKey, TransactionType.AUTHORIZE, state.getName(), amount, currency, null, EMPTY_PROPERTIES);
        paymentDao.insertPaymentAttemptWithProperties(attempt, internalCallContext);
        paymentDao.insertPaymentWithFirstTransaction(new PaymentModelDao(paymentId, utcNow, utcNow, account.getId(), paymentMethodId, -1, paymentExternalKey), new PaymentTransactionModelDao(transactionId, attempt.getId(), paymentTransactionExternalKey, utcNow, utcNow, paymentId, TransactionType.AUTHORIZE, utcNow, TransactionStatus.PAYMENT_FAILURE, amount, currency, "bla", "foo"), internalCallContext);
        processor.retryPaymentTransaction(attempt.getId(), ImmutableList.<String>of(MockPaymentControlProviderPlugin.PLUGIN_NAME), internalCallContext);
        final List<PaymentAttemptModelDao> pas = paymentDao.getPaymentAttemptByTransactionExternalKey(paymentTransactionExternalKey, internalCallContext);
        assertEquals(pas.size(), 2);
        final PaymentAttemptModelDao failedAttempt = Iterables.tryFind(pas, new Predicate<PaymentAttemptModelDao>() {

            @Override
            public boolean apply(final PaymentAttemptModelDao input) {
                return input.getTransactionType() == TransactionType.AUTHORIZE && input.getStateName().equals("ABORTED");
            }
        }).orNull();
        assertNotNull(failedAttempt);
    } finally {
        if (lock != null) {
            lock.release();
        }
    }
}
Also used : GlobalLock(org.killbill.commons.locker.GlobalLock) PaymentAttemptModelDao(org.killbill.billing.payment.dao.PaymentAttemptModelDao) PaymentTransactionModelDao(org.killbill.billing.payment.dao.PaymentTransactionModelDao) PaymentModelDao(org.killbill.billing.payment.dao.PaymentModelDao) State(org.killbill.automaton.State) UUID(java.util.UUID) Predicate(com.google.common.base.Predicate) Test(org.testng.annotations.Test)

Example 17 with PaymentTransactionModelDao

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

the class MockRetryAuthorizeOperationCallback method doCallSpecificOperationCallback.

@Override
protected Payment doCallSpecificOperationCallback() throws PaymentApiException {
    if (exception != null) {
        if (exception instanceof PaymentApiException) {
            throw (PaymentApiException) exception;
        } else if (exception instanceof RuntimeException) {
            throw (RuntimeException) exception;
        } else {
            throw new RuntimeException(exception);
        }
    }
    final PaymentModelDao payment = new PaymentModelDao(clock.getUTCNow(), clock.getUTCNow(), paymentStateContext.getAccount().getId(), paymentStateContext.getPaymentMethodId(), paymentStateContext.getPaymentExternalKey());
    final PaymentTransactionModelDao transaction = new PaymentTransactionModelDao(clock.getUTCNow(), clock.getUTCNow(), paymentStateContext.getAttemptId(), paymentStateContext.getPaymentTransactionExternalKey(), paymentStateContext.getPaymentId(), paymentStateContext.getTransactionType(), clock.getUTCNow(), TransactionStatus.SUCCESS, paymentStateContext.getAmount(), paymentStateContext.getCurrency(), "", "");
    final PaymentModelDao paymentModelDao = paymentDao.insertPaymentWithFirstTransaction(payment, transaction, paymentStateContext.getInternalCallContext());
    final PaymentTransaction convertedTransaction = new DefaultPaymentTransaction(transaction.getId(), paymentStateContext.getAttemptId(), transaction.getTransactionExternalKey(), transaction.getCreatedDate(), transaction.getUpdatedDate(), transaction.getPaymentId(), transaction.getTransactionType(), transaction.getEffectiveDate(), transaction.getTransactionStatus(), transaction.getAmount(), transaction.getCurrency(), transaction.getProcessedAmount(), transaction.getProcessedCurrency(), transaction.getGatewayErrorCode(), transaction.getGatewayErrorMsg(), null);
    return new DefaultPayment(paymentModelDao.getId(), paymentModelDao.getCreatedDate(), paymentModelDao.getUpdatedDate(), paymentModelDao.getAccountId(), paymentModelDao.getPaymentMethodId(), paymentModelDao.getPaymentNumber(), paymentModelDao.getExternalKey(), Collections.singletonList(convertedTransaction), null);
}
Also used : DefaultPaymentTransaction(org.killbill.billing.payment.api.DefaultPaymentTransaction) PaymentTransaction(org.killbill.billing.payment.api.PaymentTransaction) DefaultPayment(org.killbill.billing.payment.api.DefaultPayment) PaymentTransactionModelDao(org.killbill.billing.payment.dao.PaymentTransactionModelDao) PaymentModelDao(org.killbill.billing.payment.dao.PaymentModelDao) DefaultPaymentTransaction(org.killbill.billing.payment.api.DefaultPaymentTransaction) PaymentApiException(org.killbill.billing.payment.api.PaymentApiException)

Example 18 with PaymentTransactionModelDao

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

the class TestPaymentLeavingStateCallback method setUp.

private void setUp(@Nullable final UUID paymentId) throws Exception {
    account = Mockito.mock(Account.class);
    Mockito.when(account.getId()).thenReturn(UUID.randomUUID());
    paymentStateContext = new PaymentStateContext(true, paymentId, null, null, UUID.randomUUID().toString(), UUID.randomUUID().toString(), TransactionType.CAPTURE, account, UUID.randomUUID(), new BigDecimal("192.3920111"), Currency.BRL, null, null, false, null, ImmutableList.<PluginProperty>of(), internalCallContext, callContext);
    if (paymentId != null) {
        // Create the first payment manually
        final PaymentModelDao newPaymentModelDao = new PaymentModelDao(paymentId, clock.getUTCNow(), clock.getUTCNow(), paymentStateContext.getAccount().getId(), paymentStateContext.getPaymentMethodId(), 1, paymentStateContext.getPaymentExternalKey());
        final PaymentTransactionModelDao newPaymentTransactionModelDao = new PaymentTransactionModelDao(clock.getUTCNow(), clock.getUTCNow(), null, paymentStateContext.getPaymentTransactionExternalKey(), paymentId, paymentStateContext.getTransactionType(), clock.getUTCNow(), TransactionStatus.UNKNOWN, paymentStateContext.getAmount(), paymentStateContext.getCurrency(), null, null);
        paymentDao.insertPaymentWithFirstTransaction(newPaymentModelDao, newPaymentTransactionModelDao, internalCallContext);
    }
    final PaymentAutomatonDAOHelper daoHelper = new PaymentAutomatonDAOHelper(paymentStateContext, clock.getUTCNow(), paymentDao, paymentPluginServiceRegistration, internalCallContext, eventBus, paymentSMHelper);
    callback = new PaymentLeavingStateTestCallback(daoHelper, paymentStateContext);
    Mockito.when(state.getName()).thenReturn("NEW_STATE");
}
Also used : Account(org.killbill.billing.account.api.Account) PluginProperty(org.killbill.billing.payment.api.PluginProperty) PaymentTransactionModelDao(org.killbill.billing.payment.dao.PaymentTransactionModelDao) PaymentModelDao(org.killbill.billing.payment.dao.PaymentModelDao) BigDecimal(java.math.BigDecimal)

Example 19 with PaymentTransactionModelDao

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

the class TestRetryablePayment method testRetryLogicFromRetriedStateWithPaymentApiException.

@Test(groups = "fast")
public void testRetryLogicFromRetriedStateWithPaymentApiException() {
    mockRetryProviderPlugin.setAborted(false).setNextRetryDate(null);
    mockRetryAuthorizeOperationCallback.setResult(null).setException(new PaymentApiException(ErrorCode.__UNKNOWN_ERROR_CODE, "foo"));
    runner.setOperationCallback(mockRetryAuthorizeOperationCallback).setContext(paymentStateContext);
    final State state = retrySMHelper.getRetriedState();
    final UUID transactionId = UUID.randomUUID();
    final UUID paymentId = UUID.randomUUID();
    final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(account.getId(), paymentMethodId, utcNow, utcNow, paymentExternalKey, transactionId, paymentTransactionExternalKey, TransactionType.AUTHORIZE, state.getName(), amount, currency, null, EMPTY_PROPERTIES);
    paymentDao.insertPaymentAttemptWithProperties(attempt, internalCallContext);
    paymentDao.insertPaymentWithFirstTransaction(new PaymentModelDao(paymentId, utcNow, utcNow, account.getId(), paymentMethodId, -1, paymentExternalKey), new PaymentTransactionModelDao(transactionId, attempt.getId(), paymentTransactionExternalKey, utcNow, utcNow, paymentId, TransactionType.AUTHORIZE, utcNow, TransactionStatus.PAYMENT_FAILURE, amount, currency, "bla", "foo"), internalCallContext);
    processor.retryPaymentTransaction(attempt.getId(), ImmutableList.<String>of(MockPaymentControlProviderPlugin.PLUGIN_NAME), internalCallContext);
    final List<PaymentAttemptModelDao> pas = paymentDao.getPaymentAttemptByTransactionExternalKey(paymentTransactionExternalKey, internalCallContext);
    assertEquals(pas.size(), 2);
    final PaymentAttemptModelDao failedAttempt = Iterables.tryFind(pas, new Predicate<PaymentAttemptModelDao>() {

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

Example 20 with PaymentTransactionModelDao

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

the class IncompletePaymentAttemptTask method doIteration.

@Override
public void doIteration(final PaymentAttemptModelDao attempt) {
    // We don't grab account lock here as the lock will be taken when calling the completeRun API.
    final InternalTenantContext tenantContext = internalCallContextFactory.createInternalTenantContext(attempt.getTenantRecordId(), attempt.getAccountRecordId());
    final CallContext callContext = createCallContext("AttemptCompletionJanitorTask", tenantContext);
    final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(attempt.getAccountId(), callContext);
    final List<PaymentTransactionModelDao> transactions = paymentDao.getPaymentTransactionsByExternalKey(attempt.getTransactionExternalKey(), tenantContext);
    final List<PaymentTransactionModelDao> filteredTransactions = ImmutableList.copyOf(Iterables.filter(transactions, new Predicate<PaymentTransactionModelDao>() {

        @Override
        public boolean apply(final PaymentTransactionModelDao input) {
            return input.getAttemptId().equals(attempt.getId());
        }
    }));
    // We only expect at most one transaction for a given attempt, but as a precaution we check for more; if this is the case we log a warn and continue processing the first one.
    if (filteredTransactions.size() > 1) {
        log.warn("Found {} transactions for paymentAttempt {}", filteredTransactions.size(), attempt.getId());
    }
    final PaymentTransactionModelDao transaction = filteredTransactions.isEmpty() ? null : filteredTransactions.get(0);
    if (transaction == null) {
        log.info("Moving attemptId='{}' to ABORTED", attempt.getId());
        paymentDao.updatePaymentAttempt(attempt.getId(), attempt.getTransactionId(), "ABORTED", internalCallContext);
        return;
    }
    // at which point the attempt can also be transition to a different state.
    if (transaction.getTransactionStatus() == TransactionStatus.UNKNOWN) {
        return;
    }
    try {
        log.info("Completing attemptId='{}'", attempt.getId());
        final Account account = accountInternalApi.getAccountById(attempt.getAccountId(), tenantContext);
        // unclear
        final boolean isApiPayment = true;
        final PaymentStateControlContext paymentStateContext = new PaymentStateControlContext(attempt.toPaymentControlPluginNames(), isApiPayment, null, transaction.getPaymentId(), attempt.getPaymentExternalKey(), transaction.getId(), transaction.getTransactionExternalKey(), transaction.getTransactionType(), account, attempt.getPaymentMethodId(), transaction.getAmount(), transaction.getCurrency(), PluginPropertySerializer.deserialize(attempt.getPluginProperties()), internalCallContext, callContext);
        // Normally set by leavingState Callback
        paymentStateContext.setAttemptId(attempt.getId());
        // Normally set by raw state machine
        paymentStateContext.setPaymentTransactionModelDao(transaction);
        //
        // Will rerun the state machine with special callbacks to only make the executePluginOnSuccessCalls / executePluginOnFailureCalls calls
        // to the PaymentControlPluginApi plugin and transition the state.
        //
        pluginControlledPaymentAutomatonRunner.completeRun(paymentStateContext);
    } catch (final AccountApiException e) {
        log.warn("Error completing paymentAttemptId='{}'", attempt.getId(), e);
    } catch (final PluginPropertySerializerException e) {
        log.warn("Error completing paymentAttemptId='{}'", attempt.getId(), e);
    } catch (final PaymentApiException e) {
        log.warn("Error completing paymentAttemptId='{}'", attempt.getId(), e);
    }
}
Also used : Account(org.killbill.billing.account.api.Account) PaymentTransactionModelDao(org.killbill.billing.payment.dao.PaymentTransactionModelDao) PluginPropertySerializerException(org.killbill.billing.payment.dao.PluginPropertySerializer.PluginPropertySerializerException) InternalTenantContext(org.killbill.billing.callcontext.InternalTenantContext) AccountApiException(org.killbill.billing.account.api.AccountApiException) PaymentApiException(org.killbill.billing.payment.api.PaymentApiException) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) CallContext(org.killbill.billing.util.callcontext.CallContext) Predicate(com.google.common.base.Predicate) PaymentStateControlContext(org.killbill.billing.payment.core.sm.control.PaymentStateControlContext)

Aggregations

PaymentTransactionModelDao (org.killbill.billing.payment.dao.PaymentTransactionModelDao)39 PaymentModelDao (org.killbill.billing.payment.dao.PaymentModelDao)17 PaymentApiException (org.killbill.billing.payment.api.PaymentApiException)16 Test (org.testng.annotations.Test)16 UUID (java.util.UUID)12 BigDecimal (java.math.BigDecimal)10 PaymentAttemptModelDao (org.killbill.billing.payment.dao.PaymentAttemptModelDao)10 Predicate (com.google.common.base.Predicate)8 Payment (org.killbill.billing.payment.api.Payment)7 Account (org.killbill.billing.account.api.Account)6 PaymentTransactionInfoPlugin (org.killbill.billing.payment.plugin.api.PaymentTransactionInfoPlugin)6 ImmutableList (com.google.common.collect.ImmutableList)5 List (java.util.List)5 LinkedList (java.util.LinkedList)4 LocalDate (org.joda.time.LocalDate)4 Invoice (org.killbill.billing.invoice.api.Invoice)4 PluginProperty (org.killbill.billing.payment.api.PluginProperty)4 ArrayList (java.util.ArrayList)3 TimeoutException (java.util.concurrent.TimeoutException)3 OperationException (org.killbill.automaton.OperationException)3