Search in sources :

Example 1 with PaymentTransaction

use of org.killbill.billing.payment.api.PaymentTransaction in project killbill by killbill.

the class PaymentChecker method checkPayment.

private void checkPayment(final UUID accountId, final Payment payment, final CallContext context, final ExpectedPaymentCheck expected) {
    Assert.assertEquals(payment.getAccountId(), accountId);
    Assert.assertEquals(payment.getCurrency(), expected.getCurrency());
    if (expected.getInvoiceId() != null) {
        for (final InvoicePayment invoicePayment : invoicePaymentApi.getInvoicePayments(payment.getId(), context)) {
            Assert.assertEquals(invoicePayment.getInvoiceId(), expected.getInvoiceId());
        }
    }
    final PaymentTransaction transaction = getPurchaseTransaction(payment);
    Assert.assertTrue(transaction.getAmount().compareTo(expected.getAmount()) == 0, "Actual amount " + transaction.getAmount() + ", expected amount " + expected.getAmount());
    Assert.assertEquals(transaction.getTransactionStatus(), expected.getStatus());
    Assert.assertEquals(transaction.getEffectiveDate().toLocalDate().compareTo(expected.getPaymentDate()), 0);
    auditChecker.checkPaymentCreated(payment, context);
}
Also used : PaymentTransaction(org.killbill.billing.payment.api.PaymentTransaction) InvoicePayment(org.killbill.billing.invoice.api.InvoicePayment)

Example 2 with PaymentTransaction

use of org.killbill.billing.payment.api.PaymentTransaction in project killbill by killbill.

the class PaymentChecker method checkPaymentNoAuditForRuntimeException.

private void checkPaymentNoAuditForRuntimeException(final UUID accountId, final Payment payment, final ExpectedPaymentCheck expected) {
    Assert.assertEquals(payment.getAccountId(), accountId);
    final PaymentTransaction transaction = getPurchaseTransaction(payment);
    Assert.assertTrue(transaction.getAmount().compareTo(expected.getAmount()) == 0);
    Assert.assertEquals(transaction.getTransactionStatus(), expected.getStatus());
    Assert.assertEquals(payment.getCurrency(), expected.getCurrency());
}
Also used : PaymentTransaction(org.killbill.billing.payment.api.PaymentTransaction)

Example 3 with PaymentTransaction

use of org.killbill.billing.payment.api.PaymentTransaction in project killbill by killbill.

the class PaymentChecker method checkPayment.

public Payment checkPayment(final UUID accountId, final int paymentOrderingNumber, final CallContext context, final ExpectedPaymentCheck expected) throws PaymentApiException {
    final List<Payment> payments = paymentApi.getAccountPayments(accountId, false, false, ImmutableList.<PluginProperty>of(), context);
    Assert.assertEquals(payments.size(), paymentOrderingNumber);
    final Payment payment = payments.get(paymentOrderingNumber - 1);
    final PaymentTransaction transaction = getPurchaseTransaction(payment);
    if (transaction.getTransactionStatus() == TransactionStatus.UNKNOWN) {
        checkPaymentNoAuditForRuntimeException(accountId, payment, expected);
    } else {
        checkPayment(accountId, payment, context, expected);
    }
    return payment;
}
Also used : PaymentTransaction(org.killbill.billing.payment.api.PaymentTransaction) InvoicePayment(org.killbill.billing.invoice.api.InvoicePayment) Payment(org.killbill.billing.payment.api.Payment)

Example 4 with PaymentTransaction

use of org.killbill.billing.payment.api.PaymentTransaction in project killbill by killbill.

the class OperationControlCallback method doOperationCallback.

