killbill-memoizeit
Changes
payment/src/main/java/org/killbill/billing/payment/api/svcs/DefaultDirectPaymentApi.java 46(+35 -11)
payment/src/main/java/org/killbill/billing/payment/provider/DefaultNoOpPaymentMethodPlugin.java 4(+2 -2)
pom.xml 2(+1 -1)
Details
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
index 889b975..33faf6c 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
@@ -615,12 +615,9 @@ public class AccountResource extends JaxRsResourceBase {
@Path("/{accountId:" + UUID_PATTERN + "}/" + DIRECT_PAYMENTS)
@Produces(APPLICATION_JSON)
public Response getDirectPaymentsForAccount(@PathParam("accountId") final String accountIdStr,
- @QueryParam(QUERY_PAYMENT_METHOD_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo,
- @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
@javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException {
- final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
final UUID accountId = UUID.fromString(accountIdStr);
- final List<DirectPayment> payments = directPaymentApi.getAccountPayments(accountId, withPluginInfo, pluginProperties, context.createContext(request));
+ final List<DirectPayment> payments = directPaymentApi.getAccountPayments(accountId, context.createContext(request));
final List<DirectPaymentJson> result = ImmutableList.copyOf(Iterables.transform(payments, new Function<DirectPayment, DirectPaymentJson>() {
@Override
public DirectPaymentJson apply(final DirectPayment input) {
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/svcs/DefaultDirectPaymentApi.java b/payment/src/main/java/org/killbill/billing/payment/api/svcs/DefaultDirectPaymentApi.java
index 8783076..a090091 100644
--- a/payment/src/main/java/org/killbill/billing/payment/api/svcs/DefaultDirectPaymentApi.java
+++ b/payment/src/main/java/org/killbill/billing/payment/api/svcs/DefaultDirectPaymentApi.java
@@ -1,5 +1,6 @@
/*
* Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
*
* The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
@@ -22,6 +23,7 @@ import java.util.UUID;
import javax.inject.Inject;
+import org.killbill.billing.ErrorCode;
import org.killbill.billing.account.api.Account;
import org.killbill.billing.payment.api.DirectPayment;
import org.killbill.billing.payment.api.DirectPaymentApi;
@@ -31,19 +33,17 @@ import org.killbill.billing.payment.core.DirectPaymentProcessor;
import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
import org.killbill.billing.util.callcontext.TenantContext;
-import org.killbill.clock.Clock;
+import org.killbill.billing.util.entity.Pagination;
public class DefaultDirectPaymentApi implements DirectPaymentApi {
private final DirectPaymentProcessor directPaymentProcessor;
private final InternalCallContextFactory internalCallContextFactory;
- private final Clock clock;
@Inject
- public DefaultDirectPaymentApi(final DirectPaymentProcessor directPaymentProcessor, final InternalCallContextFactory internalCallContextFactory, final Clock clock) {
+ public DefaultDirectPaymentApi(final DirectPaymentProcessor directPaymentProcessor, final InternalCallContextFactory internalCallContextFactory) {
this.directPaymentProcessor = directPaymentProcessor;
this.internalCallContextFactory = internalCallContextFactory;
- this.clock = clock;
}
@Override
@@ -63,21 +63,45 @@ public class DefaultDirectPaymentApi implements DirectPaymentApi {
@Override
public DirectPayment createVoid(final Account account, final UUID directPaymentId, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentApiException {
- return null;
+ return directPaymentProcessor.createVoid(account, directPaymentId, properties, internalCallContextFactory.createInternalCallContext(account.getId(), callContext));
}
@Override
- public DirectPayment createCredit(final Account account, final UUID directPaymentId, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentApiException {
- return null;
+ public DirectPayment createCredit(final Account account, final UUID directPaymentId, final BigDecimal amount, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentApiException {
+ return directPaymentProcessor.createCredit(account, directPaymentId, amount, properties, internalCallContextFactory.createInternalCallContext(account.getId(), callContext));
}
@Override
- public List<DirectPayment> getAccountPayments(final UUID accountId, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final TenantContext tenantContext) throws PaymentApiException {
- return directPaymentProcessor.getAccountPayments(accountId, withPluginInfo, internalCallContextFactory.createInternalTenantContext(accountId, tenantContext));
+ public List<DirectPayment> getAccountPayments(final UUID accountId, final TenantContext tenantContext) throws PaymentApiException {
+ return directPaymentProcessor.getAccountPayments(accountId, internalCallContextFactory.createInternalTenantContext(accountId, tenantContext));
}
@Override
- public DirectPayment getPayment(final UUID directPaymentId, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final TenantContext tenantContext) throws PaymentApiException {
- return directPaymentProcessor.getPayment(directPaymentId, withPluginInfo, internalCallContextFactory.createInternalTenantContext(tenantContext));
+ public Pagination<DirectPayment> getPayments(final Long offset, final Long limit, final Iterable<PluginProperty> properties, final TenantContext context) {
+ return directPaymentProcessor.getPayments(offset, limit, properties, context, internalCallContextFactory.createInternalTenantContext(context));
+ }
+
+ @Override
+ public Pagination<DirectPayment> getPayments(final Long offset, final Long limit, final String pluginName, final Iterable<PluginProperty> properties, final TenantContext tenantContext) throws PaymentApiException {
+ return directPaymentProcessor.getPayments(offset, limit, pluginName, properties, tenantContext, internalCallContextFactory.createInternalTenantContext(tenantContext));
+ }
+
+ @Override
+ public DirectPayment getPayment(final UUID paymentId, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final TenantContext context) throws PaymentApiException {
+ final DirectPayment payment = directPaymentProcessor.getPayment(paymentId, withPluginInfo, properties, internalCallContextFactory.createInternalTenantContext(context));
+ if (payment == null) {
+ throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT, paymentId);
+ }
+ return payment;
+ }
+
+ @Override
+ public Pagination<DirectPayment> searchPayments(final String searchKey, final Long offset, final Long limit, final Iterable<PluginProperty> properties, final TenantContext context) {
+ return directPaymentProcessor.searchPayments(searchKey, offset, limit, properties, internalCallContextFactory.createInternalTenantContext(context));
+ }
+
+ @Override
+ public Pagination<DirectPayment> searchPayments(final String searchKey, final Long offset, final Long limit, final String pluginName, final Iterable<PluginProperty> properties, final TenantContext context) throws PaymentApiException {
+ return directPaymentProcessor.searchPayments(searchKey, offset, limit, pluginName, properties, internalCallContextFactory.createInternalTenantContext(context));
}
}
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 685a244..69da111 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
@@ -19,16 +19,18 @@
package org.killbill.billing.payment.core;
import java.math.BigDecimal;
-import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import javax.annotation.Nullable;
import javax.inject.Inject;
import org.joda.time.DateTime;
+import org.killbill.billing.ErrorCode;
import org.killbill.billing.ObjectType;
import org.killbill.billing.account.api.Account;
import org.killbill.billing.account.api.AccountInternalApi;
@@ -40,7 +42,6 @@ import org.killbill.billing.payment.api.DefaultDirectPayment;
import org.killbill.billing.payment.api.DefaultDirectPaymentTransaction;
import org.killbill.billing.payment.api.DirectPayment;
import org.killbill.billing.payment.api.DirectPaymentTransaction;
-import org.killbill.billing.payment.api.Payment;
import org.killbill.billing.payment.api.PaymentApiException;
import org.killbill.billing.payment.api.PaymentStatus;
import org.killbill.billing.payment.api.PluginProperty;
@@ -52,11 +53,15 @@ import org.killbill.billing.payment.dispatcher.PluginDispatcher;
import org.killbill.billing.payment.plugin.api.PaymentInfoPlugin;
import org.killbill.billing.payment.plugin.api.PaymentPluginApi;
import org.killbill.billing.payment.plugin.api.PaymentPluginApiException;
-import org.killbill.billing.payment.plugin.api.PaymentPluginStatus;
import org.killbill.billing.tag.TagInternalApi;
+import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
+import org.killbill.billing.util.callcontext.TenantContext;
import org.killbill.billing.util.config.PaymentConfig;
import org.killbill.billing.util.dao.NonEntityDao;
+import org.killbill.billing.util.entity.Pagination;
+import org.killbill.billing.util.entity.dao.DefaultPaginationHelper.EntityPaginationBuilder;
+import org.killbill.billing.util.entity.dao.DefaultPaginationHelper.SourcePaginationBuilder;
import org.killbill.bus.api.PersistentBus;
import org.killbill.clock.Clock;
import org.killbill.commons.locker.GlobalLocker;
@@ -65,21 +70,20 @@ import org.slf4j.LoggerFactory;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import com.google.inject.name.Named;
import static org.killbill.billing.payment.glue.PaymentModule.PLUGIN_EXECUTOR_NAMED;
+import static org.killbill.billing.util.entity.dao.DefaultPaginationHelper.getEntityPagination;
+import static org.killbill.billing.util.entity.dao.DefaultPaginationHelper.getEntityPaginationFromPlugins;
public class DirectPaymentProcessor extends ProcessorBase {
private final Clock clock;
- private final PaymentConfig paymentConfig;
-
- private final PluginDispatcher<Payment> paymentPluginDispatcher;
- private final PluginDispatcher<Void> voidPluginDispatcher;
+ private final PluginDispatcher<DirectPayment> paymentPluginDispatcher;
private final InternalCallContextFactory internalCallContextFactory;
private static final Logger log = LoggerFactory.getLogger(DirectPaymentProcessor.class);
@@ -100,119 +104,222 @@ public class DirectPaymentProcessor extends ProcessorBase {
super(pluginRegistry, accountUserApi, eventBus, paymentDao, nonEntityDao, tagUserApi, locker, executor, invoiceApi);
this.clock = clock;
this.internalCallContextFactory = internalCallContextFactory;
- this.paymentConfig = paymentConfig;
final long paymentPluginTimeoutSec = TimeUnit.SECONDS.convert(paymentConfig.getPaymentPluginTimeout().getPeriod(), paymentConfig.getPaymentPluginTimeout().getUnit());
- this.paymentPluginDispatcher = new PluginDispatcher<Payment>(paymentPluginTimeoutSec, executor);
- this.voidPluginDispatcher = new PluginDispatcher<Void>(paymentPluginTimeoutSec, executor);
+ this.paymentPluginDispatcher = new PluginDispatcher<DirectPayment>(paymentPluginTimeoutSec, executor);
}
public DirectPayment createAuthorization(final Account account, final BigDecimal amount, final String externalKey, final Iterable<PluginProperty> properties, final InternalCallContext callContext) throws PaymentApiException {
-
- final PaymentPluginApi plugin = getPaymentProviderPlugin(account, callContext);
-
- final DateTime utcNow = clock.getUTCNow();
- final DirectPaymentModelDao pmd = new DirectPaymentModelDao(utcNow, utcNow, account.getId(), account.getPaymentMethodId(), externalKey);
- final DirectPaymentTransactionModelDao ptmd = new DirectPaymentTransactionModelDao(utcNow, utcNow, pmd.getId(),
- TransactionType.AUTHORIZE, utcNow, PaymentStatus.UNKNOWN,
- amount, account.getCurrency(), null, null);
-
- final DirectPaymentModelDao inserted = paymentDao.insertDirectPaymentWithFirstTransaction(pmd, ptmd, callContext);
- final UUID tenantId = nonEntityDao.retrieveIdFromObject(callContext.getTenantRecordId(), ObjectType.TENANT);
-
- PaymentStatus paymentStatus;
- PaymentInfoPlugin infoPlugin;
- try {
-
- try {
- infoPlugin = plugin.authorizePayment(account.getId(), pmd.getId(), ptmd.getId(), amount, account.getCurrency(), properties, callContext.toCallContext(tenantId));
- } catch (final 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", pmd.getId());
- throw new PaymentPluginApiException(formatError, e);
- }
-
- switch (infoPlugin.getStatus()) {
- case PROCESSED:
- case PENDING:
- // Update Payment/PaymentAttempt status
- paymentStatus = infoPlugin.getStatus() == PaymentPluginStatus.PROCESSED ? PaymentStatus.SUCCESS : PaymentStatus.PENDING;
- paymentDao.updateDirectPaymentAndTransactionOnCompletion(pmd.getId(), paymentStatus, amount, account.getCurrency(),
- ptmd.getId(), infoPlugin.getGatewayErrorCode(), null, callContext);
- break;
-
- case ERROR:
- paymentStatus = PaymentStatus.PLUGIN_FAILURE_ABORTED;
- paymentDao.updateDirectPaymentAndTransactionOnCompletion(pmd.getId(), paymentStatus, amount, account.getCurrency(),
- ptmd.getId(), infoPlugin.getGatewayErrorCode(), infoPlugin.getGatewayError(), callContext);
- break;
-
- case UNDEFINED:
- default:
- final String formatError = String.format("Plugin return status %s for payment %s", infoPlugin.getStatus(), pmd.getId());
- // This caught right below as a retryable Plugin failure
- throw new PaymentPluginApiException("", formatError);
- }
- } catch (final PaymentPluginApiException e) {
- paymentStatus = PaymentStatus.PAYMENT_FAILURE_ABORTED;
- infoPlugin = null;
- paymentDao.updateDirectPaymentAndTransactionOnCompletion(pmd.getId(), paymentStatus, amount, account.getCurrency(),
- ptmd.getId(), null, e.getMessage(), callContext);
- } finally {
- }
-
- final DirectPaymentTransaction transaction = new DefaultDirectPaymentTransaction(ptmd.getId(), utcNow, utcNow, pmd.getId(), ptmd.getTransactionType(), utcNow, 0,
- paymentStatus, amount, account.getCurrency(),
- ((infoPlugin != null) ? infoPlugin.getGatewayErrorCode() : null),
- ((infoPlugin != null) ? infoPlugin.getGatewayError() : null),
- infoPlugin);
- final List<DirectPaymentTransaction> transactions = Collections.singletonList(transaction);
- final DirectPayment result = new DefaultDirectPayment(inserted.getId(), utcNow, utcNow, account.getId(), account.getPaymentMethodId(), inserted.getPaymentNumber(), externalKey, transactions);
- return result;
+ return initiateDirectPayment(TransactionType.AUTHORIZE,
+ new PluginWrapper() {
+ @Override
+ public PaymentInfoPlugin doPluginOperation(final PaymentPluginApi plugin, final Account account, final BigDecimal amount, final UUID directPaymentId, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentPluginApiException {
+ return plugin.authorizePayment(account.getId(), directPaymentId, account.getPaymentMethodId(), amount, account.getCurrency(), properties, callContext);
+ }
+ },
+ externalKey,
+ account,
+ amount,
+ properties,
+ callContext
+ );
}
public DirectPayment createCapture(final Account account, final UUID directPaymentId, final BigDecimal amount, final Iterable<PluginProperty> properties, final InternalCallContext callContext) throws PaymentApiException {
- return null;
+ return createDirectPayment(TransactionType.CAPTURE,
+ new PluginWrapper() {
+ @Override
+ public PaymentInfoPlugin doPluginOperation(final PaymentPluginApi plugin, final Account account, final BigDecimal amount, final UUID directPaymentId, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentPluginApiException {
+ return plugin.capturePayment(account.getId(), directPaymentId, account.getPaymentMethodId(), amount, account.getCurrency(), properties, callContext);
+ }
+ },
+ directPaymentId,
+ account,
+ amount,
+ properties,
+ callContext
+ );
}
public DirectPayment createPurchase(final Account account, final BigDecimal amount, final String externalKey, final Iterable<PluginProperty> properties, final InternalCallContext callContext) throws PaymentApiException {
- return null;
+ return initiateDirectPayment(TransactionType.PURCHASE,
+ new PluginWrapper() {
+ @Override
+ public PaymentInfoPlugin doPluginOperation(final PaymentPluginApi plugin, final Account account, final BigDecimal amount, final UUID directPaymentId, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentPluginApiException {
+ return plugin.authorizePayment(account.getId(), directPaymentId, account.getPaymentMethodId(), amount, account.getCurrency(), properties, callContext);
+ }
+ },
+ externalKey,
+ account,
+ amount,
+ properties,
+ callContext
+ );
}
public DirectPayment createVoid(final Account account, final UUID directPaymentId, final Iterable<PluginProperty> properties, final InternalCallContext callContext) throws PaymentApiException {
- return null;
+ return createDirectPayment(TransactionType.VOID,
+ new PluginWrapper() {
+ @Override
+ public PaymentInfoPlugin doPluginOperation(final PaymentPluginApi plugin, final Account account, final BigDecimal amount, final UUID directPaymentId, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentPluginApiException {
+ return plugin.voidPayment(account.getId(), directPaymentId, account.getPaymentMethodId(), properties, callContext);
+ }
+ },
+ directPaymentId,
+ account,
+ null,
+ properties,
+ callContext
+ );
}
- public DirectPayment createCredit(final Account account, final UUID directPaymentId, final Iterable<PluginProperty> properties, final InternalCallContext callContext) throws PaymentApiException {
- return null;
+ public DirectPayment createCredit(final Account account, final UUID directPaymentId, final BigDecimal amount, final Iterable<PluginProperty> properties, final InternalCallContext callContext) throws PaymentApiException {
+ return createDirectPayment(TransactionType.CREDIT,
+ new PluginWrapper() {
+ @Override
+ public PaymentInfoPlugin doPluginOperation(final PaymentPluginApi plugin, final Account account, final BigDecimal amount, final UUID directPaymentId, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentPluginApiException {
+ return plugin.voidPayment(account.getId(), directPaymentId, account.getPaymentMethodId(), properties, callContext);
+ }
+ },
+ directPaymentId,
+ account,
+ amount,
+ properties,
+ callContext
+ );
}
- public List<DirectPayment> getAccountPayments(final UUID accountId, final boolean withPluginInfo, final InternalTenantContext tenantContext) throws PaymentApiException {
-
+ public List<DirectPayment> getAccountPayments(final UUID accountId, final InternalTenantContext tenantContext) throws PaymentApiException {
final List<DirectPaymentModelDao> paymentsModelDao = paymentDao.getDirectPaymentsForAccount(accountId, tenantContext);
final List<DirectPaymentTransactionModelDao> transactionsModelDao = paymentDao.getDirectTransactionsForAccount(accountId, tenantContext);
- final Iterable<DirectPayment> payments = Iterables.transform(paymentsModelDao, new Function<DirectPaymentModelDao, DirectPayment>() {
+ return Lists.transform(paymentsModelDao, new Function<DirectPaymentModelDao, DirectPayment>() {
@Override
public DirectPayment apply(final DirectPaymentModelDao curDirectPaymentModelDao) {
- return toDirectPayment(curDirectPaymentModelDao, transactionsModelDao);
+ return toDirectPayment(curDirectPaymentModelDao, transactionsModelDao, null);
}
-
});
- return ImmutableList.copyOf(payments);
}
- public DirectPayment getPayment(final UUID directPaymentId, final boolean withPluginInfo, final InternalTenantContext tenantContext) throws PaymentApiException {
+ public DirectPayment getPayment(final UUID directPaymentId, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final InternalTenantContext tenantContext) throws PaymentApiException {
final DirectPaymentModelDao paymentModelDao = paymentDao.getDirectPayment(directPaymentId, tenantContext);
+ if (paymentModelDao == null) {
+ return null;
+ }
final InternalTenantContext tenantContextWithAccountRecordId = internalCallContextFactory.createInternalTenantContext(paymentModelDao.getAccountId(), tenantContext);
final List<DirectPaymentTransactionModelDao> transactionsForAccount = paymentDao.getDirectTransactionsForAccount(paymentModelDao.getAccountId(), tenantContextWithAccountRecordId);
- return toDirectPayment(paymentModelDao, transactionsForAccount);
+ final PaymentPluginApi plugin = withPluginInfo ? getPaymentProviderPlugin(paymentModelDao.getPaymentMethodId(), tenantContext) : null;
+ PaymentInfoPlugin pluginInfo = null;
+ if (plugin != null) {
+ try {
+ pluginInfo = plugin.getPaymentInfo(paymentModelDao.getAccountId(), directPaymentId, properties, buildTenantContext(tenantContext));
+ } catch (final PaymentPluginApiException e) {
+ throw new PaymentApiException(ErrorCode.PAYMENT_PLUGIN_GET_PAYMENT_INFO, directPaymentId, e.toString());
+ }
+ }
+ return toDirectPayment(paymentModelDao, transactionsForAccount, pluginInfo);
+ }
+
+ public Pagination<DirectPayment> getPayments(final Long offset, final Long limit, final Iterable<PluginProperty> properties,
+ final TenantContext tenantContext, final InternalTenantContext internalTenantContext) {
+ return getEntityPaginationFromPlugins(getAvailablePlugins(),
+ offset,
+ limit,
+ new EntityPaginationBuilder<DirectPayment, PaymentApiException>() {
+ @Override
+ public Pagination<DirectPayment> build(final Long offset, final Long limit, final String pluginName) throws PaymentApiException {
+ return getPayments(offset, limit, pluginName, properties, tenantContext, internalTenantContext);
+ }
+ }
+ );
}
- private DirectPayment toDirectPayment(final DirectPaymentModelDao curDirectPaymentModelDao, final List<DirectPaymentTransactionModelDao> transactionsModelDao) {
+ public Pagination<DirectPayment> getPayments(final Long offset, final Long limit, final String pluginName, final Iterable<PluginProperty> properties, final TenantContext tenantContext, final InternalTenantContext internalTenantContext) throws PaymentApiException {
+ final PaymentPluginApi pluginApi = getPaymentPluginApi(pluginName);
+
+ return getEntityPagination(limit,
+ new SourcePaginationBuilder<DirectPaymentModelDao, PaymentApiException>() {
+ @Override
+ public Pagination<DirectPaymentModelDao> build() {
+ // Find all payments for all accounts
+ return paymentDao.getDirectPayments(pluginName, offset, limit, internalTenantContext);
+ }
+ },
+ new Function<DirectPaymentModelDao, DirectPayment>() {
+ @Override
+ public DirectPayment apply(final DirectPaymentModelDao paymentModelDao) {
+ PaymentInfoPlugin pluginInfo = null;
+ try {
+ pluginInfo = pluginApi.getPaymentInfo(paymentModelDao.getAccountId(), paymentModelDao.getId(), properties, tenantContext);
+ } catch (final PaymentPluginApiException e) {
+ log.warn("Unable to find payment id " + paymentModelDao.getId() + " in plugin " + pluginName);
+ // We still want to return a payment object, even though the plugin details are missing
+ }
+
+ return toDirectPayment(paymentModelDao.getId(), pluginInfo, internalTenantContext);
+ }
+ }
+ );
+ }
+
+ public Pagination<DirectPayment> searchPayments(final String searchKey, final Long offset, final Long limit, final Iterable<PluginProperty> properties, final InternalTenantContext internalTenantContext) {
+ return getEntityPaginationFromPlugins(getAvailablePlugins(),
+ offset,
+ limit,
+ new EntityPaginationBuilder<DirectPayment, PaymentApiException>() {
+ @Override
+ public Pagination<DirectPayment> build(final Long offset, final Long limit, final String pluginName) throws PaymentApiException {
+ return searchPayments(searchKey, offset, limit, pluginName, properties, internalTenantContext);
+ }
+ }
+ );
+ }
+
+ public Pagination<DirectPayment> searchPayments(final String searchKey, final Long offset, final Long limit, final String pluginName, final Iterable<PluginProperty> properties, final InternalTenantContext internalTenantContext) throws PaymentApiException {
+ final PaymentPluginApi pluginApi = getPaymentPluginApi(pluginName);
+
+ return getEntityPagination(limit,
+ new SourcePaginationBuilder<PaymentInfoPlugin, PaymentApiException>() {
+ @Override
+ public Pagination<PaymentInfoPlugin> build() throws PaymentApiException {
+ try {
+ return pluginApi.searchPayments(searchKey, offset, limit, properties, buildTenantContext(internalTenantContext));
+ } catch (final PaymentPluginApiException e) {
+ throw new PaymentApiException(e, ErrorCode.PAYMENT_PLUGIN_SEARCH_PAYMENTS, pluginName, searchKey);
+ }
+ }
+ },
+ new Function<PaymentInfoPlugin, DirectPayment>() {
+ @Override
+ public DirectPayment apply(final PaymentInfoPlugin paymentInfoPlugin) {
+ if (paymentInfoPlugin.getKbPaymentId() == null) {
+ // Garbage from the plugin?
+ log.debug("Plugin {} returned a payment without a kbPaymentId for searchKey {}", pluginName, searchKey);
+ return null;
+ }
+
+ return toDirectPayment(paymentInfoPlugin.getKbPaymentId(), paymentInfoPlugin, internalTenantContext);
+ }
+ }
+ );
+ }
+ private DirectPayment toDirectPayment(final UUID directPaymentId, @Nullable final PaymentInfoPlugin pluginInfo, final InternalTenantContext tenantContext) {
+ final DirectPaymentModelDao paymentModelDao = paymentDao.getDirectPayment(directPaymentId, tenantContext);
+ if (paymentModelDao == null) {
+ log.warn("Unable to find direct payment id " + directPaymentId);
+ return null;
+ }
+
+ final InternalTenantContext tenantContextWithAccountRecordId = internalCallContextFactory.createInternalTenantContext(paymentModelDao.getAccountId(), tenantContext);
+ final List<DirectPaymentTransactionModelDao> transactionsForAccount = paymentDao.getDirectTransactionsForAccount(paymentModelDao.getAccountId(), tenantContextWithAccountRecordId);
+
+ return toDirectPayment(paymentModelDao, transactionsForAccount, pluginInfo);
+ }
+
+ private DirectPayment toDirectPayment(final DirectPaymentModelDao curDirectPaymentModelDao, final Iterable<DirectPaymentTransactionModelDao> transactionsModelDao, @Nullable final PaymentInfoPlugin pluginInfo) {
final Ordering<DirectPaymentTransaction> perPaymentTransactionOrdering = Ordering.<DirectPaymentTransaction>from(new Comparator<DirectPaymentTransaction>() {
@Override
public int compare(final DirectPaymentTransaction o1, final DirectPaymentTransaction o2) {
@@ -232,8 +339,7 @@ public class DirectPaymentProcessor extends ProcessorBase {
public DirectPaymentTransaction apply(final DirectPaymentTransactionModelDao input) {
return new DefaultDirectPaymentTransaction(input.getId(), input.getCreatedDate(), input.getUpdatedDate(), input.getDirectPaymentId(),
input.getTransactionType(), input.getEffectiveDate(), 0, input.getPaymentStatus(), input.getAmount(), input.getCurrency(),
- // STEPH_DP fill in details plugin info if required
- input.getGatewayErrorCode(), input.getGatewayErrorMsg(), null);
+ input.getGatewayErrorCode(), input.getGatewayErrorMsg(), pluginInfo);
}
});
@@ -241,4 +347,118 @@ public class DirectPaymentProcessor extends ProcessorBase {
return new DefaultDirectPayment(curDirectPaymentModelDao.getId(), curDirectPaymentModelDao.getCreatedDate(), curDirectPaymentModelDao.getUpdatedDate(), curDirectPaymentModelDao.getAccountId(),
curDirectPaymentModelDao.getPaymentMethodId(), curDirectPaymentModelDao.getPaymentNumber(), curDirectPaymentModelDao.getExternalKey(), sortedTransactions);
}
+
+ private static interface PluginWrapper {
+
+ PaymentInfoPlugin doPluginOperation(final PaymentPluginApi plugin, final Account account, final BigDecimal amount, final UUID directPaymentId, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentPluginApiException;
+ }
+
+ private DirectPayment initiateDirectPayment(final TransactionType transactionType, final PluginWrapper pluginWrapper, final String externalKey, final Account account, final BigDecimal amount,
+ final Iterable<PluginProperty> properties, final InternalCallContext callContext) throws PaymentApiException {
+ try {
+ return paymentPluginDispatcher.dispatchWithAccountLock(new CallableWithAccountLock<DirectPayment>(locker,
+ account.getExternalKey(),
+ new WithAccountLockCallback<DirectPayment>() {
+
+ @Override
+ public DirectPayment doOperation() throws PaymentApiException {
+ final DateTime utcNow = clock.getUTCNow();
+ final DirectPaymentModelDao pmd = new DirectPaymentModelDao(utcNow, utcNow, account.getId(), account.getPaymentMethodId(), externalKey);
+ final DirectPaymentTransactionModelDao ptmd = new DirectPaymentTransactionModelDao(utcNow, utcNow, pmd.getId(),
+ transactionType, utcNow, PaymentStatus.UNKNOWN,
+ amount, account.getCurrency(), null, null);
+
+ final DirectPaymentModelDao inserted = paymentDao.insertDirectPaymentWithFirstTransaction(pmd, ptmd, callContext);
+ final DirectPaymentTransactionModelDao insertedTransaction = paymentDao.getDirectTransactionsForAccount(account.getId(), callContext).get(0);
+
+ return getDirectPayment(pluginWrapper, account, amount, inserted.getId(), insertedTransaction.getId(), properties, callContext);
+ }
+ }
+ ));
+ } catch (final TimeoutException e) {
+ // TODO PIERRE
+ throw new PaymentApiException(ErrorCode.PAYMENT_PLUGIN_TIMEOUT, account.getId(), null);
+ } catch (final RuntimeException e) {
+ throw new PaymentApiException(ErrorCode.PAYMENT_INTERNAL_ERROR, null);
+ }
+ }
+
+ private DirectPayment createDirectPayment(final TransactionType transactionType, final PluginWrapper pluginWrapper, final UUID directPaymentId,
+ final Account account, @Nullable final BigDecimal amount,
+ final Iterable<PluginProperty> properties, final InternalCallContext callContext) throws PaymentApiException {
+ try {
+ return paymentPluginDispatcher.dispatchWithAccountLock(new CallableWithAccountLock<DirectPayment>(locker,
+ account.getExternalKey(),
+ new WithAccountLockCallback<DirectPayment>() {
+
+ @Override
+ public DirectPayment doOperation() throws PaymentApiException {
+ final DateTime utcNow = clock.getUTCNow();
+ final DirectPaymentTransactionModelDao ptmd = new DirectPaymentTransactionModelDao(utcNow, utcNow, directPaymentId,
+ transactionType, utcNow, PaymentStatus.UNKNOWN,
+ amount, account.getCurrency(), null, null);
+ final DirectPaymentTransactionModelDao inserted = paymentDao.updateDirectPaymentWithNewTransaction(directPaymentId, ptmd, callContext);
+
+ return getDirectPayment(pluginWrapper, account, amount, directPaymentId, inserted.getId(), properties, callContext);
+ }
+ }
+ ));
+ } catch (final TimeoutException e) {
+ // TODO PIERRE
+ throw new PaymentApiException(ErrorCode.PAYMENT_PLUGIN_TIMEOUT, account.getId(), null);
+ } catch (final RuntimeException e) {
+ throw new PaymentApiException(ErrorCode.PAYMENT_INTERNAL_ERROR, null);
+ }
+ }
+
+ private DirectPayment getDirectPayment(final PluginWrapper pluginWrapper, final Account account, @Nullable final BigDecimal amount,
+ final UUID directPaymentId, final UUID directPaymentTransactionId, final Iterable<PluginProperty> properties,
+ final InternalCallContext callContext) throws PaymentApiException {
+ final UUID tenantId = nonEntityDao.retrieveIdFromObject(callContext.getTenantRecordId(), ObjectType.TENANT);
+ final PaymentPluginApi plugin = getPaymentProviderPlugin(account, callContext);
+
+ try {
+ final PaymentInfoPlugin infoPlugin;
+ try {
+ infoPlugin = pluginWrapper.doPluginOperation(plugin, account, amount, directPaymentId, properties, callContext.toCallContext(tenantId));
+ } catch (final 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 direct payment %s", directPaymentId);
+ throw new PaymentPluginApiException(formatError, e);
+ }
+
+ processPaymentInfoPlugin(infoPlugin, account, amount, directPaymentId, directPaymentTransactionId, callContext);
+ } catch (final PaymentPluginApiException e) {
+ paymentDao.updateDirectPaymentAndTransactionOnCompletion(directPaymentId, PaymentStatus.PAYMENT_FAILURE_ABORTED, amount, account.getCurrency(), directPaymentTransactionId, null, e.getMessage(), callContext);
+ }
+
+ return getPayment(directPaymentId, false, properties, callContext);
+ }
+
+ private PaymentStatus processPaymentInfoPlugin(final PaymentInfoPlugin infoPlugin, final Account account, @Nullable final BigDecimal amount,
+ final UUID directPaymentId, final UUID directPaymentTransactionId, final InternalCallContext callContext) throws PaymentPluginApiException {
+ final PaymentStatus paymentStatus;
+ switch (infoPlugin.getStatus()) {
+ case PROCESSED:
+ paymentStatus = PaymentStatus.SUCCESS;
+ break;
+ case PENDING:
+ paymentStatus = PaymentStatus.PENDING;
+ break;
+ case ERROR:
+ paymentStatus = PaymentStatus.PLUGIN_FAILURE_ABORTED;
+ break;
+ case UNDEFINED:
+ default:
+ final String formatError = String.format("Plugin return status %s for direct payment %s", infoPlugin.getStatus(), directPaymentId);
+ // This will be caught as a retryable Plugin failure
+ throw new PaymentPluginApiException("", formatError);
+ }
+
+ // Update Payment/PaymentAttempt status
+ paymentDao.updateDirectPaymentAndTransactionOnCompletion(directPaymentId, paymentStatus, amount, account.getCurrency(),
+ directPaymentTransactionId, infoPlugin.getGatewayErrorCode(), infoPlugin.getGatewayError(), callContext);
+
+ return paymentStatus;
+ }
}
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 b15f20c..f0d65ad 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
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
@@ -24,16 +26,11 @@ import java.util.UUID;
import javax.inject.Inject;
-import org.killbill.billing.ObjectType;
-import org.killbill.billing.payment.api.DirectPaymentTransaction;
-import org.killbill.billing.util.cache.Cachable.CacheType;
-import org.skife.jdbi.v2.IDBI;
-
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.catalog.api.Currency;
-import org.killbill.clock.Clock;
import org.killbill.billing.entity.EntityPersistenceException;
+import org.killbill.billing.payment.api.DirectPayment;
import org.killbill.billing.payment.api.Payment;
import org.killbill.billing.payment.api.PaymentMethod;
import org.killbill.billing.payment.api.PaymentStatus;
@@ -48,6 +45,8 @@ import org.killbill.billing.util.entity.dao.EntitySqlDao;
import org.killbill.billing.util.entity.dao.EntitySqlDaoTransactionWrapper;
import org.killbill.billing.util.entity.dao.EntitySqlDaoTransactionalJdbiWrapper;
import org.killbill.billing.util.entity.dao.EntitySqlDaoWrapperFactory;
+import org.killbill.clock.Clock;
+import org.skife.jdbi.v2.IDBI;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
@@ -75,6 +74,26 @@ public class DefaultPaymentDao implements PaymentDao {
}
@Override
+ public Pagination<DirectPaymentModelDao> getDirectPayments(final String pluginName, final Long offset, final Long limit, final InternalTenantContext context) {
+ return paginationHelper.getPagination(DirectPaymentSqlDao.class,
+ new PaginationIteratorBuilder<DirectPaymentModelDao, DirectPayment, DirectPaymentSqlDao>() {
+ @Override
+ public Long getCount(final DirectPaymentSqlDao directPaymentSqlDao, final InternalTenantContext context) {
+ return directPaymentSqlDao.getCountByPluginName(pluginName, context);
+ }
+
+ @Override
+ public Iterator<DirectPaymentModelDao> build(final DirectPaymentSqlDao directPaymentSqlDao, final Long limit, final InternalTenantContext context) {
+ return directPaymentSqlDao.getByPluginName(pluginName, offset, limit, context);
+ }
+ },
+ offset,
+ limit,
+ context
+ );
+ }
+
+ @Override
public DirectPaymentModelDao insertDirectPaymentWithFirstTransaction(final DirectPaymentModelDao directPayment, final DirectPaymentTransactionModelDao directPaymentTransaction, final InternalCallContext context) {
return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<DirectPaymentModelDao>() {
@@ -84,7 +103,23 @@ public class DefaultPaymentDao implements PaymentDao {
final DirectPaymentSqlDao directPaymentSqlDao = entitySqlDaoWrapperFactory.become(DirectPaymentSqlDao.class);
directPaymentSqlDao.create(directPayment, context);
entitySqlDaoWrapperFactory.become(DirectTransactionSqlDao.class).create(directPaymentTransaction, context);
- return directPaymentSqlDao.getById(directPayment.getId().toString(), context);
+ return directPaymentSqlDao.getById(directPayment.getId().toString(), context);
+ }
+ });
+ }
+
+ @Override
+ public DirectPaymentTransactionModelDao updateDirectPaymentWithNewTransaction(final UUID directPaymentId, final DirectPaymentTransactionModelDao directPaymentTransaction, final InternalCallContext context) {
+ return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<DirectPaymentTransactionModelDao>() {
+ @Override
+ public DirectPaymentTransactionModelDao inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
+ final DirectTransactionSqlDao transactional = entitySqlDaoWrapperFactory.become(DirectTransactionSqlDao.class);
+ transactional.create(directPaymentTransaction, context);
+ final DirectPaymentTransactionModelDao directPaymentTransactionModelDao = transactional.getById(directPaymentTransaction.getId().toString(), context);
+
+ entitySqlDaoWrapperFactory.become(DirectPaymentSqlDao.class).updateDirectPaymentForNewTransaction(directPaymentId.toString(), context);
+
+ return directPaymentTransactionModelDao;
}
});
}
@@ -92,7 +127,7 @@ public class DefaultPaymentDao implements PaymentDao {
@Override
public void updateDirectPaymentAndTransactionOnCompletion(final UUID directPaymentId, final PaymentStatus paymentStatus,
final BigDecimal processedAmount, final Currency processedCurrency,
- final UUID directTransactionId, final String gatewayErrorCode, final String gatewayErrorMsg, final InternalCallContext context) {
+ final UUID directTransactionId, final String gatewayErrorCode, final String gatewayErrorMsg, final InternalCallContext context) {
transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {
@Override
@@ -149,7 +184,6 @@ public class DefaultPaymentDao implements PaymentDao {
});
}
-
@Override
public PaymentModelDao insertPaymentWithFirstAttempt(final PaymentModelDao payment, final PaymentAttemptModelDao attempt, final InternalCallContext context) {
return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<PaymentModelDao>() {
@@ -261,7 +295,8 @@ public class DefaultPaymentDao implements PaymentDao {
},
offset,
limit,
- context);
+ context
+ );
}
@Override
@@ -340,7 +375,8 @@ public class DefaultPaymentDao implements PaymentDao {
},
offset,
limit,
- context);
+ context
+ );
}
@Override
@@ -410,7 +446,8 @@ public class DefaultPaymentDao implements PaymentDao {
},
offset,
limit,
- context);
+ context
+ );
}
@Override
@@ -463,7 +500,8 @@ public class DefaultPaymentDao implements PaymentDao {
public boolean apply(final PaymentMethodModelDao paymentMethod) {
return pluginName.equals(paymentMethod.getPluginName());
}
- });
+ }
+ );
for (final PaymentMethodModelDao finalPaymentMethod : newPaymentMethods) {
PaymentMethodModelDao foundExistingPaymentMethod = null;
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/DirectPaymentSqlDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/DirectPaymentSqlDao.java
index 1714d4f..6813a31 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dao/DirectPaymentSqlDao.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/DirectPaymentSqlDao.java
@@ -16,15 +16,11 @@
package org.killbill.billing.payment.dao;
-import java.math.BigDecimal;
import java.util.Iterator;
-import java.util.List;
import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
-import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.payment.api.DirectPayment;
-import org.killbill.billing.payment.api.Refund;
import org.killbill.billing.util.audit.ChangeType;
import org.killbill.billing.util.entity.dao.Audited;
import org.killbill.billing.util.entity.dao.EntitySqlDao;
@@ -38,17 +34,19 @@ import org.skife.jdbi.v2.sqlobject.SqlUpdate;
@EntitySqlDaoStringTemplate
public interface DirectPaymentSqlDao extends EntitySqlDao<DirectPaymentModelDao, DirectPayment> {
+ @SqlUpdate
+ @Audited(ChangeType.UPDATE)
+ void updateDirectPaymentForNewTransaction(@Bind("id") final String directPaymentId,
+ @BindBean final InternalCallContext context);
- /*
@SqlQuery
@SmartFetchSize(shouldStream = true)
public Iterator<DirectPaymentModelDao> getByPluginName(@Bind("pluginName") final String pluginName,
- @Bind("offset") final Long offset,
- @Bind("rowCount") final Long rowCount,
- @BindBean final InternalTenantContext context);
+ @Bind("offset") final Long offset,
+ @Bind("rowCount") final Long rowCount,
+ @BindBean final InternalTenantContext context);
@SqlQuery
public Long getCountByPluginName(@Bind("pluginName") final String pluginName,
@BindBean final InternalTenantContext context);
- */
}
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 12606f9..e13bc91 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
@@ -29,11 +29,15 @@ import org.killbill.billing.util.entity.Pagination;
public interface PaymentDao {
+ public Pagination<DirectPaymentModelDao> getDirectPayments(String pluginName, Long offset, Long limit, InternalTenantContext context);
+
public DirectPaymentModelDao insertDirectPaymentWithFirstTransaction(DirectPaymentModelDao directPayment, DirectPaymentTransactionModelDao directPaymentTransaction, InternalCallContext context);
+ public DirectPaymentTransactionModelDao updateDirectPaymentWithNewTransaction(UUID dirctPaymentId, DirectPaymentTransactionModelDao directPaymentTransaction, InternalCallContext context);
+
public void updateDirectPaymentAndTransactionOnCompletion(final UUID directPaymentId, final PaymentStatus paymentStatus,
final BigDecimal processedAmount, final Currency processedCurrency,
- final UUID directTransactionId, final String gatewayErrorCode, final String gatewayErrorMsg, final InternalCallContext context);
+ final UUID directTransactionId, final String gatewayErrorCode, final String gatewayErrorMsg, final InternalCallContext context);
public DirectPaymentModelDao getDirectPayment(UUID directPaymentId, InternalTenantContext context);
diff --git a/payment/src/main/java/org/killbill/billing/payment/provider/DefaultNoOpPaymentMethodPlugin.java b/payment/src/main/java/org/killbill/billing/payment/provider/DefaultNoOpPaymentMethodPlugin.java
index 27ae2d2..3982880 100644
--- a/payment/src/main/java/org/killbill/billing/payment/provider/DefaultNoOpPaymentMethodPlugin.java
+++ b/payment/src/main/java/org/killbill/billing/payment/provider/DefaultNoOpPaymentMethodPlugin.java
@@ -51,11 +51,11 @@ public class DefaultNoOpPaymentMethodPlugin implements PaymentMethodPlugin {
public DefaultNoOpPaymentMethodPlugin(@Nullable final UUID kbPaymentMethodId,
final String externalId,
final boolean isDefault,
- final Iterable<PluginProperty> props) {
+ @Nullable final Iterable<PluginProperty> props) {
this.kbPaymentMethodId = kbPaymentMethodId;
this.externalId = externalId;
this.isDefault = isDefault;
- this.props = ImmutableList.<PluginProperty>copyOf(props);
+ this.props = props == null ? ImmutableList.<PluginProperty>of() : ImmutableList.<PluginProperty>copyOf(props);
}
@Override
diff --git a/payment/src/main/resources/org/killbill/billing/payment/dao/DirectPaymentSqlDao.sql.stg b/payment/src/main/resources/org/killbill/billing/payment/dao/DirectPaymentSqlDao.sql.stg
index 1845370..3767b96 100644
--- a/payment/src/main/resources/org/killbill/billing/payment/dao/DirectPaymentSqlDao.sql.stg
+++ b/payment/src/main/resources/org/killbill/billing/payment/dao/DirectPaymentSqlDao.sql.stg
@@ -23,7 +23,7 @@ tableFields(prefix) ::= <<
>>
tableValues() ::= <<
-:accountId
+ :accountId
, :paymentMethodId
, :externalKey
, :createdBy
@@ -32,4 +32,11 @@ tableValues() ::= <<
, :updatedDate
>>
-
+updateDirectPaymentForNewTransaction() ::= <<
+update <tableName()>
+set updated_by = :updatedBy
+, updated_date = :createdDate
+where id = :id
+<AND_CHECK_TENANT()>
+;
+>>
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 60282d0..6e98657 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
@@ -41,13 +41,22 @@ public class MockPaymentDao implements PaymentDao {
private final Map<UUID, PaymentAttemptModelDao> attempts = new HashMap<UUID, PaymentAttemptModelDao>();
@Override
+ public Pagination<DirectPaymentModelDao> getDirectPayments(final String pluginName, final Long offset, final Long limit, final InternalTenantContext context) {
+ return null;
+ }
+
+ @Override
public DirectPaymentModelDao insertDirectPaymentWithFirstTransaction(final DirectPaymentModelDao directPayment, final DirectPaymentTransactionModelDao directPaymentTransaction, final InternalCallContext context) {
return null;
}
@Override
- public void updateDirectPaymentAndTransactionOnCompletion(final UUID directPaymentId, final PaymentStatus paymentStatus, final BigDecimal processedAmount, final Currency processedCurrency, final UUID directTransactionId, final String gatewayErrorCode, final String gatewayErrorMsg, final InternalCallContext context) {
+ public DirectPaymentTransactionModelDao updateDirectPaymentWithNewTransaction(final UUID dirctPaymentId, final DirectPaymentTransactionModelDao directPaymentTransaction, final InternalCallContext context) {
+ return null;
+ }
+ @Override
+ public void updateDirectPaymentAndTransactionOnCompletion(final UUID directPaymentId, final PaymentStatus paymentStatus, final BigDecimal processedAmount, final Currency processedCurrency, final UUID directTransactionId, final String gatewayErrorCode, final String gatewayErrorMsg, final InternalCallContext context) {
}
@Override
pom.xml 2(+1 -1)
diff --git a/pom.xml b/pom.xml
index 392015d..b67ae73 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill-oss-parent</artifactId>
<groupId>org.kill-bill.billing</groupId>
- <version>0.7.2</version>
+ <version>0.7.3</version>
</parent>
<artifactId>killbill</artifactId>
<version>0.11.2-SNAPSHOT</version>