use of org.killbill.billing.payment.api.PaymentApiException in project killbill by killbill.
the class TestJanitor method testUnknownEntriesWithExceptions.
@Test(groups = "slow")
public void testUnknownEntriesWithExceptions() throws PaymentApiException, EventBusException {
final BigDecimal requestedAmount = BigDecimal.TEN;
final String paymentExternalKey = "minus";
final String transactionExternalKey = "plus";
// Make sure the state as seen by the plugin will be in PaymentPluginStatus.ERROR, which will be returned later to Janitor
mockPaymentProviderPlugin.makeNextPaymentFailWithException();
try {
testListener.pushExpectedEvent(NextEvent.PAYMENT_PLUGIN_ERROR);
paymentApi.createAuthorization(account, account.getPaymentMethodId(), null, requestedAmount, account.getCurrency(), null, paymentExternalKey, transactionExternalKey, ImmutableList.<PluginProperty>of(), callContext);
} catch (PaymentApiException ignore) {
testListener.assertListenerStatus();
}
final Payment payment = paymentApi.getPaymentByExternalKey(paymentExternalKey, false, false, ImmutableList.<PluginProperty>of(), callContext);
// Artificially move the transaction status to UNKNOWN
final String paymentStateName = paymentSMHelper.getErroredStateForTransaction(TransactionType.AUTHORIZE).toString();
testListener.pushExpectedEvent(NextEvent.PAYMENT_PLUGIN_ERROR);
paymentDao.updatePaymentAndTransactionOnCompletion(account.getId(), null, payment.getId(), TransactionType.AUTHORIZE, paymentStateName, paymentStateName, payment.getTransactions().get(0).getId(), TransactionStatus.UNKNOWN, requestedAmount, account.getCurrency(), "foo", "bar", true, internalCallContext);
testListener.assertListenerStatus();
// Move clock for notification to be processed
clock.addDeltaFromReality(5 * 60 * 1000);
// NO because we will keep retrying as we can't fix it...
// assertNotificationsCompleted(internalCallContext, 5);
final List<AuditLogWithHistory> paymentTransactionHistoryBeforeJanitor = paymentDao.getPaymentTransactionAuditLogsWithHistoryForId(payment.getTransactions().get(0).getId(), AuditLevel.FULL, internalCallContext);
Assert.assertEquals(paymentTransactionHistoryBeforeJanitor.size(), 3);
// Nothing new happened
final List<AuditLogWithHistory> paymentTransactionHistoryAfterJanitor = paymentDao.getPaymentTransactionAuditLogsWithHistoryForId(payment.getTransactions().get(0).getId(), AuditLevel.FULL, internalCallContext);
Assert.assertEquals(paymentTransactionHistoryAfterJanitor.size(), 3);
}
use of org.killbill.billing.payment.api.PaymentApiException in project killbill by killbill.
the class TestJanitor method testCreateSuccessPurchaseWithPaymentControl.
@Test(groups = "slow")
public void testCreateSuccessPurchaseWithPaymentControl() throws PaymentApiException, InvoiceApiException, EventBusException {
final BigDecimal requestedAmount = BigDecimal.TEN;
final UUID subscriptionId = UUID.randomUUID();
final UUID bundleId = UUID.randomUUID();
final LocalDate now = clock.getUTCToday();
testListener.pushExpectedEvent(NextEvent.INVOICE);
final Invoice invoice = testHelper.createTestInvoice(account, now, Currency.USD);
testListener.assertListenerStatus();
final String paymentExternalKey = invoice.getId().toString();
final String transactionExternalKey = "wouf wouf";
invoice.addInvoiceItem(new MockRecurringInvoiceItem(invoice.getId(), account.getId(), subscriptionId, bundleId, "test plan", "test phase", null, now, now.plusMonths(1), requestedAmount, new BigDecimal("1.0"), Currency.USD));
testListener.pushExpectedEvent(NextEvent.PAYMENT);
invoicePaymentApi.createPurchaseForInvoicePayment(account, invoice.getId(), account.getPaymentMethodId(), null, requestedAmount, Currency.USD, null, paymentExternalKey, transactionExternalKey, ImmutableList.<PluginProperty>of(), INVOICE_PAYMENT, callContext);
final Payment payment = paymentApi.getPaymentByExternalKey(paymentExternalKey, false, false, ImmutableList.<PluginProperty>of(), callContext);
testListener.assertListenerStatus();
assertEquals(payment.getTransactions().size(), 1);
assertEquals(payment.getTransactions().get(0).getTransactionStatus(), TransactionStatus.SUCCESS);
assertEquals(payment.getTransactions().get(0).getTransactionType(), TransactionType.PURCHASE);
final List<PaymentAttemptModelDao> attempts = paymentDao.getPaymentAttempts(paymentExternalKey, internalCallContext);
assertEquals(attempts.size(), 1);
final PaymentAttemptModelDao attempt = attempts.get(0);
assertEquals(attempt.getStateName(), "SUCCESS");
assertEquals(attempt.getAmount().compareTo(requestedAmount), 0);
assertEquals(attempt.getCurrency(), Currency.USD);
// Ok now the fun part starts... we modify the attempt state to be 'INIT' and wait the the Janitor to do its job.
paymentDao.updatePaymentAttemptWithProperties(attempt.getId(), attempt.getPaymentMethodId(), attempt.getTransactionId(), "INIT", null, null, null, internalCallContext);
final PaymentAttemptModelDao attempt2 = paymentDao.getPaymentAttempt(attempt.getId(), internalCallContext);
assertEquals(attempt2.getStateName(), "INIT");
assertNull(attempt2.getAmount());
assertNull(attempt2.getCurrency());
clock.addDays(1);
Awaitility.await().atMost(5, TimeUnit.SECONDS).until(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
final PaymentAttemptModelDao attempt3 = paymentDao.getPaymentAttempt(attempt.getId(), internalCallContext);
return "SUCCESS".equals(attempt3.getStateName());
}
});
final PaymentAttemptModelDao attempt3 = paymentDao.getPaymentAttempt(attempt.getId(), internalCallContext);
assertEquals(attempt3.getStateName(), "SUCCESS");
assertEquals(attempt3.getAmount().compareTo(requestedAmount), 0);
assertEquals(attempt3.getCurrency(), Currency.USD);
}
use of org.killbill.billing.payment.api.PaymentApiException in project killbill by killbill.
the class TestRetryService method testAbortedPlugin.
// PLUGIN_EXCEPTION will lead to UNKNOWN row that will not be retried by the plugin
@Test(groups = "fast")
public void testAbortedPlugin() 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.PLUGIN_EXCEPTION);
boolean failed = false;
final String paymentExternalKey = UUID.randomUUID().toString();
final String transactionExternalKey = UUID.randomUUID().toString();
try {
invoicePaymentInternalApi.createPurchaseForInvoicePayment(false, account, invoice.getId(), account.getPaymentMethodId(), null, amount, Currency.USD, null, paymentExternalKey, transactionExternalKey, NO_PROPERTIES, PAYMENT_OPTIONS, internalCallContext);
} catch (final PaymentApiException e) {
failed = true;
}
assertTrue(failed);
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);
attempts = paymentDao.getPaymentAttempts(payment.getExternalKey(), internalCallContext);
final int expectedAttempts = 1;
assertEquals(attempts.size(), expectedAttempts);
assertEquals(attempts.get(0).getStateName(), "ABORTED");
}
use of org.killbill.billing.payment.api.PaymentApiException in project killbill by killbill.
the class TestRetryablePayment method testInitToSuccessWithPaymentExceptionAndRetries.
@Test(groups = "fast")
public void testInitToSuccessWithPaymentExceptionAndRetries() {
mockRetryProviderPlugin.setAborted(false).setNextRetryDate(new DateTime(clock.getUTCNow().plusDays(1)));
mockRetryAuthorizeOperationCallback.setResult(null).setException(new PaymentApiException(ErrorCode.__UNKNOWN_ERROR_CODE, "bla bla"));
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("Expected PaymentApiException...");
} catch (final PaymentApiException e) {
final PaymentAttemptModelDao pa = paymentDao.getPaymentAttemptByTransactionExternalKey(paymentTransactionExternalKey, internalCallContext).get(0);
assertEquals(pa.getTransactionExternalKey(), paymentTransactionExternalKey);
assertEquals(pa.getStateName(), "RETRIED");
assertEquals(pa.getTransactionType(), TransactionType.AUTHORIZE);
}
}
use of org.killbill.billing.payment.api.PaymentApiException in project killbill by killbill.
the class TestRetryablePayment method testInitToSuccessWithRuntimeExceptionAndRetries.
@Test(groups = "fast")
public void testInitToSuccessWithRuntimeExceptionAndRetries() {
mockRetryProviderPlugin.setAborted(false).setNextRetryDate(new DateTime(clock.getUTCNow().plusDays(1)));
mockRetryAuthorizeOperationCallback.setResult(null).setException(new RuntimeException());
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("Expected Exception...");
} catch (final PaymentApiException e) {
final PaymentAttemptModelDao pa = paymentDao.getPaymentAttemptByTransactionExternalKey(paymentTransactionExternalKey, internalCallContext).get(0);
assertEquals(pa.getTransactionExternalKey(), paymentTransactionExternalKey);
assertEquals(pa.getStateName(), "RETRIED");
assertEquals(pa.getTransactionType(), TransactionType.AUTHORIZE);
}
}
Aggregations