@Override
public OperationResult doOperationCallback() throws OperationException {
    final List<String> pluginNameList = paymentStateControlContext.getPaymentControlPluginNames();
    final String pluginNames = JOINER.join(pluginNameList);
    return dispatchWithAccountLockAndTimeout(pluginNames, new DispatcherCallback<PluginDispatcherReturnType<OperationResult>, OperationException>() {

        @Override
        public PluginDispatcherReturnType<OperationResult> doOperation() throws OperationException {
            final PaymentControlContext paymentControlContext = new DefaultPaymentControlContext(paymentStateContext.getAccount(), paymentStateContext.getPaymentMethodId(), paymentStateControlContext.getAttemptId(), paymentStateContext.getPaymentId(), paymentStateContext.getPaymentExternalKey(), paymentStateContext.getTransactionId(), paymentStateContext.getPaymentTransactionExternalKey(), PaymentApiType.PAYMENT_TRANSACTION, paymentStateContext.getTransactionType(), null, paymentStateContext.getAmount(), paymentStateContext.getCurrency(), paymentStateControlContext.getProcessedAmount(), paymentStateControlContext.getProcessedCurrency(), paymentStateControlContext.isApiPayment(), paymentStateContext.getCallContext());
            try {
                executePluginPriorCalls(paymentStateControlContext.getPaymentControlPluginNames(), paymentControlContext);
            } catch (final PaymentControlApiAbortException e) {
                // Transition to ABORTED
                final PaymentApiException paymentAbortedException = new PaymentApiException(ErrorCode.PAYMENT_PLUGIN_API_ABORTED, e.getPluginName());
                throw new OperationException(paymentAbortedException, OperationResult.EXCEPTION);
            } catch (final PaymentControlApiException e) {
                // Transition to ABORTED and throw PaymentControlApiException to caller.
                throw new OperationException(e, OperationResult.EXCEPTION);
            }
            final boolean success;
            try {
                final Payment result = doCallSpecificOperationCallback();
                ((PaymentStateControlContext) paymentStateContext).setResult(result);
                final PaymentTransaction transaction = ((PaymentStateControlContext) paymentStateContext).getCurrentTransaction();
                success = transaction.getTransactionStatus() == TransactionStatus.SUCCESS || transaction.getTransactionStatus() == TransactionStatus.PENDING;
                final PaymentControlContext updatedPaymentControlContext = new DefaultPaymentControlContext(paymentStateContext.getAccount(), paymentStateContext.getPaymentMethodId(), paymentStateControlContext.getAttemptId(), result.getId(), result.getExternalKey(), transaction.getId(), paymentStateContext.getPaymentTransactionExternalKey(), PaymentApiType.PAYMENT_TRANSACTION, paymentStateContext.getTransactionType(), null, transaction.getAmount(), transaction.getCurrency(), transaction.getProcessedAmount(), transaction.getProcessedCurrency(), paymentStateControlContext.isApiPayment(), paymentStateContext.getCallContext());
                if (success) {
                    executePluginOnSuccessCalls(paymentStateControlContext.getPaymentControlPluginNames(), updatedPaymentControlContext);
                    return PluginDispatcher.createPluginDispatcherReturnType(OperationResult.SUCCESS);
                } else {
                    throw new OperationException(null, executePluginOnFailureCallsAndSetRetryDate(updatedPaymentControlContext));
                }
            } catch (final PaymentApiException e) {
                // Wrap PaymentApiException, and throw a new OperationException with an ABORTED/FAILURE state based on the retry result.
                throw new OperationException(e, executePluginOnFailureCallsAndSetRetryDate(paymentControlContext));
            } catch (final RuntimeException e) {
                // Attempts to set the retry date in context if needed.
                throw new OperationException(e, executePluginOnFailureCallsAndSetRetryDate(paymentControlContext));
            }
        }
    });
}
Also used : PluginDispatcherReturnType(org.killbill.billing.payment.dispatcher.PluginDispatcher.PluginDispatcherReturnType) PaymentApiException(org.killbill.billing.payment.api.PaymentApiException) PaymentControlApiException(org.killbill.billing.control.plugin.api.PaymentControlApiException) PaymentTransaction(org.killbill.billing.payment.api.PaymentTransaction) Payment(org.killbill.billing.payment.api.Payment) DefaultPaymentControlContext(org.killbill.billing.payment.core.sm.control.ControlPluginRunner.DefaultPaymentControlContext) PaymentControlContext(org.killbill.billing.control.plugin.api.PaymentControlContext) DefaultPaymentControlContext(org.killbill.billing.payment.core.sm.control.ControlPluginRunner.DefaultPaymentControlContext) OperationException(org.killbill.automaton.OperationException)

Example 5 with PaymentTransaction

use of org.killbill.billing.payment.api.PaymentTransaction in project killbill by killbill.

the class PluginControlPaymentProcessor method retryPaymentTransaction.

