killbill-memoizeit
Changes
payment/src/main/java/org/killbill/billing/payment/core/janitor/IncompletePaymentTransactionTask.java 2(+1 -1)
payment/src/main/java/org/killbill/billing/payment/core/sm/control/OperationControlCallback.java 34(+15 -19)
Details
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ComboPaymentTransactionJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ComboPaymentTransactionJson.java
new file mode 100644
index 0000000..9a50741
--- /dev/null
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ComboPaymentTransactionJson.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2014-2015 Groupon, Inc
+ * Copyright 2014-2015 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
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.jaxrs.json;
+
+import java.util.List;
+
+import javax.annotation.Nullable;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class ComboPaymentTransactionJson extends JsonBase {
+
+ private final AccountJson account;
+ private final PaymentMethodJson paymentMethod;
+ private final PaymentTransactionJson transaction;
+ private final Iterable<PluginPropertyJson> paymentMethodPluginProperties;
+ private final Iterable<PluginPropertyJson> transactionPluginProperties;
+
+ @JsonCreator
+ public ComboPaymentTransactionJson(@JsonProperty("account") final AccountJson account,
+ @JsonProperty("paymentMethod") final PaymentMethodJson paymentMethod,
+ @JsonProperty("transaction") final PaymentTransactionJson transaction,
+ @JsonProperty("paymentMethodPluginProperties") final Iterable<PluginPropertyJson> paymentMethodPluginProperties,
+ @JsonProperty("transactionPluginProperties") final Iterable<PluginPropertyJson> transactionPluginProperties,
+ @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
+ super(auditLogs);
+ this.account = account;
+ this.paymentMethod = paymentMethod;
+ this.transaction = transaction;
+ this.paymentMethodPluginProperties = paymentMethodPluginProperties;
+ this.transactionPluginProperties = transactionPluginProperties;
+ }
+
+
+ public AccountJson getAccount() {
+ return account;
+ }
+
+ public PaymentMethodJson getPaymentMethod() {
+ return paymentMethod;
+ }
+
+ public PaymentTransactionJson getTransaction() {
+ return transaction;
+ }
+
+ public Iterable<PluginPropertyJson> getPaymentMethodPluginProperties() {
+ return paymentMethodPluginProperties;
+ }
+
+ public Iterable<PluginPropertyJson> getTransactionPluginProperties() {
+ return transactionPluginProperties;
+ }
+
+ @Override
+ public String toString() {
+ return "ComboPaymentTransactionJson{" +
+ "account=" + account +
+ ", paymentMethod=" + paymentMethod +
+ ", transaction=" + transaction +
+ ", paymentMethodPluginProperties=" + paymentMethodPluginProperties +
+ ", transactionPluginProperties=" + transactionPluginProperties +
+ '}';
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof ComboPaymentTransactionJson)) {
+ return false;
+ }
+
+ final ComboPaymentTransactionJson that = (ComboPaymentTransactionJson) o;
+
+ if (account != null ? !account.equals(that.account) : that.account != null) {
+ return false;
+ }
+ if (paymentMethod != null ? !paymentMethod.equals(that.paymentMethod) : that.paymentMethod != null) {
+ return false;
+ }
+ if (transaction != null ? !transaction.equals(that.transaction) : that.transaction != null) {
+ return false;
+ }
+ if (paymentMethodPluginProperties != null ? !paymentMethodPluginProperties.equals(that.paymentMethodPluginProperties) : that.paymentMethodPluginProperties != null) {
+ return false;
+ }
+ return !(transactionPluginProperties != null ? !transactionPluginProperties.equals(that.transactionPluginProperties) : that.transactionPluginProperties != null);
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = account != null ? account.hashCode() : 0;
+ result = 31 * result + (paymentMethod != null ? paymentMethod.hashCode() : 0);
+ result = 31 * result + (transaction != null ? transaction.hashCode() : 0);
+ result = 31 * result + (paymentMethodPluginProperties != null ? paymentMethodPluginProperties.hashCode() : 0);
+ result = 31 * result + (transactionPluginProperties != null ? transactionPluginProperties.hashCode() : 0);
+ return result;
+ }
+}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
index 4c5dabb..d29d527 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
@@ -223,4 +223,6 @@ public interface JaxrsResource {
public static final String UPCOMING_INVOICE_TARGET_DATE = "upcomingInvoiceTargetDate";
+ public static final String COMBO = "combo";
+
}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
index 43b3464..42b942f 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
@@ -24,6 +24,7 @@ import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
+import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
@@ -37,6 +38,7 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
import javax.ws.rs.core.UriInfo;
import org.killbill.billing.ObjectType;
@@ -44,14 +46,21 @@ import org.killbill.billing.account.api.Account;
import org.killbill.billing.account.api.AccountApiException;
import org.killbill.billing.account.api.AccountUserApi;
import org.killbill.billing.catalog.api.Currency;
+import org.killbill.billing.jaxrs.json.AccountJson;
+import org.killbill.billing.jaxrs.json.ComboPaymentTransactionJson;
import org.killbill.billing.jaxrs.json.PaymentJson;
+import org.killbill.billing.jaxrs.json.PaymentMethodJson;
import org.killbill.billing.jaxrs.json.PaymentTransactionJson;
+import org.killbill.billing.jaxrs.json.PluginPropertyJson;
import org.killbill.billing.jaxrs.util.Context;
import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
import org.killbill.billing.payment.api.Payment;
import org.killbill.billing.payment.api.PaymentApi;
import org.killbill.billing.payment.api.PaymentApiException;
+import org.killbill.billing.payment.api.PaymentMethod;
+import org.killbill.billing.payment.api.PaymentOptions;
import org.killbill.billing.payment.api.PluginProperty;
+import org.killbill.billing.payment.api.TransactionType;
import org.killbill.billing.util.api.AuditUserApi;
import org.killbill.billing.util.api.CustomFieldUserApi;
import org.killbill.billing.util.api.TagUserApi;
@@ -63,8 +72,12 @@ import org.killbill.clock.Clock;
import com.codahale.metrics.annotation.Timed;
import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiResponse;
@@ -106,7 +119,25 @@ public class PaymentResource extends JaxRsResourceBase {
final Payment payment = paymentApi.getPayment(paymentIdId, withPluginInfo, pluginProperties, tenantContext);
final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(payment.getAccountId(), auditMode.getLevel(), tenantContext);
final PaymentJson result = new PaymentJson(payment, accountAuditLogs);
+ return Response.status(Response.Status.OK).entity(result).build();
+ }
+ @Timed
+ @GET
+ @Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Retrieve a payment by id", response = PaymentJson.class)
+ @ApiResponses(value = {@ApiResponse(code = 404, message = "Payment not found")})
+ public Response getPaymentByExternalKey(@QueryParam(QUERY_WITH_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo,
+ @QueryParam(QUERY_EXTERNAL_KEY) final String paymentExternalKey,
+ @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
+ @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
+ @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException {
+ verifyNonNullOrEmpty(paymentExternalKey, "Payment externalKey needs to be specified");
+ final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
+ final TenantContext tenantContext = context.createContext(request);
+ final Payment payment = paymentApi.getPaymentByExternalKey(paymentExternalKey, withPluginInfo, pluginProperties, tenantContext);
+ final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(payment.getAccountId(), auditMode.getLevel(), tenantContext);
+ final PaymentJson result = new PaymentJson(payment, accountAuditLogs);
return Response.status(Response.Status.OK).entity(result).build();
}
@@ -215,18 +246,45 @@ public class PaymentResource extends JaxRsResourceBase {
@HeaderParam(HDR_COMMENT) final String comment,
@javax.ws.rs.core.Context final UriInfo uriInfo,
@javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
+ return captureAuthorizationInternal(json, paymentIdStr, pluginPropertiesString, createdBy, reason, comment, uriInfo, request);
+ }
+
+ @Timed
+ @POST
+ @Consumes(APPLICATION_JSON)
+ @Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Capture an existing authorization")
+ @ApiResponses(value = {@ApiResponse(code = 404, message = "Account or payment not found")})
+ public Response captureAuthorizationByExternalKey(final PaymentTransactionJson json,
+ @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment,
+ @javax.ws.rs.core.Context final UriInfo uriInfo,
+ @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
+ return captureAuthorizationInternal(json, null, pluginPropertiesString, createdBy, reason, comment, uriInfo, request);
+ }
+
+ private Response captureAuthorizationInternal(final PaymentTransactionJson json,
+ @Nullable final String paymentIdStr,
+ final List<String> pluginPropertiesString,
+ final String createdBy,
+ final String reason,
+ final String comment,
+ final UriInfo uriInfo,
+ final HttpServletRequest request) throws PaymentApiException, AccountApiException {
+
verifyNonNullOrEmpty(json, "PaymentTransactionJson body should be specified");
verifyNonNullOrEmpty(json.getAmount(), "PaymentTransactionJson amount needs to be set");
final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
final CallContext callContext = context.createContext(createdBy, reason, comment, request);
- final UUID paymentId = UUID.fromString(paymentIdStr);
- final Payment initialPayment = paymentApi.getPayment(paymentId, false, pluginProperties, callContext);
+ final Payment initialPayment = getPaymentByIdOrKey(paymentIdStr, json.getPaymentExternalKey(), pluginProperties, callContext);
final Account account = accountUserApi.getAccountById(initialPayment.getAccountId(), callContext);
final Currency currency = json.getCurrency() == null ? account.getCurrency() : Currency.valueOf(json.getCurrency());
- final Payment payment = paymentApi.createCapture(account, paymentId, json.getAmount(), currency,
+ final Payment payment = paymentApi.createCapture(account, initialPayment.getId(), json.getAmount(), currency,
json.getTransactionExternalKey(), pluginProperties, callContext);
return uriBuilder.buildResponse(uriInfo, PaymentResource.class, "getPayment", payment.getId());
}
@@ -247,20 +305,50 @@ public class PaymentResource extends JaxRsResourceBase {
@HeaderParam(HDR_COMMENT) final String comment,
@javax.ws.rs.core.Context final UriInfo uriInfo,
@javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
+ return refundPaymentInternal(json, paymentIdStr, pluginPropertiesString, createdBy, reason, comment, uriInfo, request);
+ }
+
+ @Timed
+ @POST
+ @Path("/" + REFUNDS)
+ @Consumes(APPLICATION_JSON)
+ @Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Refund an existing payment")
+ @ApiResponses(value = {@ApiResponse(code = 404, message = "Account or payment not found")})
+ public Response refundPaymentByExternalKey(final PaymentTransactionJson json,
+ @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment,
+ @javax.ws.rs.core.Context final UriInfo uriInfo,
+ @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
+ return refundPaymentInternal(json, null, pluginPropertiesString, createdBy, reason, comment, uriInfo, request);
+
+ }
+
+ private Response refundPaymentInternal(final PaymentTransactionJson json,
+ @Nullable final String paymentIdStr,
+ final List<String> pluginPropertiesString,
+ final String createdBy,
+ final String reason,
+ final String comment,
+ final UriInfo uriInfo,
+ final HttpServletRequest request) throws PaymentApiException, AccountApiException {
+
verifyNonNullOrEmpty(json, "PaymentTransactionJson body should be specified");
verifyNonNullOrEmpty(json.getAmount(), "PaymentTransactionJson amount needs to be set");
final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
final CallContext callContext = context.createContext(createdBy, reason, comment, request);
- final UUID paymentId = UUID.fromString(paymentIdStr);
- final Payment initialPayment = paymentApi.getPayment(paymentId, false, pluginProperties, callContext);
+ final Payment initialPayment = getPaymentByIdOrKey(paymentIdStr, json.getPaymentExternalKey(), pluginProperties, callContext);
final Account account = accountUserApi.getAccountById(initialPayment.getAccountId(), callContext);
final Currency currency = json.getCurrency() == null ? account.getCurrency() : Currency.valueOf(json.getCurrency());
- final Payment payment = paymentApi.createRefund(account, paymentId, json.getAmount(), currency,
+ final Payment payment = paymentApi.createRefund(account, initialPayment.getId(), json.getAmount(), currency,
json.getTransactionExternalKey(), pluginProperties, callContext);
return uriBuilder.buildResponse(uriInfo, PaymentResource.class, "getPayment", payment.getId());
+
}
@Timed
@@ -279,15 +367,41 @@ public class PaymentResource extends JaxRsResourceBase {
@HeaderParam(HDR_COMMENT) final String comment,
@javax.ws.rs.core.Context final UriInfo uriInfo,
@javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
+ return voidPaymentInternal(json, paymentIdStr, pluginPropertiesString, createdBy, reason, comment, uriInfo, request);
+ }
+
+ @Timed
+ @DELETE
+ @Consumes(APPLICATION_JSON)
+ @Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Void an existing payment")
+ @ApiResponses(value = {@ApiResponse(code = 404, message = "Account or payment not found")})
+ public Response voidPaymentByExternalKey(final PaymentTransactionJson json,
+ @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment,
+ @javax.ws.rs.core.Context final UriInfo uriInfo,
+ @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
+ return voidPaymentInternal(json, null, pluginPropertiesString, createdBy, reason, comment, uriInfo, request);
+ }
+
+ private Response voidPaymentInternal(final PaymentTransactionJson json,
+ @Nullable final String paymentIdStr,
+ final List<String> pluginPropertiesString,
+ final String createdBy,
+ final String reason,
+ final String comment,
+ final UriInfo uriInfo,
+ final HttpServletRequest request) throws PaymentApiException, AccountApiException {
final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
final CallContext callContext = context.createContext(createdBy, reason, comment, request);
- final UUID paymentId = UUID.fromString(paymentIdStr);
- final Payment initialPayment = paymentApi.getPayment(paymentId, false, pluginProperties, callContext);
+ final Payment initialPayment = getPaymentByIdOrKey(paymentIdStr, json.getPaymentExternalKey(), pluginProperties, callContext);
final Account account = accountUserApi.getAccountById(initialPayment.getAccountId(), callContext);
final String transactionExternalKey = json != null ? json.getTransactionExternalKey() : null;
- final Payment payment = paymentApi.createVoid(account, paymentId, transactionExternalKey, pluginProperties, callContext);
+ final Payment payment = paymentApi.createVoid(account, initialPayment.getId(), transactionExternalKey, pluginProperties, callContext);
return uriBuilder.buildResponse(uriInfo, PaymentResource.class, "getPayment", payment.getId());
}
@@ -307,25 +421,190 @@ public class PaymentResource extends JaxRsResourceBase {
@HeaderParam(HDR_COMMENT) final String comment,
@javax.ws.rs.core.Context final UriInfo uriInfo,
@javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
+ return chargebackPaymentInternal(json, paymentIdStr, pluginPropertiesString, createdBy, reason, comment, uriInfo, request);
+ }
+
+ @Timed
+ @POST
+ @Path("/" + CHARGEBACKS)
+ @Consumes(APPLICATION_JSON)
+ @Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Record a chargeback")
+ @ApiResponses(value = {@ApiResponse(code = 404, message = "Account not found")})
+ public Response chargebackPaymentByExternalKey(final PaymentTransactionJson json,
+ @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment,
+ @javax.ws.rs.core.Context final UriInfo uriInfo,
+ @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
+ return chargebackPaymentInternal(json, null, pluginPropertiesString, createdBy, reason, comment, uriInfo, request);
+ }
+
+ private Response chargebackPaymentInternal(final PaymentTransactionJson json,
+ @Nullable final String paymentIdStr,
+ final List<String> pluginPropertiesString,
+ final String createdBy,
+ final String reason,
+ final String comment,
+ final UriInfo uriInfo,
+ final HttpServletRequest request) throws PaymentApiException, AccountApiException {
verifyNonNullOrEmpty(json, "PaymentTransactionJson body should be specified");
verifyNonNullOrEmpty(json.getAmount(), "PaymentTransactionJson amount needs to be set");
final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
final CallContext callContext = context.createContext(createdBy, reason, comment, request);
- final UUID paymentId = UUID.fromString(paymentIdStr);
- final Payment initialPayment = paymentApi.getPayment(paymentId, false, pluginProperties, callContext);
+ final Payment initialPayment = getPaymentByIdOrKey(paymentIdStr, json.getPaymentExternalKey(), pluginProperties, callContext);
final Account account = accountUserApi.getAccountById(initialPayment.getAccountId(), callContext);
final Currency currency = json.getCurrency() == null ? account.getCurrency() : Currency.valueOf(json.getCurrency());
- final Payment payment = paymentApi.createChargeback(account, paymentId, json.getAmount(), currency,
+ final Payment payment = paymentApi.createChargeback(account, initialPayment.getId(), json.getAmount(), currency,
json.getTransactionExternalKey(), callContext);
return uriBuilder.buildResponse(uriInfo, PaymentResource.class, "getPayment", payment.getId());
}
+ @Timed
+ @POST
+ @Consumes(APPLICATION_JSON)
+ @Produces(APPLICATION_JSON)
+ @Path("/" + COMBO)
+ @ApiOperation(value = "Combo api to create a new payment transaction on a existing (or not) account ")
+ @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid data for Account or PaymentMethod")})
+ public Response createComboPayment(final ComboPaymentTransactionJson json,
+ @QueryParam(QUERY_PAYMENT_CONTROL_PLUGIN_NAME) final List<String> paymentControlPluginNames,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment,
+ @javax.ws.rs.core.Context final UriInfo uriInfo,
+ @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
+
+ verifyNonNullOrEmpty(json, "ComboPaymentTransactionJson body should be specified");
+
+ final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+ final Account account = getOrCreateAccount(json.getAccount(), callContext);
+
+ final Iterable<PluginProperty> paymentMethodPluginProperties = json.getPaymentMethodPluginProperties() != null ?
+ Iterables.<PluginPropertyJson, PluginProperty>transform(json.getPaymentMethodPluginProperties(),
+ new Function<PluginPropertyJson, PluginProperty>() {
+ @Override
+ public PluginProperty apply(final PluginPropertyJson pluginPropertyJson) {
+ return pluginPropertyJson.toPluginProperty();
+ }
+ }
+ ) :
+ ImmutableList.<PluginProperty>of();
+
+ final UUID paymentMethodId = getOrCreatePaymentMethod(account, json.getPaymentMethod(), paymentMethodPluginProperties, callContext);
+
+ final PaymentTransactionJson paymentTransactionJson = json.getTransaction();
+ final TransactionType transactionType = TransactionType.valueOf(paymentTransactionJson.getTransactionType());
+ final PaymentOptions paymentOptions = createControlPluginApiPaymentOptions(paymentControlPluginNames);
+ final Payment result;
+
+ final Iterable<PluginProperty> transactionPluginProperties = json.getTransactionPluginProperties() != null ?
+ Iterables.<PluginPropertyJson, PluginProperty>transform(json.getTransactionPluginProperties(),
+ new Function<PluginPropertyJson, PluginProperty>() {
+ @Override
+ public PluginProperty apply(final PluginPropertyJson pluginPropertyJson) {
+ return pluginPropertyJson.toPluginProperty();
+ }
+ }
+ ) :
+ ImmutableList.<PluginProperty>of();
+
+ final Currency currency = paymentTransactionJson.getCurrency() == null ? account.getCurrency() : Currency.valueOf(paymentTransactionJson.getCurrency());
+ final UUID paymentId = null; // If we need to specify a paymentId (e.g 3DS authorization, we can use regular API, no need for combo call)
+ switch (transactionType) {
+ case AUTHORIZE:
+ result = paymentApi.createAuthorizationWithPaymentControl(account, paymentMethodId, paymentId, paymentTransactionJson.getAmount(), currency,
+ paymentTransactionJson.getPaymentExternalKey(), paymentTransactionJson.getTransactionExternalKey(),
+ transactionPluginProperties, paymentOptions, callContext);
+ break;
+ case PURCHASE:
+ result = paymentApi.createPurchaseWithPaymentControl(account, paymentMethodId, paymentId, paymentTransactionJson.getAmount(), currency,
+ paymentTransactionJson.getPaymentExternalKey(), paymentTransactionJson.getTransactionExternalKey(),
+ transactionPluginProperties, paymentOptions, callContext);
+ break;
+ case CREDIT:
+ result = paymentApi.createCreditWithPaymentControl(account, paymentMethodId, paymentId, paymentTransactionJson.getAmount(), currency,
+ paymentTransactionJson.getPaymentExternalKey(), paymentTransactionJson.getTransactionExternalKey(),
+ transactionPluginProperties, paymentOptions, callContext);
+ break;
+ default:
+ return Response.status(Status.PRECONDITION_FAILED).entity("TransactionType " + transactionType + " is not allowed for an account").build();
+ }
+ return uriBuilder.buildResponse(uriInfo, PaymentResource.class, "getPayment", result.getId());
+ }
+
@Override
protected ObjectType getObjectType() {
return ObjectType.PAYMENT;
}
+ private Account getOrCreateAccount(final AccountJson accountJson, final CallContext callContext) throws AccountApiException {
+ // Attempt to retrieve by accountId if specified
+ if (accountJson.getAccountId() != null) {
+ return accountUserApi.getAccountById(UUID.fromString(accountJson.getAccountId()), callContext);
+ }
+
+ if (accountJson.getExternalKey() != null) {
+ // Attempt to retrieve by account externalKey, ignore if does not exist so we can create it with the key specified.
+ try {
+ return accountUserApi.getAccountByKey(accountJson.getExternalKey(), callContext);
+ } catch (final AccountApiException ignore) {}
+ }
+ // Finally create if does not exist
+ return accountUserApi.createAccount(accountJson.toAccountData(), callContext);
+ }
+
+ private UUID getOrCreatePaymentMethod(final Account account, final PaymentMethodJson paymentMethodJson, final Iterable<PluginProperty> pluginProperties, final CallContext callContext) throws PaymentApiException {
+
+ // Get all payment methods for account
+ final List<PaymentMethod> accountPaymentMethods = paymentApi.getAccountPaymentMethods(account.getId(), false, ImmutableList.<PluginProperty>of(), callContext);
+
+ // If we were specified a paymentMethod id and we find it, we return it
+ if (paymentMethodJson.getPaymentMethodId() != null) {
+ final UUID match = UUID.fromString(paymentMethodJson.getPaymentMethodId());
+ if (Iterables.any(accountPaymentMethods, new Predicate<PaymentMethod>() {
+ @Override
+ public boolean apply(final PaymentMethod input) {
+ return input.getId().equals(match);
+ }
+ })) {
+ return match;
+ }
+ }
+
+ // If we were specified a paymentMethod externalKey and we find it, we return it
+ if (paymentMethodJson.getExternalKey() != null) {
+ final PaymentMethod match = Iterables.tryFind(accountPaymentMethods, new Predicate<PaymentMethod>() {
+ @Override
+ public boolean apply(final PaymentMethod input) {
+ return input.getExternalKey().equals(paymentMethodJson.getExternalKey());
+ }
+ }).orNull();
+ if (match != null) {
+ return match.getId();
+ }
+ }
+
+ // Only set as default if this is the first paymentMethod on the account
+ final boolean isDefault = accountPaymentMethods.isEmpty();
+ final PaymentMethod paymentData = paymentMethodJson.toPaymentMethod(account.getId().toString());
+ return paymentApi.addPaymentMethod(account, paymentMethodJson.getExternalKey(), paymentMethodJson.getPluginName(), isDefault,
+ paymentData.getPluginDetail(), pluginProperties, callContext);
+ }
+
+ private Payment getPaymentByIdOrKey(@Nullable final String paymentIdStr, @Nullable final String externalKey, final Iterable<PluginProperty> pluginProperties, final TenantContext tenantContext) throws PaymentApiException {
+
+ Preconditions.checkArgument(paymentIdStr != null || externalKey != null, "Need to set either paymentId or payment externalKey");
+ if (paymentIdStr != null) {
+ final UUID paymentId = UUID.fromString(paymentIdStr);
+ return paymentApi.getPayment(paymentId, false, pluginProperties, tenantContext);
+ } else {
+ return paymentApi.getPaymentByExternalKey(externalKey, false, pluginProperties, tenantContext);
+ }
+ }
+
}
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/janitor/IncompletePaymentTransactionTask.java b/payment/src/main/java/org/killbill/billing/payment/core/janitor/IncompletePaymentTransactionTask.java
index 1547008..cdc58a7 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/janitor/IncompletePaymentTransactionTask.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/janitor/IncompletePaymentTransactionTask.java
@@ -233,7 +233,7 @@ public class IncompletePaymentTransactionTask extends CompletionTaskBase<Payment
private PaymentPluginApi getPaymentPluginApi(final PaymentModelDao item, final String pluginName) {
final PaymentPluginApi pluginApi = pluginRegistry.getServiceForName(pluginName);
- Preconditions.checkState(pluginApi != null, "Janitor IncompletePaymentTransactionTask cannot retrieve PaymentPluginApi " + item.getId() + ", skipping");
+ Preconditions.checkState(pluginApi != null, "Janitor IncompletePaymentTransactionTask cannot retrieve PaymentPluginApi for plugin %s (payment id %s), skipping", pluginName, item.getId());
return pluginApi;
}
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/control/OperationControlCallback.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/control/OperationControlCallback.java
index 34e2fd8..d5855d0 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/control/OperationControlCallback.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/control/OperationControlCallback.java
@@ -56,6 +56,8 @@ import org.killbill.commons.locker.LockFailedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.MoreObjects;
+
public abstract class OperationControlCallback extends OperationCallbackBase<Payment, PaymentApiException> implements OperationCallback {
protected final PaymentProcessor paymentProcessor;
@@ -151,30 +153,26 @@ public abstract class OperationControlCallback extends OperationCallbackBase<Pay
}
@Override
- protected OperationException rewrapExecutionException(final PaymentStateContext paymentStateContext, final ExecutionException e) {
- if (e.getCause() instanceof OperationException) {
- return (OperationException) e.getCause();
- } else if (e.getCause() instanceof LockFailedException) {
+ protected OperationException unwrapExceptionFromDispatchedTask(final PaymentStateContext paymentStateContext, final Exception e) {
+
+ // If this is an ExecutionException we attempt to extract the cause first
+ final Throwable originalExceptionOrCause = e instanceof ExecutionException ? MoreObjects.firstNonNull(e.getCause(), e) : e;
+
+ if (originalExceptionOrCause instanceof OperationException) {
+ return (OperationException) originalExceptionOrCause;
+ } else if (originalExceptionOrCause instanceof LockFailedException) {
final String format = String.format("Failed to lock account %s", paymentStateContext.getAccount().getExternalKey());
logger.error(String.format(format));
- return new OperationException(e, getOperationResultOnException(paymentStateContext));
+ } else if (originalExceptionOrCause instanceof TimeoutException) {
+ logger.warn("RetryOperationCallback call TIMEOUT for account {}", paymentStateContext.getAccount().getExternalKey());
+ } else if (originalExceptionOrCause instanceof InterruptedException) {
+ logger.error("RetryOperationCallback call was interrupted for account {}", paymentStateContext.getAccount().getExternalKey());
} else /* most probably RuntimeException */ {
logger.warn("RetryOperationCallback failed for account {}", paymentStateContext.getAccount().getExternalKey(), e);
- return new OperationException(e, getOperationResultOnException(paymentStateContext));
}
- }
-
- @Override
- protected OperationException wrapTimeoutException(final PaymentStateContext paymentStateContext, final TimeoutException e) {
- logger.warn("RetryOperationCallback call TIMEOUT for account {}", paymentStateContext.getAccount().getExternalKey());
return new OperationException(e, getOperationResultOnException(paymentStateContext));
}
- @Override
- protected OperationException wrapInterruptedException(final PaymentStateContext paymentStateContext, final InterruptedException e) {
- logger.error("RetryOperationCallback call was interrupted for account {}", paymentStateContext.getAccount().getExternalKey());
- return new OperationException(e, getOperationResultOnException(paymentStateContext));
- }
protected void executePluginOnSuccessCalls(final List<String> paymentControlPluginNames, final PaymentRoutingContext paymentControlContext) {
for (final String pluginName : paymentControlPluginNames) {
@@ -253,10 +251,8 @@ public abstract class OperationControlCallback extends OperationCallbackBase<Pay
final DateTime retryDate = executePluginOnFailureCalls(paymentStateControlContext.getPaymentControlPluginNames(), paymentControlContext);
if (retryDate != null) {
((PaymentStateControlContext) paymentStateContext).setRetryDate(retryDate);
- return OperationResult.FAILURE;
- } else {
- return OperationResult.EXCEPTION;
}
+ return getOperationResultOnException(paymentStateContext);
}
private DateTime executePluginOnFailureCalls(final List<String> paymentControlPluginNames, final PaymentRoutingContext paymentControlContext) {
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/OperationCallbackBase.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/OperationCallbackBase.java
index 6a81f1d..8ab58ff 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/OperationCallbackBase.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/OperationCallbackBase.java
@@ -66,12 +66,12 @@ public abstract class OperationCallbackBase<CallbackOperationResult, CallbackOpe
logger.debug("Successful plugin call for account {} with result {}", account.getExternalKey(), operationResult);
return operationResult;
} catch (final ExecutionException e) {
- throw rewrapExecutionException(paymentStateContext, e);
+ throw unwrapExceptionFromDispatchedTask(paymentStateContext, e);
} catch (final TimeoutException e) {
- throw wrapTimeoutException(paymentStateContext, e);
+ throw unwrapExceptionFromDispatchedTask(paymentStateContext, e);
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
- throw wrapInterruptedException(paymentStateContext, e);
+ throw unwrapExceptionFromDispatchedTask(paymentStateContext, e);
}
}
@@ -83,12 +83,5 @@ public abstract class OperationCallbackBase<CallbackOperationResult, CallbackOpe
//
protected abstract CallbackOperationResult doCallSpecificOperationCallback() throws CallbackOperationException;
- //
- // The methods below allow to convert the exceptions thrown back by the Executor into an appropriate OperationException
- //
- protected abstract OperationException rewrapExecutionException(final PaymentStateContext paymentStateContext, final ExecutionException e);
-
- protected abstract OperationException wrapTimeoutException(final PaymentStateContext paymentStateContext, final TimeoutException e);
-
- protected abstract OperationException wrapInterruptedException(final PaymentStateContext paymentStateContext, final InterruptedException e);
+ protected abstract OperationException unwrapExceptionFromDispatchedTask(final PaymentStateContext paymentStateContext, final Exception e);
}
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/sm/payments/PaymentOperation.java b/payment/src/main/java/org/killbill/billing/payment/core/sm/payments/PaymentOperation.java
index 6d57033..ba6e48d 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/sm/payments/PaymentOperation.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/sm/payments/PaymentOperation.java
@@ -85,24 +85,26 @@ public abstract class PaymentOperation extends OperationCallbackBase<PaymentTran
}
@Override
- protected OperationException rewrapExecutionException(final PaymentStateContext paymentStateContext, final ExecutionException e) {
+ protected OperationException unwrapExceptionFromDispatchedTask(final PaymentStateContext paymentStateContext, final Exception e) {
+
+ // If this is an ExecutionException we attempt to extract the cause first
+ final Throwable originalExceptionOrCause = e instanceof ExecutionException ? MoreObjects.firstNonNull(e.getCause(), e) : e;
+
//
// Any case of exception (checked or runtime) should lead to a TransactionStatus.UNKNOWN (and a XXX_ERRORED payment state).
// In order to reach that state we create PaymentTransactionInfoPlugin with an PaymentPluginStatus.UNDEFINED status (and an OperationResult.EXCEPTION).
//
- final Throwable originalExceptionOrCause = MoreObjects.firstNonNull(e.getCause(), e);
if (originalExceptionOrCause instanceof LockFailedException) {
logger.warn("Failed to lock account {}", paymentStateContext.getAccount().getExternalKey());
+ } else if (originalExceptionOrCause instanceof TimeoutException) {
+ logger.error("Plugin call TIMEOUT for account {}", paymentStateContext.getAccount().getExternalKey());
+ } else if (originalExceptionOrCause instanceof InterruptedException) {
+ logger.error("Plugin call was interrupted for account {}", paymentStateContext.getAccount().getExternalKey());
} else {
logger.warn("Payment plugin call threw an exception for account {}", paymentStateContext.getAccount().getExternalKey(), originalExceptionOrCause);
}
return convertToUnknownTransactionStatusAndErroredPaymentState(originalExceptionOrCause);
- }
- @Override
- protected OperationException wrapTimeoutException(final PaymentStateContext paymentStateContext, final TimeoutException e) {
- logger.error("Plugin call TIMEOUT for account {}", paymentStateContext.getAccount().getExternalKey());
- return convertToUnknownTransactionStatusAndErroredPaymentState(e);
}
//
@@ -122,16 +124,10 @@ public abstract class PaymentOperation extends OperationCallbackBase<PaymentTran
paymentStateContext.getCallContext().getCreatedDate(),
PaymentPluginStatus.UNDEFINED,
null);
-
paymentStateContext.setPaymentTransactionInfoPlugin(paymentInfoPlugin);
return new OperationException(e, OperationResult.EXCEPTION);
}
- @Override
- protected OperationException wrapInterruptedException(final PaymentStateContext paymentStateContext, final InterruptedException e) {
- logger.error("Plugin call was interrupted for account {}", paymentStateContext.getAccount().getExternalKey());
- return new OperationException(e, OperationResult.EXCEPTION);
- }
@Override
protected abstract PaymentTransactionInfoPlugin doCallSpecificOperationCallback() throws PaymentPluginApiException;
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPayment.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPayment.java
index 1c11ac8..3aab61a 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPayment.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPayment.java
@@ -24,16 +24,20 @@ import javax.annotation.Nullable;
import org.killbill.billing.client.KillBillClientException;
import org.killbill.billing.client.model.Account;
-import org.killbill.billing.client.model.InvoicePayments;
+import org.killbill.billing.client.model.ComboPaymentTransaction;
import org.killbill.billing.client.model.Payment;
import org.killbill.billing.client.model.PaymentMethod;
import org.killbill.billing.client.model.PaymentMethodPluginDetail;
-import org.killbill.billing.client.model.Payments;
import org.killbill.billing.client.model.PaymentTransaction;
+import org.killbill.billing.client.model.Payments;
+import org.killbill.billing.client.model.PluginProperty;
+import org.killbill.billing.jaxrs.json.PluginPropertyJson;
import org.testng.Assert;
import org.testng.annotations.Test;
import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
public class TestPayment extends TestJaxrsBase {
@@ -47,7 +51,44 @@ public class TestPayment extends TestJaxrsBase {
testCreateRetrievePayment(account, nonDefaultPaymentMethod.getPaymentMethodId(), UUID.randomUUID().toString(), 2);
}
- public void testCreateRetrievePayment(final Account account, @Nullable final UUID paymentMethodId,
+ @Test(groups = "slow")
+ public void testComboAuthorization() throws Exception {
+ final Account accountJson = getAccount();
+ accountJson.setAccountId(null);
+
+ final PaymentMethodPluginDetail info = new PaymentMethodPluginDetail();
+ info.setProperties(null);
+
+ final String paymentMethodExternalKey = UUID.randomUUID().toString();
+ final PaymentMethod paymentMethodJson = new PaymentMethod(null, paymentMethodExternalKey, null, true, PLUGIN_NAME, info);
+
+ final String paymentExternalKey = UUID.randomUUID().toString();
+ final String authTransactionExternalKey = UUID.randomUUID().toString();
+ final PaymentTransaction authTransactionJson = new PaymentTransaction();
+ authTransactionJson.setAmount(BigDecimal.TEN);
+ authTransactionJson.setCurrency(accountJson.getCurrency());
+ authTransactionJson.setPaymentExternalKey(paymentExternalKey);
+ authTransactionJson.setTransactionExternalKey(authTransactionExternalKey);
+ authTransactionJson.setTransactionType("AUTHORIZE");
+
+ final ComboPaymentTransaction comboPaymentTransaction = new ComboPaymentTransaction(accountJson, paymentMethodJson, authTransactionJson, ImmutableList.<PluginProperty>of(), ImmutableList.<PluginProperty>of());
+
+ final Payment payment = killBillClient.createPayment(comboPaymentTransaction, ImmutableMap.<String, String>of(), createdBy, reason, comment);
+ verifyComboPayment(payment, paymentExternalKey,
+ BigDecimal.TEN, BigDecimal.ZERO, BigDecimal.ZERO, 1, 1);
+
+
+ // Void payment using externalKey
+ final String voidTransactionExternalKey = UUID.randomUUID().toString();
+ final Payment voidPayment = killBillClient.voidPayment(null, paymentExternalKey, voidTransactionExternalKey, ImmutableMap.<String, String>of(), createdBy, reason, comment);
+ verifyPaymentTransaction(voidPayment.getPaymentId(), voidPayment.getTransactions().get(1),
+ paymentExternalKey, voidTransactionExternalKey,
+ accountJson, null, "VOID");
+
+
+ }
+
+ private void testCreateRetrievePayment(final Account account, @Nullable final UUID paymentMethodId,
final String PaymentExternalKey, final int PaymentNb) throws Exception {
// Authorization
final String authTransactionExternalKey = UUID.randomUUID().toString();
@@ -59,7 +100,7 @@ public class TestPayment extends TestJaxrsBase {
authTransaction.setTransactionType("AUTHORIZE");
final Payment authPayment = killBillClient.createPayment(account.getAccountId(), paymentMethodId, authTransaction, createdBy, reason, comment);
verifyPayment(account, paymentMethodId, authPayment, PaymentExternalKey, authTransactionExternalKey,
- BigDecimal.TEN, BigDecimal.ZERO, BigDecimal.ZERO, 1, PaymentNb);
+ BigDecimal.TEN, BigDecimal.ZERO, BigDecimal.ZERO, 1, PaymentNb);
// Capture 1
final String capture1TransactionExternalKey = UUID.randomUUID().toString();
@@ -69,22 +110,25 @@ public class TestPayment extends TestJaxrsBase {
captureTransaction.setCurrency(account.getCurrency());
captureTransaction.setPaymentExternalKey(PaymentExternalKey);
captureTransaction.setTransactionExternalKey(capture1TransactionExternalKey);
+ // captureAuthorization is using paymentId
final Payment capturedPayment1 = killBillClient.captureAuthorization(captureTransaction, createdBy, reason, comment);
verifyPayment(account, paymentMethodId, capturedPayment1, PaymentExternalKey, authTransactionExternalKey,
- BigDecimal.TEN, BigDecimal.ONE, BigDecimal.ZERO, 2, PaymentNb);
+ BigDecimal.TEN, BigDecimal.ONE, BigDecimal.ZERO, 2, PaymentNb);
verifyPaymentTransaction(authPayment.getPaymentId(), capturedPayment1.getTransactions().get(1),
- PaymentExternalKey, capture1TransactionExternalKey,
- account, captureTransaction.getAmount(), "CAPTURE");
+ PaymentExternalKey, capture1TransactionExternalKey,
+ account, captureTransaction.getAmount(), "CAPTURE");
// Capture 2
final String capture2TransactionExternalKey = UUID.randomUUID().toString();
captureTransaction.setTransactionExternalKey(capture2TransactionExternalKey);
+ // captureAuthorization is using externalKey
+ captureTransaction.setPaymentId(null);
final Payment capturedPayment2 = killBillClient.captureAuthorization(captureTransaction, createdBy, reason, comment);
verifyPayment(account, paymentMethodId, capturedPayment2, PaymentExternalKey, authTransactionExternalKey,
- BigDecimal.TEN, new BigDecimal("2"), BigDecimal.ZERO, 3, PaymentNb);
+ BigDecimal.TEN, new BigDecimal("2"), BigDecimal.ZERO, 3, PaymentNb);
verifyPaymentTransaction(authPayment.getPaymentId(), capturedPayment2.getTransactions().get(2),
- PaymentExternalKey, capture2TransactionExternalKey,
- account, captureTransaction.getAmount(), "CAPTURE");
+ PaymentExternalKey, capture2TransactionExternalKey,
+ account, captureTransaction.getAmount(), "CAPTURE");
// Refund
final String refundTransactionExternalKey = UUID.randomUUID().toString();
@@ -96,16 +140,16 @@ public class TestPayment extends TestJaxrsBase {
refundTransaction.setTransactionExternalKey(refundTransactionExternalKey);
final Payment refundPayment = killBillClient.refundPayment(refundTransaction, createdBy, reason, comment);
verifyPayment(account, paymentMethodId, refundPayment, PaymentExternalKey, authTransactionExternalKey,
- BigDecimal.TEN, new BigDecimal("2"), new BigDecimal("2"), 4, PaymentNb);
+ BigDecimal.TEN, new BigDecimal("2"), new BigDecimal("2"), 4, PaymentNb);
verifyPaymentTransaction(authPayment.getPaymentId(), refundPayment.getTransactions().get(3),
- PaymentExternalKey, refundTransactionExternalKey,
- account, refundTransaction.getAmount(), "REFUND");
+ PaymentExternalKey, refundTransactionExternalKey,
+ account, refundTransaction.getAmount(), "REFUND");
}
private void verifyPayment(final Account account, @Nullable final UUID paymentMethodId, final Payment Payment,
- final String PaymentExternalKey, final String authTransactionExternalKey,
- final BigDecimal authAmount, final BigDecimal capturedAmount,
- final BigDecimal refundedAmount, final int nbTransactions, final int PaymentNb) throws KillBillClientException {
+ final String PaymentExternalKey, final String authTransactionExternalKey,
+ final BigDecimal authAmount, final BigDecimal capturedAmount,
+ final BigDecimal refundedAmount, final int nbTransactions, final int PaymentNb) throws KillBillClientException {
Assert.assertEquals(Payment.getAccountId(), account.getAccountId());
Assert.assertEquals(Payment.getPaymentMethodId(), Objects.firstNonNull(paymentMethodId, account.getPaymentMethodId()));
Assert.assertNotNull(Payment.getPaymentId());
@@ -118,7 +162,7 @@ public class TestPayment extends TestJaxrsBase {
Assert.assertEquals(Payment.getTransactions().size(), nbTransactions);
verifyPaymentTransaction(Payment.getPaymentId(), Payment.getTransactions().get(0),
- PaymentExternalKey, authTransactionExternalKey, account, authAmount, "AUTHORIZE");
+ PaymentExternalKey, authTransactionExternalKey, account, authAmount, "AUTHORIZE");
final Payments Payments = killBillClient.getPayments();
Assert.assertEquals(Payments.size(), PaymentNb);
@@ -132,9 +176,30 @@ public class TestPayment extends TestJaxrsBase {
Assert.assertEquals(paymentsForAccount.get(PaymentNb - 1), Payment);
}
+ private void verifyComboPayment(final Payment payment,
+ final String paymentExternalKey,
+ final BigDecimal authAmount,
+ final BigDecimal capturedAmount,
+ final BigDecimal refundedAmount,
+ final int nbTransactions,
+ final int PaymentNb) throws KillBillClientException {
+
+ Assert.assertNotNull(payment.getPaymentNumber());
+ Assert.assertEquals(payment.getPaymentExternalKey(), paymentExternalKey);
+ Assert.assertEquals(payment.getAuthAmount().compareTo(authAmount), 0);
+ Assert.assertEquals(payment.getCapturedAmount().compareTo(capturedAmount), 0);
+ Assert.assertEquals(payment.getRefundedAmount().compareTo(refundedAmount), 0);
+ Assert.assertEquals(payment.getTransactions().size(), nbTransactions);
+
+ final Payments Payments = killBillClient.getPayments();
+ Assert.assertEquals(Payments.size(), PaymentNb);
+ Assert.assertEquals(Payments.get(PaymentNb - 1), payment);
+
+ }
+
private void verifyPaymentTransaction(final UUID PaymentId, final PaymentTransaction PaymentTransaction,
- final String PaymentExternalKey, final String TransactionExternalKey,
- final Account account, @Nullable final BigDecimal amount, final String transactionType) {
+ final String PaymentExternalKey, final String TransactionExternalKey,
+ final Account account, @Nullable final BigDecimal amount, final String transactionType) {
Assert.assertEquals(PaymentTransaction.getPaymentId(), PaymentId);
Assert.assertNotNull(PaymentTransaction.getTransactionId());
Assert.assertEquals(PaymentTransaction.getTransactionType(), transactionType);