killbill-uncached

Details

diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/DirectPaymentAutomatonDAOHelper.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/DirectPaymentAutomatonDAOHelper.java
index 5a3c457..abfad57 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/DirectPaymentAutomatonDAOHelper.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/DirectPaymentAutomatonDAOHelper.java
@@ -18,6 +18,7 @@
 package org.killbill.billing.payment.core.sm;
 
 import java.math.BigDecimal;
+import java.util.List;
 import java.util.UUID;
 
 import javax.annotation.Nullable;
@@ -29,10 +30,10 @@ import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.osgi.api.OSGIServiceRegistration;
 import org.killbill.billing.payment.api.PaymentApiException;
 import org.killbill.billing.payment.api.TransactionStatus;
-import org.killbill.billing.payment.dao.PaymentModelDao;
-import org.killbill.billing.payment.dao.PaymentTransactionModelDao;
 import org.killbill.billing.payment.dao.PaymentDao;
 import org.killbill.billing.payment.dao.PaymentMethodModelDao;
+import org.killbill.billing.payment.dao.PaymentModelDao;
+import org.killbill.billing.payment.dao.PaymentTransactionModelDao;
 import org.killbill.billing.payment.plugin.api.PaymentPluginApi;
 import org.killbill.billing.payment.plugin.api.PaymentTransactionInfoPlugin;
 
@@ -58,7 +59,9 @@ public class DirectPaymentAutomatonDAOHelper {
         this.internalCallContext = internalCallContext;
     }
 
