use of org.killbill.billing.payment.dao.PaymentTransactionModelDao in project killbill by killbill.
the class PaymentProcessor method cancelScheduledPaymentTransaction.
public void cancelScheduledPaymentTransaction(@Nullable final UUID paymentTransactionId, @Nullable final String paymentTransactionExternalKey, final CallContext callContext) throws PaymentApiException {
final InternalCallContext internalCallContextWithoutAccountRecordId = internalCallContextFactory.createInternalCallContextWithoutAccountRecordId(callContext);
final String effectivePaymentTransactionExternalKey;
if (paymentTransactionExternalKey == null) {
final PaymentTransactionModelDao transaction = paymentDao.getPaymentTransaction(paymentTransactionId, internalCallContextWithoutAccountRecordId);
effectivePaymentTransactionExternalKey = transaction.getTransactionExternalKey();
} else {
effectivePaymentTransactionExternalKey = paymentTransactionExternalKey;
}
final List<PaymentAttemptModelDao> attempts = paymentDao.getPaymentAttemptByTransactionExternalKey(effectivePaymentTransactionExternalKey, internalCallContextWithoutAccountRecordId);
if (attempts.isEmpty()) {
return;
}
final PaymentAttemptModelDao lastPaymentAttempt = attempts.get(attempts.size() - 1);
final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(lastPaymentAttempt.getAccountId(), callContext);
cancelScheduledPaymentTransaction(lastPaymentAttempt.getId(), internalCallContext);
}
use of org.killbill.billing.payment.dao.PaymentTransactionModelDao in project killbill by killbill.
the class PaymentProcessor method toPayment.
// Used in bulk get API (getAccountPayments)
private Payment toPayment(final PaymentModelDao curPaymentModelDao, final Collection<PaymentTransactionModelDao> curTransactionsModelDao, @Nullable final Iterable<PaymentTransactionInfoPlugin> pluginTransactions, final boolean withAttempts, final InternalTenantContext internalTenantContext) {
final Collection<PaymentTransactionModelDao> transactionsModelDao = new LinkedList<PaymentTransactionModelDao>(curTransactionsModelDao);
invokeJanitor(curPaymentModelDao, transactionsModelDao, pluginTransactions, internalTenantContext);
final Collection<PaymentTransaction> transactions = new LinkedList<PaymentTransaction>();
for (final PaymentTransactionModelDao newPaymentTransactionModelDao : transactionsModelDao) {
final PaymentTransactionInfoPlugin paymentTransactionInfoPlugin = findPaymentTransactionInfoPlugin(newPaymentTransactionModelDao, pluginTransactions);
final PaymentTransaction transaction = new DefaultPaymentTransaction(newPaymentTransactionModelDao.getId(), newPaymentTransactionModelDao.getAttemptId(), newPaymentTransactionModelDao.getTransactionExternalKey(), newPaymentTransactionModelDao.getCreatedDate(), newPaymentTransactionModelDao.getUpdatedDate(), newPaymentTransactionModelDao.getPaymentId(), newPaymentTransactionModelDao.getTransactionType(), newPaymentTransactionModelDao.getEffectiveDate(), newPaymentTransactionModelDao.getTransactionStatus(), newPaymentTransactionModelDao.getAmount(), newPaymentTransactionModelDao.getCurrency(), newPaymentTransactionModelDao.getProcessedAmount(), newPaymentTransactionModelDao.getProcessedCurrency(), newPaymentTransactionModelDao.getGatewayErrorCode(), newPaymentTransactionModelDao.getGatewayErrorMsg(), paymentTransactionInfoPlugin);
transactions.add(transaction);
}
final Ordering<PaymentTransaction> perPaymentTransactionOrdering = Ordering.<PaymentTransaction>from(new Comparator<PaymentTransaction>() {
@Override
public int compare(final PaymentTransaction o1, final PaymentTransaction o2) {
return o1.getEffectiveDate().compareTo(o2.getEffectiveDate());
}
});
final List<PaymentTransaction> sortedTransactions = perPaymentTransactionOrdering.immutableSortedCopy(transactions);
return new DefaultPayment(curPaymentModelDao.getId(), curPaymentModelDao.getCreatedDate(), curPaymentModelDao.getUpdatedDate(), curPaymentModelDao.getAccountId(), curPaymentModelDao.getPaymentMethodId(), curPaymentModelDao.getPaymentNumber(), curPaymentModelDao.getExternalKey(), sortedTransactions, (withAttempts && !sortedTransactions.isEmpty()) ? getPaymentAttempts(paymentDao.getPaymentAttempts(curPaymentModelDao.getExternalKey(), internalTenantContext), internalTenantContext) : null);
}
use of org.killbill.billing.payment.dao.PaymentTransactionModelDao in project killbill by killbill.
the class CompletionControlOperation method doOperationCallback.
@Override
public OperationResult doOperationCallback() throws OperationException {
final List<String> controlPluginNameList = paymentStateControlContext.getPaymentControlPluginNames();
final String controlPluginNames = JOINER.join(controlPluginNameList);
return dispatchWithAccountLockAndTimeout(controlPluginNames, new DispatcherCallback<PluginDispatcherReturnType<OperationResult>, OperationException>() {
@Override
public PluginDispatcherReturnType<OperationResult> doOperation() throws OperationException {
final PaymentTransactionModelDao transaction = paymentStateContext.getPaymentTransactionModelDao();
final PaymentControlContext updatedPaymentControlContext = new DefaultPaymentControlContext(paymentStateContext.getAccount(), paymentStateContext.getPaymentMethodId(), paymentStateControlContext.getAttemptId(), transaction.getPaymentId(), paymentStateContext.getPaymentExternalKey(), transaction.getId(), paymentStateContext.getPaymentTransactionExternalKey(), PaymentApiType.PAYMENT_TRANSACTION, paymentStateContext.getTransactionType(), null, transaction.getAmount(), transaction.getCurrency(), transaction.getProcessedAmount(), transaction.getProcessedCurrency(), paymentStateControlContext.isApiPayment(), paymentStateContext.getCallContext());
try {
final Payment result = doCallSpecificOperationCallback();
((PaymentStateControlContext) paymentStateContext).setResult(result);
final boolean success = transaction.getTransactionStatus() == TransactionStatus.SUCCESS || transaction.getTransactionStatus() == TransactionStatus.PENDING;
if (success) {
executePluginOnSuccessCalls(paymentStateControlContext.getPaymentControlPluginNames(), updatedPaymentControlContext);
// Remove scheduled retry, if any
paymentProcessor.cancelScheduledPaymentTransaction(paymentStateControlContext.getAttemptId(), paymentStateControlContext.getInternalCallContext());
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(updatedPaymentControlContext));
} catch (final RuntimeException e) {
// Attempts to set the retry date in context if needed.
throw new OperationException(e, executePluginOnFailureCallsAndSetRetryDate(updatedPaymentControlContext));
}
}
});
}
use of org.killbill.billing.payment.dao.PaymentTransactionModelDao in project killbill by killbill.
the class DefaultControlInitiated method leavingState.
@Override
public void leavingState(final State state) throws OperationException {
final DateTime utcNow = pluginControlPaymentAutomatonRunner.getClock().getUTCNow();
// Retrieve the associated payment transaction, if any
PaymentTransactionModelDao paymentTransactionModelDaoCandidate = null;
if (stateContext.getTransactionId() != null) {
paymentTransactionModelDaoCandidate = paymentDao.getPaymentTransaction(stateContext.getTransactionId(), stateContext.getInternalCallContext());
Preconditions.checkNotNull(paymentTransactionModelDaoCandidate, "paymentTransaction cannot be null for id " + stateContext.getTransactionId());
} else if (stateContext.getPaymentTransactionExternalKey() != null) {
final List<PaymentTransactionModelDao> paymentTransactionModelDaos = paymentDao.getPaymentTransactionsByExternalKey(stateContext.getPaymentTransactionExternalKey(), stateContext.getInternalCallContext());
if (!paymentTransactionModelDaos.isEmpty()) {
paymentTransactionModelDaoCandidate = paymentTransactionModelDaos.get(paymentTransactionModelDaos.size() - 1);
}
}
final PaymentTransactionModelDao paymentTransactionModelDao = paymentTransactionModelDaoCandidate != null && TRANSIENT_TRANSACTION_STATUSES.contains(paymentTransactionModelDaoCandidate.getTransactionStatus()) ? paymentTransactionModelDaoCandidate : null;
if (stateContext.getPaymentId() != null && stateContext.getPaymentExternalKey() == null) {
final PaymentModelDao payment = paymentDao.getPayment(stateContext.getPaymentId(), stateContext.getInternalCallContext());
Preconditions.checkNotNull(payment, "payment cannot be null for id " + stateContext.getPaymentId());
stateContext.setPaymentExternalKey(payment.getExternalKey());
stateContext.setPaymentMethodId(payment.getPaymentMethodId());
} else if (stateContext.getPaymentExternalKey() == null) {
final UUID paymentIdForNewPayment = UUIDs.randomUUID();
stateContext.setPaymentIdForNewPayment(paymentIdForNewPayment);
stateContext.setPaymentExternalKey(paymentIdForNewPayment.toString());
}
if (paymentTransactionModelDao != null) {
stateContext.setPaymentTransactionModelDao(paymentTransactionModelDao);
stateContext.setProcessedAmount(paymentTransactionModelDao.getProcessedAmount());
stateContext.setProcessedCurrency(paymentTransactionModelDao.getProcessedCurrency());
} else if (stateContext.getPaymentTransactionExternalKey() == null) {
final UUID paymentTransactionIdForNewPaymentTransaction = UUIDs.randomUUID();
stateContext.setPaymentTransactionIdForNewPaymentTransaction(paymentTransactionIdForNewPaymentTransaction);
stateContext.setPaymentTransactionExternalKey(paymentTransactionIdForNewPaymentTransaction.toString());
}
if (stateContext.getPaymentMethodId() == null) {
// Similar logic in PaymentAutomatonRunner
stateContext.setPaymentMethodId(stateContext.getAccount().getPaymentMethodId());
}
if (state.getName().equals(initialState.getName()) || state.getName().equals(retriedState.getName())) {
try {
final PaymentAttemptModelDao attempt;
if (paymentTransactionModelDao != null && paymentTransactionModelDao.getAttemptId() != null) {
attempt = pluginControlPaymentAutomatonRunner.getPaymentDao().getPaymentAttempt(paymentTransactionModelDao.getAttemptId(), stateContext.getInternalCallContext());
Preconditions.checkNotNull(attempt, "attempt cannot be null for id " + paymentTransactionModelDao.getAttemptId());
} else {
//
// We don't serialize any properties at this stage to avoid serializing sensitive information.
// However, if after going through the control plugins, the attempt end up in RETRIED state,
// the properties will be serialized in the enteringState callback (any plugin that sets a
// retried date is responsible to correctly remove sensitive information such as CVV, ...)
//
final byte[] serializedProperties = PluginPropertySerializer.serialize(ImmutableList.<PluginProperty>of());
attempt = new PaymentAttemptModelDao(stateContext.getAccount().getId(), stateContext.getPaymentMethodId(), utcNow, utcNow, stateContext.getPaymentExternalKey(), stateContext.getTransactionId(), stateContext.getPaymentTransactionExternalKey(), transactionType, initialState.getName(), stateContext.getAmount(), stateContext.getCurrency(), stateContext.getPaymentControlPluginNames(), serializedProperties);
pluginControlPaymentAutomatonRunner.getPaymentDao().insertPaymentAttemptWithProperties(attempt, stateContext.getInternalCallContext());
}
stateContext.setAttemptId(attempt.getId());
} catch (final PluginPropertySerializerException e) {
throw new OperationException(e);
}
}
}
use of org.killbill.billing.payment.dao.PaymentTransactionModelDao in project killbill by killbill.
the class ChargebackInitiated method leavingState.
@Override
public void leavingState(final State oldState) throws OperationException {
// Sanity: chargeback reversals can only happen after a successful chargeback
if (OperationResult.FAILURE.equals(paymentStateContext.getOverridePluginOperationResult())) {
final List<PaymentTransactionModelDao> paymentTransactionsForCurrentPayment = paymentStateContext.getPaymentId() != null ? daoHelper.getPaymentDao().getTransactionsForPayment(paymentStateContext.getPaymentId(), paymentStateContext.getInternalCallContext()) : ImmutableList.<PaymentTransactionModelDao>of();
final Iterable<PaymentTransactionModelDao> existingPaymentTransactionsForTransactionIdOrKey = filterExistingPaymentTransactionsForTransactionIdOrKey(paymentTransactionsForCurrentPayment, paymentStateContext.getTransactionId(), paymentStateContext.getPaymentTransactionExternalKey());
if (Iterables.<PaymentTransactionModelDao>isEmpty(existingPaymentTransactionsForTransactionIdOrKey)) {
// Chargeback reversals can only happen after a successful chargeback
throw new OperationException(new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_SUCCESS_PAYMENT, paymentStateContext.getPaymentId()));
}
}
super.leavingState(oldState);
}
Aggregations