killbill-memoizeit

Disable payment event notification when call bails early (no

7/2/2014 6:05:52 PM

Details

diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultDirectPayment.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultDirectPayment.java
index 73a0d4e..d009ebc 100644
--- a/payment/src/main/java/org/killbill/billing/payment/api/DefaultDirectPayment.java
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultDirectPayment.java
@@ -136,7 +136,7 @@ public class DefaultDirectPayment extends EntityBase implements DirectPayment {
 
     @Override
     public boolean isAuthVoided() {
-        return false;
+        return isVoided;
     }
 
     @Override
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultDirectPaymentApi.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultDirectPaymentApi.java
index 8edb561..3bd6283 100644
--- a/payment/src/main/java/org/killbill/billing/payment/api/DefaultDirectPaymentApi.java
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultDirectPaymentApi.java
@@ -40,6 +40,7 @@ import org.killbill.billing.util.entity.Pagination;
 public class DefaultDirectPaymentApi implements DirectPaymentApi {
 
     private static final boolean SHOULD_LOCK_ACCOUNT = true;
+    private static final boolean IS_API_PAYMENT = true;
 
     private final DirectPaymentProcessor directPaymentProcessor;
     private final PaymentMethodProcessor paymentMethodProcessor;
@@ -68,7 +69,7 @@ public class DefaultDirectPaymentApi implements DirectPaymentApi {
         checkPositiveAmount(amount);
 
         final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(account.getId(), callContext);
-        return directPaymentProcessor.createAuthorization(account, paymentMethodId, directPaymentId, amount, currency, directPaymentExternalKey, directPaymentTransactionExternalKey,
+        return directPaymentProcessor.createAuthorization(IS_API_PAYMENT, account, paymentMethodId, directPaymentId, amount, currency, directPaymentExternalKey, directPaymentTransactionExternalKey,
                                                           SHOULD_LOCK_ACCOUNT, properties, callContext, internalCallContext);
     }
 
@@ -84,7 +85,7 @@ public class DefaultDirectPaymentApi implements DirectPaymentApi {
         checkPositiveAmount(amount);
 
         final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(account.getId(), callContext);
-        return directPaymentProcessor.createCapture(account, directPaymentId, amount, currency, directPaymentTransactionExternalKey,
+        return directPaymentProcessor.createCapture(IS_API_PAYMENT, account, directPaymentId, amount, currency, directPaymentTransactionExternalKey,
                                                     SHOULD_LOCK_ACCOUNT, properties, callContext, internalCallContext);
     }
 
@@ -102,7 +103,7 @@ public class DefaultDirectPaymentApi implements DirectPaymentApi {
         checkPositiveAmount(amount);
 
         final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(account.getId(), callContext);
-        return directPaymentProcessor.createPurchase(account, paymentMethodId, directPaymentId, amount, currency, directPaymentExternalKey, directPaymentTransactionExternalKey,
+        return directPaymentProcessor.createPurchase(IS_API_PAYMENT, account, paymentMethodId, directPaymentId, amount, currency, directPaymentExternalKey, directPaymentTransactionExternalKey,
                                                      SHOULD_LOCK_ACCOUNT, properties, callContext, internalCallContext);
     }
 
@@ -128,7 +129,7 @@ public class DefaultDirectPaymentApi implements DirectPaymentApi {
         final UUID nonNulPaymentMethodId = (paymentMethodId != null) ?
                                            paymentMethodId :
                                            paymentMethodProcessor.createOrGetExternalPaymentMethod(UUID.randomUUID().toString(), account, properties, callContext, internalCallContext);
-        return pluginControlledPaymentProcessor.createPurchase(true, account, nonNulPaymentMethodId, directPaymentId, amount, currency, directPaymentExternalKey, directPaymentTransactionExternalKey,
+        return pluginControlledPaymentProcessor.createPurchase(IS_API_PAYMENT, account, nonNulPaymentMethodId, directPaymentId, amount, currency, directPaymentExternalKey, directPaymentTransactionExternalKey,
                                                                properties, paymentOptions.getPaymentControlPluginName(), callContext, internalCallContext);
 
     }
@@ -143,7 +144,7 @@ public class DefaultDirectPaymentApi implements DirectPaymentApi {
         checkNotNullParameter(properties, "plugin properties");
 
         final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(account.getId(), callContext);
-        return directPaymentProcessor.createVoid(account, directPaymentId, directPaymentTransactionExternalKey,
+        return directPaymentProcessor.createVoid(IS_API_PAYMENT, account, directPaymentId, directPaymentTransactionExternalKey,
                                                  SHOULD_LOCK_ACCOUNT, properties, callContext, internalCallContext);
 
     }
@@ -161,7 +162,7 @@ public class DefaultDirectPaymentApi implements DirectPaymentApi {
         checkPositiveAmount(amount);
 
         final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(account.getId(), callContext);
-        return directPaymentProcessor.createRefund(account, directPaymentId, amount, currency, directPaymentTransactionExternalKey,
+        return directPaymentProcessor.createRefund(IS_API_PAYMENT, account, directPaymentId, amount, currency, directPaymentTransactionExternalKey,
                                                    SHOULD_LOCK_ACCOUNT, properties, callContext, internalCallContext);
     }
 
@@ -179,7 +180,7 @@ public class DefaultDirectPaymentApi implements DirectPaymentApi {
         }
 
         final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(account.getId(), callContext);
-        return pluginControlledPaymentProcessor.createRefund(true, account, directPaymentId, amount, currency, directPaymentTransactionExternalKey,
+        return pluginControlledPaymentProcessor.createRefund(IS_API_PAYMENT, account, directPaymentId, amount, currency, directPaymentTransactionExternalKey,
                                                              properties, paymentOptions.getPaymentControlPluginName(), callContext, internalCallContext);
 
     }
@@ -200,7 +201,7 @@ public class DefaultDirectPaymentApi implements DirectPaymentApi {
         checkPositiveAmount(amount);
 
         final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(account.getId(), callContext);
-        return directPaymentProcessor.createCredit(account, paymentMethodId, directPaymentId, amount, currency, directPaymentExternalKey, directPaymentTransactionExternalKey,
+        return directPaymentProcessor.createCredit(IS_API_PAYMENT, account, paymentMethodId, directPaymentId, amount, currency, directPaymentExternalKey, directPaymentTransactionExternalKey,
                                                    SHOULD_LOCK_ACCOUNT, properties, callContext, internalCallContext);
 
     }
@@ -233,7 +234,7 @@ public class DefaultDirectPaymentApi implements DirectPaymentApi {
         checkPositiveAmount(amount);
 
         final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(account.getId(), callContext);
-        return directPaymentProcessor.notifyChargeback(account, null, directPaymentTransactionId, chargebackTransactionExternalKey, amount, currency, true,
+        return directPaymentProcessor.notifyChargeback(IS_API_PAYMENT, account, null, directPaymentTransactionId, chargebackTransactionExternalKey, amount, currency, true,
                                                        callContext, internalCallContext);
     }
 
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/DirectPaymentProcessor.java b/payment/src/main/java/org/killbill/billing/payment/core/DirectPaymentProcessor.java
index e11a89c..7695561 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/DirectPaymentProcessor.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/DirectPaymentProcessor.java
@@ -108,49 +108,49 @@ public class DirectPaymentProcessor extends ProcessorBase {
         this.directPaymentAutomatonRunner = directPaymentAutomatonRunner;
     }
 
-    public DirectPayment createAuthorization(final Account account, @Nullable final UUID paymentMethodId, @Nullable final UUID directPaymentId, final BigDecimal amount, final Currency currency,
+    public DirectPayment createAuthorization(final boolean isApiPayment, final Account account, @Nullable final UUID paymentMethodId, @Nullable final UUID directPaymentId, final BigDecimal amount, final Currency currency,
                                              final String directPaymentExternalKey, final String directPaymentTransactionExternalKey, final boolean shouldLockAccountAndDispatch,
                                              final Iterable<PluginProperty> properties, final CallContext callContext, final InternalCallContext internalCallContext) throws PaymentApiException {
-        return performOperation(TransactionType.AUTHORIZE, account, paymentMethodId, directPaymentId, amount, currency, directPaymentExternalKey, directPaymentTransactionExternalKey, shouldLockAccountAndDispatch, properties, callContext, internalCallContext);
+        return performOperation(isApiPayment, TransactionType.AUTHORIZE, account, paymentMethodId, directPaymentId, amount, currency, directPaymentExternalKey, directPaymentTransactionExternalKey, shouldLockAccountAndDispatch, properties, callContext, internalCallContext);
     }
 
-    public DirectPayment createCapture(final Account account, final UUID directPaymentId, final BigDecimal amount, final Currency currency,
+    public DirectPayment createCapture(final boolean isApiPayment, final Account account, final UUID directPaymentId, final BigDecimal amount, final Currency currency,
                                        final String directPaymentTransactionExternalKey, final boolean shouldLockAccountAndDispatch,
                                        final Iterable<PluginProperty> properties, final CallContext callContext, final InternalCallContext internalCallContext) throws PaymentApiException {
 
-        return performOperation(TransactionType.CAPTURE, account, null, directPaymentId, amount, currency, null, directPaymentTransactionExternalKey, shouldLockAccountAndDispatch, properties, callContext, internalCallContext);
+        return performOperation(isApiPayment, TransactionType.CAPTURE, account, null, directPaymentId, amount, currency, null, directPaymentTransactionExternalKey, shouldLockAccountAndDispatch, properties, callContext, internalCallContext);
     }
 
-    public DirectPayment createPurchase(final Account account, @Nullable final UUID paymentMethodId, @Nullable final UUID directPaymentId, final BigDecimal amount, final Currency currency,
+    public DirectPayment createPurchase(final boolean isApiPayment, final Account account, @Nullable final UUID paymentMethodId, @Nullable final UUID directPaymentId, final BigDecimal amount, final Currency currency,
                                         final String directPaymentExternalKey, final String directPaymentTransactionExternalKey, final boolean shouldLockAccountAndDispatch,
                                         final Iterable<PluginProperty> properties, final CallContext callContext, final InternalCallContext internalCallContext) throws PaymentApiException {
-        return performOperation(TransactionType.PURCHASE, account, paymentMethodId, directPaymentId, amount, currency, directPaymentExternalKey, directPaymentTransactionExternalKey, shouldLockAccountAndDispatch, properties, callContext, internalCallContext);
+        return performOperation(isApiPayment, TransactionType.PURCHASE, account, paymentMethodId, directPaymentId, amount, currency, directPaymentExternalKey, directPaymentTransactionExternalKey, shouldLockAccountAndDispatch, properties, callContext, internalCallContext);
     }
 
-    public DirectPayment createVoid(final Account account, final UUID directPaymentId, final String directPaymentTransactionExternalKey, final boolean shouldLockAccountAndDispatch,
+    public DirectPayment createVoid(final boolean isApiPayment, final Account account, final UUID directPaymentId, final String directPaymentTransactionExternalKey, final boolean shouldLockAccountAndDispatch,
                                     final Iterable<PluginProperty> properties, final CallContext callContext, final InternalCallContext internalCallContext) throws PaymentApiException {
-        return performOperation(TransactionType.VOID, account, null, directPaymentId, null, null, null, directPaymentTransactionExternalKey, shouldLockAccountAndDispatch, properties, callContext, internalCallContext);
+        return performOperation(isApiPayment, TransactionType.VOID, account, null, directPaymentId, null, null, null, directPaymentTransactionExternalKey, shouldLockAccountAndDispatch, properties, callContext, internalCallContext);
     }
 
-    public DirectPayment createRefund(final Account account, final UUID directPaymentId, final BigDecimal amount, final Currency currency,
+    public DirectPayment createRefund(final boolean isApiPayment, final Account account, final UUID directPaymentId, final BigDecimal amount, final Currency currency,
                                       final String directPaymentTransactionExternalKey, final boolean shouldLockAccountAndDispatch,
                                       final Iterable<PluginProperty> properties, final CallContext callContext, final InternalCallContext internalCallContext) throws PaymentApiException {
-        return performOperation(TransactionType.REFUND, account, null, directPaymentId, amount, currency, null, directPaymentTransactionExternalKey, shouldLockAccountAndDispatch, properties, callContext, internalCallContext);
+        return performOperation(isApiPayment, TransactionType.REFUND, account, null, directPaymentId, amount, currency, null, directPaymentTransactionExternalKey, shouldLockAccountAndDispatch, properties, callContext, internalCallContext);
     }
 
-    public DirectPayment createCredit(final Account account, @Nullable final UUID paymentMethodId, @Nullable final UUID directPaymentId, final BigDecimal amount, final Currency currency,
+    public DirectPayment createCredit(final boolean isApiPayment, final Account account, @Nullable final UUID paymentMethodId, @Nullable final UUID directPaymentId, final BigDecimal amount, final Currency currency,
                                       final String directPaymentExternalKey, final String directPaymentTransactionExternalKey, final boolean shouldLockAccountAndDispatch,
                                       final Iterable<PluginProperty> properties, final CallContext callContext, final InternalCallContext internalCallContext) throws PaymentApiException {
-        return performOperation(TransactionType.CREDIT, account, paymentMethodId, directPaymentId, amount, currency, directPaymentExternalKey, directPaymentTransactionExternalKey, shouldLockAccountAndDispatch, properties, callContext, internalCallContext);
+        return performOperation(isApiPayment, TransactionType.CREDIT, account, paymentMethodId, directPaymentId, amount, currency, directPaymentExternalKey, directPaymentTransactionExternalKey, shouldLockAccountAndDispatch, properties, callContext, internalCallContext);
     }
 
-    public DirectPayment notifyChargeback(final Account account, @Nullable final UUID paymentId, @Nullable final UUID transactionId, final String directPaymentTransactionExternalKey, final BigDecimal amount, final Currency currency, final boolean shouldLockAccountAndDispatch,
+    public DirectPayment notifyChargeback(final boolean isApiPayment, final Account account, @Nullable final UUID paymentId, @Nullable final UUID transactionId, final String directPaymentTransactionExternalKey, final BigDecimal amount, final Currency currency, final boolean shouldLockAccountAndDispatch,
                                           final CallContext callContext, final InternalCallContext internalCallContext) throws PaymentApiException {
 
         // We need to have something...
         Preconditions.checkState(paymentId != null || transactionId != null);
         final UUID nonNullPaymentId = retrieveNonNullPaymentIdFromArguments(paymentId, transactionId, internalCallContext);
-        return performOperation(TransactionType.CHARGEBACK, account, null, nonNullPaymentId, amount, currency, null, directPaymentTransactionExternalKey, shouldLockAccountAndDispatch, ImmutableList.<PluginProperty>of(), callContext, internalCallContext);
+        return performOperation(isApiPayment, TransactionType.CHARGEBACK, account, null, nonNullPaymentId, amount, currency, null, directPaymentTransactionExternalKey, shouldLockAccountAndDispatch, ImmutableList.<PluginProperty>of(), callContext, internalCallContext);
     }
 
     public List<DirectPayment> getAccountPayments(final UUID accountId, final InternalTenantContext tenantContext) throws PaymentApiException {
@@ -316,7 +316,7 @@ public class DirectPaymentProcessor extends ProcessorBase {
         return toDirectPayment(paymentModelDao, transactionsForAccount, pluginTransactions);
     }
 
-    private DirectPayment performOperation(final TransactionType transactionType, final Account account, final UUID paymentMethodId, final UUID directPaymentId, final BigDecimal amount, final Currency currency,
+    private DirectPayment performOperation(final boolean isApiPayment, final TransactionType transactionType, final Account account, final UUID paymentMethodId, final UUID directPaymentId, final BigDecimal amount, final Currency currency,
                                            final String directPaymentExternalKey, final String directPaymentTransactionExternalKey,
                                            final boolean shouldLockAccountAndDispatch, final Iterable<PluginProperty> properties, final CallContext callContext,
                                            final InternalCallContext internalCallContext) throws PaymentApiException {
@@ -340,7 +340,7 @@ public class DirectPaymentProcessor extends ProcessorBase {
             directPayment = getPayment(nonNullDirectPaymentId, true, properties, callContext, internalCallContext);
             return directPayment;
         } finally {
-            postPaymentEvent(account, transactionType, directPayment, directPaymentTransactionExternalKey, internalCallContext);
+            postPaymentEvent(isApiPayment, account, transactionType, directPayment, directPaymentTransactionExternalKey, internalCallContext);
 
         }
     }
@@ -405,19 +405,19 @@ public class DirectPaymentProcessor extends ProcessorBase {
                                         curPaymentModelDao.getPaymentMethodId(), curPaymentModelDao.getPaymentNumber(), curPaymentModelDao.getExternalKey(), sortedTransactions);
     }
 
-    private void postPaymentEvent(final Account account, final TransactionType transactionType, @Nullable final DirectPayment directPayment, final String transactionExternalKey, final InternalCallContext context) {
-        final BusInternalEvent event = buildPaymentEvent(account, transactionType, directPayment, transactionExternalKey, context);
+    private void postPaymentEvent(final boolean isApiPayment, final Account account, final TransactionType transactionType, @Nullable final DirectPayment directPayment, final String transactionExternalKey, final InternalCallContext context) {
+        final BusInternalEvent event = buildPaymentEvent(isApiPayment, account, transactionType, directPayment, transactionExternalKey, context);
         postPaymentEvent(event, account.getId(), context);
     }
 
-    private BusInternalEvent buildPaymentEvent(final Account account, final TransactionType transactionType, @Nullable final DirectPayment directPayment, final String transactionExternalKey, final InternalCallContext context) {
+    private BusInternalEvent buildPaymentEvent(final boolean isApiPayment, final Account account, final TransactionType transactionType, @Nullable final DirectPayment directPayment, final String transactionExternalKey, final InternalCallContext context) {
 
-        if (directPayment == null) {
+        if (!isApiPayment && directPayment == null) {
             return new DefaultPaymentErrorEvent(account.getId(),
                                                 null,
                                                 null,
                                                 transactionType,
-                                                "No payment method",
+                                                "Early abortion of payment transaction",
                                                 context.getAccountRecordId(),
                                                 context.getTenantRecordId(),
                                                 context.getUserToken());
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 abfad57..8a129f5 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
@@ -139,10 +139,10 @@ public class DirectPaymentAutomatonDAOHelper {
         final DateTime updatedDate = utcNow;
 
         return new PaymentModelDao(createdDate,
-                                         updatedDate,
-                                         directPaymentStateContext.getAccount().getId(),
-                                         directPaymentStateContext.getPaymentMethodId(),
-                                         directPaymentStateContext.getDirectPaymentExternalKey());
+                                   updatedDate,
+                                   directPaymentStateContext.getAccount().getId(),
+                                   directPaymentStateContext.getPaymentMethodId(),
+                                   directPaymentStateContext.getDirectPaymentExternalKey());
     }
 
     private PaymentTransactionModelDao buildNewDirectPaymentTransactionModelDao(final UUID directPaymentId) {
@@ -153,16 +153,16 @@ public class DirectPaymentAutomatonDAOHelper {
         final String gatewayErrorMsg = null;
 
         return new PaymentTransactionModelDao(createdDate,
-                                                    updatedDate,
-                                                    directPaymentStateContext.getDirectPaymentTransactionExternalKey(),
-                                                    directPaymentId,
-                                                    directPaymentStateContext.getTransactionType(),
-                                                    effectiveDate,
-                                                    TransactionStatus.UNKNOWN,
-                                                    directPaymentStateContext.getAmount(),
-                                                    directPaymentStateContext.getCurrency(),
-                                                    gatewayErrorCode,
-                                                    gatewayErrorMsg);
+                                              updatedDate,
+                                              directPaymentStateContext.getDirectPaymentTransactionExternalKey(),
+                                              directPaymentId,
+                                              directPaymentStateContext.getTransactionType(),
+                                              effectiveDate,
+                                              TransactionStatus.UNKNOWN,
+                                              directPaymentStateContext.getAmount(),
+                                              directPaymentStateContext.getCurrency(),
+                                              gatewayErrorCode,
+                                              gatewayErrorMsg);
     }
 
     private PaymentPluginApi getPaymentPluginApi(final String pluginName) throws PaymentApiException {
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryAuthorizeOperationCallback.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryAuthorizeOperationCallback.java
index 5993143..5159d46 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryAuthorizeOperationCallback.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryAuthorizeOperationCallback.java
@@ -33,6 +33,17 @@ public class RetryAuthorizeOperationCallback extends RetryOperationCallback {
 
     @Override
     protected DirectPayment doCallSpecificOperationCallback() throws PaymentApiException {
-        return directPaymentProcessor.createAuthorization(directPaymentStateContext.account, directPaymentStateContext.paymentMethodId, directPaymentStateContext.directPaymentId, directPaymentStateContext.getAmount(), directPaymentStateContext.getCurrency(), directPaymentStateContext.directPaymentExternalKey, directPaymentStateContext.directPaymentTransactionExternalKey, false, directPaymentStateContext.getProperties(), directPaymentStateContext.callContext, directPaymentStateContext.internalCallContext);
+        return directPaymentProcessor.createAuthorization(retryableDirectPaymentStateContext.isApiPayment(),
+                                                          retryableDirectPaymentStateContext.getAccount(),
+                                                          retryableDirectPaymentStateContext.getPaymentMethodId(),
+                                                          retryableDirectPaymentStateContext.getDirectPaymentId(),
+                                                          retryableDirectPaymentStateContext.getAmount(),
+                                                          retryableDirectPaymentStateContext.getCurrency(),
+                                                          retryableDirectPaymentStateContext.getDirectPaymentExternalKey(),
+                                                          retryableDirectPaymentStateContext.getDirectPaymentTransactionExternalKey(),
+                                                          false,
+                                                          retryableDirectPaymentStateContext.getProperties(),
+                                                          retryableDirectPaymentStateContext.getCallContext(),
+                                                          retryableDirectPaymentStateContext.getInternalCallContext());
     }
 }
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryCaptureOperationCallback.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryCaptureOperationCallback.java
index 508a83e..88cd362 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryCaptureOperationCallback.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryCaptureOperationCallback.java
@@ -33,10 +33,15 @@ public class RetryCaptureOperationCallback extends RetryOperationCallback {
 
     @Override
     protected DirectPayment doCallSpecificOperationCallback() throws PaymentApiException {
-        return directPaymentProcessor.createCapture(directPaymentStateContext.account, directPaymentStateContext.directPaymentId,
-                                                    directPaymentStateContext.getAmount(), directPaymentStateContext.getCurrency(),
-                                                    directPaymentStateContext.directPaymentTransactionExternalKey,
-                                                    false, directPaymentStateContext.getProperties(),
-                                                    directPaymentStateContext.callContext, directPaymentStateContext.internalCallContext);
+        return directPaymentProcessor.createCapture(retryableDirectPaymentStateContext.isApiPayment(),
+                                                    retryableDirectPaymentStateContext.getAccount(),
+                                                    retryableDirectPaymentStateContext.getPaymentMethodId(),
+                                                    retryableDirectPaymentStateContext.getAmount(),
+                                                    retryableDirectPaymentStateContext.getCurrency(),
+                                                    retryableDirectPaymentStateContext.getDirectPaymentTransactionExternalKey(),
+                                                    false,
+                                                    retryableDirectPaymentStateContext.getProperties(),
+                                                    retryableDirectPaymentStateContext.getCallContext(),
+                                                    retryableDirectPaymentStateContext.getInternalCallContext());
     }
 }
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryChargebackOperationCallback.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryChargebackOperationCallback.java
index 1b3bd88..f644088 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryChargebackOperationCallback.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryChargebackOperationCallback.java
@@ -34,9 +34,15 @@ public class RetryChargebackOperationCallback extends RetryOperationCallback {
 
     @Override
     protected DirectPayment doCallSpecificOperationCallback() throws PaymentApiException {
-        return directPaymentProcessor.notifyChargeback(directPaymentStateContext.account, directPaymentStateContext.getDirectPaymentId(), null, directPaymentStateContext.directPaymentTransactionExternalKey, directPaymentStateContext.getAmount(),
-                                                       directPaymentStateContext.getCurrency(), false,
-                                                       directPaymentStateContext.callContext, directPaymentStateContext.internalCallContext);
-
+        return directPaymentProcessor.notifyChargeback(retryableDirectPaymentStateContext.isApiPayment(),
+                                                    retryableDirectPaymentStateContext.getAccount(),
+                                                    retryableDirectPaymentStateContext.getDirectPaymentId(),
+                                                    null,
+                                                    retryableDirectPaymentStateContext.getDirectPaymentTransactionExternalKey(),
+                                                    retryableDirectPaymentStateContext.getAmount(),
+                                                    retryableDirectPaymentStateContext.getCurrency(),
+                                                    false,
+                                                    retryableDirectPaymentStateContext.getCallContext(),
+                                                    retryableDirectPaymentStateContext.getInternalCallContext());
     }
 }
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryCreditOperationCallback.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryCreditOperationCallback.java
index 6f25017..1b309d9 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryCreditOperationCallback.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryCreditOperationCallback.java
@@ -33,6 +33,17 @@ public class RetryCreditOperationCallback extends RetryOperationCallback {
 
     @Override
     protected DirectPayment doCallSpecificOperationCallback() throws PaymentApiException {
-        return directPaymentProcessor.createCredit(directPaymentStateContext.account, directPaymentStateContext.paymentMethodId, directPaymentStateContext.directPaymentId, directPaymentStateContext.getAmount(), directPaymentStateContext.getCurrency(), directPaymentStateContext.directPaymentExternalKey, directPaymentStateContext.directPaymentTransactionExternalKey, false, directPaymentStateContext.getProperties(), directPaymentStateContext.callContext, directPaymentStateContext.internalCallContext);
+        return directPaymentProcessor.createCredit(retryableDirectPaymentStateContext.isApiPayment(),
+                                                   retryableDirectPaymentStateContext.getAccount(),
+                                                   retryableDirectPaymentStateContext.getPaymentMethodId(),
+                                                   retryableDirectPaymentStateContext.getDirectPaymentId(),
+                                                   retryableDirectPaymentStateContext.getAmount(),
+                                                   retryableDirectPaymentStateContext.getCurrency(),
+                                                   retryableDirectPaymentStateContext.getDirectPaymentExternalKey(),
+                                                   retryableDirectPaymentStateContext.getDirectPaymentTransactionExternalKey(),
+                                                   false,
+                                                   retryableDirectPaymentStateContext.getProperties(),
+                                                   retryableDirectPaymentStateContext.getCallContext(),
+                                                   retryableDirectPaymentStateContext.getInternalCallContext());
     }
 }
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryOperationCallback.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryOperationCallback.java
index 5f44768..7c7bd6e 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryOperationCallback.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryOperationCallback.java
@@ -53,15 +53,19 @@ import org.slf4j.LoggerFactory;
 
 public abstract class RetryOperationCallback extends OperationCallbackBase implements OperationCallback {
 
-    protected final DirectPaymentProcessor directPaymentProcessor;
     private final OSGIServiceRegistration<PaymentControlPluginApi> paymentControlPluginRegistry;
 
+    protected final DirectPaymentProcessor directPaymentProcessor;
+    protected final RetryableDirectPaymentStateContext retryableDirectPaymentStateContext;
+
+
     private final Logger logger = LoggerFactory.getLogger(RetryOperationCallback.class);
 
     protected RetryOperationCallback(final GlobalLocker locker, final PluginDispatcher<OperationResult> paymentPluginDispatcher, final RetryableDirectPaymentStateContext directPaymentStateContext, final DirectPaymentProcessor directPaymentProcessor, final OSGIServiceRegistration<PaymentControlPluginApi> retryPluginRegistry) {
         super(locker, paymentPluginDispatcher, directPaymentStateContext);
         this.directPaymentProcessor = directPaymentProcessor;
         this.paymentControlPluginRegistry = retryPluginRegistry;
+        this.retryableDirectPaymentStateContext = directPaymentStateContext;
     }
 
 
@@ -76,7 +80,6 @@ public abstract class RetryOperationCallback extends OperationCallbackBase imple
             @Override
             public OperationResult doOperation() throws OperationException {
 
-                final RetryableDirectPaymentStateContext retryableDirectPaymentStateContext = (RetryableDirectPaymentStateContext) directPaymentStateContext;
                 final PaymentControlContext paymentControlContext = new DefaultPaymentControlContext(directPaymentStateContext.getAccount(),
                                                                                                      directPaymentStateContext.getPaymentMethodId(),
                                                                                                      retryableDirectPaymentStateContext.getAttemptId(),
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryPurchaseOperationCallback.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryPurchaseOperationCallback.java
index 7876e9e..1e5636a 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryPurchaseOperationCallback.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryPurchaseOperationCallback.java
@@ -33,8 +33,17 @@ public class RetryPurchaseOperationCallback extends RetryOperationCallback {
 
     @Override
     protected DirectPayment doCallSpecificOperationCallback() throws PaymentApiException {
-        return directPaymentProcessor.createPurchase(directPaymentStateContext.account, directPaymentStateContext.paymentMethodId, directPaymentStateContext.directPaymentId, directPaymentStateContext.getAmount(),
-                                                     directPaymentStateContext.getCurrency(), directPaymentStateContext.directPaymentExternalKey, directPaymentStateContext.directPaymentTransactionExternalKey, false,
-                                                     directPaymentStateContext.getProperties(), directPaymentStateContext.callContext, directPaymentStateContext.internalCallContext);
+        return directPaymentProcessor.createPurchase(retryableDirectPaymentStateContext.isApiPayment(),
+                                                     retryableDirectPaymentStateContext.getAccount(),
+                                                     retryableDirectPaymentStateContext.getPaymentMethodId(),
+                                                     retryableDirectPaymentStateContext.getDirectPaymentId(),
+                                                     retryableDirectPaymentStateContext.getAmount(),
+                                                     retryableDirectPaymentStateContext.getCurrency(),
+                                                     retryableDirectPaymentStateContext.getDirectPaymentExternalKey(),
+                                                     retryableDirectPaymentStateContext.getDirectPaymentTransactionExternalKey(),
+                                                     false,
+                                                     retryableDirectPaymentStateContext.getProperties(),
+                                                     retryableDirectPaymentStateContext.getCallContext(),
+                                                     retryableDirectPaymentStateContext.getInternalCallContext());
     }
 }
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryRefundOperationCallback.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryRefundOperationCallback.java
index 414f2f8..2fc77fb 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryRefundOperationCallback.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryRefundOperationCallback.java
@@ -33,6 +33,15 @@ public class RetryRefundOperationCallback extends RetryOperationCallback {
 
     @Override
     protected DirectPayment doCallSpecificOperationCallback() throws PaymentApiException {
-        return directPaymentProcessor.createRefund(directPaymentStateContext.account, directPaymentStateContext.directPaymentId, directPaymentStateContext.getAmount(), directPaymentStateContext.getCurrency(), directPaymentStateContext.directPaymentTransactionExternalKey, false, directPaymentStateContext.getProperties(), directPaymentStateContext.callContext, directPaymentStateContext.internalCallContext);
+        return directPaymentProcessor.createRefund(retryableDirectPaymentStateContext.isApiPayment(),
+                                                   retryableDirectPaymentStateContext.getAccount(),
+                                                   retryableDirectPaymentStateContext.getDirectPaymentId(),
+                                                   retryableDirectPaymentStateContext.getAmount(),
+                                                   retryableDirectPaymentStateContext.getCurrency(),
+                                                   retryableDirectPaymentStateContext.getDirectPaymentTransactionExternalKey(),
+                                                   false,
+                                                   retryableDirectPaymentStateContext.getProperties(),
+                                                   retryableDirectPaymentStateContext.getCallContext(),
+                                                   retryableDirectPaymentStateContext.getInternalCallContext());
     }
 }
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryVoidOperationCallback.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryVoidOperationCallback.java
index 45ea703..a2f2382 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryVoidOperationCallback.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/RetryVoidOperationCallback.java
@@ -33,6 +33,13 @@ public class RetryVoidOperationCallback extends RetryOperationCallback {
 
     @Override
     protected DirectPayment doCallSpecificOperationCallback() throws PaymentApiException {
-        return directPaymentProcessor.createVoid(directPaymentStateContext.account, directPaymentStateContext.directPaymentId, directPaymentStateContext.directPaymentTransactionExternalKey, false, directPaymentStateContext.getProperties(), directPaymentStateContext.callContext, directPaymentStateContext.internalCallContext);
+        return directPaymentProcessor.createVoid(retryableDirectPaymentStateContext.isApiPayment(),
+                                                   retryableDirectPaymentStateContext.getAccount(),
+                                                   retryableDirectPaymentStateContext.getDirectPaymentId(),
+                                                   retryableDirectPaymentStateContext.getDirectPaymentTransactionExternalKey(),
+                                                   false,
+                                                   retryableDirectPaymentStateContext.getProperties(),
+                                                   retryableDirectPaymentStateContext.getCallContext(),
+                                                   retryableDirectPaymentStateContext.getInternalCallContext());
     }
 }
diff --git a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApiNoDB.java b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApiNoDB.java
index e5fda6b..398e859 100644
--- a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApiNoDB.java
+++ b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApiNoDB.java
@@ -78,7 +78,7 @@ public class TestPaymentApiNoDB extends PaymentTestSuiteNoDB {
     }
 
     @Test(groups = "fast")
-    public void testSimplePaymentWithNoAmount() throws Exception {
+    public void testSimpleInvoicePaymentWithNoAmount() throws Exception {
         final BigDecimal invoiceAmount = new BigDecimal("10.0011");
         final BigDecimal requestedAmount = null;
         final BigDecimal expectedAmount = null;
@@ -87,7 +87,7 @@ public class TestPaymentApiNoDB extends PaymentTestSuiteNoDB {
     }
 
     @Test(groups = "fast")
-    public void testSimplePaymentWithInvoiceAmount() throws Exception {
+    public void testSimpleInvoicePaymentWithInvoiceAmount() throws Exception {
         final BigDecimal invoiceAmount = new BigDecimal("10.0011");
         final BigDecimal requestedAmount = invoiceAmount;
         final BigDecimal expectedAmount = invoiceAmount;
@@ -96,7 +96,7 @@ public class TestPaymentApiNoDB extends PaymentTestSuiteNoDB {
     }
 
     @Test(groups = "fast")
-    public void testSimplePaymentWithLowerAmount() throws Exception {
+    public void testSimpleInvoicePaymentWithLowerAmount() throws Exception {
         final BigDecimal invoiceAmount = new BigDecimal("10.0011");
         final BigDecimal requestedAmount = new BigDecimal("8.0091");
         final BigDecimal expectedAmount = requestedAmount;
@@ -105,7 +105,7 @@ public class TestPaymentApiNoDB extends PaymentTestSuiteNoDB {
     }
 
     @Test(groups = "fast")
-    public void testSimplePaymentWithInvalidAmount() throws Exception {
+    public void testSimpleInvoicePaymentWithInvalidAmount() throws Exception {
         final BigDecimal invoiceAmount = new BigDecimal("10.0011");
         final BigDecimal requestedAmount = new BigDecimal("80.0091");
         final BigDecimal expectedAmount = null;
diff --git a/payment/src/test/java/org/killbill/billing/payment/core/TestDirectPaymentProcessor.java b/payment/src/test/java/org/killbill/billing/payment/core/TestDirectPaymentProcessor.java
index 7e2de1d..cfa5141 100644
--- a/payment/src/test/java/org/killbill/billing/payment/core/TestDirectPaymentProcessor.java
+++ b/payment/src/test/java/org/killbill/billing/payment/core/TestDirectPaymentProcessor.java
@@ -75,7 +75,7 @@ public class TestDirectPaymentProcessor extends PaymentTestSuiteWithEmbeddedDB {
 
         // AUTH pre-3DS
         final String authorizationKey = UUID.randomUUID().toString();
-        final DirectPayment authorization = directPaymentProcessor.createAuthorization(account, null, null, TEN, CURRENCY, directPaymentExternalKey, authorizationKey,
+        final DirectPayment authorization = directPaymentProcessor.createAuthorization(true, account, null, null, TEN, CURRENCY, directPaymentExternalKey, authorizationKey,
                                                                                        SHOULD_LOCK_ACCOUNT, PLUGIN_PROPERTIES, callContext, internalCallContext);
         verifyDirectPayment(authorization, directPaymentExternalKey, TEN, ZERO, ZERO, 1);
         final UUID directPaymentId = authorization.getId();
@@ -84,7 +84,7 @@ public class TestDirectPaymentProcessor extends PaymentTestSuiteWithEmbeddedDB {
 
         // AUTH post-3DS
         final String authorizationPost3DSKey = UUID.randomUUID().toString();
-        final DirectPayment authorizationPost3DS = directPaymentProcessor.createAuthorization(account, null, directPaymentId, TEN, CURRENCY, directPaymentExternalKey, authorizationPost3DSKey,
+        final DirectPayment authorizationPost3DS = directPaymentProcessor.createAuthorization(true, account, null, directPaymentId, TEN, CURRENCY, directPaymentExternalKey, authorizationPost3DSKey,
                                                                                               SHOULD_LOCK_ACCOUNT, PLUGIN_PROPERTIES, callContext, internalCallContext);
         verifyDirectPayment(authorizationPost3DS, directPaymentExternalKey, TEN, ZERO, ZERO, 2);
         verifyDirectPaymentTransaction(authorizationPost3DS.getTransactions().get(1), authorizationPost3DSKey, TransactionType.AUTHORIZE, TEN, directPaymentId);
@@ -92,7 +92,7 @@ public class TestDirectPaymentProcessor extends PaymentTestSuiteWithEmbeddedDB {
 
         // CAPTURE
         final String capture1Key = UUID.randomUUID().toString();
-        final DirectPayment partialCapture1 = directPaymentProcessor.createCapture(account, directPaymentId, FIVE, CURRENCY, capture1Key,
+        final DirectPayment partialCapture1 = directPaymentProcessor.createCapture(true, account, directPaymentId, FIVE, CURRENCY, capture1Key,
                                                                                    SHOULD_LOCK_ACCOUNT, PLUGIN_PROPERTIES, callContext, internalCallContext);
         verifyDirectPayment(partialCapture1, directPaymentExternalKey, TEN, FIVE, ZERO, 3);
         verifyDirectPaymentTransaction(partialCapture1.getTransactions().get(2), capture1Key, TransactionType.CAPTURE, FIVE, directPaymentId);
@@ -100,7 +100,7 @@ public class TestDirectPaymentProcessor extends PaymentTestSuiteWithEmbeddedDB {
 
         // CAPTURE
         final String capture2Key = UUID.randomUUID().toString();
-        final DirectPayment partialCapture2 = directPaymentProcessor.createCapture(account, directPaymentId, FIVE, CURRENCY, capture2Key,
+        final DirectPayment partialCapture2 = directPaymentProcessor.createCapture(true, account, directPaymentId, FIVE, CURRENCY, capture2Key,
                                                                                    SHOULD_LOCK_ACCOUNT, PLUGIN_PROPERTIES, callContext, internalCallContext);
         verifyDirectPayment(partialCapture2, directPaymentExternalKey, TEN, TEN, ZERO, 4);
         verifyDirectPaymentTransaction(partialCapture2.getTransactions().get(3), capture2Key, TransactionType.CAPTURE, FIVE, directPaymentId);
@@ -108,7 +108,7 @@ public class TestDirectPaymentProcessor extends PaymentTestSuiteWithEmbeddedDB {
 
         // REFUND
         final String refund1Key = UUID.randomUUID().toString();
-        final DirectPayment partialRefund1 = directPaymentProcessor.createRefund(account, directPaymentId, FIVE, CURRENCY, refund1Key,
+        final DirectPayment partialRefund1 = directPaymentProcessor.createRefund(true, account, directPaymentId, FIVE, CURRENCY, refund1Key,
                                                                                  SHOULD_LOCK_ACCOUNT, PLUGIN_PROPERTIES, callContext, internalCallContext);
         verifyDirectPayment(partialRefund1, directPaymentExternalKey, TEN, TEN, FIVE, 5);
         verifyDirectPaymentTransaction(partialRefund1.getTransactions().get(4), refund1Key, TransactionType.REFUND, FIVE, directPaymentId);
@@ -116,7 +116,7 @@ public class TestDirectPaymentProcessor extends PaymentTestSuiteWithEmbeddedDB {
 
         // REFUND
         final String refund2Key = UUID.randomUUID().toString();
-        final DirectPayment partialRefund2 = directPaymentProcessor.createRefund(account, directPaymentId, FIVE, CURRENCY, refund2Key,
+        final DirectPayment partialRefund2 = directPaymentProcessor.createRefund(true, account, directPaymentId, FIVE, CURRENCY, refund2Key,
                                                                                  SHOULD_LOCK_ACCOUNT, PLUGIN_PROPERTIES, callContext, internalCallContext);
         verifyDirectPayment(partialRefund2, directPaymentExternalKey, TEN, TEN, TEN, 6);
         verifyDirectPaymentTransaction(partialRefund2.getTransactions().get(5), refund2Key, TransactionType.REFUND, FIVE, directPaymentId);
@@ -129,7 +129,7 @@ public class TestDirectPaymentProcessor extends PaymentTestSuiteWithEmbeddedDB {
 
         // AUTH
         final String authorizationKey = UUID.randomUUID().toString();
-        final DirectPayment authorization = directPaymentProcessor.createAuthorization(account, null, null, TEN, CURRENCY, directPaymentExternalKey, authorizationKey,
+        final DirectPayment authorization = directPaymentProcessor.createAuthorization(true, account, null, null, TEN, CURRENCY, directPaymentExternalKey, authorizationKey,
                                                                                        SHOULD_LOCK_ACCOUNT, PLUGIN_PROPERTIES, callContext, internalCallContext);
         verifyDirectPayment(authorization, directPaymentExternalKey, TEN, ZERO, ZERO, 1);
         final UUID directPaymentId = authorization.getId();
@@ -138,7 +138,7 @@ public class TestDirectPaymentProcessor extends PaymentTestSuiteWithEmbeddedDB {
 
         // VOID
         final String voidKey = UUID.randomUUID().toString();
-        final DirectPayment voidTransaction = directPaymentProcessor.createVoid(account, directPaymentId, voidKey,
+        final DirectPayment voidTransaction = directPaymentProcessor.createVoid(true, account, directPaymentId, voidKey,
                                                                                 SHOULD_LOCK_ACCOUNT, PLUGIN_PROPERTIES, callContext, internalCallContext);
         verifyDirectPayment(voidTransaction, directPaymentExternalKey, TEN, ZERO, ZERO, 2);
         verifyDirectPaymentTransaction(voidTransaction.getTransactions().get(1), voidKey, TransactionType.VOID, null, directPaymentId);
@@ -151,7 +151,7 @@ public class TestDirectPaymentProcessor extends PaymentTestSuiteWithEmbeddedDB {
 
         // PURCHASE
         final String purchaseKey = UUID.randomUUID().toString();
-        final DirectPayment purchase = directPaymentProcessor.createPurchase(account, null, null, TEN, CURRENCY, directPaymentExternalKey, purchaseKey,
+        final DirectPayment purchase = directPaymentProcessor.createPurchase(true, account, null, null, TEN, CURRENCY, directPaymentExternalKey, purchaseKey,
                                                                              SHOULD_LOCK_ACCOUNT, PLUGIN_PROPERTIES, callContext, internalCallContext);
         verifyDirectPayment(purchase, directPaymentExternalKey, ZERO, ZERO, ZERO, 1);
         final UUID directPaymentId = purchase.getId();
@@ -165,7 +165,7 @@ public class TestDirectPaymentProcessor extends PaymentTestSuiteWithEmbeddedDB {
 
         // CREDIT
         final String creditKey = UUID.randomUUID().toString();
-        final DirectPayment purchase = directPaymentProcessor.createCredit(account, null, null, TEN, CURRENCY, directPaymentExternalKey, creditKey,
+        final DirectPayment purchase = directPaymentProcessor.createCredit(true, account, null, null, TEN, CURRENCY, directPaymentExternalKey, creditKey,
                                                                            SHOULD_LOCK_ACCOUNT, PLUGIN_PROPERTIES, callContext, internalCallContext);
         verifyDirectPayment(purchase, directPaymentExternalKey, ZERO, ZERO, ZERO, 1);
         final UUID directPaymentId = purchase.getId();