Details
diff --git a/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java b/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
index e4f6d82..b7d1296 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
@@ -432,18 +432,18 @@ public class PaymentProcessor extends ProcessorBase {
final PaymentStatus paymentStatus = PaymentStatus.AUTO_PAY_OFF;
final PaymentModelDao paymentInfo = new PaymentModelDao(account.getId(), invoice.getId(), paymentMethodId, requestedAmount, invoice.getCurrency(), clock.getUTCNow(), paymentStatus);
- final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(account.getId(), invoice.getId(), paymentInfo.getId(), paymentStatus, clock.getUTCNow(), requestedAmount);
+ final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(account.getId(), invoice.getId(), paymentInfo.getId(), paymentMethodId, paymentStatus, clock.getUTCNow(), requestedAmount);
- paymentDao.insertPaymentWithAttempt(paymentInfo, attempt, context);
+ paymentDao.insertPaymentWithFirstAttempt(paymentInfo, attempt, context);
return fromPaymentModelDao(paymentInfo, null, context);
}
private Payment processNewPaymentWithAccountLocked(final UUID paymentMethodId, final PaymentPluginApi plugin, final Account account, final Invoice invoice,
final BigDecimal requestedAmount, final boolean isInstantPayment, final InternalCallContext context) throws PaymentApiException {
final PaymentModelDao payment = new PaymentModelDao(account.getId(), invoice.getId(), paymentMethodId, requestedAmount.setScale(2, RoundingMode.HALF_UP), invoice.getCurrency(), clock.getUTCNow());
- final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(account.getId(), invoice.getId(), payment.getId(), clock.getUTCNow(), requestedAmount);
+ final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(account.getId(), invoice.getId(), payment.getId(), paymentMethodId, clock.getUTCNow(), requestedAmount);
- final PaymentModelDao savedPayment = paymentDao.insertPaymentWithAttempt(payment, attempt, context);
+ final PaymentModelDao savedPayment = paymentDao.insertPaymentWithFirstAttempt(payment, attempt, context);
return processPaymentWithAccountLocked(plugin, account, invoice, savedPayment, attempt, isInstantPayment, context);
}
@@ -464,9 +464,9 @@ public class PaymentProcessor extends ProcessorBase {
default:
throw new IllegalStateException("Unexpected payment status for retry " + payment.getPaymentStatus());
}
- final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(account.getId(), invoice.getId(), payment.getId(), clock.getUTCNow(), requestedAmount);
- paymentDao.insertNewAttemptForPayment(payment.getId(), attempt, context);
- paymentDao.updateStatusAndEffectiveDateForPaymentWithAttempt(payment.getId(), paymentStatus, clock.getUTCNow(), attempt.getId(), null, terminalStateReason, context);
+ final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(account.getId(), invoice.getId(), payment.getId(), account.getPaymentMethodId(), clock.getUTCNow(), requestedAmount);
+ paymentDao.updatePaymentWithNewAttempt(payment.getId(), attempt, context);
+ paymentDao.updatePaymentAndAttemptOnCompletion(payment.getId(), paymentStatus, attempt.getId(), null, terminalStateReason, context);
final List<PaymentAttemptModelDao> allAttempts = paymentDao.getAttemptsForPayment(payment.getId(), context);
return new DefaultPayment(payment, null, allAttempts, Collections.<RefundModelDao>emptyList());
@@ -475,8 +475,8 @@ public class PaymentProcessor extends ProcessorBase {
private Payment processRetryPaymentWithAccountLocked(final PaymentPluginApi plugin, final Account account, final Invoice invoice, final PaymentModelDao payment,
final BigDecimal requestedAmount, final InternalCallContext context) throws PaymentApiException {
- final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(account.getId(), invoice.getId(), payment.getId(), clock.getUTCNow(), requestedAmount);
- paymentDao.insertNewAttemptForPayment(payment.getId(), attempt, context);
+ final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(account.getId(), invoice.getId(), payment.getId(), account.getPaymentMethodId(), clock.getUTCNow(), requestedAmount);
+ paymentDao.updatePaymentWithNewAttempt(payment.getId(), attempt, context);
return processPaymentWithAccountLocked(plugin, account, invoice, payment, attempt, false, context);
}
@@ -487,7 +487,7 @@ public class PaymentProcessor extends ProcessorBase {
List<PaymentAttemptModelDao> allAttempts = null;
if (paymentConfig.isPaymentOff()) {
- paymentDao.updateStatusAndEffectiveDateForPaymentWithAttempt(paymentInput.getId(), PaymentStatus.PAYMENT_SYSTEM_OFF, clock.getUTCNow(), attemptInput.getId(), null, null, context);
+ paymentDao.updatePaymentAndAttemptOnCompletion(paymentInput.getId(), PaymentStatus.PAYMENT_SYSTEM_OFF, attemptInput.getId(), null, null, context);
allAttempts = paymentDao.getAttemptsForPayment(paymentInput.getId(), context);
return new DefaultPayment(paymentInput, null, allAttempts, Collections.<RefundModelDao>emptyList());
}
@@ -498,7 +498,7 @@ public class PaymentProcessor extends ProcessorBase {
final PaymentInfoPlugin paymentPluginInfo;
try {
try {
- paymentPluginInfo = plugin.processPayment(account.getId(), paymentInput.getId(), paymentInput.getPaymentMethodId(), attemptInput.getRequestedAmount(), account.getCurrency(), context.toCallContext());
+ paymentPluginInfo = plugin.processPayment(account.getId(), paymentInput.getId(), attemptInput.getPaymentMethodId(), attemptInput.getRequestedAmount(), account.getCurrency(), context.toCallContext());
} catch (RuntimeException e) {
// Handle case of plugin RuntimeException to be handled the same as a Plugin failure (PaymentPluginApiException)
final String formatError = String.format("Plugin threw RuntimeException for payment %s", paymentInput.getId());
@@ -509,12 +509,7 @@ public class PaymentProcessor extends ProcessorBase {
// Update Payment/PaymentAttempt status
paymentStatus = PaymentStatus.SUCCESS;
- /*
- UUID paymentId, PaymentStatus paymentStatus, DateTime newEffectiveDate,
- String gatewayErrorMsg, UUID attemptId, InternalCallContext callcontext, String gatewayErrorCode
- */
-
- paymentDao.updateStatusAndEffectiveDateForPaymentWithAttempt(paymentInput.getId(), paymentStatus, clock.getUTCNow(), attemptInput.getId(), paymentPluginInfo.getGatewayErrorCode(), null, context);
+ paymentDao.updatePaymentAndAttemptOnCompletion(paymentInput.getId(), paymentStatus, attemptInput.getId(), paymentPluginInfo.getGatewayErrorCode(), null, context);
// Fetch latest objects
allAttempts = paymentDao.getAttemptsForPayment(paymentInput.getId(), context);
@@ -546,7 +541,7 @@ public class PaymentProcessor extends ProcessorBase {
paymentStatus = PaymentStatus.PAYMENT_FAILURE_ABORTED;
}
- paymentDao.updateStatusAndEffectiveDateForPaymentWithAttempt(paymentInput.getId(), paymentStatus, clock.getUTCNow(), attemptInput.getId(), paymentPluginInfo.getGatewayErrorCode(), paymentPluginInfo.getGatewayError(), context);
+ paymentDao.updatePaymentAndAttemptOnCompletion(paymentInput.getId(), paymentStatus, attemptInput.getId(), paymentPluginInfo.getGatewayErrorCode(), paymentPluginInfo.getGatewayError(), context);
log.info(String.format("Could not process payment for account %s, invoice %s, error = %s",
account.getId(), invoice.getId(), paymentPluginInfo.getGatewayError()));
@@ -569,7 +564,7 @@ public class PaymentProcessor extends ProcessorBase {
paymentStatus = isInstantPayment ? PaymentStatus.PAYMENT_FAILURE_ABORTED : scheduleRetryOnPluginFailure(paymentInput.getId(), context);
// STEPH message might need truncation to fit??
- paymentDao.updateStatusAndEffectiveDateForPaymentWithAttempt(paymentInput.getId(), paymentStatus, clock.getUTCNow(), attemptInput.getId(), null, e.getMessage(), context);
+ paymentDao.updatePaymentAndAttemptOnCompletion(paymentInput.getId(), paymentStatus, attemptInput.getId(), null, e.getMessage(), context);
event = new DefaultPaymentPluginErrorEvent(account.getId(), invoice.getId(), paymentInput.getId(), e.getMessage(),
context.getAccountRecordId(), context.getTenantRecordId(), context.getUserToken()
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/DefaultPaymentDao.java b/payment/src/main/java/com/ning/billing/payment/dao/DefaultPaymentDao.java
index a5fa055..0b50ee1 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/DefaultPaymentDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/DefaultPaymentDao.java
@@ -22,7 +22,6 @@ import java.util.UUID;
import javax.inject.Inject;
-import org.joda.time.DateTime;
import org.skife.jdbi.v2.IDBI;
import com.ning.billing.payment.api.PaymentStatus;
@@ -50,24 +49,19 @@ public class DefaultPaymentDao implements PaymentDao {
this.transactionalSqlDao = new EntitySqlDaoTransactionalJdbiWrapper(dbi, clock, cacheControllerDispatcher, nonEntityDao);
}
+
@Override
- public PaymentAttemptModelDao insertNewAttemptForPayment(final UUID paymentId, final PaymentAttemptModelDao attempt, final InternalCallContext context) {
+ public PaymentAttemptModelDao getPaymentAttempt(final UUID attemptId, final InternalTenantContext context) {
return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<PaymentAttemptModelDao>() {
@Override
public PaymentAttemptModelDao inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
- final PaymentAttemptSqlDao transactional = entitySqlDaoWrapperFactory.become(PaymentAttemptSqlDao.class);
- transactional.create(attempt, context);
- final PaymentAttemptModelDao savedAttempt = transactional.getById(attempt.getId().toString(), context);
-
- entitySqlDaoWrapperFactory.become(PaymentSqlDao.class).updatePaymentAmount(paymentId.toString(), savedAttempt.getRequestedAmount(), context);
-
- return savedAttempt;
+ return entitySqlDaoWrapperFactory.become(PaymentAttemptSqlDao.class).getById(attemptId.toString(), context);
}
});
}
@Override
- public PaymentModelDao insertPaymentWithAttempt(final PaymentModelDao payment, final PaymentAttemptModelDao attempt, final InternalCallContext context) {
+ public PaymentModelDao insertPaymentWithFirstAttempt(final PaymentModelDao payment, final PaymentAttemptModelDao attempt, final InternalCallContext context) {
return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<PaymentModelDao>() {
@Override
@@ -84,28 +78,34 @@ public class DefaultPaymentDao implements PaymentDao {
}
@Override
- public PaymentAttemptModelDao getPaymentAttempt(final UUID attemptId, final InternalTenantContext context) {
+ public PaymentAttemptModelDao updatePaymentWithNewAttempt(final UUID paymentId, final PaymentAttemptModelDao attempt, final InternalCallContext context) {
return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<PaymentAttemptModelDao>() {
@Override
public PaymentAttemptModelDao inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
- return entitySqlDaoWrapperFactory.become(PaymentAttemptSqlDao.class).getById(attemptId.toString(), context);
+ final PaymentAttemptSqlDao transactional = entitySqlDaoWrapperFactory.become(PaymentAttemptSqlDao.class);
+ transactional.create(attempt, context);
+ final PaymentAttemptModelDao savedAttempt = transactional.getById(attempt.getId().toString(), context);
+
+ entitySqlDaoWrapperFactory.become(PaymentSqlDao.class).updatePaymentForNewAttempt(paymentId.toString(), attempt.getPaymentMethodId().toString(),
+ savedAttempt.getRequestedAmount(), attempt.getEffectiveDate().toDate(), context);
+
+ return savedAttempt;
}
});
}
@Override
- public void updateStatusAndEffectiveDateForPaymentWithAttempt(final UUID paymentId,
- final PaymentStatus paymentStatus,
- final DateTime newEffectiveDate,
- final UUID attemptId,
- final String gatewayErrorCode,
- final String gatewayErrorMsg,
- final InternalCallContext context) {
+ public void updatePaymentAndAttemptOnCompletion(final UUID paymentId,
+ final PaymentStatus paymentStatus,
+ final UUID attemptId,
+ final String gatewayErrorCode,
+ final String gatewayErrorMsg,
+ final InternalCallContext context) {
transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {
@Override
public Void inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
- entitySqlDaoWrapperFactory.become(PaymentSqlDao.class).updatePaymentStatus(paymentId.toString(), paymentStatus.toString(), newEffectiveDate.toDate(), context);
+ entitySqlDaoWrapperFactory.become(PaymentSqlDao.class).updatePaymentStatus(paymentId.toString(), paymentStatus.toString(), context);
entitySqlDaoWrapperFactory.become(PaymentAttemptSqlDao.class).updatePaymentAttemptStatus(attemptId.toString(), paymentStatus.toString(), gatewayErrorCode, gatewayErrorMsg, context);
return null;
}
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptModelDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptModelDao.java
index b321484..cbed1f1 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptModelDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentAttemptModelDao.java
@@ -34,6 +34,7 @@ public class PaymentAttemptModelDao extends EntityBase implements EntityModelDao
private UUID accountId;
private UUID invoiceId;
private UUID paymentId;
+ private UUID paymentMethodId;
private PaymentStatus processingStatus;
private DateTime effectiveDate;
private String gatewayErrorCode;
@@ -44,12 +45,14 @@ public class PaymentAttemptModelDao extends EntityBase implements EntityModelDao
public PaymentAttemptModelDao(final UUID id, @Nullable final DateTime createdDate, @Nullable final DateTime updatedDate,
final UUID accountId, final UUID invoiceId,
- final UUID paymentId, final PaymentStatus processingStatus, final DateTime effectiveDate,
+ final UUID paymentId, final UUID paymentMethodId,
+ final PaymentStatus processingStatus, final DateTime effectiveDate,
final BigDecimal requestedAmount, final String gatewayErrorCode, final String gatewayErrorMsg) {
super(id, createdDate, updatedDate);
this.accountId = accountId;
this.invoiceId = invoiceId;
this.paymentId = paymentId;
+ this.paymentMethodId = paymentMethodId;
this.processingStatus = processingStatus;
this.effectiveDate = effectiveDate;
this.requestedAmount = requestedAmount;
@@ -57,17 +60,17 @@ public class PaymentAttemptModelDao extends EntityBase implements EntityModelDao
this.gatewayErrorMsg = gatewayErrorMsg;
}
- public PaymentAttemptModelDao(final UUID accountId, final UUID invoiceId, final UUID paymentId, final PaymentStatus paymentStatus, final DateTime effectiveDate, final BigDecimal requestedAmount) {
- this(UUID.randomUUID(), null, null, accountId, invoiceId, paymentId, paymentStatus, effectiveDate, requestedAmount, null, null);
+ public PaymentAttemptModelDao(final UUID accountId, final UUID invoiceId, final UUID paymentId, final UUID paymentMethodId, final PaymentStatus paymentStatus, final DateTime effectiveDate, final BigDecimal requestedAmount) {
+ this(UUID.randomUUID(), null, null, accountId, invoiceId, paymentId, paymentMethodId, paymentStatus, effectiveDate, requestedAmount, null, null);
}
- public PaymentAttemptModelDao(final UUID accountId, final UUID invoiceId, final UUID paymentId, final DateTime effectiveDate, final BigDecimal requestedAmount) {
- this(UUID.randomUUID(), null, null, accountId, invoiceId, paymentId, PaymentStatus.UNKNOWN, effectiveDate, requestedAmount, null, null);
+ public PaymentAttemptModelDao(final UUID accountId, final UUID invoiceId, final UUID paymentId, final UUID paymentMethodId, final DateTime effectiveDate, final BigDecimal requestedAmount) {
+ this(UUID.randomUUID(), null, null, accountId, invoiceId, paymentId, paymentMethodId, PaymentStatus.UNKNOWN, effectiveDate, requestedAmount, null, null);
}
public PaymentAttemptModelDao(final PaymentAttemptModelDao src, final PaymentStatus newProcessingStatus, final String gatewayErrorCode, final String gatewayErrorMsg) {
- this(src.getId(), src.getCreatedDate(), src.getUpdatedDate(), src.getAccountId(), src.getInvoiceId(), src.getPaymentId(), newProcessingStatus,
- src.getEffectiveDate(), src.getRequestedAmount(), gatewayErrorCode, gatewayErrorMsg);
+ this(src.getId(), src.getCreatedDate(), src.getUpdatedDate(), src.getAccountId(), src.getInvoiceId(), src.getPaymentId(), src.getPaymentMethodId(),
+ newProcessingStatus, src.getEffectiveDate(), src.getRequestedAmount(), gatewayErrorCode, gatewayErrorMsg);
}
public UUID getAccountId() {
@@ -82,6 +85,10 @@ public class PaymentAttemptModelDao extends EntityBase implements EntityModelDao
return paymentId;
}
+ public UUID getPaymentMethodId() {
+ return paymentMethodId;
+ }
+
public PaymentStatus getProcessingStatus() {
return processingStatus;
}
@@ -150,6 +157,9 @@ public class PaymentAttemptModelDao extends EntityBase implements EntityModelDao
if (paymentId != null ? !paymentId.equals(that.paymentId) : that.paymentId != null) {
return false;
}
+ if (paymentMethodId != null ? !paymentMethodId.equals(that.paymentMethodId) : that.paymentMethodId != null) {
+ return false;
+ }
if (processingStatus != that.processingStatus) {
return false;
}
@@ -166,6 +176,7 @@ public class PaymentAttemptModelDao extends EntityBase implements EntityModelDao
result = 31 * result + (accountId != null ? accountId.hashCode() : 0);
result = 31 * result + (invoiceId != null ? invoiceId.hashCode() : 0);
result = 31 * result + (paymentId != null ? paymentId.hashCode() : 0);
+ result = 31 * result + (paymentMethodId != null ? paymentMethodId.hashCode() : 0);
result = 31 * result + (processingStatus != null ? processingStatus.hashCode() : 0);
result = 31 * result + (effectiveDate != null ? effectiveDate.hashCode() : 0);
result = 31 * result + (gatewayErrorCode != null ? gatewayErrorCode.hashCode() : 0);
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentDao.java
index f16ced0..3ea92e4 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentDao.java
@@ -28,13 +28,12 @@ import com.ning.billing.callcontext.InternalTenantContext;
public interface PaymentDao {
- // STEPH do we need object returned?
- public PaymentModelDao insertPaymentWithAttempt(PaymentModelDao paymentInfo, PaymentAttemptModelDao attempt, InternalCallContext context);
+ public PaymentModelDao insertPaymentWithFirstAttempt(PaymentModelDao paymentInfo, PaymentAttemptModelDao attempt, InternalCallContext context);
- public PaymentAttemptModelDao insertNewAttemptForPayment(UUID paymentId, PaymentAttemptModelDao attempt, InternalCallContext context);
+ public PaymentAttemptModelDao updatePaymentWithNewAttempt(UUID paymentId, PaymentAttemptModelDao attempt, InternalCallContext context);
- public void updateStatusAndEffectiveDateForPaymentWithAttempt(UUID paymentId, PaymentStatus paymentStatus, DateTime newEffectiveDate,
- UUID attemptId, String gatewayErrorMsg, String gatewayErrorCode, InternalCallContext context);
+ public void updatePaymentAndAttemptOnCompletion(UUID paymentId, PaymentStatus paymentStatus,
+ UUID attemptId, String gatewayErrorMsg, String gatewayErrorCode, InternalCallContext context);
public PaymentAttemptModelDao getPaymentAttempt(UUID attemptId, InternalTenantContext context);
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java
index f3a8e5e..19a367c 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java
@@ -40,14 +40,15 @@ public interface PaymentSqlDao extends EntitySqlDao<PaymentModelDao, Payment> {
@Audited(ChangeType.UPDATE)
void updatePaymentStatus(@Bind("id") final String paymentId,
@Bind("paymentStatus") final String paymentStatus,
- @Bind("effectiveDate") final Date effectiveDate,
@BindBean final InternalCallContext context);
@SqlUpdate
@Audited(ChangeType.UPDATE)
- void updatePaymentAmount(@Bind("id") final String paymentId,
- @Bind("amount") final BigDecimal amount,
- @BindBean final InternalCallContext context);
+ void updatePaymentForNewAttempt(@Bind("id") final String paymentId,
+ @Bind("paymentMethodId") final String paymentMethodId,
+ @Bind("amount") final BigDecimal amount,
+ @Bind("effectiveDate") final Date effectiveDate,
+ @BindBean final InternalCallContext context);
@SqlQuery
PaymentModelDao getLastPaymentForAccountAndPaymentMethod(@Bind("accountId") final String accountId,
diff --git a/payment/src/main/resources/com/ning/billing/payment/dao/PaymentAttemptSqlDao.sql.stg b/payment/src/main/resources/com/ning/billing/payment/dao/PaymentAttemptSqlDao.sql.stg
index 2e2402a..071968b 100644
--- a/payment/src/main/resources/com/ning/billing/payment/dao/PaymentAttemptSqlDao.sql.stg
+++ b/payment/src/main/resources/com/ning/billing/payment/dao/PaymentAttemptSqlDao.sql.stg
@@ -2,6 +2,7 @@ group PaymentAttemptSqlDao: EntitySqlDao;
tableFields(prefix) ::= <<
<prefix>payment_id
+, <prefix>payment_method_id
, <prefix>gateway_error_code
, <prefix>gateway_error_msg
, <prefix>processing_status
@@ -14,6 +15,7 @@ tableFields(prefix) ::= <<
tableValues() ::= <<
:paymentId
+, :paymentMethodId
, :gatewayErrorCode
, :gatewayErrorMsg
, :processingStatus
diff --git a/payment/src/main/resources/com/ning/billing/payment/dao/PaymentSqlDao.sql.stg b/payment/src/main/resources/com/ning/billing/payment/dao/PaymentSqlDao.sql.stg
index b7bc670..c7121a5 100644
--- a/payment/src/main/resources/com/ning/billing/payment/dao/PaymentSqlDao.sql.stg
+++ b/payment/src/main/resources/com/ning/billing/payment/dao/PaymentSqlDao.sql.stg
@@ -71,16 +71,18 @@ order by effective_date desc limit 1
updatePaymentStatus() ::= <<
update payments
-set payment_status = :paymentStatus,
-effective_date = :effectiveDate
+set payment_status = :paymentStatus
where id = :id
<AND_CHECK_TENANT()>
;
>>
-updatePaymentAmount() ::= <<
+
+updatePaymentForNewAttempt() ::= <<
update <tableName()>
set amount = :amount
+, effective_date = :effectiveDate
+, payment_method_id= :paymentMethodId
where id = :id
<AND_CHECK_TENANT()>
;
diff --git a/payment/src/main/resources/com/ning/billing/payment/ddl.sql b/payment/src/main/resources/com/ning/billing/payment/ddl.sql
index cc27122..6dfc718 100644
--- a/payment/src/main/resources/com/ning/billing/payment/ddl.sql
+++ b/payment/src/main/resources/com/ning/billing/payment/ddl.sql
@@ -55,6 +55,7 @@ CREATE TABLE payment_attempts (
record_id int(11) unsigned NOT NULL AUTO_INCREMENT,
id char(36) NOT NULL,
payment_id char(36) NOT NULL,
+ payment_method_id char(36) NOT NULL,
gateway_error_code varchar(32),
gateway_error_msg varchar(256),
processing_status varchar(50),
@@ -77,6 +78,7 @@ CREATE TABLE payment_attempt_history (
id char(36) NOT NULL,
target_record_id int(11) unsigned NOT NULL,
payment_id char(36) NOT NULL,
+ payment_method_id char(36) NOT NULL,
gateway_error_code varchar(32),
gateway_error_msg varchar(256),
processing_status varchar(50),
diff --git a/payment/src/test/java/com/ning/billing/payment/dao/MockPaymentDao.java b/payment/src/test/java/com/ning/billing/payment/dao/MockPaymentDao.java
index 3dba5c0..2c5e51f 100644
--- a/payment/src/test/java/com/ning/billing/payment/dao/MockPaymentDao.java
+++ b/payment/src/test/java/com/ning/billing/payment/dao/MockPaymentDao.java
@@ -25,8 +25,6 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
-import org.joda.time.DateTime;
-
import com.ning.billing.payment.api.PaymentStatus;
import com.ning.billing.payment.dao.RefundModelDao.RefundStatus;
import com.ning.billing.callcontext.InternalCallContext;
@@ -40,8 +38,8 @@ public class MockPaymentDao implements PaymentDao {
private final Map<UUID, PaymentAttemptModelDao> attempts = new HashMap<UUID, PaymentAttemptModelDao>();
@Override
- public PaymentModelDao insertPaymentWithAttempt(final PaymentModelDao paymentInfo, final PaymentAttemptModelDao attempt,
- final InternalCallContext context) {
+ public PaymentModelDao insertPaymentWithFirstAttempt(final PaymentModelDao paymentInfo, final PaymentAttemptModelDao attempt,
+ final InternalCallContext context) {
synchronized (this) {
payments.put(paymentInfo.getId(), paymentInfo);
attempts.put(attempt.getId(), attempt);
@@ -50,7 +48,7 @@ public class MockPaymentDao implements PaymentDao {
}
@Override
- public PaymentAttemptModelDao insertNewAttemptForPayment(final UUID paymentId, final PaymentAttemptModelDao attempt, final InternalCallContext context) {
+ public PaymentAttemptModelDao updatePaymentWithNewAttempt(final UUID paymentId, final PaymentAttemptModelDao attempt, final InternalCallContext context) {
synchronized (this) {
attempts.put(attempt.getId(), attempt);
}
@@ -58,9 +56,9 @@ public class MockPaymentDao implements PaymentDao {
}
@Override
- public void updateStatusAndEffectiveDateForPaymentWithAttempt(final UUID paymentId, final PaymentStatus paymentStatus, final DateTime effectibeDate, final UUID attemptId, final String gatewayErrorCode,
- final String gatewayErrorMsg,
- final InternalCallContext context) {
+ public void updatePaymentAndAttemptOnCompletion(final UUID paymentId, final PaymentStatus paymentStatus, final UUID attemptId, final String gatewayErrorCode,
+ final String gatewayErrorMsg,
+ final InternalCallContext context) {
synchronized (this) {
final PaymentModelDao entry = payments.remove(paymentId);
if (entry != null) {
diff --git a/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java b/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java
index d090ef6..29a5162 100644
--- a/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java
+++ b/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java
@@ -22,15 +22,12 @@ import java.util.List;
import java.util.UUID;
import org.joda.time.DateTime;
-import org.testng.Assert;
import org.testng.annotations.Test;
import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.catalog.api.Duration;
import com.ning.billing.payment.PaymentTestSuiteWithEmbeddedDB;
import com.ning.billing.payment.api.PaymentStatus;
import com.ning.billing.payment.dao.RefundModelDao.RefundStatus;
-import com.ning.billing.payment.provider.MockPaymentProviderPlugin;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
@@ -98,16 +95,15 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
final DateTime effectiveDate = clock.getUTCNow();
final PaymentModelDao payment = new PaymentModelDao(accountId, invoiceId, paymentMethodId, amount, currency, effectiveDate);
- final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId(), clock.getUTCNow(), amount);
- PaymentModelDao savedPayment = paymentDao.insertPaymentWithAttempt(payment, attempt, internalCallContext);
+ final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId(), paymentMethodId, effectiveDate, amount);
+ PaymentModelDao savedPayment = paymentDao.insertPaymentWithFirstAttempt(payment, attempt, internalCallContext);
assertEquals(savedPayment.getEffectiveDate().compareTo(effectiveDate), 0);
final PaymentStatus paymentStatus = PaymentStatus.SUCCESS;
final String gatewayErrorCode = "OK";
clock.addDays(1);
- final DateTime newEffectiveDate = clock.getUTCNow();
- paymentDao.updateStatusAndEffectiveDateForPaymentWithAttempt(payment.getId(), paymentStatus, newEffectiveDate, attempt.getId(), gatewayErrorCode, null, internalCallContext);
+ paymentDao.updatePaymentAndAttemptOnCompletion(payment.getId(), paymentStatus, attempt.getId(), gatewayErrorCode, null, internalCallContext);
final List<PaymentModelDao> payments = paymentDao.getPaymentsForInvoice(invoiceId, internalCallContext);
assertEquals(payments.size(), 1);
@@ -118,7 +114,7 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
assertEquals(savedPayment.getPaymentMethodId(), paymentMethodId);
assertEquals(savedPayment.getAmount().compareTo(amount), 0);
assertEquals(savedPayment.getCurrency(), currency);
- assertEquals(savedPayment.getEffectiveDate().compareTo(newEffectiveDate), 0);
+ assertEquals(savedPayment.getEffectiveDate().compareTo(effectiveDate), 0);
assertEquals(savedPayment.getPaymentStatus(), PaymentStatus.SUCCESS);
final List<PaymentAttemptModelDao> attempts = paymentDao.getAttemptsForPayment(payment.getId(), internalCallContext);
@@ -143,9 +139,9 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
final DateTime effectiveDate = clock.getUTCNow();
final PaymentModelDao payment = new PaymentModelDao(accountId, invoiceId, paymentMethodId, amount, currency, effectiveDate);
- final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId(), clock.getUTCNow(), amount);
+ final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId(), paymentMethodId, clock.getUTCNow(), amount);
- PaymentModelDao savedPayment = paymentDao.insertPaymentWithAttempt(payment, attempt, internalCallContext);
+ PaymentModelDao savedPayment = paymentDao.insertPaymentWithFirstAttempt(payment, attempt, internalCallContext);
assertEquals(savedPayment.getId(), payment.getId());
assertEquals(savedPayment.getAccountId(), accountId);
assertEquals(savedPayment.getInvoiceId(), invoiceId);
@@ -195,8 +191,8 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
final DateTime effectiveDate = clock.getUTCNow();
final PaymentModelDao payment = new PaymentModelDao(accountId, invoiceId, paymentMethodId, amount, currency, effectiveDate);
- final PaymentAttemptModelDao firstAttempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId(), clock.getUTCNow(), amount);
- PaymentModelDao savedPayment = paymentDao.insertPaymentWithAttempt(payment, firstAttempt, internalCallContext);
+ final PaymentAttemptModelDao firstAttempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId(), paymentMethodId, effectiveDate, amount);
+ PaymentModelDao savedPayment = paymentDao.insertPaymentWithFirstAttempt(payment, firstAttempt, internalCallContext);
final PaymentModelDao lastPayment = paymentDao.getLastPaymentForPaymentMethod(accountId, paymentMethodId, internalCallContext);
assertNotNull(lastPayment);
@@ -209,9 +205,13 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
assertEquals(lastPayment.getEffectiveDate().compareTo(effectiveDate), 0);
assertEquals(lastPayment.getPaymentStatus(), PaymentStatus.UNKNOWN);
+
+ clock.addDays(3);
+ final DateTime newEffectiveDate = clock.getUTCNow();
+ final UUID newPaymentMethodId = UUID.randomUUID();
final BigDecimal newAmount = new BigDecimal(15.23).setScale(2, RoundingMode.HALF_EVEN);
- final PaymentAttemptModelDao secondAttempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId(), clock.getUTCNow(), newAmount);
- paymentDao.insertNewAttemptForPayment(payment.getId(), secondAttempt, internalCallContext);
+ final PaymentAttemptModelDao secondAttempt = new PaymentAttemptModelDao(accountId, invoiceId, payment.getId(), newPaymentMethodId, newEffectiveDate, newAmount);
+ paymentDao.updatePaymentWithNewAttempt(payment.getId(), secondAttempt, internalCallContext);
final List<PaymentModelDao> payments = paymentDao.getPaymentsForInvoice(invoiceId, internalCallContext);
assertEquals(payments.size(), 1);
@@ -219,25 +219,27 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
assertEquals(savedPayment.getId(), payment.getId());
assertEquals(savedPayment.getAccountId(), accountId);
assertEquals(savedPayment.getInvoiceId(), invoiceId);
- assertEquals(savedPayment.getPaymentMethodId(), paymentMethodId);
+ assertEquals(savedPayment.getPaymentMethodId(), newPaymentMethodId);
assertEquals(savedPayment.getAmount().compareTo(newAmount), 0);
assertEquals(savedPayment.getCurrency(), currency);
- assertEquals(savedPayment.getEffectiveDate().compareTo(effectiveDate), 0);
+ assertEquals(savedPayment.getEffectiveDate().compareTo(newEffectiveDate), 0);
assertEquals(savedPayment.getPaymentStatus(), PaymentStatus.UNKNOWN);
final List<PaymentAttemptModelDao> attempts = paymentDao.getAttemptsForPayment(payment.getId(), internalCallContext);
assertEquals(attempts.size(), 2);
final PaymentAttemptModelDao savedAttempt1 = attempts.get(0);
assertEquals(savedAttempt1.getPaymentId(), payment.getId());
+ assertEquals(savedAttempt1.getPaymentMethodId(), paymentMethodId);
assertEquals(savedAttempt1.getAccountId(), accountId);
assertEquals(savedAttempt1.getInvoiceId(), invoiceId);
- assertEquals(savedAttempt1.getProcessingStatus(), PaymentStatus.UNKNOWN);
+ assertEquals(savedAttempt1.getInvoiceId(), invoiceId);
assertEquals(savedAttempt1.getGatewayErrorCode(), null);
assertEquals(savedAttempt1.getGatewayErrorMsg(), null);
assertEquals(savedAttempt1.getRequestedAmount().compareTo(amount), 0);
final PaymentAttemptModelDao savedAttempt2 = attempts.get(1);
assertEquals(savedAttempt2.getPaymentId(), payment.getId());
+ assertEquals(savedAttempt2.getPaymentMethodId(), newPaymentMethodId);
assertEquals(savedAttempt2.getAccountId(), accountId);
assertEquals(savedAttempt2.getInvoiceId(), invoiceId);
assertEquals(savedAttempt2.getProcessingStatus(), PaymentStatus.UNKNOWN);