killbill-memoizeit
Changes
osgi-bundles/bundles/jruby/src/main/java/org/killbill/billing/osgi/bundles/jruby/JRubyPaymentPlugin.java 29(+29 -0)
osgi-bundles/bundles/logger/pom.xml 2(+1 -1)
osgi-bundles/tests/beatrix/src/test/java/org/killbill/billing/osgi/bundles/test/TestPaymentPluginApi.java 28(+28 -0)
osgi-bundles/tests/payment/src/test/java/org/killbill/billing/osgi/bundles/test/TestPaymentPluginApi.java 88(+37 -51)
payment/src/main/java/org/killbill/billing/payment/api/DefaultDirectPaymentTransaction.java 100(+100 -0)
payment/src/main/java/org/killbill/billing/payment/dao/DirectPaymentTransactionModelDao.java 209(+209 -0)
payment/src/main/java/org/killbill/billing/payment/provider/DefaultNoOpPaymentProviderPlugin.java 50(+43 -7)
payment/src/main/java/org/killbill/billing/payment/provider/ExternalPaymentProviderPlugin.java 28(+28 -0)
payment/src/main/resources/org/killbill/billing/payment/dao/DirectTransactionSqlDao.sql.stg 55(+55 -0)
payment/src/test/java/org/killbill/billing/payment/provider/MockPaymentProviderPlugin.java 51(+43 -8)
pom.xml 2(+1 -1)
Details
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/DirectPaymentJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/DirectPaymentJson.java
new file mode 100644
index 0000000..40485d6
--- /dev/null
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/DirectPaymentJson.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ *
+ * Groupon 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.math.BigDecimal;
+import java.util.List;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+import org.killbill.billing.payment.api.DirectPayment;
+import org.killbill.billing.payment.api.DirectPaymentTransaction;
+import org.killbill.billing.payment.api.TransactionType;
+import org.killbill.billing.util.audit.AuditLog;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+public class DirectPaymentJson extends JsonBase {
+
+ private final String accountId;
+ private final String directPaymentId;
+ private final String paymentNumber;
+ private final BigDecimal authAmount;
+ private final BigDecimal capturedAmount;
+ private final BigDecimal refundedAmount;
+ private final String currency;
+ private final String paymentMethodId;
+ private final List<DirectTransactionJson> transactions;
+
+ @JsonCreator
+ public DirectPaymentJson(@JsonProperty("accountId") final String accountId,
+ @JsonProperty("directPaymentId") final String directPaymentId,
+ @JsonProperty("paymentNumber") final String paymentNumber,
+ @JsonProperty("authAmount") final BigDecimal authAmount,
+ @JsonProperty("capturedAmount") final BigDecimal capturedAmount,
+ @JsonProperty("refundedAmount") final BigDecimal refundedAmount,
+ @JsonProperty("currency") final String currency,
+ @JsonProperty("paymentMethodId") final String paymentMethodId,
+ @JsonProperty("transactions") final List<DirectTransactionJson> transactions,
+ @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
+ super(auditLogs);
+ this.accountId = accountId;
+ this.directPaymentId = directPaymentId;
+ this.paymentNumber = paymentNumber;
+ this.authAmount = authAmount;
+ this.capturedAmount = capturedAmount;
+ this.refundedAmount = refundedAmount;
+ this.currency = currency;
+ this.paymentMethodId = paymentMethodId;
+ this.transactions = transactions;
+ }
+
+ public DirectPaymentJson(final DirectPayment dp, @Nullable final List<AuditLog> directPaymentLogs, @Nullable final List<AuditLog> directTransactionLogs) {
+ this(dp.getAccountId().toString(),
+ dp.getId().toString(),
+ dp.getPaymentNumber().toString(),
+ dp.getAuthAmount(),
+ dp.getCapturedAmount(),
+ dp.getRefundedAmount(),
+ dp.getCurrency() != null ? dp.getCurrency().toString() : null,
+ dp.getPaymentMethodId() != null ? dp.getPaymentMethodId().toString() : null,
+ getTransactions(dp.getTransactions(), dp.getId(), dp.getExternalKey(), directTransactionLogs),
+ toAuditLogJson(directPaymentLogs));
+ }
+
+
+ private static List<DirectTransactionJson> getTransactions(final List<DirectPaymentTransaction> transactions, final UUID directPaymentId, final String externalKey, @Nullable final List<AuditLog> directTransactionLogs) {
+ return ImmutableList.copyOf(Iterables.transform(transactions, new Function<DirectPaymentTransaction, DirectTransactionJson>() {
+ @Override
+ public DirectTransactionJson apply(final DirectPaymentTransaction input) {
+ return new DirectTransactionJson(input,directPaymentId, externalKey, directTransactionLogs);
+ }
+ }));
+ }
+
+ public String getAccountId() {
+ return accountId;
+ }
+
+ public String getDirectPaymentId() {
+ return directPaymentId;
+ }
+
+ public String getPaymentNumber() {
+ return paymentNumber;
+ }
+
+ public BigDecimal getAuthAmount() {
+ return authAmount;
+ }
+
+ public BigDecimal getCapturedAmount() {
+ return capturedAmount;
+ }
+
+ public BigDecimal getRefundedAmount() {
+ return refundedAmount;
+ }
+
+ public String getCurrency() {
+ return currency;
+ }
+
+ public String getPaymentMethodId() {
+ return paymentMethodId;
+ }
+
+ public List<DirectTransactionJson> getTransactions() {
+ return transactions;
+ }
+
+ @Override
+ public String toString() {
+ return "DirectPaymentJson{" +
+ "accountId='" + accountId + '\'' +
+ ", directPaymentId='" + directPaymentId + '\'' +
+ ", paymentNumber='" + paymentNumber + '\'' +
+ ", authAmount=" + authAmount +
+ ", capturedAmount=" + capturedAmount +
+ ", refundedAmount=" + refundedAmount +
+ ", currency='" + currency + '\'' +
+ ", paymentMethodId='" + paymentMethodId + '\'' +
+ ", transactions=" + transactions +
+ '}';
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof DirectPaymentJson)) {
+ return false;
+ }
+
+ final DirectPaymentJson that = (DirectPaymentJson) o;
+
+ if (accountId != null ? !accountId.equals(that.accountId) : that.accountId != null) {
+ return false;
+ }
+ if (authAmount != null ? authAmount.compareTo(that.authAmount) != 0 : that.authAmount != null) {
+ return false;
+ }
+ if (capturedAmount != null ? capturedAmount.compareTo(that.capturedAmount) != 0 : that.capturedAmount != null) {
+ return false;
+ }
+ if (currency != null ? !currency.equals(that.currency) : that.currency != null) {
+ return false;
+ }
+ if (directPaymentId != null ? !directPaymentId.equals(that.directPaymentId) : that.directPaymentId != null) {
+ return false;
+ }
+ if (paymentMethodId != null ? !paymentMethodId.equals(that.paymentMethodId) : that.paymentMethodId != null) {
+ return false;
+ }
+ if (paymentNumber != null ? !paymentNumber.equals(that.paymentNumber) : that.paymentNumber != null) {
+ return false;
+ }
+ if (refundedAmount != null ? refundedAmount.compareTo(that.refundedAmount) != 0 : that.refundedAmount != null) {
+ return false;
+ }
+ if (transactions != null ? !transactions.equals(that.transactions) : that.transactions != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = accountId != null ? accountId.hashCode() : 0;
+ result = 31 * result + (directPaymentId != null ? directPaymentId.hashCode() : 0);
+ result = 31 * result + (paymentNumber != null ? paymentNumber.hashCode() : 0);
+ result = 31 * result + (authAmount != null ? authAmount.hashCode() : 0);
+ result = 31 * result + (capturedAmount != null ? capturedAmount.hashCode() : 0);
+ result = 31 * result + (refundedAmount != null ? refundedAmount.hashCode() : 0);
+ result = 31 * result + (currency != null ? currency.hashCode() : 0);
+ result = 31 * result + (paymentMethodId != null ? paymentMethodId.hashCode() : 0);
+ result = 31 * result + (transactions != null ? transactions.hashCode() : 0);
+ return result;
+ }
+}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/DirectTransactionJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/DirectTransactionJson.java
new file mode 100644
index 0000000..29df0bf
--- /dev/null
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/DirectTransactionJson.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ *
+ * Groupon 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.math.BigDecimal;
+import java.util.List;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+import org.joda.time.DateTime;
+import org.killbill.billing.payment.api.DirectPaymentTransaction;
+import org.killbill.billing.util.audit.AuditLog;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class DirectTransactionJson extends JsonBase {
+
+ private final String directTransactionId;
+ private final String directPaymentId;
+ private final String transactionType;
+ private final DateTime effectiveDate;
+ private final Integer retryCount;
+ private final String status;
+ private final BigDecimal amount;
+ private final String currency;
+ private final String externalKey;
+ private final String gatewayErrorCode;
+ private final String gatewayErrorMsg;
+
+ @JsonCreator
+ public DirectTransactionJson(@JsonProperty("directTransactionId") final String directTransactionId,
+ @JsonProperty("directPaymentId") final String directPaymentId,
+ @JsonProperty("transactionType") final String transactionType,
+ @JsonProperty("amount") final BigDecimal amount,
+ @JsonProperty("currency") final String currency,
+ @JsonProperty("effectiveDate") final DateTime effectiveDate,
+ @JsonProperty("status") final String status,
+ @JsonProperty("retryCount") final Integer retryCount,
+ @JsonProperty("externalKey") final String externalKey,
+ @JsonProperty("gatewayErrorCode") final String gatewayErrorCode,
+ @JsonProperty("gatewayErrorMsg") final String gatewayErrorMsg,
+ @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
+ super(auditLogs);
+ this.directTransactionId = directTransactionId;
+ this.directPaymentId = directPaymentId;
+ this.transactionType = transactionType;
+ this.effectiveDate = effectiveDate;
+ this.retryCount = retryCount;
+ this.externalKey = externalKey;
+ this.status = status;
+ this.amount = amount;
+ this.currency = currency;
+ this.gatewayErrorCode = gatewayErrorCode;
+ this.gatewayErrorMsg = gatewayErrorMsg;
+ }
+
+ public DirectTransactionJson(final DirectPaymentTransaction dpt, final UUID directPaymentId, final String externalKey, @Nullable final List<AuditLog> directTransactionLogs) {
+ this(dpt.getId().toString(),
+ directPaymentId.toString(),
+ dpt.getTransactionType().toString(),
+ dpt.getAmount(),
+ dpt.getCurrency().toString(),
+ dpt.getEffectiveDate(),
+ dpt.getPaymentStatus().toString(),
+ 1,
+ externalKey,
+ dpt.getGatewayErrorCode(),
+ dpt.getGatewayErrorMsg(),
+ toAuditLogJson(directTransactionLogs));
+ }
+
+ public String getDirectTransactionId() {
+ return directTransactionId;
+ }
+
+ public String getDirectPaymentId() {
+ return directPaymentId;
+ }
+
+ public String getTransactionType() {
+ return transactionType;
+ }
+
+ public DateTime getEffectiveDate() {
+ return effectiveDate;
+ }
+
+ public Integer getRetryCount() {
+ return retryCount;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public BigDecimal getAmount() {
+ return amount;
+ }
+
+ public String getCurrency() {
+ return currency;
+ }
+
+ public String getGatewayErrorCode() {
+ return gatewayErrorCode;
+ }
+
+ public String getGatewayErrorMsg() {
+ return gatewayErrorMsg;
+ }
+
+ public String getExternalKey() {
+ return externalKey;
+ }
+
+ @Override
+ public String toString() {
+ return "DirectTransactionJson{" +
+ "directPaymentId=" + directPaymentId +
+ "directTransactionId=" + directTransactionId +
+ "transactionType=" + transactionType +
+ ", effectiveDate=" + effectiveDate +
+ ", retryCount=" + retryCount +
+ ", status='" + status + '\'' +
+ ", externalKey='" + externalKey + '\'' +
+ ", amount=" + amount +
+ ", currency='" + currency + '\'' +
+ ", gatewayErrorCode='" + gatewayErrorCode + '\'' +
+ ", gatewayErrorMsg='" + gatewayErrorMsg + '\'' +
+ '}';
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof DirectTransactionJson)) {
+ return false;
+ }
+
+ final DirectTransactionJson that = (DirectTransactionJson) o;
+
+ if (directPaymentId != null ? !directPaymentId.equals(that.directPaymentId) : that.directPaymentId != null) {
+ return false;
+ }
+ if (directTransactionId != null ? !directTransactionId.equals(that.directTransactionId) : that.directTransactionId != null) {
+ return false;
+ }
+ if (amount != null ? amount.compareTo(that.amount) != 0 : that.amount != null) {
+ return false;
+ }
+ if (currency != null ? !currency.equals(that.currency) : that.currency != null) {
+ return false;
+ }
+ if (effectiveDate != null ? effectiveDate.compareTo(that.effectiveDate) != 0 : that.effectiveDate != null) {
+ return false;
+ }
+ if (gatewayErrorCode != null ? !gatewayErrorCode.equals(that.gatewayErrorCode) : that.gatewayErrorCode != null) {
+ return false;
+ }
+ if (gatewayErrorMsg != null ? !gatewayErrorMsg.equals(that.gatewayErrorMsg) : that.gatewayErrorMsg != null) {
+ return false;
+ }
+ if (retryCount != null ? !retryCount.equals(that.retryCount) : that.retryCount != null) {
+ return false;
+ }
+ if (externalKey != null ? !externalKey.equals(that.externalKey) : that.externalKey != null) {
+ return false;
+ }
+ if (status != null ? !status.equals(that.status) : that.status != null) {
+ return false;
+ }
+ if (transactionType.equals(that.transactionType)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = transactionType != null ? transactionType.hashCode() : 0;
+ result = 31 * result + (directPaymentId != null ? directPaymentId.hashCode() : 0);
+ result = 31 * result + (directTransactionId != null ? directTransactionId.hashCode() : 0);
+ result = 31 * result + (effectiveDate != null ? effectiveDate.hashCode() : 0);
+ result = 31 * result + (retryCount != null ? retryCount.hashCode() : 0);
+ result = 31 * result + (status != null ? status.hashCode() : 0);
+ result = 31 * result + (externalKey != null ? externalKey.hashCode() : 0);
+ result = 31 * result + (amount != null ? amount.hashCode() : 0);
+ result = 31 * result + (currency != null ? currency.hashCode() : 0);
+ result = 31 * result + (gatewayErrorCode != null ? gatewayErrorCode.hashCode() : 0);
+ result = 31 * result + (gatewayErrorMsg != null ? gatewayErrorMsg.hashCode() : 0);
+ return result;
+ }
+}
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 3d76f01..e4c0274 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
@@ -50,12 +50,11 @@ import org.killbill.billing.account.api.AccountData;
import org.killbill.billing.account.api.AccountEmail;
import org.killbill.billing.account.api.AccountUserApi;
import org.killbill.billing.account.api.MutableAccountData;
-import org.killbill.billing.invoice.api.InvoiceApiException;
-import org.killbill.clock.Clock;
import org.killbill.billing.entitlement.api.SubscriptionApi;
import org.killbill.billing.entitlement.api.SubscriptionApiException;
import org.killbill.billing.entitlement.api.SubscriptionBundle;
import org.killbill.billing.invoice.api.Invoice;
+import org.killbill.billing.invoice.api.InvoiceApiException;
import org.killbill.billing.invoice.api.InvoicePayment;
import org.killbill.billing.invoice.api.InvoicePaymentApi;
import org.killbill.billing.invoice.api.InvoiceUserApi;
@@ -65,6 +64,8 @@ import org.killbill.billing.jaxrs.json.AccountTimelineJson;
import org.killbill.billing.jaxrs.json.BundleJson;
import org.killbill.billing.jaxrs.json.ChargebackJson;
import org.killbill.billing.jaxrs.json.CustomFieldJson;
+import org.killbill.billing.jaxrs.json.DirectPaymentJson;
+import org.killbill.billing.jaxrs.json.DirectTransactionJson;
import org.killbill.billing.jaxrs.json.InvoiceEmailJson;
import org.killbill.billing.jaxrs.json.InvoiceJson;
import org.killbill.billing.jaxrs.json.OverdueStateJson;
@@ -77,11 +78,14 @@ import org.killbill.billing.overdue.OverdueApiException;
import org.killbill.billing.overdue.OverdueState;
import org.killbill.billing.overdue.OverdueUserApi;
import org.killbill.billing.overdue.config.api.OverdueException;
+import org.killbill.billing.payment.api.DirectPayment;
+import org.killbill.billing.payment.api.DirectPaymentApi;
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.Refund;
+import org.killbill.billing.payment.api.TransactionType;
import org.killbill.billing.util.api.AuditLevel;
import org.killbill.billing.util.api.AuditUserApi;
import org.killbill.billing.util.api.CustomFieldApiException;
@@ -94,11 +98,13 @@ import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.TenantContext;
import org.killbill.billing.util.entity.Pagination;
import org.killbill.billing.util.tag.ControlTagType;
+import org.killbill.clock.Clock;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap;
@@ -117,6 +123,7 @@ public class AccountResource extends JaxRsResourceBase {
private final InvoiceUserApi invoiceApi;
private final InvoicePaymentApi invoicePaymentApi;
private final PaymentApi paymentApi;
+ private final DirectPaymentApi directPaymentApi;
private final OverdueUserApi overdueApi;
@Inject
@@ -125,6 +132,7 @@ public class AccountResource extends JaxRsResourceBase {
final InvoiceUserApi invoiceApi,
final InvoicePaymentApi invoicePaymentApi,
final PaymentApi paymentApi,
+ final DirectPaymentApi directPaymentApi,
final TagUserApi tagUserApi,
final AuditUserApi auditUserApi,
final CustomFieldUserApi customFieldUserApi,
@@ -137,6 +145,7 @@ public class AccountResource extends JaxRsResourceBase {
this.invoiceApi = invoiceApi;
this.invoicePaymentApi = invoicePaymentApi;
this.paymentApi = paymentApi;
+ this.directPaymentApi = directPaymentApi;
this.overdueApi = overdueApi;
}
@@ -177,7 +186,8 @@ public class AccountResource extends JaxRsResourceBase {
return getAccount(account, accountWithBalance, accountWithBalanceAndCBA, accountAuditLogs, tenantContext);
}
},
- nextPageUri);
+ nextPageUri
+ );
}
@GET
@@ -204,7 +214,8 @@ public class AccountResource extends JaxRsResourceBase {
return getAccount(account, accountWithBalance, accountWithBalanceAndCBA, accountAuditLogs, tenantContext);
}
},
- nextPageUri);
+ nextPageUri
+ );
}
@GET
@@ -588,6 +599,74 @@ public class AccountResource extends JaxRsResourceBase {
}
/*
+ * ************************* DIRECT PAYMENTS *****************************
+ */
+ @GET
+ @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,
+ @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException {
+
+ final UUID accountId = UUID.fromString(accountIdStr);
+ final List<DirectPayment> payments = directPaymentApi.getAccountPayments(accountId, withPluginInfo, context.createContext(request));
+ final List<DirectPaymentJson> result = ImmutableList.copyOf(Iterables.transform(payments, new Function<DirectPayment, DirectPaymentJson>() {
+ @Override
+ public DirectPaymentJson apply(final DirectPayment input) {
+ // STEPH_DP audits
+ return new DirectPaymentJson(input, null, null);
+ }
+ }));
+ return Response.status(Response.Status.OK).entity(result).build();
+ }
+
+ @POST
+ @Path("/{accountId:" + UUID_PATTERN + "}/" + DIRECT_PAYMENTS)
+ @Consumes(APPLICATION_JSON)
+ @Produces(APPLICATION_JSON)
+ public Response processDirectPayment(final DirectTransactionJson json,
+ @PathParam("accountId") final String accountIdStr,
+ @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 {
+
+ final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+ final UUID accountId = UUID.fromString(accountIdStr);
+ final Account account = accountUserApi.getAccountById(accountId, callContext);
+
+ final TransactionType transactionType = TransactionType.valueOf(json.getTransactionType());
+ DirectPayment result;
+ switch (transactionType) {
+ case AUTHORIZE:
+ result = directPaymentApi.createAuthorization(account, json.getAmount(), json.getExternalKey(), callContext);
+ break;
+
+ case CAPTURE:
+ result = directPaymentApi.createCapture(account, UUID.fromString(json.getDirectPaymentId()), json.getAmount(), callContext);
+ break;
+
+ case CREDIT:
+ result = directPaymentApi.createCredit(account, UUID.fromString(json.getDirectPaymentId()), callContext);
+ break;
+
+ case PURCHASE:
+ result = directPaymentApi.createPurchase(account, json.getAmount(), json.getExternalKey(), callContext);
+ break;
+
+ case VOID:
+ result = directPaymentApi.createVoid(account, UUID.fromString(json.getDirectPaymentId()), callContext);
+ break;
+
+ default:
+ return Response.status(Status.PRECONDITION_FAILED).entity("Unknown transactionType " + transactionType).build();
+ }
+ // STEPH_DP needs to return 201 with Location
+ return Response.status(Response.Status.OK).entity(new DirectPaymentJson(result, null, null)).build();
+ }
+
+ /*
* ************************** CHARGEBACKS ********************************
*/
@GET
@@ -791,7 +870,8 @@ public class AccountResource extends JaxRsResourceBase {
public boolean apply(final AccountEmail input) {
return input.getEmail().equals(json.getEmail());
}
- })
+ }
+ )
.orNull();
if (existingEmail == null) {
accountUserApi.addEmail(accountId, json.toAccountEmail(UUID.randomUUID()), callContext);
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 35c1972..e4747ce 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
@@ -138,6 +138,9 @@ public interface JaxrsResource {
public static final String PAYMENTS = "payments";
public static final String PAYMENTS_PATH = PREFIX + "/" + PAYMENTS;
+ public static final String DIRECT_PAYMENTS = "directPayments";
+ public static final String DIRECT_PAYMENTS_PATH = PREFIX + "/" + DIRECT_PAYMENTS;
+
public static final String REFUNDS = "refunds";
public static final String REFUNDS_PATH = PREFIX + "/" + "refunds";
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 c52b05b..e9198e7 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
@@ -296,19 +296,6 @@ public class PaymentResource extends JaxRsResourceBase {
throw new UnsupportedOperationException();
}
- @POST
- @Path("/{paymentId:" + UUID_PATTERN + "}/")
- @Consumes(APPLICATION_JSON)
- @Produces(APPLICATION_JSON)
- public Response processPayment(final PaymentJson json,
- @PathParam("paymentId") final String paymentId,
- @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 {
- throw new UnsupportedOperationException();
- }
@DELETE
@Path("/{paymentId:" + UUID_PATTERN + "}/")
diff --git a/osgi-bundles/bundles/jruby/src/main/java/org/killbill/billing/osgi/bundles/jruby/JRubyPaymentPlugin.java b/osgi-bundles/bundles/jruby/src/main/java/org/killbill/billing/osgi/bundles/jruby/JRubyPaymentPlugin.java
index 6a88c2f..01f13e7 100644
--- a/osgi-bundles/bundles/jruby/src/main/java/org/killbill/billing/osgi/bundles/jruby/JRubyPaymentPlugin.java
+++ b/osgi-bundles/bundles/jruby/src/main/java/org/killbill/billing/osgi/bundles/jruby/JRubyPaymentPlugin.java
@@ -23,6 +23,9 @@ import java.util.List;
import java.util.UUID;
import org.jruby.Ruby;
+import org.killbill.billing.payment.plugin.api.HostedPaymentPageDescriptorFields;
+import org.killbill.billing.payment.plugin.api.HostedPaymentPageFormDescriptor;
+import org.killbill.billing.payment.plugin.api.HostedPaymentPageNotification;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.log.LogService;
@@ -67,6 +70,17 @@ public class JRubyPaymentPlugin extends JRubyPlugin implements PaymentPluginApi
super.stopPlugin(context);
}
+ // STEPH_DP
+ @Override
+ public PaymentInfoPlugin authorizePayment(final UUID uuid, final UUID uuid2, final UUID uuid3, final BigDecimal bigDecimal, final Currency currency, final CallContext callContext) throws PaymentPluginApiException {
+ return null;
+ }
+
+ @Override
+ public PaymentInfoPlugin capturePayment(final UUID uuid, final UUID uuid2, final UUID uuid3, final BigDecimal bigDecimal, final Currency currency, final CallContext callContext) throws PaymentPluginApiException {
+ return null;
+ }
+
@Override
public PaymentInfoPlugin processPayment(final UUID kbAccountId, final UUID kbPaymentId, final UUID kbPaymentMethodId, final BigDecimal amount, final Currency currency, final CallContext context) throws PaymentPluginApiException {
@@ -79,6 +93,11 @@ public class JRubyPaymentPlugin extends JRubyPlugin implements PaymentPluginApi
}
@Override
+ public PaymentInfoPlugin voidPayment(final UUID uuid, final UUID uuid2, final UUID uuid3, final CallContext callContext) throws PaymentPluginApiException {
+ return null;
+ }
+
+ @Override
public PaymentInfoPlugin getPaymentInfo(final UUID kbAccountId, final UUID kbPaymentId, final TenantContext context) throws PaymentPluginApiException {
return callWithRuntimeAndChecking(new PluginCallback(VALIDATION_PLUGIN_TYPE.PAYMENT) {
@@ -209,4 +228,14 @@ public class JRubyPaymentPlugin extends JRubyPlugin implements PaymentPluginApi
}
});
}
+
+ @Override
+ public HostedPaymentPageFormDescriptor buildFormDescriptor(final UUID uuid, final HostedPaymentPageDescriptorFields hostedPaymentPageDescriptorFields, final TenantContext tenantContext) {
+ return null;
+ }
+
+ @Override
+ public HostedPaymentPageNotification processNotification(final String s, final TenantContext tenantContext) throws PaymentPluginApiException {
+ return null;
+ }
}
osgi-bundles/bundles/logger/pom.xml 2(+1 -1)
diff --git a/osgi-bundles/bundles/logger/pom.xml b/osgi-bundles/bundles/logger/pom.xml
index 048e123..d5380cd 100644
--- a/osgi-bundles/bundles/logger/pom.xml
+++ b/osgi-bundles/bundles/logger/pom.xml
@@ -56,7 +56,7 @@
<configuration>
<instructions>
<Bundle-Activator>org.killbill.billing.osgi.bundles.logger.Activator</Bundle-Activator>
- <Export-Package />
+ <Export-Package></Export-Package>
<Private-Package>org.killbill.billing.osgi.bundles.logger.*</Private-Package>
<!-- Optional resolution because exported by the Felix system bundle -->
<Import-Package>*;resolution:=optional</Import-Package>
diff --git a/osgi-bundles/tests/beatrix/src/test/java/org/killbill/billing/osgi/bundles/test/TestPaymentPluginApi.java b/osgi-bundles/tests/beatrix/src/test/java/org/killbill/billing/osgi/bundles/test/TestPaymentPluginApi.java
index 21267b2..6e7947b 100644
--- a/osgi-bundles/tests/beatrix/src/test/java/org/killbill/billing/osgi/bundles/test/TestPaymentPluginApi.java
+++ b/osgi-bundles/tests/beatrix/src/test/java/org/killbill/billing/osgi/bundles/test/TestPaymentPluginApi.java
@@ -27,6 +27,9 @@ import org.joda.time.DateTime;
import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.osgi.bundles.test.dao.TestDao;
import org.killbill.billing.payment.api.PaymentMethodPlugin;
+import org.killbill.billing.payment.plugin.api.HostedPaymentPageDescriptorFields;
+import org.killbill.billing.payment.plugin.api.HostedPaymentPageFormDescriptor;
+import org.killbill.billing.payment.plugin.api.HostedPaymentPageNotification;
import org.killbill.billing.payment.plugin.api.PaymentInfoPlugin;
import org.killbill.billing.payment.plugin.api.PaymentMethodInfoPlugin;
import org.killbill.billing.payment.plugin.api.PaymentPluginApi;
@@ -48,6 +51,16 @@ public class TestPaymentPluginApi implements PaymentPluginApi {
}
@Override
+ public PaymentInfoPlugin authorizePayment(final UUID uuid, final UUID uuid2, final UUID uuid3, final BigDecimal bigDecimal, final Currency currency, final CallContext callContext) throws PaymentPluginApiException {
+ return null;
+ }
+
+ @Override
+ public PaymentInfoPlugin capturePayment(final UUID uuid, final UUID uuid2, final UUID uuid3, final BigDecimal bigDecimal, final Currency currency, final CallContext callContext) throws PaymentPluginApiException {
+ return null;
+ }
+
+ @Override
public PaymentInfoPlugin processPayment(final UUID kbAccountId, final UUID kbPaymentId, final UUID kbPaymentMethodId, final BigDecimal amount, final Currency currency, final CallContext context) throws PaymentPluginApiException {
testDao.insertProcessedPayment(kbPaymentId, kbPaymentMethodId, amount);
return new PaymentInfoPlugin() {
@@ -104,6 +117,11 @@ public class TestPaymentPluginApi implements PaymentPluginApi {
}
@Override
+ public PaymentInfoPlugin voidPayment(final UUID uuid, final UUID uuid2, final UUID uuid3, final CallContext callContext) throws PaymentPluginApiException {
+ return null;
+ }
+
+ @Override
public PaymentInfoPlugin getPaymentInfo(final UUID kbAccountId, final UUID kbPaymentId, final TenantContext context) throws PaymentPluginApiException {
return null;
}
@@ -233,4 +251,14 @@ public class TestPaymentPluginApi implements PaymentPluginApi {
@Override
public void resetPaymentMethods(final UUID kbAccountId, final List<PaymentMethodInfoPlugin> paymentMethods) throws PaymentPluginApiException {
}
+
+ @Override
+ public HostedPaymentPageFormDescriptor buildFormDescriptor(final UUID uuid, final HostedPaymentPageDescriptorFields hostedPaymentPageDescriptorFields, final TenantContext tenantContext) {
+ return null;
+ }
+
+ @Override
+ public HostedPaymentPageNotification processNotification(final String s, final TenantContext tenantContext) throws PaymentPluginApiException {
+ return null;
+ }
}
diff --git a/osgi-bundles/tests/payment/src/test/java/org/killbill/billing/osgi/bundles/test/TestPaymentPluginApi.java b/osgi-bundles/tests/payment/src/test/java/org/killbill/billing/osgi/bundles/test/TestPaymentPluginApi.java
index 9c713ba..46d5685 100644
--- a/osgi-bundles/tests/payment/src/test/java/org/killbill/billing/osgi/bundles/test/TestPaymentPluginApi.java
+++ b/osgi-bundles/tests/payment/src/test/java/org/killbill/billing/osgi/bundles/test/TestPaymentPluginApi.java
@@ -26,6 +26,9 @@ import org.joda.time.DateTime;
import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.payment.api.PaymentMethodPlugin;
+import org.killbill.billing.payment.plugin.api.HostedPaymentPageDescriptorFields;
+import org.killbill.billing.payment.plugin.api.HostedPaymentPageFormDescriptor;
+import org.killbill.billing.payment.plugin.api.HostedPaymentPageNotification;
import org.killbill.billing.payment.plugin.api.PaymentInfoPlugin;
import org.killbill.billing.payment.plugin.api.PaymentMethodInfoPlugin;
import org.killbill.billing.payment.plugin.api.PaymentPluginApiException;
@@ -50,7 +53,23 @@ public class TestPaymentPluginApi implements PaymentPluginApiWithTestControl {
}
@Override
+ public PaymentInfoPlugin authorizePayment(UUID kbAccountId, UUID kbPaymentId, UUID kbPaymentMethodId, BigDecimal amount, Currency currency, CallContext context)
+ throws PaymentPluginApiException {
+ return getPaymentInfoPluginResult(kbPaymentId, amount, currency);
+ }
+
+ @Override
+ public PaymentInfoPlugin capturePayment(UUID kbAccountId, UUID kbPaymentId, UUID kbPaymentMethodId, BigDecimal amount, Currency currency, CallContext context)
+ throws PaymentPluginApiException {
+ return getPaymentInfoPluginResult(kbPaymentId, amount, currency);
+ }
+
+ @Override
public PaymentInfoPlugin processPayment(final UUID accountId, final UUID kbPaymentId, final UUID kbPaymentMethodId, final BigDecimal amount, final Currency currency, final CallContext context) throws PaymentPluginApiException {
+ return getPaymentInfoPluginResult(kbPaymentId, amount, currency);
+ }
+
+ private PaymentInfoPlugin getPaymentInfoPluginResult(final UUID kbPaymentId, final BigDecimal amount, final Currency currency) throws PaymentPluginApiException {
return withRuntimeCheckForExceptions(new PaymentInfoPlugin() {
@Override
public UUID getKbPaymentId() {
@@ -105,60 +124,17 @@ public class TestPaymentPluginApi implements PaymentPluginApiWithTestControl {
}
@Override
- public PaymentInfoPlugin getPaymentInfo(final UUID accountId, final UUID kbPaymentId, final TenantContext context) throws PaymentPluginApiException {
-
- final BigDecimal someAmount = new BigDecimal("12.45");
- return withRuntimeCheckForExceptions(new PaymentInfoPlugin() {
- @Override
- public UUID getKbPaymentId() {
- return kbPaymentId;
- }
-
- @Override
- public BigDecimal getAmount() {
- return someAmount;
- }
-
- @Override
- public Currency getCurrency() {
- return null;
- }
-
- @Override
- public DateTime getCreatedDate() {
- return new DateTime();
- }
-
- @Override
- public DateTime getEffectiveDate() {
- return new DateTime();
- }
+ public PaymentInfoPlugin voidPayment(UUID kbAccountId, UUID kbPaymentId, UUID kbPaymentMethodId, CallContext context)
+ throws PaymentPluginApiException {
+ return getPaymentInfoPluginResult(kbPaymentId, BigDecimal.ZERO, null);
- @Override
- public PaymentPluginStatus getStatus() {
- return PaymentPluginStatus.PROCESSED;
- }
-
- @Override
- public String getGatewayError() {
- return null;
- }
-
- @Override
- public String getGatewayErrorCode() {
- return null;
- }
+ }
- @Override
- public String getFirstPaymentReferenceId() {
- return null;
- }
+ @Override
+ public PaymentInfoPlugin getPaymentInfo(final UUID accountId, final UUID kbPaymentId, final TenantContext context) throws PaymentPluginApiException {
- @Override
- public String getSecondPaymentReferenceId() {
- return null;
- }
- });
+ final BigDecimal someAmount = new BigDecimal("12.45");
+ return getPaymentInfoPluginResult(kbPaymentId, someAmount, null);
}
@Override
@@ -337,6 +313,16 @@ public class TestPaymentPluginApi implements PaymentPluginApiWithTestControl {
public void resetPaymentMethods(final UUID accountId, final List<PaymentMethodInfoPlugin> paymentMethods) throws PaymentPluginApiException {
}
+ @Override
+ public HostedPaymentPageFormDescriptor buildFormDescriptor(final UUID uuid, final HostedPaymentPageDescriptorFields hostedPaymentPageDescriptorFields, final TenantContext tenantContext) {
+ return null;
+ }
+
+ @Override
+ public HostedPaymentPageNotification processNotification(final String s, final TenantContext tenantContext) throws PaymentPluginApiException {
+ return null;
+ }
+
private <T> T withRuntimeCheckForExceptions(final T result) throws PaymentPluginApiException {
if (paymentPluginApiExceptionOnNextCalls != null) {
throw paymentPluginApiExceptionOnNextCalls;
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultDirectPayment.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultDirectPayment.java
new file mode 100644
index 0000000..a7a822a
--- /dev/null
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultDirectPayment.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ *
+ * Groupon 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.payment.api;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+import org.joda.time.DateTime;
+import org.killbill.billing.catalog.api.Currency;
+import org.killbill.billing.entity.EntityBase;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+
+public class DefaultDirectPayment extends EntityBase implements DirectPayment {
+
+ private final UUID accountId;
+ private final UUID paymentMethodId;
+ private final Integer paymentNumber;
+ private final String externalKey;
+ private final BigDecimal authAmount;
+ private final BigDecimal captureAmount;
+ private final BigDecimal refundAmount;
+ private final Currency currency;
+ private final PaymentStatus paymentStatus;
+ private final List<DirectPaymentTransaction> transactions;
+
+ public DefaultDirectPayment(final UUID id, @Nullable final DateTime createdDate, @Nullable final DateTime updatedDate, final UUID accountId,
+ final UUID paymentMethodId,
+ final Integer paymentNumber,
+ final String externalKey,
+ final List<DirectPaymentTransaction> transactions) {
+ super(id, createdDate, updatedDate);
+ this.accountId = accountId;
+ this.paymentMethodId = paymentMethodId;
+ this.paymentNumber = paymentNumber;
+ this.externalKey = externalKey;
+ this.transactions = transactions;
+ this.authAmount = getAmountForType(transactions, TransactionType.AUTHORIZE);
+ this.captureAmount = getAmountForType(transactions, TransactionType.CAPTURE);
+ this.refundAmount = getAmountForType(transactions, TransactionType.CREDIT);
+ this.currency = (transactions != null && transactions.size() > 0) ? transactions.get(0).getCurrency() : null;
+ this.paymentStatus = (transactions != null && transactions.size() > 0) ? transactions.get(transactions.size() - 1).getPaymentStatus() : null;
+ }
+
+ private static BigDecimal getAmountForType(final List<DirectPaymentTransaction> transactions, final TransactionType transactiontype) {
+ BigDecimal result = BigDecimal.ZERO;
+ final Iterable<DirectPaymentTransaction> filtered = Iterables.filter(transactions, new Predicate<DirectPaymentTransaction>() {
+ @Override
+ public boolean apply(final DirectPaymentTransaction input) {
+ return input.getTransactionType() == transactiontype;
+ }
+ });
+ for (DirectPaymentTransaction dpt : filtered) {
+ result = result.add(dpt.getAmount());
+ }
+ return result;
+ }
+
+ @Override
+ public UUID getAccountId() {
+ return accountId;
+ }
+
+ @Override
+ public UUID getPaymentMethodId() {
+ return paymentMethodId;
+ }
+
+ @Override
+ public Integer getPaymentNumber() {
+ return paymentNumber;
+ }
+
+ @Override
+ public String getExternalKey() {
+ return externalKey;
+ }
+
+ @Override
+ public BigDecimal getAuthAmount() {
+ return authAmount;
+ }
+
+ @Override
+ public BigDecimal getCapturedAmount() {
+ return captureAmount;
+ }
+
+ @Override
+ public BigDecimal getRefundedAmount() {
+ return refundAmount;
+ }
+
+ @Override
+ public Currency getCurrency() {
+ return currency;
+ }
+
+ @Override
+ public PaymentStatus getPaymentStatus() {
+ return paymentStatus;
+ }
+
+ @Override
+ public List<DirectPaymentTransaction> getTransactions() {
+ return transactions;
+ }
+
+}
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultDirectPaymentTransaction.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultDirectPaymentTransaction.java
new file mode 100644
index 0000000..27c927b
--- /dev/null
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultDirectPaymentTransaction.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ *
+ * 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.payment.api;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.killbill.billing.catalog.api.Currency;
+import org.killbill.billing.entity.EntityBase;
+import org.killbill.billing.payment.plugin.api.PaymentInfoPlugin;
+
+public class DefaultDirectPaymentTransaction extends EntityBase implements DirectPaymentTransaction {
+
+ private final UUID directTransactionId;
+ private final TransactionType transactionType;
+ private final DateTime effectiveDate;
+ private final PaymentStatus status;
+ private final BigDecimal amount;
+ private final Currency currency;
+ private final String gatewayErrorCode;
+ private final String gatewayErrorMsg;
+ private final PaymentInfoPlugin infoPlugin;
+ private final Integer retryCount;
+
+ public DefaultDirectPaymentTransaction(final UUID id, final DateTime createdDate, final DateTime updatedDate, final UUID directTransactionId, final TransactionType transactionType,
+ final DateTime effectiveDate, final Integer retryCount, final PaymentStatus status, final BigDecimal amount, final Currency currency,
+ final String gatewayErrorCode, final String gatewayErrorMsg, final PaymentInfoPlugin infoPlugin) {
+ super(id, createdDate, updatedDate);
+ this.directTransactionId = directTransactionId;
+ this.transactionType = transactionType;
+ this.effectiveDate = effectiveDate;
+ this.retryCount = retryCount;
+ this.status = status;
+ this.amount = amount;
+ this.currency = currency;
+ this.gatewayErrorCode = gatewayErrorCode;
+ this.gatewayErrorMsg = gatewayErrorMsg;
+ this.infoPlugin = infoPlugin;
+ }
+
+ @Override
+ public UUID getDirectPaymentId() {
+ return directTransactionId;
+ }
+
+ @Override
+ public TransactionType getTransactionType() {
+ return transactionType;
+ }
+
+ @Override
+ public DateTime getEffectiveDate() {
+ return effectiveDate;
+ }
+
+ @Override
+ public BigDecimal getAmount() {
+ return amount;
+ }
+
+ @Override
+ public Currency getCurrency() {
+ return currency;
+ }
+
+ @Override
+ public String getGatewayErrorCode() {
+ return gatewayErrorCode;
+ }
+
+ @Override
+ public String getGatewayErrorMsg() {
+ return gatewayErrorMsg;
+ }
+
+ @Override
+ public PaymentStatus getPaymentStatus() {
+ return status;
+ }
+
+ @Override
+ public PaymentInfoPlugin getPaymentInfoPlugin() {
+ return infoPlugin;
+ }
+}
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
new file mode 100644
index 0000000..b8438b6
--- /dev/null
+++ b/payment/src/main/java/org/killbill/billing/payment/api/svcs/DefaultDirectPaymentApi.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ *
+ * 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.payment.api.svcs;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import org.killbill.billing.account.api.Account;
+import org.killbill.billing.payment.api.DirectPayment;
+import org.killbill.billing.payment.api.DirectPaymentApi;
+import org.killbill.billing.payment.api.PaymentApiException;
+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;
+
+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) {
+ this.directPaymentProcessor = directPaymentProcessor;
+ this.internalCallContextFactory = internalCallContextFactory;
+ this.clock = clock;
+ }
+
+ @Override
+ public DirectPayment createAuthorization(final Account account, final BigDecimal amount, final String externalKey, final CallContext callContext) throws PaymentApiException {
+ return directPaymentProcessor.createAuthorization(account, amount, externalKey, internalCallContextFactory.createInternalCallContext(account.getId(), callContext));
+ }
+
+ @Override
+ public DirectPayment createCapture(final Account account, final UUID directPaymentId, final BigDecimal amount, final CallContext callContext) throws PaymentApiException {
+ return directPaymentProcessor.createCapture(account, directPaymentId, amount, internalCallContextFactory.createInternalCallContext(account.getId(), callContext));
+ }
+
+ @Override
+ public DirectPayment createPurchase(final Account account, final BigDecimal amount, final String externalKey, final CallContext callContext) throws PaymentApiException {
+ return directPaymentProcessor.createPurchase(account, amount, externalKey, internalCallContextFactory.createInternalCallContext(account.getId(), callContext));
+ }
+
+ @Override
+ public DirectPayment createVoid(final Account account, final UUID directPaymentId, final CallContext callContext) throws PaymentApiException {
+ return null;
+ }
+
+ @Override
+ public DirectPayment createCredit(final Account account, final UUID directPaymentId, final CallContext callContext) throws PaymentApiException {
+ return null;
+ }
+
+ @Override
+ public List<DirectPayment> getAccountPayments(final UUID accountId, final boolean withPluginInfo, final TenantContext tenantContext) throws PaymentApiException {
+ return directPaymentProcessor.getAccountPayments(accountId, withPluginInfo, internalCallContextFactory.createInternalTenantContext(accountId, tenantContext));
+ }
+
+ @Override
+ public DirectPayment getPayment(final UUID directPaymentId, final boolean withPluginInfo, final TenantContext tenantContext) throws PaymentApiException {
+ return directPaymentProcessor.getPayment(directPaymentId, withPluginInfo, internalCallContextFactory.createInternalTenantContext(tenantContext));
+ }
+}
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
new file mode 100644
index 0000000..a27eb32
--- /dev/null
+++ b/payment/src/main/java/org/killbill/billing/payment/core/DirectPaymentProcessor.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ *
+ * Groupon 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.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 javax.annotation.Nullable;
+import javax.inject.Inject;
+
+import org.joda.time.DateTime;
+import org.killbill.billing.ObjectType;
+import org.killbill.billing.account.api.Account;
+import org.killbill.billing.account.api.AccountInternalApi;
+import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.catalog.api.Currency;
+import org.killbill.billing.invoice.api.InvoiceInternalApi;
+import org.killbill.billing.osgi.api.OSGIServiceRegistration;
+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.TransactionType;
+import org.killbill.billing.payment.dao.DirectPaymentModelDao;
+import org.killbill.billing.payment.dao.DirectPaymentTransactionModelDao;
+import org.killbill.billing.payment.dao.PaymentDao;
+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.config.PaymentConfig;
+import org.killbill.billing.util.dao.NonEntityDao;
+import org.killbill.bus.api.PersistentBus;
+import org.killbill.clock.Clock;
+import org.killbill.commons.locker.GlobalLocker;
+import org.slf4j.Logger;
+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.Ordering;
+import com.google.inject.name.Named;
+
+import static org.killbill.billing.payment.glue.PaymentModule.PLUGIN_EXECUTOR_NAMED;
+
+public class DirectPaymentProcessor extends ProcessorBase {
+
+ private final Clock clock;
+
+ private final PaymentConfig paymentConfig;
+
+ private final PluginDispatcher<Payment> paymentPluginDispatcher;
+ private final PluginDispatcher<Void> voidPluginDispatcher;
+
+ private static final Logger log = LoggerFactory.getLogger(DirectPaymentProcessor.class);
+
+ @Inject
+ public DirectPaymentProcessor(final OSGIServiceRegistration<PaymentPluginApi> pluginRegistry,
+ final AccountInternalApi accountUserApi,
+ final InvoiceInternalApi invoiceApi,
+ final TagInternalApi tagUserApi,
+ final PaymentDao paymentDao,
+ final NonEntityDao nonEntityDao,
+ final PersistentBus eventBus,
+ final Clock clock,
+ final GlobalLocker locker,
+ final PaymentConfig paymentConfig,
+ @Named(PLUGIN_EXECUTOR_NAMED) final ExecutorService executor) {
+ super(pluginRegistry, accountUserApi, eventBus, paymentDao, nonEntityDao, tagUserApi, locker, executor, invoiceApi);
+ this.clock = clock;
+ 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);
+ }
+
+ public DirectPayment createAuthorization(final Account account, final BigDecimal amount, final String externalKey, final InternalCallContext callContext) throws PaymentApiException {
+
+ final PaymentPluginApi plugin = getPaymentProviderPlugin(account, callContext);
+
+ 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(), callContext.toCallContext(tenantId));
+ } catch (RuntimeException e) {
+ // Handle case of plugin RuntimeException to be handled the same as a Plugin failure (PaymentPluginApiException)
+ final String formatError = String.format("Plugin threw RuntimeException for payment %s", 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 (PaymentPluginApiException e) {
+ paymentStatus = PaymentStatus.PAYMENT_FAILURE_ABORTED;
+ infoPlugin = null;
+ paymentDao.updateDirectPaymentAndTransactionOnCompletion(pmd.getId(), paymentStatus, amount, account.getCurrency(),
+ ptmd.getId(), null, e.getMessage(), callContext);
+ } finally {
+ }
+
+ 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;
+ }
+
+ public DirectPayment createCapture(final Account account, final UUID directPaymentId, final BigDecimal amount, final InternalCallContext callContext) throws PaymentApiException {
+ return null;
+ }
+
+ public DirectPayment createPurchase(final Account account, final BigDecimal amount, final String externalKey, final InternalCallContext callContext) throws PaymentApiException {
+ return null;
+ }
+
+ public DirectPayment createVoid(final Account account, final UUID directPaymentId, final InternalCallContext callContext) throws PaymentApiException {
+ return null;
+ }
+
+ public DirectPayment createCredit(final Account account, final UUID directPaymentId, final InternalCallContext callContext) throws PaymentApiException {
+ return null;
+ }
+
+ public List<DirectPayment> getAccountPayments(final UUID accountId, final boolean withPluginInfo, 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>() {
+
+ final Ordering<DirectPaymentTransaction> perPaymentTransactionOrdering = Ordering.<DirectPaymentTransaction>from(new Comparator<DirectPaymentTransaction>() {
+ @Override
+ public int compare(final DirectPaymentTransaction o1, final DirectPaymentTransaction o2) {
+ return o1.getEffectiveDate().compareTo(o2.getEffectiveDate());
+ }
+ });
+
+ @Override
+ public DirectPayment apply(final DirectPaymentModelDao curDirectPaymentModelDao) {
+
+ final Iterable<DirectPaymentTransactionModelDao> filteredTransactions = Iterables.filter(transactionsModelDao, new Predicate<DirectPaymentTransactionModelDao>() {
+ @Override
+ public boolean apply(final DirectPaymentTransactionModelDao curDirectPaymentTransactionModelDao) {
+ return curDirectPaymentTransactionModelDao.getDirectPaymentId().equals(curDirectPaymentModelDao.getId());
+ }
+ });
+
+ final Iterable<DirectPaymentTransaction> transactions = Iterables.transform(filteredTransactions, new Function<DirectPaymentTransactionModelDao, DirectPaymentTransaction>() {
+ @Override
+ 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);
+ }
+ });
+
+ final List<DirectPaymentTransaction> sortedTransactions = perPaymentTransactionOrdering.immutableSortedCopy(transactions);
+ return new DefaultDirectPayment(curDirectPaymentModelDao.getId(), curDirectPaymentModelDao.getCreatedDate(), curDirectPaymentModelDao.getUpdatedDate(), curDirectPaymentModelDao.getAccountId(),
+ curDirectPaymentModelDao.getPaymentMethodId(), curDirectPaymentModelDao.getPaymentNumber(), curDirectPaymentModelDao.getExternalKey(), sortedTransactions);
+ }
+ });
+ return ImmutableList.copyOf(payments);
+ }
+
+ public DirectPayment getPayment(final UUID directPaymentId, final boolean withPluginInfo, final InternalTenantContext tenantContext) throws PaymentApiException {
+ return null;
+ }
+
+}
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 f21c20d..b15f20c 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
@@ -24,6 +24,9 @@ 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;
@@ -46,6 +49,7 @@ 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 com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
@@ -71,6 +75,82 @@ public class DefaultPaymentDao implements PaymentDao {
}
@Override
+ public DirectPaymentModelDao insertDirectPaymentWithFirstTransaction(final DirectPaymentModelDao directPayment, final DirectPaymentTransactionModelDao directPaymentTransaction, final InternalCallContext context) {
+
+ return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<DirectPaymentModelDao>() {
+
+ @Override
+ public DirectPaymentModelDao inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
+ 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);
+ }
+ });
+ }
+
+ @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) {
+ transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {
+
+ @Override
+ public Void inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
+ entitySqlDaoWrapperFactory.become(DirectTransactionSqlDao.class).updateTransactionStatus(directTransactionId.toString(), paymentStatus.toString(), gatewayErrorCode, gatewayErrorMsg, context);
+ return null;
+ }
+ });
+
+ }
+
+ @Override
+ public DirectPaymentModelDao getDirectPayment(final UUID directPaymentId, final InternalTenantContext context) {
+ return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<DirectPaymentModelDao>() {
+ @Override
+ public DirectPaymentModelDao inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
+ return entitySqlDaoWrapperFactory.become(DirectPaymentSqlDao.class).getById(directPaymentId.toString(), context);
+ }
+ });
+ }
+
+ @Override
+ public DirectPaymentTransactionModelDao getDirectPaymentTransaction(final UUID directTransactionId, final InternalTenantContext context) {
+ // getByAccountRecordId
+ return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<DirectPaymentTransactionModelDao>() {
+ @Override
+ public DirectPaymentTransactionModelDao inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
+ return entitySqlDaoWrapperFactory.become(DirectTransactionSqlDao.class).getById(directTransactionId.toString(), context);
+ }
+ });
+ }
+
+ @Override
+ public List<DirectPaymentModelDao> getDirectPaymentsForAccount(final UUID accountId, final InternalTenantContext context) {
+ Preconditions.checkArgument(context.getAccountRecordId() != null);
+ return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<List<DirectPaymentModelDao>>() {
+ @Override
+ public List<DirectPaymentModelDao> inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
+ List<DirectPaymentModelDao> payments = entitySqlDaoWrapperFactory.become(DirectPaymentSqlDao.class).getByAccountRecordId(context);
+ return payments;
+ }
+ });
+ }
+
+ @Override
+ public List<DirectPaymentTransactionModelDao> getDirectTransactionsForAccount(final UUID accountId, final InternalTenantContext context) {
+ Preconditions.checkArgument(context.getAccountRecordId() != null);
+ return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<List<DirectPaymentTransactionModelDao>>() {
+ @Override
+ public List<DirectPaymentTransactionModelDao> inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
+ List<DirectPaymentTransactionModelDao> transactions = entitySqlDaoWrapperFactory.become(DirectTransactionSqlDao.class).getByAccountRecordId(context);
+ return transactions;
+ }
+ });
+ }
+
+
+ @Override
public PaymentModelDao insertPaymentWithFirstAttempt(final PaymentModelDao payment, final PaymentAttemptModelDao attempt, final InternalCallContext context) {
return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<PaymentModelDao>() {
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/DirectPaymentModelDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/DirectPaymentModelDao.java
new file mode 100644
index 0000000..20a5d85
--- /dev/null
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/DirectPaymentModelDao.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ *
+ * Groupon 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.payment.dao;
+
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+import org.joda.time.DateTime;
+import org.killbill.billing.entity.EntityBase;
+import org.killbill.billing.payment.api.DirectPayment;
+import org.killbill.billing.util.dao.TableName;
+import org.killbill.billing.util.entity.dao.EntityModelDao;
+
+public class DirectPaymentModelDao extends EntityBase implements EntityModelDao<DirectPayment> {
+
+ public static final Integer INVALID_PAYMENT_NUMBER = new Integer(-17);
+
+ private UUID accountId;
+ private Integer paymentNumber;
+ private UUID paymentMethodId;
+ private String externalKey;
+
+ public DirectPaymentModelDao() { /* For the DAO mapper */ }
+
+ public DirectPaymentModelDao(final UUID id, @Nullable final DateTime createdDate, @Nullable final DateTime updatedDate, final UUID accountId,
+ final UUID paymentMethodId, final Integer paymentNumber, final String externalKey) {
+ super(id, createdDate, updatedDate);
+ this.accountId = accountId;
+ this.paymentMethodId = paymentMethodId;
+ this.paymentNumber = paymentNumber;
+ this.externalKey = externalKey;
+ }
+
+ public DirectPaymentModelDao(@Nullable final DateTime createdDate, @Nullable final DateTime updatedDate, final UUID accountId,
+ final UUID paymentMethodId, final String externalKey) {
+ this(UUID.randomUUID(), createdDate, updatedDate, accountId, paymentMethodId, INVALID_PAYMENT_NUMBER, externalKey);
+ }
+
+ public UUID getAccountId() { return accountId; }
+
+ public void setAccountId(final UUID accountId) {
+ this.accountId = accountId;
+ }
+
+ public Integer getPaymentNumber() {
+ return paymentNumber;
+ }
+
+ public void setPaymentNumber(final Integer paymentNumber) {
+ this.paymentNumber = paymentNumber;
+ }
+
+ public UUID getPaymentMethodId() {
+ return paymentMethodId;
+ }
+
+ public void setPaymentMethodId(final UUID paymentMethodId) {
+ this.paymentMethodId = paymentMethodId;
+ }
+
+ public String getExternalKey() {
+ return externalKey;
+ }
+
+ public void setExternalKey(final String externalKey) {
+ this.externalKey = externalKey;
+ }
+
+ @Override
+ public String toString() {
+ return "DirectPaymentModelDao{" +
+ "accountId=" + accountId +
+ ", paymentNumber=" + paymentNumber +
+ ", paymentMethodId=" + paymentMethodId +
+ '}';
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof DirectPaymentModelDao)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ final DirectPaymentModelDao that = (DirectPaymentModelDao) o;
+
+ if (accountId != null ? !accountId.equals(that.accountId) : that.accountId != null) {
+ return false;
+ }
+ if (paymentMethodId != null ? !paymentMethodId.equals(that.paymentMethodId) : that.paymentMethodId != null) {
+ return false;
+ }
+ if (paymentNumber != null ? !paymentNumber.equals(that.paymentNumber) : that.paymentNumber != null) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (accountId != null ? accountId.hashCode() : 0);
+ result = 31 * result + (paymentNumber != null ? paymentNumber.hashCode() : 0);
+ result = 31 * result + (paymentMethodId != null ? paymentMethodId.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public TableName getTableName() {
+ return TableName.DIRECT_PAYMENTS;
+ }
+
+ @Override
+ public TableName getHistoryTableName() {
+ return TableName.DIRECT_PAYMENT_HISTORY;
+ }
+}
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
new file mode 100644
index 0000000..1714d4f
--- /dev/null
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/DirectPaymentSqlDao.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ *
+ * Groupon 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.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;
+import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.killbill.commons.jdbi.statement.SmartFetchSize;
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+
+@EntitySqlDaoStringTemplate
+public interface DirectPaymentSqlDao extends EntitySqlDao<DirectPaymentModelDao, DirectPayment> {
+
+
+ /*
+ @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);
+
+ @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/DirectPaymentTransactionModelDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/DirectPaymentTransactionModelDao.java
new file mode 100644
index 0000000..cbdd328
--- /dev/null
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/DirectPaymentTransactionModelDao.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ *
+ * Groupon 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.payment.dao;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import javax.annotation.Nullable;
+
+import org.joda.time.DateTime;
+import org.killbill.billing.catalog.api.Currency;
+import org.killbill.billing.entity.EntityBase;
+import org.killbill.billing.payment.api.DirectPaymentTransaction;
+import org.killbill.billing.payment.api.PaymentStatus;
+import org.killbill.billing.payment.api.TransactionType;
+import org.killbill.billing.util.dao.TableName;
+import org.killbill.billing.util.entity.dao.EntityModelDao;
+
+public class DirectPaymentTransactionModelDao extends EntityBase implements EntityModelDao<DirectPaymentTransaction> {
+
+ private UUID directPaymentId;
+ private TransactionType transactionType;
+ private DateTime effectiveDate;
+ private PaymentStatus paymentStatus;
+ private BigDecimal amount;
+ private Currency currency;
+ private String gatewayErrorCode;
+ private String gatewayErrorMsg;
+
+ public DirectPaymentTransactionModelDao() { /* For the DAO mapper */ }
+
+ public DirectPaymentTransactionModelDao(final UUID id, @Nullable final DateTime createdDate, @Nullable final DateTime updatedDate,
+ final UUID directPaymentId, final TransactionType transactionType, final DateTime effectiveDate,
+ final PaymentStatus paymentStatus, final BigDecimal amount, final Currency currency, final String gatewayErrorCode, final String gatewayErrorMsg) {
+ super(id, createdDate, updatedDate);
+ this.directPaymentId = directPaymentId;
+ this.transactionType = transactionType;
+ this.effectiveDate = effectiveDate;
+ this.paymentStatus = paymentStatus;
+ this.amount = amount;
+ this.currency = currency;
+ this.gatewayErrorCode = gatewayErrorCode;
+ this.gatewayErrorMsg = gatewayErrorMsg;
+ }
+
+ public DirectPaymentTransactionModelDao(@Nullable final DateTime createdDate, @Nullable final DateTime updatedDate,
+ final UUID directPaymentId, final TransactionType transactionType, final DateTime effectiveDate,
+ final PaymentStatus paymentStatus, final BigDecimal amount, final Currency currency, final String gatewayErrorCode, final String gatewayErrorMsg) {
+ this(UUID.randomUUID(), createdDate, updatedDate, directPaymentId, transactionType, effectiveDate, paymentStatus, amount, currency, gatewayErrorCode, gatewayErrorMsg);
+ }
+
+ public UUID getDirectPaymentId() {
+ return directPaymentId;
+ }
+
+ public void setDirectPaymentId(final UUID directPaymentId) {
+ this.directPaymentId = directPaymentId;
+ }
+
+ public TransactionType getTransactionType() {
+ return transactionType;
+ }
+
+ public void setTransactionType(final TransactionType transactionType) {
+ this.transactionType = transactionType;
+ }
+
+ public DateTime getEffectiveDate() {
+ return effectiveDate;
+ }
+
+ public void setEffectiveDate(final DateTime effectiveDate) {
+ this.effectiveDate = effectiveDate;
+ }
+
+ public PaymentStatus getPaymentStatus() {
+ return paymentStatus;
+ }
+
+ public void setPaymentStatus(final PaymentStatus paymentStatus) {
+ this.paymentStatus = paymentStatus;
+ }
+
+ public BigDecimal getAmount() {
+ return amount;
+ }
+
+ public void setAmount(final BigDecimal amount) {
+ this.amount = amount;
+ }
+
+ public Currency getCurrency() {
+ return currency;
+ }
+
+ public void setCurrency(final Currency currency) {
+ this.currency = currency;
+ }
+
+ public String getGatewayErrorCode() {
+ return gatewayErrorCode;
+ }
+
+ public void setGatewayErrorCode(final String gatewayErrorCode) {
+ this.gatewayErrorCode = gatewayErrorCode;
+ }
+
+ public String getGatewayErrorMsg() {
+ return gatewayErrorMsg;
+ }
+
+ public void setGatewayErrorMsg(final String gatewayErrorMsg) {
+ this.gatewayErrorMsg = gatewayErrorMsg;
+ }
+
+ @Override
+ public String toString() {
+ return "DirectPaymentTransactionModelDao{" +
+ "directPaymentId=" + directPaymentId +
+ ", transactionType=" + transactionType +
+ ", effectiveDate=" + effectiveDate +
+ ", paymentStatus=" + paymentStatus +
+ ", amount=" + amount +
+ ", currency=" + currency +
+ ", gatewayErrorCode='" + gatewayErrorCode + '\'' +
+ ", gatewayErrorMsg='" + gatewayErrorMsg + '\'' +
+ '}';
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof DirectPaymentTransactionModelDao)) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ final DirectPaymentTransactionModelDao that = (DirectPaymentTransactionModelDao) o;
+
+ if (amount != null ? amount.compareTo(that.amount) != 0 : that.amount != null) {
+ return false;
+ }
+ if (currency != that.currency) {
+ return false;
+ }
+ if (directPaymentId != null ? !directPaymentId.equals(that.directPaymentId) : that.directPaymentId != null) {
+ return false;
+ }
+ if (effectiveDate != null ? effectiveDate.compareTo(that.effectiveDate) != 0 : that.effectiveDate != null) {
+ return false;
+ }
+ if (gatewayErrorCode != null ? !gatewayErrorCode.equals(that.gatewayErrorCode) : that.gatewayErrorCode != null) {
+ return false;
+ }
+ if (gatewayErrorMsg != null ? !gatewayErrorMsg.equals(that.gatewayErrorMsg) : that.gatewayErrorMsg != null) {
+ return false;
+ }
+ if (paymentStatus != that.paymentStatus) {
+ return false;
+ }
+ if (transactionType != that.transactionType) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (directPaymentId != null ? directPaymentId.hashCode() : 0);
+ result = 31 * result + (transactionType != null ? transactionType.hashCode() : 0);
+ result = 31 * result + (effectiveDate != null ? effectiveDate.hashCode() : 0);
+ result = 31 * result + (paymentStatus != null ? paymentStatus.hashCode() : 0);
+ result = 31 * result + (amount != null ? amount.hashCode() : 0);
+ result = 31 * result + (currency != null ? currency.hashCode() : 0);
+ result = 31 * result + (gatewayErrorCode != null ? gatewayErrorCode.hashCode() : 0);
+ result = 31 * result + (gatewayErrorMsg != null ? gatewayErrorMsg.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public TableName getTableName() {
+ return TableName.DIRECT_TRANSACTIONS;
+ }
+
+ @Override
+ public TableName getHistoryTableName() {
+ return TableName.DIRECT_TRANSACTION_HISTORY;
+ }
+}
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/DirectTransactionSqlDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/DirectTransactionSqlDao.java
new file mode 100644
index 0000000..0c2f5a1
--- /dev/null
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/DirectTransactionSqlDao.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ *
+ * 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.payment.dao;
+
+import java.util.List;
+
+import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.payment.api.DirectPaymentTransaction;
+import org.killbill.billing.util.audit.ChangeType;
+import org.killbill.billing.util.entity.dao.Audited;
+import org.killbill.billing.util.entity.dao.EntitySqlDao;
+import org.killbill.billing.util.entity.dao.EntitySqlDaoStringTemplate;
+import org.skife.jdbi.v2.sqlobject.Bind;
+import org.skife.jdbi.v2.sqlobject.BindBean;
+import org.skife.jdbi.v2.sqlobject.SqlQuery;
+import org.skife.jdbi.v2.sqlobject.SqlUpdate;
+
+@EntitySqlDaoStringTemplate
+public interface DirectTransactionSqlDao extends EntitySqlDao<DirectPaymentTransactionModelDao, DirectPaymentTransaction> {
+
+ @SqlUpdate
+ @Audited(ChangeType.UPDATE)
+ void updateTransactionStatus(@Bind("id") final String transactionId,
+ @Bind("paymentStatus") final String paymentStatus,
+ @Bind("gatewayErrorCode") final String gatewayErrorCode,
+ @Bind("gatewayErrorMsg") final String gatewayErrorMsg,
+ @BindBean final InternalCallContext context);
+
+ /*
+ @SqlQuery
+ @SmartFetchSize(shouldStream = true)
+ public Iterator<DirectPaymentTransactionModelDao> getByPluginName(@Bind("pluginName") final String pluginName,
+ @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 7649fc0..12606f9 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,6 +29,20 @@ import org.killbill.billing.util.entity.Pagination;
public interface PaymentDao {
+ public DirectPaymentModelDao insertDirectPaymentWithFirstTransaction(DirectPaymentModelDao directPayment, 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);
+
+ public DirectPaymentModelDao getDirectPayment(UUID directPaymentId, InternalTenantContext context);
+
+ public DirectPaymentTransactionModelDao getDirectPaymentTransaction(UUID directTransactionId, InternalTenantContext context);
+
+ public List<DirectPaymentModelDao> getDirectPaymentsForAccount(UUID accountId, InternalTenantContext context);
+
+ public List<DirectPaymentTransactionModelDao> getDirectTransactionsForAccount(final UUID accountId, final InternalTenantContext context);
+
public PaymentModelDao insertPaymentWithFirstAttempt(PaymentModelDao paymentInfo, PaymentAttemptModelDao attempt, InternalCallContext context);
public PaymentAttemptModelDao updatePaymentWithNewAttempt(UUID paymentId, PaymentAttemptModelDao attempt, InternalCallContext context);
diff --git a/payment/src/main/java/org/killbill/billing/payment/glue/PaymentModule.java b/payment/src/main/java/org/killbill/billing/payment/glue/PaymentModule.java
index a221bbd..397927f 100644
--- a/payment/src/main/java/org/killbill/billing/payment/glue/PaymentModule.java
+++ b/payment/src/main/java/org/killbill/billing/payment/glue/PaymentModule.java
@@ -20,6 +20,9 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
+import org.killbill.billing.payment.api.DirectPaymentApi;
+import org.killbill.billing.payment.api.svcs.DefaultDirectPaymentApi;
+import org.killbill.billing.payment.core.DirectPaymentProcessor;
import org.skife.config.ConfigSource;
import org.skife.config.ConfigurationObjectFactory;
@@ -89,6 +92,7 @@ public class PaymentModule extends AbstractModule {
});
bind(ExecutorService.class).annotatedWith(Names.named(PLUGIN_EXECUTOR_NAMED)).toInstance(pluginExecutorService);
bind(PaymentProcessor.class).asEagerSingleton();
+ bind(DirectPaymentProcessor.class).asEagerSingleton();
bind(RefundProcessor.class).asEagerSingleton();
bind(PaymentMethodProcessor.class).asEagerSingleton();
}
@@ -103,6 +107,7 @@ public class PaymentModule extends AbstractModule {
bind(PaymentInternalApi.class).to(DefaultPaymentInternalApi.class).asEagerSingleton();
bind(PaymentApi.class).to(DefaultPaymentApi.class).asEagerSingleton();
+ bind(DirectPaymentApi.class).to(DefaultDirectPaymentApi.class).asEagerSingleton();
bind(InvoiceHandler.class).asEagerSingleton();
bind(PaymentTagHandler.class).asEagerSingleton();
bind(PaymentService.class).to(DefaultPaymentService.class).asEagerSingleton();
diff --git a/payment/src/main/java/org/killbill/billing/payment/provider/DefaultNoOpPaymentProviderPlugin.java b/payment/src/main/java/org/killbill/billing/payment/provider/DefaultNoOpPaymentProviderPlugin.java
index fd1deed..5cdebfe 100644
--- a/payment/src/main/java/org/killbill/billing/payment/provider/DefaultNoOpPaymentProviderPlugin.java
+++ b/payment/src/main/java/org/killbill/billing/payment/provider/DefaultNoOpPaymentProviderPlugin.java
@@ -25,6 +25,9 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import org.killbill.billing.catalog.api.Currency;
+import org.killbill.billing.payment.plugin.api.HostedPaymentPageDescriptorFields;
+import org.killbill.billing.payment.plugin.api.HostedPaymentPageFormDescriptor;
+import org.killbill.billing.payment.plugin.api.HostedPaymentPageNotification;
import org.killbill.clock.Clock;
import org.killbill.billing.payment.api.PaymentMethodPlugin;
import org.killbill.billing.payment.plugin.api.NoOpPaymentPluginApi;
@@ -90,15 +93,26 @@ public class DefaultNoOpPaymentProviderPlugin implements NoOpPaymentPluginApi {
}
@Override
+ public PaymentInfoPlugin authorizePayment(UUID kbAccountId, UUID kbPaymentId, UUID kbPaymentMethodId, BigDecimal amount, Currency currency, CallContext context)
+ throws PaymentPluginApiException {
+ return getInternalNoopPaymentInfoResult(kbPaymentId, amount, currency);
+ }
+
+ @Override
+ public PaymentInfoPlugin capturePayment(UUID kbAccountId, UUID kbPaymentId, UUID kbPaymentMethodId, BigDecimal amount, Currency currency, CallContext context)
+ throws PaymentPluginApiException {
+ return getInternalNoopPaymentInfoResult(kbPaymentId, amount, currency);
+ }
+
+ @Override
public PaymentInfoPlugin processPayment(final UUID kbAccountId, final UUID kbPaymentId, final UUID kbPaymentMethodId, final BigDecimal amount, final Currency currency, final CallContext context) throws PaymentPluginApiException {
- if (makeNextInvoiceFailWithException.getAndSet(false)) {
- throw new PaymentPluginApiException("", "test error");
- }
+ return getInternalNoopPaymentInfoResult(kbPaymentId, amount, currency);
+ }
- final PaymentPluginStatus status = (makeAllInvoicesFailWithError.get() || makeNextInvoiceFailWithError.getAndSet(false)) ? PaymentPluginStatus.ERROR : PaymentPluginStatus.PROCESSED;
- final PaymentInfoPlugin result = new DefaultNoOpPaymentInfoPlugin(kbPaymentId, amount, currency, clock.getUTCNow(), clock.getUTCNow(), status, null);
- payments.put(kbPaymentId.toString(), result);
- return result;
+ @Override
+ public PaymentInfoPlugin voidPayment(UUID kbAccountId, UUID kbPaymentId, UUID kbPaymentMethodId, CallContext context)
+ throws PaymentPluginApiException {
+ return getInternalNoopPaymentInfoResult(kbPaymentId, BigDecimal.ZERO, null);
}
@Override
@@ -213,6 +227,16 @@ public class DefaultNoOpPaymentProviderPlugin implements NoOpPaymentPluginApi {
}
@Override
+ public HostedPaymentPageFormDescriptor buildFormDescriptor(final UUID uuid, final HostedPaymentPageDescriptorFields hostedPaymentPageDescriptorFields, final TenantContext tenantContext) {
+ return null;
+ }
+
+ @Override
+ public HostedPaymentPageNotification processNotification(final String s, final TenantContext tenantContext) throws PaymentPluginApiException {
+ return null;
+ }
+
+ @Override
public RefundInfoPlugin processRefund(final UUID kbAccountId, final UUID kbPaymentId, final BigDecimal refundAmount, final Currency currency, final CallContext context) throws PaymentPluginApiException {
final PaymentInfoPlugin paymentInfoPlugin = getPaymentInfo(kbAccountId, kbPaymentId, context);
if (paymentInfoPlugin == null) {
@@ -260,4 +284,16 @@ public class DefaultNoOpPaymentProviderPlugin implements NoOpPaymentPluginApi {
return new DefaultPagination<RefundInfoPlugin>(offset, limit, (long) results.size(), (long) refunds.values().size(), results.iterator());
}
+
+ private PaymentInfoPlugin getInternalNoopPaymentInfoResult(final UUID kbPaymentId, final BigDecimal amount, final Currency currency) throws PaymentPluginApiException {
+ if (makeNextInvoiceFailWithException.getAndSet(false)) {
+ throw new PaymentPluginApiException("", "test error");
+ }
+
+ final PaymentPluginStatus status = (makeAllInvoicesFailWithError.get() || makeNextInvoiceFailWithError.getAndSet(false)) ? PaymentPluginStatus.ERROR : PaymentPluginStatus.PROCESSED;
+ final PaymentInfoPlugin result = new DefaultNoOpPaymentInfoPlugin(kbPaymentId, amount, currency, clock.getUTCNow(), clock.getUTCNow(), status, null);
+ payments.put(kbPaymentId.toString(), result);
+ return result;
+ }
+
}
diff --git a/payment/src/main/java/org/killbill/billing/payment/provider/ExternalPaymentProviderPlugin.java b/payment/src/main/java/org/killbill/billing/payment/provider/ExternalPaymentProviderPlugin.java
index 6c5579a..dc5a304 100644
--- a/payment/src/main/java/org/killbill/billing/payment/provider/ExternalPaymentProviderPlugin.java
+++ b/payment/src/main/java/org/killbill/billing/payment/provider/ExternalPaymentProviderPlugin.java
@@ -22,6 +22,9 @@ import java.util.List;
import java.util.UUID;
import org.killbill.billing.catalog.api.Currency;
+import org.killbill.billing.payment.plugin.api.HostedPaymentPageDescriptorFields;
+import org.killbill.billing.payment.plugin.api.HostedPaymentPageFormDescriptor;
+import org.killbill.billing.payment.plugin.api.HostedPaymentPageNotification;
import org.killbill.clock.Clock;
import org.killbill.billing.payment.api.PaymentMethodKVInfo;
import org.killbill.billing.payment.api.PaymentMethodPlugin;
@@ -59,11 +62,26 @@ public class ExternalPaymentProviderPlugin implements PaymentPluginApi {
}
@Override
+ public PaymentInfoPlugin authorizePayment(final UUID kbAccountId, final UUID kbPaymentId, final UUID kbPaymentMethodId, final BigDecimal amount, final Currency currency, final CallContext callContext) throws PaymentPluginApiException {
+ return new DefaultNoOpPaymentInfoPlugin(kbPaymentId, amount, currency, clock.getUTCNow(), clock.getUTCNow(), PaymentPluginStatus.PROCESSED, null);
+ }
+
+ @Override
+ public PaymentInfoPlugin capturePayment(final UUID kbAccountId, final UUID kbPaymentId, final UUID kbPaymentMethodId, final BigDecimal amount, final Currency currency, final CallContext callContext) throws PaymentPluginApiException {
+ return new DefaultNoOpPaymentInfoPlugin(kbPaymentId, amount, currency, clock.getUTCNow(), clock.getUTCNow(), PaymentPluginStatus.PROCESSED, null);
+ }
+
+ @Override
public PaymentInfoPlugin processPayment(final UUID kbAccountId, final UUID kbPaymentId, final UUID kbPaymentMethodId, final BigDecimal amount, final Currency currency, final CallContext context) throws PaymentPluginApiException {
return new DefaultNoOpPaymentInfoPlugin(kbPaymentId, amount, currency, clock.getUTCNow(), clock.getUTCNow(), PaymentPluginStatus.PROCESSED, null);
}
@Override
+ public PaymentInfoPlugin voidPayment(final UUID kbAccountId, final UUID kbPaymentId, final UUID kbPaymentMethodId, final CallContext callContext) throws PaymentPluginApiException {
+ return new DefaultNoOpPaymentInfoPlugin(kbPaymentId, BigDecimal.ZERO, null, clock.getUTCNow(), clock.getUTCNow(), PaymentPluginStatus.PROCESSED, null);
+ }
+
+ @Override
public PaymentInfoPlugin getPaymentInfo(final UUID kbAccountId, final UUID kbPaymentId, final TenantContext context) throws PaymentPluginApiException {
return new DefaultNoOpPaymentInfoPlugin(kbPaymentId, BigDecimal.ZERO, null, clock.getUTCNow(), clock.getUTCNow(), PaymentPluginStatus.PROCESSED, null);
}
@@ -118,4 +136,14 @@ public class ExternalPaymentProviderPlugin implements PaymentPluginApi {
@Override
public void resetPaymentMethods(final UUID kbAccountId, final List<PaymentMethodInfoPlugin> paymentMethods) throws PaymentPluginApiException {
}
+
+ @Override
+ public HostedPaymentPageFormDescriptor buildFormDescriptor(final UUID uuid, final HostedPaymentPageDescriptorFields hostedPaymentPageDescriptorFields, final TenantContext tenantContext) {
+ return null;
+ }
+
+ @Override
+ public HostedPaymentPageNotification processNotification(final String s, final TenantContext tenantContext) throws PaymentPluginApiException {
+ return null;
+ }
}
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
new file mode 100644
index 0000000..1845370
--- /dev/null
+++ b/payment/src/main/resources/org/killbill/billing/payment/dao/DirectPaymentSqlDao.sql.stg
@@ -0,0 +1,35 @@
+group DirectPaymentSqlDao: EntitySqlDao;
+
+tableName() ::= "direct_payments"
+
+historyTableName() ::= "direct_payment_history"
+
+extraTableFieldsWithComma(prefix) ::= <<
+, <prefix>record_id as payment_number
+>>
+
+defaultOrderBy(prefix) ::= <<
+order by <prefix>created_date ASC, <recordIdField(prefix)> ASC
+>>
+
+tableFields(prefix) ::= <<
+ <prefix>account_id
+, <prefix>payment_method_id
+, <prefix>external_key
+, <prefix>created_by
+, <prefix>created_date
+, <prefix>updated_by
+, <prefix>updated_date
+>>
+
+tableValues() ::= <<
+:accountId
+, :paymentMethodId
+, :externalKey
+, :createdBy
+, :createdDate
+, :updatedBy
+, :updatedDate
+>>
+
+
diff --git a/payment/src/main/resources/org/killbill/billing/payment/dao/DirectTransactionSqlDao.sql.stg b/payment/src/main/resources/org/killbill/billing/payment/dao/DirectTransactionSqlDao.sql.stg
new file mode 100644
index 0000000..0a5f8b6
--- /dev/null
+++ b/payment/src/main/resources/org/killbill/billing/payment/dao/DirectTransactionSqlDao.sql.stg
@@ -0,0 +1,55 @@
+group DirectTransactionSqlDao: EntitySqlDao;
+
+tableName() ::= "direct_transactions"
+
+historyTableName() ::= "direct_transaction_history"
+
+defaultOrderBy(prefix) ::= <<
+order by <prefix>effective_date ASC, <recordIdField(prefix)> ASC
+>>
+
+
+tableFields(prefix) ::= <<
+ <prefix>transaction_type
+, <prefix>effective_date
+, <prefix>payment_status
+, <prefix>amount
+, <prefix>currency
+, <prefix>direct_payment_id
+, <prefix>gateway_error_code
+, <prefix>gateway_error_msg
+, <prefix>created_by
+, <prefix>created_date
+, <prefix>updated_by
+, <prefix>updated_date
+>>
+
+tableValues() ::= <<
+ :transactionType
+, :effectiveDate
+, :paymentStatus
+, :amount
+, :currency
+, :directPaymentId
+, :gatewayErrorCode
+, :gatewayErrorMsg
+, :createdBy
+, :createdDate
+, :updatedBy
+, :updatedDate
+>>
+
+
+updateTransactionStatus() ::= <<
+update <tableName()>
+set payment_status = :paymentStatus
+, gateway_error_code = :gatewayErrorCode
+, gateway_error_msg = :gatewayErrorMsg
+, updated_by = :updatedBy
+, updated_date = :createdDate
+where id = :id
+<AND_CHECK_TENANT()>
+;
+>>
+
+
diff --git a/payment/src/main/resources/org/killbill/billing/payment/ddl.sql b/payment/src/main/resources/org/killbill/billing/payment/ddl.sql
index cbeda72..de818a2 100644
--- a/payment/src/main/resources/org/killbill/billing/payment/ddl.sql
+++ b/payment/src/main/resources/org/killbill/billing/payment/ddl.sql
@@ -191,6 +191,93 @@ CREATE INDEX refund_history_target_record_id ON refund_history(target_record_id)
CREATE INDEX refund_history_tenant_account_record_id ON refund_history(tenant_record_id, account_record_id);
+DROP TABLE IF EXISTS direct_payments;
+CREATE TABLE direct_payments (
+ record_id int(11) unsigned NOT NULL AUTO_INCREMENT,
+ id char(36) NOT NULL,
+ account_id char(36) NOT NULL,
+ payment_method_id char(36) NOT NULL,
+ external_key varchar(255),
+ created_by varchar(50) NOT NULL,
+ created_date datetime NOT NULL,
+ updated_by varchar(50) NOT NULL,
+ updated_date datetime NOT NULL,
+ account_record_id int(11) unsigned default null,
+ tenant_record_id int(11) unsigned default null,
+ PRIMARY KEY (record_id)
+) /*! CHARACTER SET utf8 COLLATE utf8_bin */;
+CREATE UNIQUE INDEX direct_payments_id ON direct_payments(id);
+CREATE UNIQUE INDEX direct_payments_key ON direct_payments(external_key);
+CREATE INDEX direct_payments_accnt ON direct_payments(account_id);
+CREATE INDEX direct_payments_tenant_account_record_id ON direct_payments(tenant_record_id, account_record_id);
+
+
+DROP TABLE IF EXISTS direct_payment_history;
+CREATE TABLE direct_payment_history (
+ record_id int(11) unsigned NOT NULL AUTO_INCREMENT,
+ id char(36) NOT NULL,
+ target_record_id int(11) unsigned NOT NULL,
+ account_id char(36) NOT NULL,
+ payment_method_id char(36) NOT NULL,
+ external_key varchar(255),
+ change_type char(6) NOT NULL,
+ created_by varchar(50) NOT NULL,
+ created_date datetime NOT NULL,
+ updated_by varchar(50) NOT NULL,
+ updated_date datetime NOT NULL,
+ account_record_id int(11) unsigned default null,
+ tenant_record_id int(11) unsigned default null,
+ PRIMARY KEY(record_id)
+) /*! CHARACTER SET utf8 COLLATE utf8_bin */;
+CREATE INDEX direct_payment_history_target_record_id ON direct_payment_history(target_record_id);
+CREATE INDEX direct_payment_history_tenant_account_record_id ON direct_payment_history(tenant_record_id, account_record_id);
+DROP TABLE IF EXISTS direct_transactions;
+CREATE TABLE direct_transactions (
+ record_id int(11) unsigned NOT NULL AUTO_INCREMENT,
+ id char(36) NOT NULL,
+ transaction_type varchar(32) NOT NULL,
+ effective_date datetime NOT NULL,
+ payment_status varchar(50),
+ amount numeric(15,9),
+ currency char(3),
+ direct_payment_id char(36) NOT NULL,
+ gateway_error_code varchar(32),
+ gateway_error_msg varchar(256),
+ created_by varchar(50) NOT NULL,
+ created_date datetime NOT NULL,
+ updated_by varchar(50) NOT NULL,
+ updated_date datetime NOT NULL,
+ account_record_id int(11) unsigned default null,
+ tenant_record_id int(11) unsigned default null,
+ PRIMARY KEY (record_id)
+) /*! CHARACTER SET utf8 COLLATE utf8_bin */;
+CREATE UNIQUE INDEX direct_transactions_id ON direct_transactions(id);
+CREATE INDEX direct_transactions_direct_id ON direct_transactions(direct_payment_id);
+CREATE INDEX direct_transactions_tenant_account_record_id ON direct_transactions(tenant_record_id, account_record_id);
+DROP TABLE IF EXISTS direct_transaction_history;
+CREATE TABLE direct_transaction_history (
+ record_id int(11) unsigned NOT NULL AUTO_INCREMENT,
+ id char(36) NOT NULL,
+ target_record_id int(11) unsigned NOT NULL,
+ transaction_type varchar(32) NOT NULL,
+ effective_date datetime NOT NULL,
+ payment_status varchar(50),
+ amount numeric(15,9),
+ currency char(3),
+ direct_payment_id char(36) NOT NULL,
+ gateway_error_code varchar(32),
+ gateway_error_msg varchar(256),
+ change_type char(6) NOT NULL,
+ created_by varchar(50) NOT NULL,
+ created_date datetime NOT NULL,
+ updated_by varchar(50) NOT NULL,
+ updated_date datetime NOT NULL,
+ account_record_id int(11) unsigned default null,
+ tenant_record_id int(11) unsigned default null,
+ PRIMARY KEY (record_id)
+) /*! CHARACTER SET utf8 COLLATE utf8_bin */;
+CREATE INDEX direct_transaction_history_target_record_id ON direct_transaction_history(target_record_id);
+CREATE INDEX direct_transaction_history_tenant_account_record_id ON direct_transaction_history(tenant_record_id, account_record_id);
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 892bc51..60282d0 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,6 +41,36 @@ public class MockPaymentDao implements PaymentDao {
private final Map<UUID, PaymentAttemptModelDao> attempts = new HashMap<UUID, PaymentAttemptModelDao>();
@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) {
+
+ }
+
+ @Override
+ public DirectPaymentModelDao getDirectPayment(final UUID directPaymentId, final InternalTenantContext context) {
+ return null;
+ }
+
+ @Override
+ public DirectPaymentTransactionModelDao getDirectPaymentTransaction(final UUID directTransactionId, final InternalTenantContext context) {
+ return null;
+ }
+
+ @Override
+ public List<DirectPaymentModelDao> getDirectPaymentsForAccount(final UUID accountId, final InternalTenantContext context) {
+ return null;
+ }
+
+ @Override
+ public List<DirectPaymentTransactionModelDao> getDirectTransactionsForAccount(final UUID accountId, final InternalTenantContext context) {
+ return null;
+ }
+
+ @Override
public PaymentModelDao insertPaymentWithFirstAttempt(final PaymentModelDao paymentInfo, final PaymentAttemptModelDao attempt,
final InternalCallContext context) {
synchronized (this) {
diff --git a/payment/src/test/java/org/killbill/billing/payment/dao/TestPaymentDao.java b/payment/src/test/java/org/killbill/billing/payment/dao/TestPaymentDao.java
index d12107b..b23b434 100644
--- a/payment/src/test/java/org/killbill/billing/payment/dao/TestPaymentDao.java
+++ b/payment/src/test/java/org/killbill/billing/payment/dao/TestPaymentDao.java
@@ -17,11 +17,11 @@
package org.killbill.billing.payment.dao;
import java.math.BigDecimal;
-import java.math.RoundingMode;
import java.util.List;
import java.util.UUID;
import org.joda.time.DateTime;
+import org.killbill.billing.payment.api.TransactionType;
import org.testng.annotations.Test;
import org.killbill.billing.catalog.api.Currency;
@@ -31,6 +31,7 @@ import org.killbill.billing.payment.api.RefundStatus;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.fail;
@@ -284,4 +285,67 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
assertEquals(deletedPaymentMethod.getId(), paymentMethodId);
assertEquals(deletedPaymentMethod.getPluginName(), pluginName);
}
+
+ @Test(groups = "slow")
+ public void testDirectPayment() {
+
+ final UUID paymentMethodId = UUID.randomUUID();
+ final UUID accountId = UUID.randomUUID();
+ final String externalName = "fo0";
+
+ DateTime utcNow = clock.getUTCNow();
+ final DirectPaymentModelDao dpmd = new DirectPaymentModelDao(utcNow, utcNow, accountId, paymentMethodId, externalName);
+ final DirectPaymentTransactionModelDao dptmd = new DirectPaymentTransactionModelDao(utcNow, utcNow, dpmd.getId(), TransactionType.AUTHORIZE,
+ utcNow, PaymentStatus.UNKNOWN, BigDecimal.TEN, Currency.USD, null, null);
+ DirectPaymentModelDao savedDirectPayment = paymentDao.insertDirectPaymentWithFirstTransaction(dpmd, dptmd, internalCallContext);
+ assertNotNull(savedDirectPayment);
+ assertEquals(savedDirectPayment.getAccountId(), accountId);
+ assertEquals(savedDirectPayment.getPaymentMethodId(), paymentMethodId);
+ assertEquals(savedDirectPayment.getExternalKey(), externalName);
+
+ savedDirectPayment = paymentDao.getDirectPayment(dpmd.getId(), internalCallContext);
+ assertNotNull(savedDirectPayment);
+ assertNotNull(savedDirectPayment.getPaymentNumber());
+ assertEquals(savedDirectPayment.getAccountId(), accountId);
+ assertEquals(savedDirectPayment.getPaymentMethodId(), paymentMethodId);
+ assertEquals(savedDirectPayment.getExternalKey(), externalName);
+
+ DirectPaymentTransactionModelDao savedTransaction = paymentDao.getDirectPaymentTransaction(dptmd.getId(), internalCallContext);
+ assertNotNull(savedTransaction);
+ assertEquals(savedTransaction.getDirectPaymentId(), dpmd.getId());
+ assertEquals(savedTransaction.getTransactionType(), TransactionType.AUTHORIZE);
+ assertEquals(savedTransaction.getAmount().compareTo(BigDecimal.TEN), 0);
+ assertEquals(savedTransaction.getEffectiveDate().compareTo(utcNow), 0);
+ assertEquals(savedTransaction.getPaymentStatus(), PaymentStatus.UNKNOWN);
+ assertEquals(savedTransaction.getCurrency(), Currency.USD);
+ assertNull(savedTransaction.getGatewayErrorCode());
+ assertNull(savedTransaction.getGatewayErrorMsg());
+
+ paymentDao.updateDirectPaymentAndTransactionOnCompletion(dpmd.getId(), PaymentStatus.SUCCESS, BigDecimal.TEN, Currency.USD, dptmd.getId(), "100", "Excellent", internalCallContext);
+
+
+ savedDirectPayment = paymentDao.getDirectPayment(dpmd.getId(), internalCallContext);
+ assertNotNull(savedDirectPayment);
+ assertEquals(savedDirectPayment.getAccountId(), accountId);
+ assertEquals(savedDirectPayment.getPaymentMethodId(), paymentMethodId);
+ assertEquals(savedDirectPayment.getExternalKey(), externalName);
+
+ savedTransaction = paymentDao.getDirectPaymentTransaction(dptmd.getId(), internalCallContext);
+ assertNotNull(savedTransaction);
+ assertEquals(savedTransaction.getDirectPaymentId(), dpmd.getId());
+ assertEquals(savedTransaction.getTransactionType(), TransactionType.AUTHORIZE);
+ assertEquals(savedTransaction.getAmount().compareTo(BigDecimal.TEN), 0);
+ assertEquals(savedTransaction.getEffectiveDate().compareTo(utcNow), 0);
+ assertEquals(savedTransaction.getPaymentStatus(), PaymentStatus.SUCCESS);
+ assertEquals(savedTransaction.getCurrency(), Currency.USD);
+ assertEquals(savedTransaction.getGatewayErrorCode(), "100");
+ assertEquals(savedTransaction.getGatewayErrorMsg(), "Excellent");
+
+ List<DirectPaymentModelDao> perAccountPayments = paymentDao.getDirectPaymentsForAccount(accountId, internalCallContext);
+ assertEquals(perAccountPayments.size(), 1);
+
+ List<DirectPaymentTransactionModelDao> perAccountTransactions = paymentDao.getDirectTransactionsForAccount(accountId, internalCallContext);
+ assertEquals(perAccountTransactions.size(), 1);
+
+ }
}
diff --git a/payment/src/test/java/org/killbill/billing/payment/provider/MockPaymentProviderPlugin.java b/payment/src/test/java/org/killbill/billing/payment/provider/MockPaymentProviderPlugin.java
index 5b98fc5..e2341ac 100644
--- a/payment/src/test/java/org/killbill/billing/payment/provider/MockPaymentProviderPlugin.java
+++ b/payment/src/test/java/org/killbill/billing/payment/provider/MockPaymentProviderPlugin.java
@@ -25,9 +25,11 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import org.killbill.billing.catalog.api.Currency;
-import org.killbill.clock.Clock;
import org.killbill.billing.payment.api.PaymentMethodPlugin;
import org.killbill.billing.payment.api.TestPaymentMethodPlugin;
+import org.killbill.billing.payment.plugin.api.HostedPaymentPageDescriptorFields;
+import org.killbill.billing.payment.plugin.api.HostedPaymentPageFormDescriptor;
+import org.killbill.billing.payment.plugin.api.HostedPaymentPageNotification;
import org.killbill.billing.payment.plugin.api.NoOpPaymentPluginApi;
import org.killbill.billing.payment.plugin.api.PaymentInfoPlugin;
import org.killbill.billing.payment.plugin.api.PaymentMethodInfoPlugin;
@@ -39,6 +41,7 @@ import org.killbill.billing.util.callcontext.CallContext;
import org.killbill.billing.util.callcontext.TenantContext;
import org.killbill.billing.util.entity.DefaultPagination;
import org.killbill.billing.util.entity.Pagination;
+import org.killbill.clock.Clock;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
@@ -96,15 +99,26 @@ public class MockPaymentProviderPlugin implements NoOpPaymentPluginApi {
}
@Override
+ public PaymentInfoPlugin authorizePayment(UUID kbAccountId, UUID kbPaymentId, UUID kbPaymentMethodId, BigDecimal amount, Currency currency, CallContext context)
+ throws PaymentPluginApiException {
+ return getPaymentInfoPluginResult(kbPaymentId, amount, currency);
+ }
+
+ @Override
+ public PaymentInfoPlugin capturePayment(UUID kbAccountId, UUID kbPaymentId, UUID kbPaymentMethodId, BigDecimal amount, Currency currency, CallContext context)
+ throws PaymentPluginApiException {
+ return getPaymentInfoPluginResult(kbPaymentId, amount, currency);
+ }
+
+ @Override
public PaymentInfoPlugin processPayment(final UUID kbAccountId, final UUID kbPaymentId, final UUID kbPaymentMethodId, final BigDecimal amount, final Currency currency, final CallContext context) throws PaymentPluginApiException {
- if (makeNextInvoiceFailWithException.getAndSet(false)) {
- throw new PaymentPluginApiException("", "test error");
- }
+ return getPaymentInfoPluginResult(kbPaymentId, amount, currency);
+ }
- final PaymentPluginStatus status = (makeAllInvoicesFailWithError.get() || makeNextInvoiceFailWithError.getAndSet(false)) ? PaymentPluginStatus.ERROR : PaymentPluginStatus.PROCESSED;
- final PaymentInfoPlugin result = new DefaultNoOpPaymentInfoPlugin(kbPaymentId, amount, currency, clock.getUTCNow(), clock.getUTCNow(), status, null);
- payments.put(kbPaymentId.toString(), result);
- return result;
+ @Override
+ public PaymentInfoPlugin voidPayment(UUID kbAccountId, UUID kbPaymentId, UUID kbPaymentMethodId, CallContext context)
+ throws PaymentPluginApiException {
+ return getPaymentInfoPluginResult(kbPaymentId, BigDecimal.ZERO, null);
}
@Override
@@ -187,6 +201,16 @@ public class MockPaymentProviderPlugin implements NoOpPaymentPluginApi {
}
@Override
+ public HostedPaymentPageFormDescriptor buildFormDescriptor(final UUID uuid, final HostedPaymentPageDescriptorFields hostedPaymentPageDescriptorFields, final TenantContext tenantContext) {
+ return null;
+ }
+
+ @Override
+ public HostedPaymentPageNotification processNotification(final String s, final TenantContext tenantContext) throws PaymentPluginApiException {
+ return null;
+ }
+
+ @Override
public RefundInfoPlugin processRefund(final UUID kbAccountId, final UUID kbPaymentId, final BigDecimal refundAmount, final Currency currency, final CallContext context) throws PaymentPluginApiException {
final PaymentInfoPlugin paymentInfoPlugin = getPaymentInfo(kbAccountId, kbPaymentId, context);
if (paymentInfoPlugin == null) {
@@ -225,4 +249,15 @@ public class MockPaymentProviderPlugin implements NoOpPaymentPluginApi {
}));
return DefaultPagination.<RefundInfoPlugin>build(offset, limit, results);
}
+
+ private PaymentInfoPlugin getPaymentInfoPluginResult(final UUID kbPaymentId, final BigDecimal amount, final Currency currency) throws PaymentPluginApiException {
+ if (makeNextInvoiceFailWithException.getAndSet(false)) {
+ throw new PaymentPluginApiException("", "test error");
+ }
+
+ final PaymentPluginStatus status = (makeAllInvoicesFailWithError.get() || makeNextInvoiceFailWithError.getAndSet(false)) ? PaymentPluginStatus.ERROR : PaymentPluginStatus.PROCESSED;
+ final PaymentInfoPlugin result = new DefaultNoOpPaymentInfoPlugin(kbPaymentId, amount, currency, clock.getUTCNow(), clock.getUTCNow(), status, null);
+ payments.put(kbPaymentId.toString(), result);
+ return result;
+ }
}
pom.xml 2(+1 -1)
diff --git a/pom.xml b/pom.xml
index 6cf7f98..610a1c0 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.5.33</version>
+ <version>0.6.34-SNAPSHOT</version>
</parent>
<artifactId>killbill</artifactId>
<version>0.10.3-SNAPSHOT</version>
diff --git a/util/src/main/java/org/killbill/billing/util/dao/TableName.java b/util/src/main/java/org/killbill/billing/util/dao/TableName.java
index 9157f35..4e00bb2 100644
--- a/util/src/main/java/org/killbill/billing/util/dao/TableName.java
+++ b/util/src/main/java/org/killbill/billing/util/dao/TableName.java
@@ -41,6 +41,10 @@ public enum TableName {
PAYMENTS("payments", ObjectType.PAYMENT, PAYMENT_HISTORY),
PAYMENT_METHOD_HISTORY("payment_method_history"),
PAYMENT_METHODS("payment_methods", ObjectType.PAYMENT_METHOD, PAYMENT_METHOD_HISTORY),
+ DIRECT_PAYMENT_HISTORY("direct_payment_history"),
+ DIRECT_PAYMENTS("direct_payments", ObjectType.DIRECT_PAYMENT, DIRECT_PAYMENT_HISTORY),
+ DIRECT_TRANSACTION_HISTORY("direct_transaction_history"),
+ DIRECT_TRANSACTIONS("direct_transactions", ObjectType.DIRECT_TRANSACTION, DIRECT_TRANSACTION_HISTORY),
SUBSCRIPTIONS("subscriptions", ObjectType.SUBSCRIPTION),
SUBSCRIPTION_EVENTS("subscription_events", ObjectType.SUBSCRIPTION_EVENT),
REFUND_HISTORY("refund_history"),