public void retryPaymentTransaction(final UUID attemptId, final List<String> paymentControlPluginNames, final InternalCallContext internalCallContext) {
    final PaymentAttemptModelDao attempt = paymentDao.getPaymentAttempt(attemptId, internalCallContext);
    log.info("Retrying attemptId='{}', paymentExternalKey='{}', transactionExternalKey='{}'. paymentControlPluginNames='{}'", attemptId, attempt.getPaymentExternalKey(), attempt.getTransactionExternalKey(), paymentControlPluginNames);
    final PaymentModelDao paymentModelDao = paymentDao.getPaymentByExternalKey(attempt.getPaymentExternalKey(), internalCallContext);
    final UUID paymentId = paymentModelDao != null ? paymentModelDao.getId() : null;
    final CallContext callContext = buildCallContext(internalCallContext);
    final String transactionType = TransactionType.PURCHASE.name();
    Account account = null;
    Payment payment = null;
    PaymentTransaction paymentTransaction = null;
    try {
        account = accountInternalApi.getAccountById(attempt.getAccountId(), internalCallContext);
        final State state = paymentControlStateMachineHelper.getState(attempt.getStateName());
        final Iterable<PluginProperty> pluginProperties = PluginPropertySerializer.deserialize(attempt.getPluginProperties());
        logEnterAPICall(log, transactionType, account, attempt.getPaymentMethodId(), paymentId, null, attempt.getAmount(), attempt.getCurrency(), attempt.getPaymentExternalKey(), attempt.getTransactionExternalKey(), null, paymentControlPluginNames);
        payment = pluginControlledPaymentAutomatonRunner.run(state, false, attempt.getTransactionType(), ControlOperation.valueOf(attempt.getTransactionType().toString()), account, attempt.getPaymentMethodId(), paymentId, attempt.getPaymentExternalKey(), attempt.getTransactionExternalKey(), attempt.getAmount(), attempt.getCurrency(), pluginProperties, paymentControlPluginNames, callContext, internalCallContext);
        paymentTransaction = Iterables.<PaymentTransaction>find(Lists.<PaymentTransaction>reverse(payment.getTransactions()), new Predicate<PaymentTransaction>() {

            @Override
            public boolean apply(final PaymentTransaction input) {
                return attempt.getTransactionExternalKey().equals(input.getExternalKey());
            }
        });
    } catch (final AccountApiException e) {
        log.warn("Failed to retry attemptId='{}', paymentControlPlugins='{}'", attemptId, toPluginNamesOnError(paymentControlPluginNames), e);
    } catch (final PaymentApiException e) {
        // Log exception unless nothing left to be paid
        if (e.getCode() == ErrorCode.PAYMENT_PLUGIN_API_ABORTED.getCode() && paymentControlPluginNames != null && paymentControlPluginNames.size() == 1 && InvoicePaymentControlPluginApi.PLUGIN_NAME.equals(paymentControlPluginNames.get(0))) {
            log.warn("Failed to retry attemptId='{}', paymentControlPlugins='{}'. Invoice has already been paid", attemptId, toPluginNamesOnError(paymentControlPluginNames));
        } else {
            log.warn("Failed to retry attemptId='{}', paymentControlPlugins='{}'", attemptId, toPluginNamesOnError(paymentControlPluginNames), e);
        }
    } catch (final PluginPropertySerializerException e) {
        log.warn("Failed to retry attemptId='{}', paymentControlPlugins='{}'", attemptId, toPluginNamesOnError(paymentControlPluginNames), e);
    } catch (final MissingEntryException e) {
        log.warn("Failed to retry attemptId='{}', paymentControlPlugins='{}'", attemptId, toPluginNamesOnError(paymentControlPluginNames), e);
    } finally {
        logExitAPICall(log, transactionType, account, payment != null ? payment.getPaymentMethodId() : null, payment != null ? payment.getId() : null, paymentTransaction != null ? paymentTransaction.getId() : null, paymentTransaction != null ? paymentTransaction.getProcessedAmount() : null, paymentTransaction != null ? paymentTransaction.getProcessedCurrency() : null, payment != null ? payment.getExternalKey() : null, paymentTransaction != null ? paymentTransaction.getExternalKey() : null, paymentTransaction != null ? paymentTransaction.getTransactionStatus() : null, paymentControlPluginNames, null);
    }
}
Also used : PaymentAttemptModelDao(org.killbill.billing.payment.dao.PaymentAttemptModelDao) Account(org.killbill.billing.account.api.Account) PaymentModelDao(org.killbill.billing.payment.dao.PaymentModelDao) PluginPropertySerializerException(org.killbill.billing.payment.dao.PluginPropertySerializer.PluginPropertySerializerException) PaymentApiException(org.killbill.billing.payment.api.PaymentApiException) InternalCallContext(org.killbill.billing.callcontext.InternalCallContext) CallContext(org.killbill.billing.util.callcontext.CallContext) Predicate(com.google.common.base.Predicate) PaymentTransaction(org.killbill.billing.payment.api.PaymentTransaction) PluginProperty(org.killbill.billing.payment.api.PluginProperty) Payment(org.killbill.billing.payment.api.Payment) State(org.killbill.automaton.State) AccountApiException(org.killbill.billing.account.api.AccountApiException) MissingEntryException(org.killbill.automaton.MissingEntryException) UUID(java.util.UUID)

Aggregations

PaymentTransaction (org.killbill.billing.payment.api.PaymentTransaction)20 Payment (org.killbill.billing.payment.api.Payment)12 PluginProperty (org.killbill.billing.payment.api.PluginProperty)7 PaymentApiException (org.killbill.billing.payment.api.PaymentApiException)6 BigDecimal (java.math.BigDecimal)5 UUID (java.util.UUID)5 Account (org.killbill.billing.account.api.Account)5 InvoicePayment (org.killbill.billing.invoice.api.InvoicePayment)4 CallContext (org.killbill.billing.util.callcontext.CallContext)4 Predicate (com.google.common.base.Predicate)3 ArrayList (java.util.ArrayList)3 LocalDate (org.joda.time.LocalDate)3 Invoice (org.killbill.billing.invoice.api.Invoice)3 Test (org.testng.annotations.Test)3 AccountApiException (org.killbill.billing.account.api.AccountApiException)2 AccountData (org.killbill.billing.account.api.AccountData)2 InternalCallContext (org.killbill.billing.callcontext.InternalCallContext)2 Currency (org.killbill.billing.catalog.api.Currency)2 DefaultEntitlement (org.killbill.billing.entitlement.api.DefaultEntitlement)2 DefaultPayment (org.killbill.billing.payment.api.DefaultPayment)2