killbill-uncached
Changes
jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageFormDescriptorJson.java 127(+127 -0)
osgi-bundles/bundles/jruby/src/main/java/org/killbill/billing/osgi/bundles/jruby/JRubyPaymentPlugin.java 13(+6 -7)
osgi-bundles/tests/beatrix/src/test/java/org/killbill/billing/osgi/bundles/test/TestPaymentPluginApi.java 7(+3 -4)
osgi-bundles/tests/payment/src/test/java/org/killbill/billing/osgi/bundles/test/TestPaymentPluginApi.java 7(+3 -4)
payment/src/main/java/org/killbill/billing/payment/api/svcs/DefaultPaymentGatewayApi.java 52(+52 -0)
payment/src/main/java/org/killbill/billing/payment/provider/DefaultNoOpPaymentProviderPlugin.java 7(+3 -4)
payment/src/main/java/org/killbill/billing/payment/provider/ExternalPaymentProviderPlugin.java 7(+3 -4)
pom.xml 2(+1 -1)
Details
diff --git a/beatrix/src/test/resources/killbill-currency-plugin-test.tar.gz b/beatrix/src/test/resources/killbill-currency-plugin-test.tar.gz
index 0006981..cec5cea 100644
Binary files a/beatrix/src/test/resources/killbill-currency-plugin-test.tar.gz and b/beatrix/src/test/resources/killbill-currency-plugin-test.tar.gz differ
diff --git a/beatrix/src/test/resources/killbill-notification-test.tar.gz b/beatrix/src/test/resources/killbill-notification-test.tar.gz
index b03cd00..41a496e 100644
Binary files a/beatrix/src/test/resources/killbill-notification-test.tar.gz and b/beatrix/src/test/resources/killbill-notification-test.tar.gz differ
diff --git a/beatrix/src/test/resources/killbill-payment-test.tar.gz b/beatrix/src/test/resources/killbill-payment-test.tar.gz
index 7263203..2bf919b 100644
Binary files a/beatrix/src/test/resources/killbill-payment-test.tar.gz and b/beatrix/src/test/resources/killbill-payment-test.tar.gz differ
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/GatewayNotificationJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/GatewayNotificationJson.java
new file mode 100644
index 0000000..04dfd7c
--- /dev/null
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/GatewayNotificationJson.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.jaxrs.json;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.ResponseBuilder;
+import javax.ws.rs.core.Response.Status;
+
+import org.killbill.billing.payment.plugin.api.GatewayNotification;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class GatewayNotificationJson extends JsonBase {
+
+ private final String kbPaymentId;
+ private final Integer status;
+ private final String entity;
+ private final Map<String, List<String>> headers;
+ private final Map<String, String> properties;
+
+ @JsonCreator
+ public GatewayNotificationJson(@JsonProperty("kbPaymentId") final String kbPaymentId,
+ @JsonProperty("status") final Integer status,
+ @JsonProperty("entity") final String entity,
+ @JsonProperty("headers") final Map<String, List<String>> headers,
+ @JsonProperty("properties") final Map<String, String> properties) {
+ this.kbPaymentId = kbPaymentId;
+ this.status = status;
+ this.entity = entity;
+ this.headers = headers;
+ this.properties = properties;
+ }
+
+ public GatewayNotificationJson(final GatewayNotification notification) {
+ this.kbPaymentId = notification.getKbPaymentId().toString();
+ this.status = notification.getStatus();
+ this.entity = notification.getEntity();
+ this.headers = notification.getHeaders();
+ this.properties = propertiesToMap(notification.getProperties());
+ }
+
+ public Response toResponse() {
+ final ResponseBuilder responseBuilder = Response.status(status == null ? Status.OK : Status.fromStatusCode(status));
+ if (entity != null) {
+ responseBuilder.entity(entity);
+ }
+ if (headers != null) {
+ for (final String key : headers.keySet()) {
+ if (headers.get(key) != null) {
+ for (final String value : headers.get(key)) {
+ responseBuilder.header(key, value);
+ }
+ }
+ }
+ }
+
+ return responseBuilder.build();
+ }
+
+ public String getKbPaymentId() {
+ return kbPaymentId;
+ }
+
+ public Integer getStatus() {
+ return status;
+ }
+
+ public String getEntity() {
+ return entity;
+ }
+
+ public Map<String, List<String>> getHeaders() {
+ return headers;
+ }
+
+ public Map<String, String> getProperties() {
+ return properties;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuffer sb = new StringBuffer("GatewayNotificationJson{");
+ sb.append("kbPaymentId='").append(kbPaymentId).append('\'');
+ sb.append(", status=").append(status);
+ sb.append(", entity='").append(entity).append('\'');
+ sb.append(", headers=").append(headers);
+ sb.append(", properties=").append(properties);
+ sb.append('}');
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ final GatewayNotificationJson that = (GatewayNotificationJson) o;
+
+ if (entity != null ? !entity.equals(that.entity) : that.entity != null) {
+ return false;
+ }
+ if (headers != null ? !headers.equals(that.headers) : that.headers != null) {
+ return false;
+ }
+ if (kbPaymentId != null ? !kbPaymentId.equals(that.kbPaymentId) : that.kbPaymentId != null) {
+ return false;
+ }
+ if (properties != null ? !properties.equals(that.properties) : that.properties != null) {
+ return false;
+ }
+ if (status != null ? !status.equals(that.status) : that.status != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = kbPaymentId != null ? kbPaymentId.hashCode() : 0;
+ result = 31 * result + (status != null ? status.hashCode() : 0);
+ result = 31 * result + (entity != null ? entity.hashCode() : 0);
+ result = 31 * result + (headers != null ? headers.hashCode() : 0);
+ result = 31 * result + (properties != null ? properties.hashCode() : 0);
+ return result;
+ }
+}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageFieldsJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageFieldsJson.java
index 2355bbe..470f8f8 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageFieldsJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageFieldsJson.java
@@ -16,183 +16,28 @@
package org.killbill.billing.jaxrs.json;
-import java.math.BigDecimal;
-import java.util.Map;
-
-import org.killbill.billing.catalog.api.Currency;
+import java.util.List;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public class HostedPaymentPageFieldsJson extends JsonBase {
- private final String credential2;
- private final String credential3;
- private final String credential4;
- private final BigDecimal amount;
- private final Currency currency;
- private final String transactionType;
- private final String authCode;
- private final String notifyUrl;
- private final String returnUrl;
- private final String forwardUrl;
- private final String cancelReturnUrl;
- private final String redirectParam;
- private final String accountName;
- private final HostedPaymentPageCustomerJson customer;
- private final HostedPaymentPageBillingAddressJson billingAddress;
- private final String order;
- private final String description;
- private final String tax;
- private final String shipping;
- private final Map<String, String> customFields;
+ private final List<PluginPropertyJson> formFields;
@JsonCreator
- public HostedPaymentPageFieldsJson(@JsonProperty("credential2") final String credential2,
- @JsonProperty("credential3") final String credential3,
- @JsonProperty("credential4") final String credential4,
- @JsonProperty("amount") final BigDecimal amount,
- @JsonProperty("currency") final Currency currency,
- @JsonProperty("transactionType") final String transactionType,
- @JsonProperty("authCode") final String authCode,
- @JsonProperty("notifyUrl") final String notifyUrl,
- @JsonProperty("returnUrl") final String returnUrl,
- @JsonProperty("forwardUrl") final String forwardUrl,
- @JsonProperty("cancelReturnUrl") final String cancelReturnUrl,
- @JsonProperty("redirectParam") final String redirectParam,
- @JsonProperty("accountName") final String accountName,
- @JsonProperty("customer") final HostedPaymentPageCustomerJson customer,
- @JsonProperty("billingAddress") final HostedPaymentPageBillingAddressJson billingAddress,
- @JsonProperty("order") final String order,
- @JsonProperty("description") final String description,
- @JsonProperty("tax") final String tax,
- @JsonProperty("shipping") final String shipping,
- @JsonProperty("customFields") final Map<String, String> customFields) {
- this.credential2 = credential2;
- this.credential3 = credential3;
- this.credential4 = credential4;
- this.amount = amount;
- this.currency = currency;
- this.transactionType = transactionType;
- this.authCode = authCode;
- this.notifyUrl = notifyUrl;
- this.returnUrl = returnUrl;
- this.forwardUrl = forwardUrl;
- this.cancelReturnUrl = cancelReturnUrl;
- this.redirectParam = redirectParam;
- this.accountName = accountName;
- this.customer = customer;
- this.billingAddress = billingAddress;
- this.order = order;
- this.description = description;
- this.tax = tax;
- this.shipping = shipping;
- this.customFields = customFields;
- }
-
- public String getCredential2() {
- return credential2;
- }
-
- public String getCredential3() {
- return credential3;
- }
-
- public String getCredential4() {
- return credential4;
- }
-
- public BigDecimal getAmount() {
- return amount;
- }
-
- public Currency getCurrency() {
- return currency;
- }
-
- public String getTransactionType() {
- return transactionType;
- }
-
- public String getAuthCode() {
- return authCode;
- }
-
- public String getNotifyUrl() {
- return notifyUrl;
- }
-
- public String getReturnUrl() {
- return returnUrl;
- }
-
- public String getForwardUrl() {
- return forwardUrl;
- }
-
- public String getCancelReturnUrl() {
- return cancelReturnUrl;
- }
-
- public String getRedirectParam() {
- return redirectParam;
- }
-
- public String getAccountName() {
- return accountName;
- }
-
- public HostedPaymentPageCustomerJson getCustomer() {
- return customer;
- }
-
- public HostedPaymentPageBillingAddressJson getBillingAddress() {
- return billingAddress;
- }
-
- public String getOrder() {
- return order;
- }
-
- public String getDescription() {
- return description;
- }
-
- public String getTax() {
- return tax;
- }
-
- public String getShipping() {
- return shipping;
+ public HostedPaymentPageFieldsJson(@JsonProperty("formFields") final List<PluginPropertyJson> formFields) {
+ this.formFields = formFields;
}
- public Map<String, String> getCustomFields() {
- return customFields;
+ public List<PluginPropertyJson> getCustomFields() {
+ return formFields;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("HostedPaymentPageFieldsJson{");
- sb.append("credential2='").append(credential2).append('\'');
- sb.append(", credential3='").append(credential3).append('\'');
- sb.append(", credential4='").append(credential4).append('\'');
- sb.append(", amount=").append(amount);
- sb.append(", currency=").append(currency);
- sb.append(", transactionType='").append(transactionType).append('\'');
- sb.append(", authCode='").append(authCode).append('\'');
- sb.append(", notifyUrl='").append(notifyUrl).append('\'');
- sb.append(", returnUrl='").append(returnUrl).append('\'');
- sb.append(", forwardUrl='").append(forwardUrl).append('\'');
- sb.append(", cancelReturnUrl='").append(cancelReturnUrl).append('\'');
- sb.append(", redirectParam='").append(redirectParam).append('\'');
- sb.append(", accountName='").append(accountName).append('\'');
- sb.append(", customer=").append(customer);
- sb.append(", billingAddress=").append(billingAddress);
- sb.append(", order='").append(order).append('\'');
- sb.append(", description='").append(description).append('\'');
- sb.append(", tax='").append(tax).append('\'');
- sb.append(", shipping='").append(shipping).append('\'');
- sb.append(", customFields=").append(customFields);
+ sb.append(", formFields=").append(formFields);
sb.append('}');
return sb.toString();
}
@@ -208,64 +53,7 @@ public class HostedPaymentPageFieldsJson extends JsonBase {
final HostedPaymentPageFieldsJson that = (HostedPaymentPageFieldsJson) o;
- if (accountName != null ? !accountName.equals(that.accountName) : that.accountName != null) {
- return false;
- }
- if (amount != null ? !amount.equals(that.amount) : that.amount != null) {
- return false;
- }
- if (authCode != null ? !authCode.equals(that.authCode) : that.authCode != null) {
- return false;
- }
- if (billingAddress != null ? !billingAddress.equals(that.billingAddress) : that.billingAddress != null) {
- return false;
- }
- if (cancelReturnUrl != null ? !cancelReturnUrl.equals(that.cancelReturnUrl) : that.cancelReturnUrl != null) {
- return false;
- }
- if (credential2 != null ? !credential2.equals(that.credential2) : that.credential2 != null) {
- return false;
- }
- if (credential3 != null ? !credential3.equals(that.credential3) : that.credential3 != null) {
- return false;
- }
- if (credential4 != null ? !credential4.equals(that.credential4) : that.credential4 != null) {
- return false;
- }
- if (currency != that.currency) {
- return false;
- }
- if (customFields != null ? !customFields.equals(that.customFields) : that.customFields != null) {
- return false;
- }
- if (customer != null ? !customer.equals(that.customer) : that.customer != null) {
- return false;
- }
- if (description != null ? !description.equals(that.description) : that.description != null) {
- return false;
- }
- if (forwardUrl != null ? !forwardUrl.equals(that.forwardUrl) : that.forwardUrl != null) {
- return false;
- }
- if (notifyUrl != null ? !notifyUrl.equals(that.notifyUrl) : that.notifyUrl != null) {
- return false;
- }
- if (order != null ? !order.equals(that.order) : that.order != null) {
- return false;
- }
- if (redirectParam != null ? !redirectParam.equals(that.redirectParam) : that.redirectParam != null) {
- return false;
- }
- if (returnUrl != null ? !returnUrl.equals(that.returnUrl) : that.returnUrl != null) {
- return false;
- }
- if (shipping != null ? !shipping.equals(that.shipping) : that.shipping != null) {
- return false;
- }
- if (tax != null ? !tax.equals(that.tax) : that.tax != null) {
- return false;
- }
- if (transactionType != null ? !transactionType.equals(that.transactionType) : that.transactionType != null) {
+ if (formFields != null ? !formFields.equals(that.formFields) : that.formFields != null) {
return false;
}
@@ -274,26 +62,6 @@ public class HostedPaymentPageFieldsJson extends JsonBase {
@Override
public int hashCode() {
- int result = credential2 != null ? credential2.hashCode() : 0;
- result = 31 * result + (credential3 != null ? credential3.hashCode() : 0);
- result = 31 * result + (credential4 != null ? credential4.hashCode() : 0);
- result = 31 * result + (amount != null ? amount.hashCode() : 0);
- result = 31 * result + (currency != null ? currency.hashCode() : 0);
- result = 31 * result + (transactionType != null ? transactionType.hashCode() : 0);
- result = 31 * result + (authCode != null ? authCode.hashCode() : 0);
- result = 31 * result + (notifyUrl != null ? notifyUrl.hashCode() : 0);
- result = 31 * result + (returnUrl != null ? returnUrl.hashCode() : 0);
- result = 31 * result + (forwardUrl != null ? forwardUrl.hashCode() : 0);
- result = 31 * result + (cancelReturnUrl != null ? cancelReturnUrl.hashCode() : 0);
- result = 31 * result + (redirectParam != null ? redirectParam.hashCode() : 0);
- result = 31 * result + (accountName != null ? accountName.hashCode() : 0);
- result = 31 * result + (customer != null ? customer.hashCode() : 0);
- result = 31 * result + (billingAddress != null ? billingAddress.hashCode() : 0);
- result = 31 * result + (order != null ? order.hashCode() : 0);
- result = 31 * result + (description != null ? description.hashCode() : 0);
- result = 31 * result + (tax != null ? tax.hashCode() : 0);
- result = 31 * result + (shipping != null ? shipping.hashCode() : 0);
- result = 31 * result + (customFields != null ? customFields.hashCode() : 0);
- return result;
+ return formFields != null ? formFields.hashCode() : 0;
}
}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageFormDescriptorJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageFormDescriptorJson.java
new file mode 100644
index 0000000..2753e70
--- /dev/null
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/HostedPaymentPageFormDescriptorJson.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.killbill.billing.jaxrs.json;
+
+import java.util.Map;
+
+import org.killbill.billing.payment.plugin.api.HostedPaymentPageFormDescriptor;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class HostedPaymentPageFormDescriptorJson extends JsonBase {
+
+ private final String kbAccountId;
+ private final String formMethod;
+ private final String formUrl;
+ private final Map<String, String> formFields;
+ private final Map<String, String> properties;
+
+ @JsonCreator
+ public HostedPaymentPageFormDescriptorJson(@JsonProperty("kbAccountId") final String kbAccountId,
+ @JsonProperty("formMethod") final String formMethod,
+ @JsonProperty("formUrl") final String formUrl,
+ @JsonProperty("formFields") final Map<String, String> formFields,
+ @JsonProperty("properties") final Map<String, String> properties) {
+ this.kbAccountId = kbAccountId;
+ this.formMethod = formMethod;
+ this.formUrl = formUrl;
+ this.formFields = formFields;
+ this.properties = properties;
+ }
+
+ public HostedPaymentPageFormDescriptorJson(final HostedPaymentPageFormDescriptor descriptor) {
+ this.kbAccountId = descriptor.getKbAccountId().toString();
+ this.formMethod = descriptor.getFormMethod();
+ this.formUrl = descriptor.getFormUrl();
+ this.formFields = propertiesToMap(descriptor.getFormFields());
+ this.properties = propertiesToMap(descriptor.getProperties());
+ }
+
+ public String getKbAccountId() {
+ return kbAccountId;
+ }
+
+ public String getFormMethod() {
+ return formMethod;
+ }
+
+ public String getFormUrl() {
+ return formUrl;
+ }
+
+ public Map<String, String> getFormFields() {
+ return formFields;
+ }
+
+ public Map<String, String> getProperties() {
+ return properties;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuffer sb = new StringBuffer("HostedPaymentPageFormDescriptorJson{");
+ sb.append("kbAccountId='").append(kbAccountId).append('\'');
+ sb.append(", formMethod='").append(formMethod).append('\'');
+ sb.append(", formUrl='").append(formUrl).append('\'');
+ sb.append(", formFields=").append(formFields);
+ sb.append(", properties=").append(properties);
+ sb.append('}');
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ final HostedPaymentPageFormDescriptorJson that = (HostedPaymentPageFormDescriptorJson) o;
+
+ if (formFields != null ? !formFields.equals(that.formFields) : that.formFields != null) {
+ return false;
+ }
+ if (formMethod != null ? !formMethod.equals(that.formMethod) : that.formMethod != null) {
+ return false;
+ }
+ if (formUrl != null ? !formUrl.equals(that.formUrl) : that.formUrl != null) {
+ return false;
+ }
+ if (kbAccountId != null ? !kbAccountId.equals(that.kbAccountId) : that.kbAccountId != null) {
+ return false;
+ }
+ if (properties != null ? !properties.equals(that.properties) : that.properties != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = kbAccountId != null ? kbAccountId.hashCode() : 0;
+ result = 31 * result + (formMethod != null ? formMethod.hashCode() : 0);
+ result = 31 * result + (formUrl != null ? formUrl.hashCode() : 0);
+ result = 31 * result + (formFields != null ? formFields.hashCode() : 0);
+ result = 31 * result + (properties != null ? properties.hashCode() : 0);
+ return result;
+ }
+}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/JsonBase.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/JsonBase.java
index 9ac1001..f73272d 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/JsonBase.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/JsonBase.java
@@ -16,11 +16,15 @@
package org.killbill.billing.jaxrs.json;
+import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.UUID;
import javax.annotation.Nullable;
+import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.util.audit.AuditLog;
import com.google.common.base.Function;
@@ -59,4 +63,23 @@ public abstract class JsonBase {
public List<AuditLogJson> getAuditLogs() {
return auditLogs;
}
+
+ protected List<PluginProperty> propertiesToList(final Map<String, String> propertiesMap) {
+ final List<PluginProperty> properties = new LinkedList<PluginProperty>();
+ for (final String key : propertiesMap.keySet()) {
+ final PluginProperty property = new PluginProperty(key, propertiesMap.get(key), false);
+ properties.add(property);
+ }
+ return properties;
+ }
+
+ protected Map<String, String> propertiesToMap(final Iterable<PluginProperty> properties) {
+ final Map<String, String> propertiesMap = new HashMap<String, String>();
+ for (final PluginProperty pluginProperty : properties) {
+ if (pluginProperty.getValue() != null) {
+ propertiesMap.put(pluginProperty.getKey(), pluginProperty.getValue().toString());
+ }
+ }
+ return propertiesMap;
+ }
}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentMethodJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentMethodJson.java
index f78fe38..9acf598 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentMethodJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentMethodJson.java
@@ -65,12 +65,12 @@ public class PaymentMethodJson extends JsonBase {
final PaymentMethodPlugin pluginDetail = in.getPluginDetail();
PaymentMethodPluginDetailJson pluginDetailJson = null;
if (pluginDetail != null) {
- List<PaymentMethodProperties> properties = null;
+ List<PluginPropertyJson> properties = null;
if (pluginDetail.getProperties() != null) {
- properties = new ArrayList<PaymentMethodJson.PaymentMethodProperties>(Collections2.transform(pluginDetail.getProperties(), new Function<PluginProperty, PaymentMethodProperties>() {
+ properties = new ArrayList<PluginPropertyJson>(Collections2.transform(pluginDetail.getProperties(), new Function<PluginProperty, PluginPropertyJson>() {
@Override
- public PaymentMethodProperties apply(final PluginProperty input) {
- return new PaymentMethodProperties(input.getKey(), input.getValue() == null ? null : input.getValue().toString(), input.getIsUpdatable());
+ public PluginPropertyJson apply(final PluginProperty input) {
+ return new PluginPropertyJson(input.getKey(), input.getValue() == null ? null : input.getValue().toString(), input.getIsUpdatable());
}
}));
}
@@ -221,8 +221,8 @@ public class PaymentMethodJson extends JsonBase {
public List<PluginProperty> getProperties() {
if (pluginInfo.getProperties() != null) {
final List<PluginProperty> result = new LinkedList<PluginProperty>();
- for (final PaymentMethodProperties cur : pluginInfo.getProperties()) {
- result.add(new PluginProperty(cur.getKey(), cur.getValue(), cur.isUpdatable));
+ for (final PluginPropertyJson cur : pluginInfo.getProperties()) {
+ result.add(new PluginProperty(cur.getKey(), cur.getValue(), cur.getIsUpdatable()));
}
return result;
}
@@ -322,7 +322,7 @@ public class PaymentMethodJson extends JsonBase {
private final String state;
private final String zip;
private final String country;
- private final List<PaymentMethodProperties> properties;
+ private final List<PluginPropertyJson> properties;
@JsonCreator
public PaymentMethodPluginDetailJson(@JsonProperty("externalPaymentId") final String externalPaymentId,
@@ -339,7 +339,7 @@ public class PaymentMethodJson extends JsonBase {
@JsonProperty("state") final String state,
@JsonProperty("zip") final String zip,
@JsonProperty("country") final String country,
- @JsonProperty("properties") final List<PaymentMethodProperties> properties) {
+ @JsonProperty("properties") final List<PluginPropertyJson> properties) {
this.externalPaymentId = externalPaymentId;
this.isDefaultPaymentMethod = isDefaultPaymentMethod;
this.type = type;
@@ -413,7 +413,7 @@ public class PaymentMethodJson extends JsonBase {
return country;
}
- public List<PaymentMethodProperties> getProperties() {
+ public List<PluginPropertyJson> getProperties() {
return properties;
}
@@ -519,75 +519,4 @@ public class PaymentMethodJson extends JsonBase {
return result;
}
}
-
- public static final class PaymentMethodProperties {
-
- private final String key;
- private final String value;
- private final Boolean isUpdatable;
-
- @JsonCreator
- public PaymentMethodProperties(@JsonProperty("key") final String key,
- @JsonProperty("value") final String value,
- @JsonProperty("isUpdatable") final Boolean isUpdatable) {
- super();
- this.key = key;
- this.value = value;
- this.isUpdatable = isUpdatable;
- }
-
- public String getKey() {
- return key;
- }
-
- public String getValue() {
- return value;
- }
-
- public Boolean getIsUpdatable() {
- return isUpdatable;
- }
-
- @Override
- public String toString() {
- final StringBuilder sb = new StringBuilder("PaymentMethodProperties{");
- sb.append("key='").append(key).append('\'');
- sb.append(", value='").append(value).append('\'');
- sb.append(", isUpdatable=").append(isUpdatable);
- sb.append('}');
- return sb.toString();
- }
-
- @Override
- public boolean equals(final Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- final PaymentMethodProperties that = (PaymentMethodProperties) o;
-
- if (isUpdatable != null ? !isUpdatable.equals(that.isUpdatable) : that.isUpdatable != null) {
- return false;
- }
- if (key != null ? !key.equals(that.key) : that.key != null) {
- return false;
- }
- if (value != null ? !value.equals(that.value) : that.value != null) {
- return false;
- }
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = key != null ? key.hashCode() : 0;
- result = 31 * result + (value != null ? value.hashCode() : 0);
- result = 31 * result + (isUpdatable != null ? isUpdatable.hashCode() : 0);
- return result;
- }
- }
}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PluginPropertyJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PluginPropertyJson.java
new file mode 100644
index 0000000..40c02c5
--- /dev/null
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PluginPropertyJson.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * 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 org.killbill.billing.payment.api.PluginProperty;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class PluginPropertyJson {
+
+ private final String key;
+ private final String value;
+ private final Boolean isUpdatable;
+
+ @JsonCreator
+ public PluginPropertyJson(@JsonProperty("key") final String key,
+ @JsonProperty("value") final String value,
+ @JsonProperty("isUpdatable") final Boolean isUpdatable) {
+ this.key = key;
+ this.value = value;
+ this.isUpdatable = isUpdatable;
+ }
+
+ public PluginPropertyJson(final PluginProperty pluginProperty) {
+ this(pluginProperty.getKey(), pluginProperty.getValue() == null ? null : pluginProperty.getValue().toString(), pluginProperty.getIsUpdatable());
+ }
+
+ public PluginProperty toPluginProperty() {
+ return new PluginProperty(key, value, isUpdatable);
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public Boolean getIsUpdatable() {
+ return isUpdatable;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("PluginPropertyJson{");
+ sb.append("key='").append(key).append('\'');
+ sb.append(", value='").append(value).append('\'');
+ sb.append(", isUpdatable=").append(isUpdatable);
+ sb.append('}');
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ final PluginPropertyJson that = (PluginPropertyJson) o;
+
+ if (isUpdatable != null ? !isUpdatable.equals(that.isUpdatable) : that.isUpdatable != null) {
+ return false;
+ }
+ if (key != null ? !key.equals(that.key) : that.key != null) {
+ return false;
+ }
+ if (value != null ? !value.equals(that.value) : that.value != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = key != null ? key.hashCode() : 0;
+ result = 31 * result + (value != null ? value.hashCode() : 0);
+ result = 31 * result + (isUpdatable != null ? isUpdatable.hashCode() : 0);
+ return result;
+ }
+}
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
index 0b9df0f..3360b9d 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
@@ -145,6 +145,9 @@ public interface JaxrsResource {
public static final String DIRECT_PAYMENTS = "directPayments";
public static final String DIRECT_PAYMENTS_PATH = PREFIX + "/" + DIRECT_PAYMENTS;
+ public static final String PAYMENT_GATEWAYS = "paymentGateways";
+ public static final String PAYMENT_GATEWAYS_PATH = PREFIX + "/" + PAYMENT_GATEWAYS;
+
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/PaymentGatewayResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentGatewayResource.java
new file mode 100644
index 0000000..e7c6aea
--- /dev/null
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentGatewayResource.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * 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.resources;
+
+import java.util.List;
+import java.util.UUID;
+
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.killbill.billing.account.api.Account;
+import org.killbill.billing.account.api.AccountApiException;
+import org.killbill.billing.account.api.AccountUserApi;
+import org.killbill.billing.jaxrs.json.GatewayNotificationJson;
+import org.killbill.billing.jaxrs.json.HostedPaymentPageFieldsJson;
+import org.killbill.billing.jaxrs.json.HostedPaymentPageFormDescriptorJson;
+import org.killbill.billing.jaxrs.json.PluginPropertyJson;
+import org.killbill.billing.jaxrs.util.Context;
+import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
+import org.killbill.billing.payment.api.PaymentApiException;
+import org.killbill.billing.payment.api.PaymentGatewayApi;
+import org.killbill.billing.payment.api.PluginProperty;
+import org.killbill.billing.payment.plugin.api.GatewayNotification;
+import org.killbill.billing.payment.plugin.api.HostedPaymentPageFormDescriptor;
+import org.killbill.billing.util.api.AuditUserApi;
+import org.killbill.billing.util.api.CustomFieldUserApi;
+import org.killbill.billing.util.api.TagUserApi;
+import org.killbill.billing.util.callcontext.CallContext;
+import org.killbill.clock.Clock;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static javax.ws.rs.core.MediaType.WILDCARD;
+
+@Path(JaxrsResource.PAYMENT_GATEWAYS_PATH)
+public class PaymentGatewayResource extends JaxRsResourceBase {
+
+ private final PaymentGatewayApi paymentGatewayApi;
+
+ @Inject
+ public PaymentGatewayResource(final JaxrsUriBuilder uriBuilder,
+ final TagUserApi tagUserApi,
+ final CustomFieldUserApi customFieldUserApi,
+ final AuditUserApi auditUserApi,
+ final AccountUserApi accountUserApi,
+ final PaymentGatewayApi paymentGatewayApi,
+ final Clock clock,
+ final Context context) {
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, accountUserApi, clock, context);
+ this.paymentGatewayApi = paymentGatewayApi;
+ }
+
+ @POST
+ @Path("/" + HOSTED + "/" + FORM + "/{" + QUERY_PAYMENT_PLUGIN_NAME + ":" + ANYTHING_PATTERN + "}/" + "/{" + QUERY_ACCOUNT_ID + ":" + UUID_PATTERN + "}")
+ @Consumes(APPLICATION_JSON)
+ @Produces(APPLICATION_JSON)
+ // Generate form data to redirect the customer to the gateway
+ public Response buildFormDescriptor(final HostedPaymentPageFieldsJson json,
+ @PathParam(QUERY_ACCOUNT_ID) final String accountIdString,
+ @PathParam(QUERY_PAYMENT_PLUGIN_NAME) final String pluginName,
+ @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment,
+ @javax.ws.rs.core.Context final UriInfo uriInfo,
+ @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
+ final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
+ final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+ final UUID accountId = UUID.fromString(accountIdString);
+ final Account account = accountUserApi.getAccountById(accountId, callContext);
+
+ final Iterable<PluginProperty> customFields = Iterables.<PluginPropertyJson, PluginProperty>transform(json.getCustomFields(),
+ new Function<PluginPropertyJson, PluginProperty>() {
+ @Override
+ public PluginProperty apply(final PluginPropertyJson pluginPropertyJson) {
+ return pluginPropertyJson.toPluginProperty();
+ }
+ }
+ );
+ final HostedPaymentPageFormDescriptor descriptor = paymentGatewayApi.buildFormDescriptor(account, customFields, pluginProperties, callContext);
+ final HostedPaymentPageFormDescriptorJson result = new HostedPaymentPageFormDescriptorJson(descriptor);
+
+ return Response.status(Response.Status.OK).entity(result).build();
+ }
+
+ @POST
+ @Path("/{" + QUERY_PAYMENT_PLUGIN_NAME + ":" + ANYTHING_PATTERN + "}")
+ @Consumes(WILDCARD)
+ @Produces(APPLICATION_JSON)
+ public Response processNotification(final String body,
+ @PathParam(QUERY_PAYMENT_PLUGIN_NAME) final String pluginName,
+ @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
+ @HeaderParam(HDR_CREATED_BY) final String createdBy,
+ @HeaderParam(HDR_REASON) final String reason,
+ @HeaderParam(HDR_COMMENT) final String comment,
+ @javax.ws.rs.core.Context final UriInfo uriInfo,
+ @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException {
+ final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
+ final CallContext callContext = context.createContext(createdBy, reason, comment, request);
+
+ // Note: the body is opaque here, as it comes from the gateway. The associated payment plugin will know how to deserialize it though
+ final GatewayNotification notification = paymentGatewayApi.processNotification(body, pluginName, pluginProperties, callContext);
+ final GatewayNotificationJson result = new GatewayNotificationJson(notification);
+
+ // The plugin told us how to build the response
+ return result.toResponse();
+ }
+}
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 7c918d4..7c59b72 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
@@ -52,7 +52,6 @@ import org.killbill.billing.invoice.api.InvoicePayment;
import org.killbill.billing.invoice.api.InvoicePaymentApi;
import org.killbill.billing.jaxrs.json.ChargebackJson;
import org.killbill.billing.jaxrs.json.CustomFieldJson;
-import org.killbill.billing.jaxrs.json.HostedPaymentPageFieldsJson;
import org.killbill.billing.jaxrs.json.InvoiceItemJson;
import org.killbill.billing.jaxrs.json.PaymentJson;
import org.killbill.billing.jaxrs.json.RefundJson;
@@ -82,7 +81,6 @@ import com.google.common.collect.ImmutableMap;
import com.google.inject.Inject;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
-import static javax.ws.rs.core.MediaType.WILDCARD;
@Path(JaxrsResource.PAYMENTS_PATH)
public class PaymentResource extends JaxRsResourceBase {
@@ -320,36 +318,6 @@ public class PaymentResource extends JaxRsResourceBase {
return uriBuilder.buildResponse(RefundResource.class, "getRefund", result.getId(), uriInfo.getBaseUri().toString());
}
- @POST
- @Path("/" + HOSTED + "/" + FORM + "/{gateway:" + ANYTHING_PATTERN + "}")
- @Consumes(APPLICATION_JSON)
- @Produces(APPLICATION_JSON)
- // Generate form data to redirect the customer to the gateway
- public Response buildFormDescriptor(final HostedPaymentPageFieldsJson json,
- @PathParam("gateway") final String gateway,
- @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();
- }
-
- @POST
- @Path("/" + HOSTED)
- @Consumes(WILDCARD)
- @Produces(APPLICATION_JSON)
- public Response processNotification(final String body,
- @PathParam("gateway") final String gateway,
- @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 {
- // Note: the body is opaque here, as it comes from the gateway. The associated payment plugin will now how to deserialize it though
- throw new UnsupportedOperationException();
- }
-
@GET
@Path("/{paymentId:" + UUID_PATTERN + "}/" + CUSTOM_FIELDS)
@Produces(APPLICATION_JSON)
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 1d4fd34..8443126 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
@@ -30,9 +30,8 @@ import org.killbill.billing.osgi.api.OSGIPluginProperties;
import org.killbill.billing.osgi.api.config.PluginRubyConfig;
import org.killbill.billing.payment.api.PaymentMethodPlugin;
import org.killbill.billing.payment.api.PluginProperty;
-import org.killbill.billing.payment.plugin.api.HostedPaymentPageDescriptorFields;
+import org.killbill.billing.payment.plugin.api.GatewayNotification;
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;
@@ -237,20 +236,20 @@ public class JRubyPaymentPlugin extends JRubyPlugin implements PaymentPluginApi
}
@Override
- public HostedPaymentPageFormDescriptor buildFormDescriptor(final UUID kbAccountId, final HostedPaymentPageDescriptorFields hostedPaymentPageDescriptorFields, final Iterable<PluginProperty> properties, final TenantContext context) throws PaymentPluginApiException {
+ public HostedPaymentPageFormDescriptor buildFormDescriptor(final UUID kbAccountId, final Iterable<PluginProperty> customFields, final Iterable<PluginProperty> properties, final CallContext context) throws PaymentPluginApiException {
return callWithRuntimeAndChecking(new PluginCallback<HostedPaymentPageFormDescriptor>(VALIDATION_PLUGIN_TYPE.PAYMENT) {
@Override
public HostedPaymentPageFormDescriptor doCall(final Ruby runtime) throws PaymentPluginApiException {
- return ((PaymentPluginApi) pluginInstance).buildFormDescriptor(kbAccountId, hostedPaymentPageDescriptorFields, properties, context);
+ return ((PaymentPluginApi) pluginInstance).buildFormDescriptor(kbAccountId, customFields, properties, context);
}
});
}
@Override
- public HostedPaymentPageNotification processNotification(final String notification, final Iterable<PluginProperty> properties, final TenantContext context) throws PaymentPluginApiException {
- return callWithRuntimeAndChecking(new PluginCallback<HostedPaymentPageNotification>(VALIDATION_PLUGIN_TYPE.PAYMENT) {
+ public GatewayNotification processNotification(final String notification, final Iterable<PluginProperty> properties, final CallContext context) throws PaymentPluginApiException {
+ return callWithRuntimeAndChecking(new PluginCallback<GatewayNotification>(VALIDATION_PLUGIN_TYPE.PAYMENT) {
@Override
- public HostedPaymentPageNotification doCall(final Ruby runtime) throws PaymentPluginApiException {
+ public GatewayNotification doCall(final Ruby runtime) throws PaymentPluginApiException {
return ((PaymentPluginApi) pluginInstance).processNotification(notification, properties, context);
}
});
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 fec09e0..3c04998 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
@@ -30,9 +30,8 @@ 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.api.PluginProperty;
-import org.killbill.billing.payment.plugin.api.HostedPaymentPageDescriptorFields;
+import org.killbill.billing.payment.plugin.api.GatewayNotification;
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;
@@ -261,12 +260,12 @@ public class TestPaymentPluginApi implements PaymentPluginApi {
}
@Override
- public HostedPaymentPageFormDescriptor buildFormDescriptor(final UUID kbAccountId, final HostedPaymentPageDescriptorFields hostedPaymentPageDescriptorFields, final Iterable<PluginProperty> properties, final TenantContext tenantContext) {
+ public HostedPaymentPageFormDescriptor buildFormDescriptor(final UUID kbAccountId, final Iterable<PluginProperty> customFields, final Iterable<PluginProperty> properties, final CallContext callContext) {
return null;
}
@Override
- public HostedPaymentPageNotification processNotification(final String notification, final Iterable<PluginProperty> properties, final TenantContext tenantContext) throws PaymentPluginApiException {
+ public GatewayNotification processNotification(final String notification, final Iterable<PluginProperty> properties, final CallContext callContext) 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 5d391cf..94cff65 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
@@ -28,9 +28,8 @@ import org.joda.time.DateTime;
import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.payment.api.PaymentMethodPlugin;
import org.killbill.billing.payment.api.PluginProperty;
-import org.killbill.billing.payment.plugin.api.HostedPaymentPageDescriptorFields;
+import org.killbill.billing.payment.plugin.api.GatewayNotification;
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;
@@ -328,12 +327,12 @@ public class TestPaymentPluginApi implements PaymentPluginApiWithTestControl {
}
@Override
- public HostedPaymentPageFormDescriptor buildFormDescriptor(final UUID kbAccountId, final HostedPaymentPageDescriptorFields hostedPaymentPageDescriptorFields, final Iterable<PluginProperty> properties, final TenantContext tenantContext) {
+ public HostedPaymentPageFormDescriptor buildFormDescriptor(final UUID kbAccountId, final Iterable<PluginProperty> customFields, final Iterable<PluginProperty> properties, final CallContext callContext) {
return null;
}
@Override
- public HostedPaymentPageNotification processNotification(final String notification, final Iterable<PluginProperty> properties, final TenantContext tenantContext) throws PaymentPluginApiException {
+ public GatewayNotification processNotification(final String notification, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentPluginApiException {
return null;
}
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/svcs/DefaultPaymentGatewayApi.java b/payment/src/main/java/org/killbill/billing/payment/api/svcs/DefaultPaymentGatewayApi.java
new file mode 100644
index 0000000..b27a38c
--- /dev/null
+++ b/payment/src/main/java/org/killbill/billing/payment/api/svcs/DefaultPaymentGatewayApi.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * 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 javax.inject.Inject;
+
+import org.killbill.billing.account.api.Account;
+import org.killbill.billing.payment.api.PaymentApiException;
+import org.killbill.billing.payment.api.PaymentGatewayApi;
+import org.killbill.billing.payment.api.PluginProperty;
+import org.killbill.billing.payment.core.PaymentGatewayProcessor;
+import org.killbill.billing.payment.plugin.api.GatewayNotification;
+import org.killbill.billing.payment.plugin.api.HostedPaymentPageFormDescriptor;
+import org.killbill.billing.util.callcontext.CallContext;
+import org.killbill.billing.util.callcontext.InternalCallContextFactory;
+
+public class DefaultPaymentGatewayApi implements PaymentGatewayApi {
+
+ private final PaymentGatewayProcessor paymentGatewayProcessor;
+ private final InternalCallContextFactory internalCallContextFactory;
+
+ @Inject
+ public DefaultPaymentGatewayApi(final PaymentGatewayProcessor paymentGatewayProcessor, final InternalCallContextFactory internalCallContextFactory) {
+ this.paymentGatewayProcessor = paymentGatewayProcessor;
+ this.internalCallContextFactory = internalCallContextFactory;
+ }
+
+ @Override
+ public HostedPaymentPageFormDescriptor buildFormDescriptor(final Account account, final Iterable<PluginProperty> customFields, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentApiException {
+ return paymentGatewayProcessor.buildFormDescriptor(account, customFields, properties, internalCallContextFactory.createInternalCallContext(account.getId(), callContext), callContext);
+ }
+
+ @Override
+ public GatewayNotification processNotification(final String notification, final String pluginName, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentApiException {
+ return paymentGatewayProcessor.processNotification(notification, pluginName, properties, callContext);
+ }
+}
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/DirectPaymentProcessor.java b/payment/src/main/java/org/killbill/billing/payment/core/DirectPaymentProcessor.java
index a157ce1..e2b6283 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/DirectPaymentProcessor.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/DirectPaymentProcessor.java
@@ -367,38 +367,38 @@ public class DirectPaymentProcessor extends ProcessorBase {
Preconditions.checkArgument(account.getCurrency().equals(currency), String.format("Currency %s doesn't match the one on the account (%s)", currency, currency));
try {
- return paymentPluginDispatcher.dispatchWithAccountLock(new CallableWithAccountLock<DirectPayment>(locker,
- account.getExternalKey(),
- new WithAccountLockCallback<DirectPayment>() {
-
- @Override
- public DirectPayment doOperation() throws PaymentApiException {
- final DateTime utcNow = clock.getUTCNow();
- final DirectPaymentModelDao paymentModelDao;
- final DirectPaymentTransactionModelDao paymentTransactionModelDao;
- if (directPaymentId == null) {
- final DirectPaymentModelDao pmd = new DirectPaymentModelDao(utcNow, utcNow, account.getId(), account.getPaymentMethodId(), externalKey);
- final DirectPaymentTransactionModelDao ptmd = new DirectPaymentTransactionModelDao(utcNow, utcNow, pmd.getId(),
- transactionType, utcNow, PaymentStatus.UNKNOWN,
- amount, currency, null, null);
-
- paymentModelDao = paymentDao.insertDirectPaymentWithFirstTransaction(pmd, ptmd, callContext);
- paymentTransactionModelDao = paymentDao.getDirectTransactionsForAccount(account.getId(), callContext).get(0);
- } else {
- paymentModelDao = paymentDao.getDirectPayment(directPaymentId, callContext);
- if (paymentModelDao == null) {
- throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT, directPaymentId);
- }
-
- final DirectPaymentTransactionModelDao ptmd = new DirectPaymentTransactionModelDao(utcNow, utcNow, directPaymentId,
- transactionType, utcNow, PaymentStatus.UNKNOWN,
- amount, currency, null, null);
- paymentTransactionModelDao = paymentDao.updateDirectPaymentWithNewTransaction(directPaymentId, ptmd, callContext);
+ return paymentPluginDispatcher.dispatchWithTimeout(new CallableWithAccountLock<DirectPayment>(locker,
+ account.getExternalKey(),
+ new WithAccountLockCallback<DirectPayment>() {
+
+ @Override
+ public DirectPayment doOperation() throws PaymentApiException {
+ final DateTime utcNow = clock.getUTCNow();
+ final DirectPaymentModelDao paymentModelDao;
+ final DirectPaymentTransactionModelDao paymentTransactionModelDao;
+ if (directPaymentId == null) {
+ final DirectPaymentModelDao pmd = new DirectPaymentModelDao(utcNow, utcNow, account.getId(), account.getPaymentMethodId(), externalKey);
+ final DirectPaymentTransactionModelDao ptmd = new DirectPaymentTransactionModelDao(utcNow, utcNow, pmd.getId(),
+ transactionType, utcNow, PaymentStatus.UNKNOWN,
+ amount, currency, null, null);
+
+ paymentModelDao = paymentDao.insertDirectPaymentWithFirstTransaction(pmd, ptmd, callContext);
+ paymentTransactionModelDao = paymentDao.getDirectTransactionsForAccount(account.getId(), callContext).get(0);
+ } else {
+ paymentModelDao = paymentDao.getDirectPayment(directPaymentId, callContext);
+ if (paymentModelDao == null) {
+ throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT, directPaymentId);
}
- return getDirectPayment(pluginWrapper, account, amount, currency, paymentModelDao.getId(), paymentTransactionModelDao.getId(), properties, callContext);
+ final DirectPaymentTransactionModelDao ptmd = new DirectPaymentTransactionModelDao(utcNow, utcNow, directPaymentId,
+ transactionType, utcNow, PaymentStatus.UNKNOWN,
+ amount, currency, null, null);
+ paymentTransactionModelDao = paymentDao.updateDirectPaymentWithNewTransaction(directPaymentId, ptmd, callContext);
}
+
+ return getDirectPayment(pluginWrapper, account, amount, currency, paymentModelDao.getId(), paymentTransactionModelDao.getId(), properties, callContext);
}
+ }
));
} catch (final TimeoutException e) {
// TODO PIERRE
@@ -414,21 +414,21 @@ public class DirectPaymentProcessor extends ProcessorBase {
Preconditions.checkArgument((amount == null && currency == null) || account.getCurrency().equals(currency), String.format("Currency %s doesn't match the one on the account (%s)", currency, currency));
try {
- return paymentPluginDispatcher.dispatchWithAccountLock(new CallableWithAccountLock<DirectPayment>(locker,
- account.getExternalKey(),
- new WithAccountLockCallback<DirectPayment>() {
-
- @Override
- public DirectPayment doOperation() throws PaymentApiException {
- final DateTime utcNow = clock.getUTCNow();
- final DirectPaymentTransactionModelDao ptmd = new DirectPaymentTransactionModelDao(utcNow, utcNow, directPaymentId,
- transactionType, utcNow, PaymentStatus.UNKNOWN,
- amount, currency, null, null);
- final DirectPaymentTransactionModelDao inserted = paymentDao.updateDirectPaymentWithNewTransaction(directPaymentId, ptmd, callContext);
-
- return getDirectPayment(pluginWrapper, account, amount, currency, directPaymentId, inserted.getId(), properties, callContext);
- }
+ return paymentPluginDispatcher.dispatchWithTimeout(new CallableWithAccountLock<DirectPayment>(locker,
+ account.getExternalKey(),
+ new WithAccountLockCallback<DirectPayment>() {
+
+ @Override
+ public DirectPayment doOperation() throws PaymentApiException {
+ final DateTime utcNow = clock.getUTCNow();
+ final DirectPaymentTransactionModelDao ptmd = new DirectPaymentTransactionModelDao(utcNow, utcNow, directPaymentId,
+ transactionType, utcNow, PaymentStatus.UNKNOWN,
+ amount, currency, null, null);
+ final DirectPaymentTransactionModelDao inserted = paymentDao.updateDirectPaymentWithNewTransaction(directPaymentId, ptmd, callContext);
+
+ return getDirectPayment(pluginWrapper, account, amount, currency, directPaymentId, inserted.getId(), properties, callContext);
}
+ }
));
} catch (final TimeoutException e) {
// TODO PIERRE
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/PaymentGatewayProcessor.java b/payment/src/main/java/org/killbill/billing/payment/core/PaymentGatewayProcessor.java
new file mode 100644
index 0000000..695c7ca
--- /dev/null
+++ b/payment/src/main/java/org/killbill/billing/payment/core/PaymentGatewayProcessor.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
+ *
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * 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.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import javax.inject.Inject;
+
+import org.killbill.billing.ErrorCode;
+import org.killbill.billing.account.api.Account;
+import org.killbill.billing.account.api.AccountInternalApi;
+import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.invoice.api.InvoiceInternalApi;
+import org.killbill.billing.osgi.api.OSGIServiceRegistration;
+import org.killbill.billing.payment.api.PaymentApiException;
+import org.killbill.billing.payment.api.PluginProperty;
+import org.killbill.billing.payment.dao.PaymentDao;
+import org.killbill.billing.payment.dispatcher.PluginDispatcher;
+import org.killbill.billing.payment.plugin.api.GatewayNotification;
+import org.killbill.billing.payment.plugin.api.HostedPaymentPageFormDescriptor;
+import org.killbill.billing.payment.plugin.api.PaymentPluginApi;
+import org.killbill.billing.payment.plugin.api.PaymentPluginApiException;
+import org.killbill.billing.tag.TagInternalApi;
+import org.killbill.billing.util.callcontext.CallContext;
+import org.killbill.billing.util.config.PaymentConfig;
+import org.killbill.billing.util.dao.NonEntityDao;
+import org.killbill.bus.api.PersistentBus;
+import org.killbill.commons.locker.GlobalLocker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.name.Named;
+
+import static org.killbill.billing.payment.glue.PaymentModule.PLUGIN_EXECUTOR_NAMED;
+
+public class PaymentGatewayProcessor extends ProcessorBase {
+
+ private final PluginDispatcher<HostedPaymentPageFormDescriptor> paymentPluginFormDispatcher;
+ private final PluginDispatcher<GatewayNotification> paymentPluginNotificationDispatcher;
+
+ private static final Logger log = LoggerFactory.getLogger(PaymentGatewayProcessor.class);
+
+ @Inject
+ public PaymentGatewayProcessor(final OSGIServiceRegistration<PaymentPluginApi> pluginRegistry,
+ final AccountInternalApi accountUserApi,
+ final InvoiceInternalApi invoiceApi,
+ final TagInternalApi tagUserApi,
+ final PaymentDao paymentDao,
+ final NonEntityDao nonEntityDao,
+ final PersistentBus eventBus,
+ final GlobalLocker locker,
+ final PaymentConfig paymentConfig,
+ @Named(PLUGIN_EXECUTOR_NAMED) final ExecutorService executor) {
+ super(pluginRegistry, accountUserApi, eventBus, paymentDao, nonEntityDao, tagUserApi, locker, executor, invoiceApi);
+ final long paymentPluginTimeoutSec = TimeUnit.SECONDS.convert(paymentConfig.getPaymentPluginTimeout().getPeriod(), paymentConfig.getPaymentPluginTimeout().getUnit());
+ this.paymentPluginFormDispatcher = new PluginDispatcher<HostedPaymentPageFormDescriptor>(paymentPluginTimeoutSec, executor);
+ this.paymentPluginNotificationDispatcher = new PluginDispatcher<GatewayNotification>(paymentPluginTimeoutSec, executor);
+ }
+
+ public HostedPaymentPageFormDescriptor buildFormDescriptor(final Account account, final Iterable<PluginProperty> customFields, final Iterable<PluginProperty> properties, final InternalCallContext internalCallContext, final CallContext callContext) throws PaymentApiException {
+ try {
+ return paymentPluginFormDispatcher.dispatchWithTimeout(new CallableWithAccountLock<HostedPaymentPageFormDescriptor>(locker,
+ account.getExternalKey(),
+ new WithAccountLockCallback<HostedPaymentPageFormDescriptor>() {
+
+ @Override
+ public HostedPaymentPageFormDescriptor doOperation() throws PaymentApiException {
+ final PaymentPluginApi plugin = getPaymentProviderPlugin(account, internalCallContext);
+
+ try {
+ return plugin.buildFormDescriptor(account.getId(), customFields, properties, callContext);
+ } catch (final RuntimeException e) {
+ throw new PaymentApiException(e, ErrorCode.PAYMENT_INTERNAL_ERROR);
+ } catch (final PaymentPluginApiException e) {
+ throw new PaymentApiException(e, ErrorCode.PAYMENT_INTERNAL_ERROR);
+ }
+ }
+ }
+ ));
+ } catch (final TimeoutException e) {
+ throw new PaymentApiException(ErrorCode.PAYMENT_PLUGIN_TIMEOUT, account.getId(), null);
+ } catch (final RuntimeException e) {
+ throw new PaymentApiException(ErrorCode.PAYMENT_INTERNAL_ERROR, null);
+ }
+ }
+
+ public GatewayNotification processNotification(final String notification, final String pluginName, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentApiException {
+ try {
+ return paymentPluginNotificationDispatcher.dispatchWithTimeout(new Callable<GatewayNotification>() {
+ @Override
+ public GatewayNotification call() throws Exception {
+ final PaymentPluginApi plugin = getPaymentPluginApi(pluginName);
+ return plugin.processNotification(notification, properties, callContext);
+ }
+ }
+ );
+ } catch (final TimeoutException e) {
+ throw new PaymentApiException(ErrorCode.PAYMENT_PLUGIN_TIMEOUT, null, null);
+ } catch (final RuntimeException e) {
+ throw new PaymentApiException(ErrorCode.PAYMENT_INTERNAL_ERROR, null);
+ }
+ }
+}
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java b/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
index 0eb2783..b0fc1d1 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
@@ -269,46 +269,46 @@ public class PaymentProcessor extends ProcessorBase {
public void process_AUTO_PAY_OFF_removal(final Account account, final InternalCallContext context) throws PaymentApiException {
try {
- voidPluginDispatcher.dispatchWithAccountLock(new CallableWithAccountLock<Void>(locker,
- account.getExternalKey(),
- new WithAccountLockCallback<Void>() {
-
- @Override
- public Void doOperation() throws PaymentApiException {
-
- final List<PaymentModelDao> payments = paymentDao.getPaymentsForAccount(account.getId(), context);
- final Collection<PaymentModelDao> paymentsToBeCompleted = Collections2.filter(payments, new Predicate<PaymentModelDao>() {
- @Override
- public boolean apply(final PaymentModelDao in) {
- // Payments left in AUTO_PAY_OFF or for which we did not retry enough
- return (in.getPaymentStatus() == PaymentStatus.AUTO_PAY_OFF ||
- in.getPaymentStatus() == PaymentStatus.PAYMENT_FAILURE ||
- in.getPaymentStatus() == PaymentStatus.PLUGIN_FAILURE ||
- in.getPaymentStatus() == PaymentStatus.UNKNOWN);
- }
- });
- // Insert one retry event for each payment left in AUTO_PAY_OFF
- for (final PaymentModelDao cur : paymentsToBeCompleted) {
- switch (cur.getPaymentStatus()) {
- case AUTO_PAY_OFF:
- autoPayoffRetryService.scheduleRetry(cur.getId(), clock.getUTCNow());
- break;
- case PAYMENT_FAILURE:
- scheduleRetryOnPaymentFailure(cur.getId(), context);
- break;
- case PLUGIN_FAILURE:
- case UNKNOWN:
- scheduleRetryOnPluginFailure(cur.getId(), context);
- break;
- default:
- // Impossible...
- throw new RuntimeException("Unexpected case " + cur.getPaymentStatus());
- }
-
+ voidPluginDispatcher.dispatchWithTimeout(new CallableWithAccountLock<Void>(locker,
+ account.getExternalKey(),
+ new WithAccountLockCallback<Void>() {
+
+ @Override
+ public Void doOperation() throws PaymentApiException {
+
+ final List<PaymentModelDao> payments = paymentDao.getPaymentsForAccount(account.getId(), context);
+ final Collection<PaymentModelDao> paymentsToBeCompleted = Collections2.filter(payments, new Predicate<PaymentModelDao>() {
+ @Override
+ public boolean apply(final PaymentModelDao in) {
+ // Payments left in AUTO_PAY_OFF or for which we did not retry enough
+ return (in.getPaymentStatus() == PaymentStatus.AUTO_PAY_OFF ||
+ in.getPaymentStatus() == PaymentStatus.PAYMENT_FAILURE ||
+ in.getPaymentStatus() == PaymentStatus.PLUGIN_FAILURE ||
+ in.getPaymentStatus() == PaymentStatus.UNKNOWN);
}
- return null;
+ });
+ // Insert one retry event for each payment left in AUTO_PAY_OFF
+ for (final PaymentModelDao cur : paymentsToBeCompleted) {
+ switch (cur.getPaymentStatus()) {
+ case AUTO_PAY_OFF:
+ autoPayoffRetryService.scheduleRetry(cur.getId(), clock.getUTCNow());
+ break;
+ case PAYMENT_FAILURE:
+ scheduleRetryOnPaymentFailure(cur.getId(), context);
+ break;
+ case PLUGIN_FAILURE:
+ case UNKNOWN:
+ scheduleRetryOnPluginFailure(cur.getId(), context);
+ break;
+ default:
+ // Impossible...
+ throw new RuntimeException("Unexpected case " + cur.getPaymentStatus());
+ }
+
}
+ return null;
}
+ }
));
} catch (final TimeoutException e) {
throw new PaymentApiException(ErrorCode.UNEXPECTED_ERROR, "Unexpected timeout for payment creation (AUTO_PAY_OFF)");
@@ -332,65 +332,65 @@ public class PaymentProcessor extends ProcessorBase {
}
try {
- return paymentPluginDispatcher.dispatchWithAccountLock(new CallableWithAccountLock<Payment>(locker,
- account.getExternalKey(),
- new WithAccountLockCallback<Payment>() {
+ return paymentPluginDispatcher.dispatchWithTimeout(new CallableWithAccountLock<Payment>(locker,
+ account.getExternalKey(),
+ new WithAccountLockCallback<Payment>() {
+
+ @Override
+ public Payment doOperation() throws PaymentApiException {
+
+ try {
+ // First, rebalance CBA and retrieve the latest version of the invoice
+ final Invoice invoice = rebalanceAndGetInvoice(account.getId(), invoiceId, context);
+ if (invoice == null || invoice.isMigrationInvoice()) {
+ log.error("Received invoice for payment that is a migration invoice - don't know how to handle those yet: {}", invoice);
+ return null;
+ }
- @Override
- public Payment doOperation() throws PaymentApiException {
+ // Second, validate the payment amount. We want to bail as early as possible if e.g. the balance is zero
+ final BigDecimal requestedAmount = getAndValidatePaymentAmount(invoice, inputAmount, isInstantPayment);
+ // Third, retrieve the payment method and associated plugin
+ final PaymentPluginApi plugin;
+ final UUID paymentMethodId;
try {
- // First, rebalance CBA and retrieve the latest version of the invoice
- final Invoice invoice = rebalanceAndGetInvoice(account.getId(), invoiceId, context);
- if (invoice == null || invoice.isMigrationInvoice()) {
- log.error("Received invoice for payment that is a migration invoice - don't know how to handle those yet: {}", invoice);
- return null;
- }
-
- // Second, validate the payment amount. We want to bail as early as possible if e.g. the balance is zero
- final BigDecimal requestedAmount = getAndValidatePaymentAmount(invoice, inputAmount, isInstantPayment);
-
- // Third, retrieve the payment method and associated plugin
- final PaymentPluginApi plugin;
- final UUID paymentMethodId;
- try {
- // Use the special external payment plugin to handle external payments
- if (isExternalPayment) {
- plugin = externalPaymentPlugin;
- paymentMethodId = paymentMethodProcessor.getExternalPaymentMethod(account, properties, context).getId();
- } else {
- plugin = getPaymentProviderPlugin(account, context);
- paymentMethodId = account.getPaymentMethodId();
- }
- } catch (final PaymentApiException e) {
-
- // Insert a payment entry with one attempt in a terminal state to keep a record of the failure
- processNewPaymentForMissingDefaultPaymentMethodWithAccountLocked(account, invoice, requestedAmount, context);
-
- // This event will be caught by overdue to refresh the overdue state, if needed.
- // Note that at this point, we don't know the exact invoice balance (see getAndValidatePaymentAmount() below).
- // This means that events will be posted for null and zero dollar invoices (e.g. trials).
- final PaymentErrorInternalEvent event = new DefaultPaymentErrorEvent(account.getId(), invoiceId, null,
- ErrorCode.PAYMENT_NO_DEFAULT_PAYMENT_METHOD.toString(),
- context.getAccountRecordId(), context.getTenantRecordId(),
- context.getUserToken());
- postPaymentEvent(event, account.getId(), context);
- throw e;
+ // Use the special external payment plugin to handle external payments
+ if (isExternalPayment) {
+ plugin = externalPaymentPlugin;
+ paymentMethodId = paymentMethodProcessor.getExternalPaymentMethod(account, properties, context).getId();
+ } else {
+ plugin = getPaymentProviderPlugin(account, context);
+ paymentMethodId = account.getPaymentMethodId();
}
+ } catch (final PaymentApiException e) {
+
+ // Insert a payment entry with one attempt in a terminal state to keep a record of the failure
+ processNewPaymentForMissingDefaultPaymentMethodWithAccountLocked(account, invoice, requestedAmount, context);
+
+ // This event will be caught by overdue to refresh the overdue state, if needed.
+ // Note that at this point, we don't know the exact invoice balance (see getAndValidatePaymentAmount() below).
+ // This means that events will be posted for null and zero dollar invoices (e.g. trials).
+ final PaymentErrorInternalEvent event = new DefaultPaymentErrorEvent(account.getId(), invoiceId, null,
+ ErrorCode.PAYMENT_NO_DEFAULT_PAYMENT_METHOD.toString(),
+ context.getAccountRecordId(), context.getTenantRecordId(),
+ context.getUserToken());
+ postPaymentEvent(event, account.getId(), context);
+ throw e;
+ }
- final boolean isAccountAutoPayOff = isAccountAutoPayOff(account.getId(), context);
- setUnsaneAccount_AUTO_PAY_OFFWithAccountLock(account.getId(), paymentMethodId, isAccountAutoPayOff, context, isInstantPayment);
+ final boolean isAccountAutoPayOff = isAccountAutoPayOff(account.getId(), context);
+ setUnsaneAccount_AUTO_PAY_OFFWithAccountLock(account.getId(), paymentMethodId, isAccountAutoPayOff, context, isInstantPayment);
- if (!isInstantPayment && isAccountAutoPayOff) {
- return processNewPaymentForAutoPayOffWithAccountLocked(paymentMethodId, account, invoice, requestedAmount, context);
- } else {
- return processNewPaymentWithAccountLocked(paymentMethodId, plugin, account, invoice, requestedAmount, isInstantPayment, properties, context);
- }
- } catch (final InvoiceApiException e) {
- throw new PaymentApiException(e);
+ if (!isInstantPayment && isAccountAutoPayOff) {
+ return processNewPaymentForAutoPayOffWithAccountLocked(paymentMethodId, account, invoice, requestedAmount, context);
+ } else {
+ return processNewPaymentWithAccountLocked(paymentMethodId, plugin, account, invoice, requestedAmount, isInstantPayment, properties, context);
}
+ } catch (final InvoiceApiException e) {
+ throw new PaymentApiException(e);
}
}
+ }
));
} catch (final TimeoutException e) {
if (isInstantPayment) {
@@ -510,43 +510,43 @@ public class PaymentProcessor extends ProcessorBase {
final Account account = accountInternalApi.getAccountById(payment.getAccountId(), context);
final PaymentPluginApi plugin = getPaymentProviderPlugin(account, context);
- voidPluginDispatcher.dispatchWithAccountLock(new CallableWithAccountLock<Void>(locker,
- account.getExternalKey(),
- new WithAccountLockCallback<Void>() {
-
- @Override
- public Void doOperation() throws PaymentApiException {
- try {
- // Fetch again with account lock this time
- final PaymentModelDao payment = paymentDao.getPayment(paymentId, context);
- boolean foundExpectedState = false;
- for (final PaymentStatus cur : expectedPaymentStates) {
- if (payment.getPaymentStatus() == cur) {
- foundExpectedState = true;
- break;
- }
- }
- if (!foundExpectedState) {
- log.info("Aborted retry for payment {} because it is {} state", paymentId, payment.getPaymentStatus());
- return null;
+ voidPluginDispatcher.dispatchWithTimeout(new CallableWithAccountLock<Void>(locker,
+ account.getExternalKey(),
+ new WithAccountLockCallback<Void>() {
+
+ @Override
+ public Void doOperation() throws PaymentApiException {
+ try {
+ // Fetch again with account lock this time
+ final PaymentModelDao payment = paymentDao.getPayment(paymentId, context);
+ boolean foundExpectedState = false;
+ for (final PaymentStatus cur : expectedPaymentStates) {
+ if (payment.getPaymentStatus() == cur) {
+ foundExpectedState = true;
+ break;
}
+ }
+ if (!foundExpectedState) {
+ log.info("Aborted retry for payment {} because it is {} state", paymentId, payment.getPaymentStatus());
+ return null;
+ }
- final Invoice invoice = rebalanceAndGetInvoice(payment.getAccountId(), payment.getInvoiceId(), context);
- if (invoice == null || invoice.isMigrationInvoice()) {
- return null;
- }
- if (invoice.getBalance().compareTo(BigDecimal.ZERO) <= 0) {
- log.info("Aborted retry for payment {} because invoice has been paid", paymentId);
- setTerminalStateOnRetryWithAccountLocked(account, invoice, payment, invoice.getBalance(), "Paid invoice", context);
- return null;
- }
- processRetryPaymentWithAccountLocked(plugin, account, invoice, payment, invoice.getBalance(), properties, context);
+ final Invoice invoice = rebalanceAndGetInvoice(payment.getAccountId(), payment.getInvoiceId(), context);
+ if (invoice == null || invoice.isMigrationInvoice()) {
return null;
- } catch (final InvoiceApiException e) {
- throw new PaymentApiException(e);
}
+ if (invoice.getBalance().compareTo(BigDecimal.ZERO) <= 0) {
+ log.info("Aborted retry for payment {} because invoice has been paid", paymentId);
+ setTerminalStateOnRetryWithAccountLocked(account, invoice, payment, invoice.getBalance(), "Paid invoice", context);
+ return null;
+ }
+ processRetryPaymentWithAccountLocked(plugin, account, invoice, payment, invoice.getBalance(), properties, context);
+ return null;
+ } catch (final InvoiceApiException e) {
+ throw new PaymentApiException(e);
}
}
+ }
));
} catch (final AccountApiException e) {
log.error(String.format("Failed to retry payment for paymentId %s", paymentId), e);
diff --git a/payment/src/main/java/org/killbill/billing/payment/dispatcher/PluginDispatcher.java b/payment/src/main/java/org/killbill/billing/payment/dispatcher/PluginDispatcher.java
index 6bb30d0..d112b14 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dispatcher/PluginDispatcher.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dispatcher/PluginDispatcher.java
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
@@ -13,6 +15,7 @@
* License for the specific language governing permissions and limitations
* under the License.
*/
+
package org.killbill.billing.payment.dispatcher;
import java.util.concurrent.Callable;
@@ -22,11 +25,10 @@ import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import org.killbill.billing.ErrorCode;
import org.killbill.billing.payment.api.PaymentApiException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class PluginDispatcher<T> {
@@ -37,34 +39,30 @@ public class PluginDispatcher<T> {
private final long timeoutSeconds;
private final ExecutorService executor;
- public PluginDispatcher(final long tiemoutSeconds, final ExecutorService executor) {
- this.timeoutSeconds = tiemoutSeconds;
+ public PluginDispatcher(final long timeoutSeconds, final ExecutorService executor) {
+ this.timeoutSeconds = timeoutSeconds;
this.executor = executor;
}
-
- public T dispatchWithAccountLock(final Callable<T> task)
- throws PaymentApiException, TimeoutException {
- return dispatchWithAccountLockAndTimeout(task, timeoutSeconds, DEEFAULT_PLUGIN_TIMEOUT_UNIT);
+ public T dispatchWithTimeout(final Callable<T> task) throws PaymentApiException, TimeoutException {
+ return dispatchWithTimeout(task, timeoutSeconds, DEEFAULT_PLUGIN_TIMEOUT_UNIT);
}
- public T dispatchWithAccountLockAndTimeout(final Callable<T> task, final long timeout, final TimeUnit unit)
+ public T dispatchWithTimeout(final Callable<T> task, final long timeout, final TimeUnit unit)
throws PaymentApiException, TimeoutException {
try {
final Future<T> future = executor.submit(task);
return future.get(timeout, unit);
- } catch (ExecutionException e) {
+ } catch (final ExecutionException e) {
if (e.getCause() instanceof PaymentApiException) {
throw (PaymentApiException) e.getCause();
} else {
throw new PaymentApiException(ErrorCode.PAYMENT_INTERNAL_ERROR, e.getMessage());
}
- } catch (InterruptedException e) {
+ } catch (final InterruptedException e) {
Thread.currentThread().interrupt();
throw new PaymentApiException(ErrorCode.PAYMENT_INTERNAL_ERROR, e.getMessage());
}
}
-
-
}
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 397927f..df19e2d 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
@@ -1,7 +1,9 @@
/*
* Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
*
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
@@ -20,20 +22,20 @@ 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;
-
import org.killbill.billing.osgi.api.OSGIServiceRegistration;
import org.killbill.billing.payment.api.DefaultPaymentApi;
+import org.killbill.billing.payment.api.DirectPaymentApi;
import org.killbill.billing.payment.api.PaymentApi;
+import org.killbill.billing.payment.api.PaymentGatewayApi;
import org.killbill.billing.payment.api.PaymentInternalApi;
import org.killbill.billing.payment.api.PaymentService;
+import org.killbill.billing.payment.api.svcs.DefaultDirectPaymentApi;
+import org.killbill.billing.payment.api.svcs.DefaultPaymentGatewayApi;
import org.killbill.billing.payment.api.svcs.DefaultPaymentInternalApi;
import org.killbill.billing.payment.bus.InvoiceHandler;
import org.killbill.billing.payment.bus.PaymentTagHandler;
+import org.killbill.billing.payment.core.DirectPaymentProcessor;
+import org.killbill.billing.payment.core.PaymentGatewayProcessor;
import org.killbill.billing.payment.core.PaymentMethodProcessor;
import org.killbill.billing.payment.core.PaymentProcessor;
import org.killbill.billing.payment.core.RefundProcessor;
@@ -47,6 +49,8 @@ import org.killbill.billing.payment.retry.FailedPaymentRetryService.FailedPaymen
import org.killbill.billing.payment.retry.PluginFailureRetryService;
import org.killbill.billing.payment.retry.PluginFailureRetryService.PluginFailureRetryServiceScheduler;
import org.killbill.billing.util.config.PaymentConfig;
+import org.skife.config.ConfigSource;
+import org.skife.config.ConfigurationObjectFactory;
import com.google.inject.AbstractModule;
import com.google.inject.TypeLiteral;
@@ -93,6 +97,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(PaymentGatewayProcessor.class).asEagerSingleton();
bind(RefundProcessor.class).asEagerSingleton();
bind(PaymentMethodProcessor.class).asEagerSingleton();
}
@@ -108,6 +113,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(PaymentGatewayApi.class).to(DefaultPaymentGatewayApi.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 d479074..44d894f 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
@@ -29,9 +29,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.payment.api.PaymentMethodPlugin;
import org.killbill.billing.payment.api.PluginProperty;
-import org.killbill.billing.payment.plugin.api.HostedPaymentPageDescriptorFields;
+import org.killbill.billing.payment.plugin.api.GatewayNotification;
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;
@@ -230,12 +229,12 @@ public class DefaultNoOpPaymentProviderPlugin implements NoOpPaymentPluginApi {
}
@Override
- public HostedPaymentPageFormDescriptor buildFormDescriptor(final UUID kbAccountId, final HostedPaymentPageDescriptorFields hostedPaymentPageDescriptorFields, final Iterable<PluginProperty> properties, final TenantContext tenantContext) {
+ public HostedPaymentPageFormDescriptor buildFormDescriptor(final UUID kbAccountId, final Iterable<PluginProperty> customFields, final Iterable<PluginProperty> properties, final CallContext callContext) {
return null;
}
@Override
- public HostedPaymentPageNotification processNotification(final String notification, final Iterable<PluginProperty> properties, final TenantContext tenantContext) throws PaymentPluginApiException {
+ public GatewayNotification processNotification(final String notification, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentPluginApiException {
return null;
}
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 045c8d1..3e03551 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
@@ -26,9 +26,8 @@ import java.util.UUID;
import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.payment.api.PaymentMethodPlugin;
import org.killbill.billing.payment.api.PluginProperty;
-import org.killbill.billing.payment.plugin.api.HostedPaymentPageDescriptorFields;
+import org.killbill.billing.payment.plugin.api.GatewayNotification;
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;
@@ -140,12 +139,12 @@ public class ExternalPaymentProviderPlugin implements PaymentPluginApi {
}
@Override
- public HostedPaymentPageFormDescriptor buildFormDescriptor(final UUID kbAccountId, final HostedPaymentPageDescriptorFields hostedPaymentPageDescriptorFields, final Iterable<PluginProperty> properties, final TenantContext tenantContext) {
+ public HostedPaymentPageFormDescriptor buildFormDescriptor(final UUID kbAccountId, final Iterable<PluginProperty> customFields, final Iterable<PluginProperty> properties, final CallContext callContext) {
return null;
}
@Override
- public HostedPaymentPageNotification processNotification(final String notification, final Iterable<PluginProperty> properties, final TenantContext tenantContext) throws PaymentPluginApiException {
+ public GatewayNotification processNotification(final String notification, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentPluginApiException {
return null;
}
}
diff --git a/payment/src/test/java/org/killbill/billing/payment/dispatcher/TestPluginDispatcher.java b/payment/src/test/java/org/killbill/billing/payment/dispatcher/TestPluginDispatcher.java
index a95ddc3..021707e 100644
--- a/payment/src/test/java/org/killbill/billing/payment/dispatcher/TestPluginDispatcher.java
+++ b/payment/src/test/java/org/killbill/billing/payment/dispatcher/TestPluginDispatcher.java
@@ -36,7 +36,7 @@ public class TestPluginDispatcher extends PaymentTestSuiteNoDB {
public void testDispatchWithTimeout() throws TimeoutException, PaymentApiException {
boolean gotIt = false;
try {
- voidPluginDispatcher.dispatchWithAccountLockAndTimeout(new Callable<Void>() {
+ voidPluginDispatcher.dispatchWithTimeout(new Callable<Void>() {
@Override
public Void call() throws Exception {
Thread.sleep(1000);
@@ -56,7 +56,7 @@ public class TestPluginDispatcher extends PaymentTestSuiteNoDB {
public void testDispatchWithPaymentApiException() throws TimeoutException, PaymentApiException {
boolean gotIt = false;
try {
- voidPluginDispatcher.dispatchWithAccountLockAndTimeout(new Callable<Void>() {
+ voidPluginDispatcher.dispatchWithTimeout(new Callable<Void>() {
@Override
public Void call() throws Exception {
throw new PaymentApiException(ErrorCode.PAYMENT_ADD_PAYMENT_METHOD, "foo", "foo");
@@ -75,7 +75,7 @@ public class TestPluginDispatcher extends PaymentTestSuiteNoDB {
public void testDispatchWithRuntimeExceptionWrappedInPaymentApiException() throws TimeoutException, PaymentApiException {
boolean gotIt = false;
try {
- voidPluginDispatcher.dispatchWithAccountLockAndTimeout(new Callable<Void>() {
+ voidPluginDispatcher.dispatchWithTimeout(new Callable<Void>() {
@Override
public Void call() throws Exception {
throw new RuntimeException("whatever");
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 665108d..41dad0e 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
@@ -30,9 +30,8 @@ import org.killbill.billing.catalog.api.Currency;
import org.killbill.billing.payment.api.PaymentMethodPlugin;
import org.killbill.billing.payment.api.PluginProperty;
import org.killbill.billing.payment.api.TestPaymentMethodPlugin;
-import org.killbill.billing.payment.plugin.api.HostedPaymentPageDescriptorFields;
+import org.killbill.billing.payment.plugin.api.GatewayNotification;
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;
@@ -204,12 +203,12 @@ public class MockPaymentProviderPlugin implements NoOpPaymentPluginApi {
}
@Override
- public HostedPaymentPageFormDescriptor buildFormDescriptor(final UUID kbAccountId, final HostedPaymentPageDescriptorFields hostedPaymentPageDescriptorFields, final Iterable<PluginProperty> properties, final TenantContext tenantContext) {
+ public HostedPaymentPageFormDescriptor buildFormDescriptor(final UUID kbAccountId, final Iterable<PluginProperty> customFields, final Iterable<PluginProperty> properties, final CallContext callContext) {
return null;
}
@Override
- public HostedPaymentPageNotification processNotification(final String notification, final Iterable<PluginProperty> properties, final TenantContext tenantContext) throws PaymentPluginApiException {
+ public GatewayNotification processNotification(final String notification, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentPluginApiException {
return null;
}
pom.xml 2(+1 -1)
diff --git a/pom.xml b/pom.xml
index 149d4c8..ef91d0f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,7 +19,7 @@
<parent>
<artifactId>killbill-oss-parent</artifactId>
<groupId>org.kill-bill.billing</groupId>
- <version>0.7.7</version>
+ <version>0.7.8</version>
</parent>
<artifactId>killbill</artifactId>
<version>0.11.3-SNAPSHOT</version>