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");
}
}
}
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");
}
}
}
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);
}
}
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);
}
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);
}
Aggregations