-    public void createNewDirectPaymentTransaction() {
+    public void createNewDirectPaymentTransaction() throws PaymentApiException {
+
+
         final PaymentTransactionModelDao paymentTransactionModelDao;
         if (directPaymentStateContext.getDirectPaymentId() == null) {
             final PaymentModelDao newPaymentModelDao = buildNewDirectPaymentModelDao();
@@ -67,12 +70,20 @@ public class DirectPaymentAutomatonDAOHelper {
             final PaymentModelDao paymentModelDao = paymentDao.insertDirectPaymentWithFirstTransaction(newPaymentModelDao, newPaymentTransactionModelDao, internalCallContext);
             paymentTransactionModelDao = paymentDao.getDirectTransactionsForDirectPayment(paymentModelDao.getId(), internalCallContext).get(0);
         } else {
+            final List<PaymentTransactionModelDao> existingTransactions = paymentDao.getDirectTransactionsForDirectPayment(directPaymentStateContext.getDirectPaymentId(), internalCallContext);
+            if (existingTransactions.isEmpty()) {
+                throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_SUCCESS_PAYMENT, directPaymentStateContext.getDirectPaymentId());
+            }
+            if (existingTransactions.get(0).getCurrency() != directPaymentStateContext.getCurrency()) {
+                throw new PaymentApiException(ErrorCode.PAYMENT_INVALID_PARAMETER, "currency", " should be " + existingTransactions.get(0).getCurrency() + " to match other existing transactions");
+            }
+
             final PaymentTransactionModelDao newPaymentTransactionModelDao = buildNewDirectPaymentTransactionModelDao(directPaymentStateContext.getDirectPaymentId());
             paymentTransactionModelDao = paymentDao.updateDirectPaymentWithNewTransaction(directPaymentStateContext.getDirectPaymentId(), newPaymentTransactionModelDao, internalCallContext);
         }
-
         // Update the context
         directPaymentStateContext.setDirectPaymentTransactionModelDao(paymentTransactionModelDao);
+
     }
 
     public void processPaymentInfoPlugin(final TransactionStatus paymentStatus, @Nullable final PaymentTransactionInfoPlugin paymentInfoPlugin,
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/DirectPaymentEnteringStateCallback.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/DirectPaymentEnteringStateCallback.java
index c63e8d8..633e089 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/DirectPaymentEnteringStateCallback.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/DirectPaymentEnteringStateCallback.java
@@ -48,13 +48,12 @@ public abstract class DirectPaymentEnteringStateCallback implements EnteringStat
     public void enteringState(final State newState, final Operation.OperationCallback operationCallback, final OperationResult operationResult, final LeavingStateCallback leavingStateCallback) {
         logger.debug("Entering state {} with result {}", newState.getName(), operationResult);
 
-        // Check for illegal state (should never happen)
-        Preconditions.checkState(directPaymentStateContext.getDirectPaymentTransactionModelDao() != null && directPaymentStateContext.getDirectPaymentTransactionModelDao().getId() != null);
-
-        final PaymentTransactionInfoPlugin paymentInfoPlugin = directPaymentStateContext.getPaymentInfoPlugin();
-        final TransactionStatus paymentStatus = paymentPluginStatusToPaymentStatus(paymentInfoPlugin, operationResult);
-
-        daoHelper.processPaymentInfoPlugin(paymentStatus, paymentInfoPlugin, newState.getName());
+        // If the transaction was not created -- for instance we had an exception in leavingState callback then we bail; if not, then update state:
+        if (directPaymentStateContext.getDirectPaymentTransactionModelDao() != null && directPaymentStateContext.getDirectPaymentTransactionModelDao().getId() != null) {
+            final PaymentTransactionInfoPlugin paymentInfoPlugin = directPaymentStateContext.getPaymentInfoPlugin();
+            final TransactionStatus paymentStatus = paymentPluginStatusToPaymentStatus(paymentInfoPlugin, operationResult);
+            daoHelper.processPaymentInfoPlugin(paymentStatus, paymentInfoPlugin, newState.getName());
+        }
     }
 
     private TransactionStatus paymentPluginStatusToPaymentStatus(@Nullable final PaymentTransactionInfoPlugin paymentInfoPlugin, final OperationResult operationResult) {
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/DirectPaymentLeavingStateCallback.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/DirectPaymentLeavingStateCallback.java
index 223837f..8790cfa 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/DirectPaymentLeavingStateCallback.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/DirectPaymentLeavingStateCallback.java
@@ -17,6 +17,7 @@
 
 package org.killbill.billing.payment.core.sm;
 
+import org.killbill.automaton.OperationException;
 import org.killbill.automaton.State;
 import org.killbill.automaton.State.LeavingStateCallback;
 import org.killbill.billing.payment.api.PaymentApiException;
@@ -34,10 +35,14 @@ public abstract class DirectPaymentLeavingStateCallback implements LeavingStateC
     }
 
     @Override
-    public void leavingState(final State oldState) {
+    public void leavingState(final State oldState) throws OperationException {
         logger.debug("Leaving state {}", oldState.getName());
 
         // Create or update the direct payment and transaction
-        daoHelper.createNewDirectPaymentTransaction();
+        try {
+            daoHelper.createNewDirectPaymentTransaction();
+        } catch (PaymentApiException e) {
+            throw new OperationException(e);
+        }
     }
 }
diff --git a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java
index a1557e5..319c824 100644
--- a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java
+++ b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java
@@ -506,6 +506,27 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
         }
     }
 
+    @Test(groups = "fast")
+    public void testSimpleAuthCaptureWithInvalidCurrency() throws Exception {
+        final BigDecimal requestedAmount = new BigDecimal("80.0091");
+
+        final DirectPayment initialPayment = paymentApi.createAuthorization(account, account.getPaymentMethodId(), null, requestedAmount, account.getCurrency(),
+                                                                            UUID.randomUUID().toString(), UUID.randomUUID().toString(), ImmutableList.<PluginProperty>of(), callContext);
+
+
+        try {
+            paymentApi.createCapture(account, initialPayment.getId(), requestedAmount, Currency.AMD, UUID.randomUUID().toString(), ImmutableList.<PluginProperty>of(), callContext);
+            Assert.fail("Expected capture to fail...");
+        } catch (PaymentApiException e) {
+            Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_INVALID_PARAMETER.getCode());
+
+            final DirectPayment latestPayment = paymentApi.getPayment(initialPayment.getId(), false, ImmutableList.<PluginProperty>of(), callContext);
+            assertEquals(latestPayment, initialPayment);
+        }
+    }
+
+
+
     private List<PluginProperty> createPropertiesForInvoice(final Invoice invoice) {
         final List<PluginProperty> result = new ArrayList<PluginProperty>();
         result.add(new PluginProperty(InvoicePaymentControlPluginApi.PROP_IPCD_INVOICE_ID, invoice.getId().toString(), false));