killbill-aplcache
Changes
payment/src/main/java/org/killbill/billing/payment/core/sm/DirectPaymentAutomatonDAOHelper.java 3(+3 -0)
Details
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 cc4fa4d..fdde4e9 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
@@ -177,7 +177,11 @@ public class DirectPaymentProcessor extends ProcessorBase {
// STEPH This works if the pending transaction we are trying to update matches is the one that gave the state to the payment. Also can we have multiple PENDING for a given payment?
final State currentPaymentState = directPaymentAutomatonRunner.fetchNextState(paymentModelDao.getStateName(), isSuccess);
// STEPH : should we insert a new transaction row to keep the PENDING one?
- paymentDao.updateDirectPaymentAndTransactionOnCompletion(transactionModelDao.getPaymentId(), currentPaymentState.getName(), transactionModelDao.getId(), newStatus,
+
+ // STEPH hack; need proper automaton API to understand what is a successful terminal state.
+ final String lastSuccessPaymentStateStrOrNull = currentPaymentState.getName().endsWith("SUCCESS") ? currentPaymentState.getName() : null;
+
+ paymentDao.updateDirectPaymentAndTransactionOnCompletion(transactionModelDao.getPaymentId(), currentPaymentState.getName(), lastSuccessPaymentStateStrOrNull, transactionModelDao.getId(), newStatus,
transactionModelDao.getProcessedAmount(), transactionModelDao.getProcessedCurrency(),
transactionModelDao.getGatewayErrorCode(), transactionModelDao.getGatewayErrorMsg(), internalCallContext);
}
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 dc6e161..0035bd7 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
@@ -97,8 +97,11 @@ public class DirectPaymentAutomatonDAOHelper {
final String gatewayErrorCode = paymentInfoPlugin == null ? null : paymentInfoPlugin.getGatewayErrorCode();
final String gatewayErrorMsg = paymentInfoPlugin == null ? null : paymentInfoPlugin.getGatewayError();
+ final String lastSuccessPaymentState = currentPaymentStateName.endsWith("SUCCESS") ? currentPaymentStateName : null;
+
paymentDao.updateDirectPaymentAndTransactionOnCompletion(directPaymentStateContext.getDirectPaymentId(),
currentPaymentStateName,
+ lastSuccessPaymentState,
directPaymentStateContext.getDirectPaymentTransactionModelDao().getId(),
paymentStatus,
processedAmount,
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/DirectPaymentAutomatonRunner.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/DirectPaymentAutomatonRunner.java
index 6d99e34..05fd7ff 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/DirectPaymentAutomatonRunner.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/DirectPaymentAutomatonRunner.java
@@ -110,7 +110,7 @@ public class DirectPaymentAutomatonRunner {
if (directPaymentId != null) {
final PaymentModelDao paymentModelDao = daoHelper.getDirectPayment();
effectivePaymentMethodId = paymentModelDao.getPaymentMethodId();
- currentStateName = paymentModelDao.getStateName();
+ currentStateName = paymentModelDao.getLastSuccessStateName() != null ? paymentModelDao.getLastSuccessStateName() : getInitState(transactionType);
currentStateMachineName = getStateMachineName(currentStateName);
// Check for illegal states (should never happen)
@@ -120,23 +120,8 @@ public class DirectPaymentAutomatonRunner {
} else {
// If the payment method is not specified, retrieve the default one on the account
effectivePaymentMethodId = paymentMethodId != null ? paymentMethodId : daoHelper.getDefaultPaymentMethodId();
-
- switch (transactionType) {
- case AUTHORIZE:
- currentStateMachineName = "AUTHORIZE";
- currentStateName = "AUTH_INIT";
- break;
- case CREDIT:
- currentStateMachineName = "CREDIT";
- currentStateName = "CREDIT_INIT";
- break;
- case PURCHASE:
- currentStateMachineName = "PURCHASE";
- currentStateName = "PURCHASE_INIT";
- break;
- default:
- throw new IllegalStateException("Unsupported transaction type " + transactionType + " for null direct payment id");
- }
+ currentStateName = getInitState(transactionType);
+ currentStateMachineName = getStateMachineName(currentStateName);
}
directPaymentStateContext.setPaymentMethodId(effectivePaymentMethodId);
@@ -227,6 +212,19 @@ public class DirectPaymentAutomatonRunner {
return stateMachine.getName();
}
+ private String getInitState(final TransactionType transactionType) {
+ switch (transactionType) {
+ case AUTHORIZE:
+ return "AUTH_INIT";
+ case CREDIT:
+ return "CREDIT_INIT";
+ case PURCHASE:
+ return "PURCHASE_INIT";
+ default:
+ throw new IllegalStateException("Unsupported transaction type " + transactionType + " for null direct payment id");
+ }
+ }
+
private StateMachine getStateMachine(final String currentStateName) {
for (final StateMachine stateMachine : stateMachineConfig.getStateMachines()) {
for (final State state : stateMachine.getStates()) {
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/DefaultPaymentDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/DefaultPaymentDao.java
index a7475b5..8c65ac1 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dao/DefaultPaymentDao.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/DefaultPaymentDao.java
@@ -212,6 +212,7 @@ public class DefaultPaymentDao implements PaymentDao {
@Override
public void updateDirectPaymentAndTransactionOnCompletion(final UUID directPaymentId, final String currentPaymentStateName,
+ @Nullable final String lastPaymentSuccessStateName,
final UUID directTransactionId, final TransactionStatus paymentStatus,
final BigDecimal processedAmount, final Currency processedCurrency,
final String gatewayErrorCode, final String gatewayErrorMsg,
@@ -224,7 +225,11 @@ public class DefaultPaymentDao implements PaymentDao {
processedAmount, processedCurrency == null ? null : processedCurrency.toString(),
paymentStatus == null ? null : paymentStatus.toString(),
gatewayErrorCode, gatewayErrorMsg, context);
- entitySqlDaoWrapperFactory.become(PaymentSqlDao.class).updatePaymentStateName(directPaymentId.toString(), currentPaymentStateName, context);
+ if (lastPaymentSuccessStateName != null) {
+ entitySqlDaoWrapperFactory.become(PaymentSqlDao.class).updateLastSuccessPaymentStateName(directPaymentId.toString(), currentPaymentStateName, lastPaymentSuccessStateName, context);
+ } else {
+ entitySqlDaoWrapperFactory.become(PaymentSqlDao.class).updatePaymentStateName(directPaymentId.toString(), currentPaymentStateName, context);
+ }
return null;
}
});
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentDao.java
index b1a2df6..cf0a59e 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentDao.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentDao.java
@@ -50,6 +50,7 @@ public interface PaymentDao {
public PaymentTransactionModelDao updateDirectPaymentWithNewTransaction(UUID directPaymentId, PaymentTransactionModelDao directPaymentTransaction, InternalCallContext context);
public void updateDirectPaymentAndTransactionOnCompletion(UUID directPaymentId, String currentPaymentStateName,
+ String lastPaymentSuccessStateName,
UUID directTransactionId, TransactionStatus paymentStatus,
BigDecimal processedAmount, Currency processedCurrency,
String gatewayErrorCode, String gatewayErrorMsg,
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentModelDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentModelDao.java
index 358dc84..de3607b 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentModelDao.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentModelDao.java
@@ -37,6 +37,7 @@ public class PaymentModelDao extends EntityBase implements EntityModelDao<Direct
private UUID paymentMethodId;
private String externalKey;
private String stateName;
+ private String lastSuccessStateName;
public PaymentModelDao() { /* For the DAO mapper */ }
@@ -93,6 +94,14 @@ public class PaymentModelDao extends EntityBase implements EntityModelDao<Direct
this.stateName = stateName;
}
+ public String getLastSuccessStateName() {
+ return lastSuccessStateName;
+ }
+
+ public void setLastSuccessStateName(final String lastSuccessStateName) {
+ this.lastSuccessStateName = lastSuccessStateName;
+ }
+
@Override
public boolean equals(final Object o) {
if (this == o) {
@@ -113,6 +122,9 @@ public class PaymentModelDao extends EntityBase implements EntityModelDao<Direct
if (stateName != null ? !stateName.equals(that.stateName) : that.stateName != null) {
return false;
}
+ if (lastSuccessStateName != null ? !lastSuccessStateName.equals(that.lastSuccessStateName) : that.lastSuccessStateName != null) {
+ return false;
+ }
if (externalKey != null ? !externalKey.equals(that.externalKey) : that.externalKey != null) {
return false;
}
@@ -133,6 +145,7 @@ public class PaymentModelDao extends EntityBase implements EntityModelDao<Direct
result = 31 * result + (paymentMethodId != null ? paymentMethodId.hashCode() : 0);
result = 31 * result + (externalKey != null ? externalKey.hashCode() : 0);
result = 31 * result + (stateName != null ? stateName.hashCode() : 0);
+ result = 31 * result + (lastSuccessStateName != null ? lastSuccessStateName.hashCode() : 0);
return result;
}
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentSqlDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentSqlDao.java
index 7552a09..2a1b8d8 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentSqlDao.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentSqlDao.java
@@ -46,6 +46,13 @@ public interface PaymentSqlDao extends EntitySqlDao<PaymentModelDao, DirectPayme
@BindBean final InternalCallContext context);
+ @SqlUpdate
+ @Audited(ChangeType.UPDATE)
+ void updateLastSuccessPaymentStateName(@Bind("id") final String directPaymentId,
+ @Bind("stateName") final String stateName,
+ @Bind("lastSuccessStateName") final String lastSuccessStateName,
+ @BindBean final InternalCallContext context);
+
@SqlQuery
public PaymentModelDao getPaymentByExternalKey(@Bind("externalKey") final String externalKey,
@BindBean final InternalTenantContext context);
diff --git a/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentSqlDao.sql.stg b/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentSqlDao.sql.stg
index 7ea79d8..1cb5262 100644
--- a/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentSqlDao.sql.stg
+++ b/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentSqlDao.sql.stg
@@ -17,6 +17,7 @@ tableFields(prefix) ::= <<
, <prefix>payment_method_id
, <prefix>external_key
, <prefix>state_name
+, <prefix>last_success_state_name
, <prefix>created_by
, <prefix>created_date
, <prefix>updated_by
@@ -28,6 +29,7 @@ tableValues() ::= <<
, :paymentMethodId
, :externalKey
, :stateName
+, :lastSuccessStateName
, :createdBy
, :createdDate
, :updatedBy
@@ -53,6 +55,17 @@ where id = :id
;
>>
+updateLastSuccessPaymentStateName() ::= <<
+update <tableName()>
+set state_name = :stateName
+, last_success_state_name = :lastSuccessStateName
+, updated_by = :updatedBy
+, updated_date = :createdDate
+where id = :id
+<AND_CHECK_TENANT()>
+;
+>>
+
getPaymentByExternalKey() ::= <<
select
<allTableFields("")>
diff --git a/payment/src/main/resources/org/killbill/billing/payment/ddl.sql b/payment/src/main/resources/org/killbill/billing/payment/ddl.sql
index d874f08..afa8c33 100644
--- a/payment/src/main/resources/org/killbill/billing/payment/ddl.sql
+++ b/payment/src/main/resources/org/killbill/billing/payment/ddl.sql
@@ -107,6 +107,7 @@ CREATE TABLE payments (
payment_method_id char(36) NOT NULL,
external_key varchar(255) NOT NULL,
state_name varchar(64) DEFAULT NULL,
+ last_success_state_name varchar(64) DEFAULT NULL,
created_by varchar(50) NOT NULL,
created_date datetime NOT NULL,
updated_by varchar(50) NOT NULL,
@@ -130,6 +131,7 @@ CREATE TABLE payment_history (
payment_method_id char(36) NOT NULL,
external_key varchar(255) NOT NULL,
state_name varchar(64) DEFAULT NULL,
+ last_success_state_name varchar(64) DEFAULT NULL,
change_type char(6) NOT NULL,
created_by varchar(50) NOT NULL,
created_date datetime NOT NULL,
diff --git a/payment/src/main/resources/org/killbill/billing/payment/PaymentStates.xml b/payment/src/main/resources/org/killbill/billing/payment/PaymentStates.xml
index b487b9c..c6f32d3 100644
--- a/payment/src/main/resources/org/killbill/billing/payment/PaymentStates.xml
+++ b/payment/src/main/resources/org/killbill/billing/payment/PaymentStates.xml
@@ -306,18 +306,6 @@
<finalState>CHARGEBACK_INIT</finalState>
</linkStateMachine>
<linkStateMachine>
- <initialStateMachine>CAPTURE</initialStateMachine>
- <initialState>CAPTURE_FAILED</initialState>
- <finalStateMachine>CAPTURE</finalStateMachine>
- <finalState>CAPTURE_INIT</finalState>
- </linkStateMachine>
- <linkStateMachine>
- <initialStateMachine>PURCHASE</initialStateMachine>
- <initialState>PURCHASE_FAILED</initialState>
- <finalStateMachine>PURCHASE</finalStateMachine>
- <finalState>PURCHASE_INIT</finalState>
- </linkStateMachine>
- <linkStateMachine>
<initialStateMachine>REFUND</initialStateMachine>
<initialState>REFUND_SUCCESS</initialState>
<finalStateMachine>REFUND</finalStateMachine>
@@ -325,23 +313,11 @@
</linkStateMachine>
<linkStateMachine>
<initialStateMachine>REFUND</initialStateMachine>
- <initialState>REFUND_FAILED</initialState>
- <finalStateMachine>REFUND</finalStateMachine>
- <finalState>REFUND_INIT</finalState>
- </linkStateMachine>
- <linkStateMachine>
- <initialStateMachine>REFUND</initialStateMachine>
<initialState>REFUND_SUCCESS</initialState>
<finalStateMachine>CHARGEBACK</finalStateMachine>
<finalState>CHARGEBACK_INIT</finalState>
</linkStateMachine>
<linkStateMachine>
- <initialStateMachine>REFUND</initialStateMachine>
- <initialState>REFUND_FAILED</initialState>
- <finalStateMachine>CHARGEBACK</finalStateMachine>
- <finalState>CHARGEBACK_INIT</finalState>
- </linkStateMachine>
- <linkStateMachine>
<initialStateMachine>PURCHASE</initialStateMachine>
<initialState>PURCHASE_SUCCESS</initialState>
<finalStateMachine>REFUND</finalStateMachine>
@@ -359,17 +335,5 @@
<finalStateMachine>CHARGEBACK</finalStateMachine>
<finalState>CHARGEBACK_INIT</finalState>
</linkStateMachine>
- <linkStateMachine>
- <initialStateMachine>CHARGEBACK</initialStateMachine>
- <initialState>CHARGEBACK_FAILED</initialState>
- <finalStateMachine>CHARGEBACK</finalStateMachine>
- <finalState>CHARGEBACK_INIT</finalState>
- </linkStateMachine>
- <linkStateMachine>
- <initialStateMachine>CHARGEBACK</initialStateMachine>
- <initialState>CHARGEBACK_ERRORED</initialState>
- <finalStateMachine>CHARGEBACK</finalStateMachine>
- <finalState>CHARGEBACK_INIT</finalState>
- </linkStateMachine>
</linkStateMachines>
</stateMachineConfig>
diff --git a/payment/src/test/java/org/killbill/billing/payment/dao/MockPaymentDao.java b/payment/src/test/java/org/killbill/billing/payment/dao/MockPaymentDao.java
index 98afc31..ba4f6cd 100644
--- a/payment/src/test/java/org/killbill/billing/payment/dao/MockPaymentDao.java
+++ b/payment/src/test/java/org/killbill/billing/payment/dao/MockPaymentDao.java
@@ -157,7 +157,7 @@ public class MockPaymentDao implements PaymentDao {
}
@Override
- public void updateDirectPaymentAndTransactionOnCompletion(final UUID directPaymentId, final String currentPaymentStateName, final UUID directTransactionId, final TransactionStatus paymentStatus, final BigDecimal processedAmount, final Currency processedCurrency, final String gatewayErrorCode, final String gatewayErrorMsg, final InternalCallContext context) {
+ public void updateDirectPaymentAndTransactionOnCompletion(final UUID directPaymentId, final String currentPaymentStateName, final String lastSuccessPaymentStateName, final UUID directTransactionId, final TransactionStatus paymentStatus, final BigDecimal processedAmount, final Currency processedCurrency, final String gatewayErrorCode, final String gatewayErrorMsg, final InternalCallContext context) {
synchronized (this) {
final PaymentModelDao payment = payments.get(directPaymentId);
if (payment != null) {
diff --git a/payment/src/test/java/org/killbill/billing/payment/dao/TestDefaultPaymentDao.java b/payment/src/test/java/org/killbill/billing/payment/dao/TestDefaultPaymentDao.java
index 105f66b..769bb22 100644
--- a/payment/src/test/java/org/killbill/billing/payment/dao/TestDefaultPaymentDao.java
+++ b/payment/src/test/java/org/killbill/billing/payment/dao/TestDefaultPaymentDao.java
@@ -63,6 +63,7 @@ public class TestDefaultPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
final String gatewayErrorMsg = UUID.randomUUID().toString();
paymentDao.updateDirectPaymentAndTransactionOnCompletion(specifiedSecondDirectPaymentTransactionModelDao.getPaymentId(),
"SOME_ERRORED_STATE",
+ "SOME_ERRORED_STATE",
specifiedSecondDirectPaymentTransactionModelDao.getId(),
TransactionStatus.PAYMENT_FAILURE,
processedAmount,
diff --git a/payment/src/test/java/org/killbill/billing/payment/dao/TestPaymentDao.java b/payment/src/test/java/org/killbill/billing/payment/dao/TestPaymentDao.java
index 19ec769..c3a87e6 100644
--- a/payment/src/test/java/org/killbill/billing/payment/dao/TestPaymentDao.java
+++ b/payment/src/test/java/org/killbill/billing/payment/dao/TestPaymentDao.java
@@ -170,7 +170,7 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
final List<PaymentTransactionModelDao> transactions = paymentDao.getDirectTransactionsForDirectPayment(savedPayment.getId(), internalCallContext);
assertEquals(transactions.size(), 2);
- paymentDao.updateDirectPaymentAndTransactionOnCompletion(savedPayment.getId(), "AUTH_SUCCESS", transactionModelDao2.getId(), TransactionStatus.SUCCESS,
+ paymentDao.updateDirectPaymentAndTransactionOnCompletion(savedPayment.getId(), "AUTH_ABORTED", "AUTH_SUCCESS", transactionModelDao2.getId(), TransactionStatus.SUCCESS,
BigDecimal.ONE, Currency.USD, null, "nothing", internalCallContext);
final PaymentModelDao savedPayment4 = paymentDao.getDirectPayment(savedPayment.getId(), internalCallContext);
@@ -178,7 +178,8 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
assertEquals(savedPayment4.getAccountId(), paymentModelDao.getAccountId());
assertEquals(savedPayment4.getExternalKey(), paymentModelDao.getExternalKey());
assertEquals(savedPayment4.getPaymentMethodId(), paymentModelDao.getPaymentMethodId());
- assertEquals(savedPayment4.getStateName(), "AUTH_SUCCESS");
+ assertEquals(savedPayment4.getStateName(), "AUTH_ABORTED");
+ assertEquals(savedPayment4.getLastSuccessStateName(), "AUTH_SUCCESS");
final PaymentTransactionModelDao savedTransactionModelDao4 = paymentDao.getDirectPaymentTransaction(savedTransactionModelDao2.getId(), internalCallContext);
assertEquals(savedTransactionModelDao4.getTransactionExternalKey(), transactionExternalKey2);
@@ -192,6 +193,23 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
assertNull(savedTransactionModelDao4.getGatewayErrorCode());
assertEquals(savedTransactionModelDao4.getGatewayErrorMsg(), "nothing");
+ paymentDao.updateDirectPaymentAndTransactionOnCompletion(savedPayment.getId(), "AUTH_ABORTED", null, transactionModelDao2.getId(), TransactionStatus.SUCCESS,
+ BigDecimal.ONE, Currency.USD, null, "nothing", internalCallContext);
+
+
+ final PaymentModelDao savedPayment4Again = paymentDao.getDirectPayment(savedPayment.getId(), internalCallContext);
+ assertEquals(savedPayment4Again.getId(), paymentModelDao.getId());
+ assertEquals(savedPayment4Again.getStateName(), "AUTH_ABORTED");
+ assertEquals(savedPayment4Again.getLastSuccessStateName(), "AUTH_SUCCESS");
+
+ paymentDao.updateDirectPaymentAndTransactionOnCompletion(savedPayment.getId(), "AUTH_ABORTED", "AUTH_SUCCESS", transactionModelDao2.getId(), TransactionStatus.SUCCESS,
+ BigDecimal.ONE, Currency.USD, null, "nothing", internalCallContext);
+
+ final PaymentModelDao savedPayment4Final = paymentDao.getDirectPayment(savedPayment.getId(), internalCallContext);
+ assertEquals(savedPayment4Final.getId(), paymentModelDao.getId());
+ assertEquals(savedPayment4Final.getStateName(), "AUTH_ABORTED");
+ assertEquals(savedPayment4Final.getLastSuccessStateName(), "AUTH_SUCCESS");
+
final List<PaymentModelDao> payments = paymentDao.getDirectPaymentsForAccount(accountId, internalCallContext);
assertEquals(payments.size(), 1);