This is an automated email from the ASF dual-hosted git repository. pawan pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/ofbiz-plugins.git
commit df753f80b2be1cb964df0bc9c3cfe30fa3bf83f2 Author: Pritam Kute <pritam.kute> AuthorDate: Wed Jun 24 17:40:55 2020 +0530 Adding new plugin for integration of First Data payment gateway with Apache OFBiz. (OFBIZ-11837) --- firstdatapaymentgateway/README.adoc | 25 ++ firstdatapaymentgateway/build.gradle | 25 ++ .../config/FirstDataUiLabels.xml | 63 +++ .../config/firstdata.properties | 23 ++ firstdatapaymentgateway/data/FirstDataDemoData.xml | 30 ++ .../data/FirstDataSecurityGroupDemoData.xml | 29 ++ .../data/FirstDataSecurityPermissionSeedData.xml | 30 ++ firstdatapaymentgateway/data/FirstDataTypeData.xml | 27 ++ firstdatapaymentgateway/entitydef/entitymodel.xml | 46 +++ firstdatapaymentgateway/ofbiz-component.xml | 51 +++ firstdatapaymentgateway/servicedef/services.xml | 54 +++ .../FirstDataPaymentServices.java | 422 +++++++++++++++++++++ .../template/FirstDataPostAuthTemplate.json.ftl | 7 + .../template/FirstDataPreAuthTemplate.json.ftl | 19 + .../template/FirstDataRefundTemplate.json.ftl | 7 + .../template/FirstDataReleaseTemplate.json.ftl | 4 + .../template/FirstDataSaleTemplate.json.ftl | 19 + .../webapp/firstdata/WEB-INF/controller.xml | 53 +++ .../webapp/firstdata/WEB-INF/web.xml | 96 +++++ firstdatapaymentgateway/webapp/firstdata/index.jsp | 20 + firstdatapaymentgateway/widget/CommonScreens.xml | 67 ++++ firstdatapaymentgateway/widget/FirstDataForms.xml | 38 ++ firstdatapaymentgateway/widget/FirstDataMenus.xml | 25 ++ .../widget/FirstDataScreens.xml | 52 +++ 24 files changed, 1232 insertions(+) diff --git a/firstdatapaymentgateway/README.adoc b/firstdatapaymentgateway/README.adoc new file mode 100644 index 0000000..6621b73 --- /dev/null +++ b/firstdatapaymentgateway/README.adoc @@ -0,0 +1,25 @@ +[[FirstDataPaymentGateway]] += First Data Payment Gateway + +[[steps-to-integrate]] +== Steps to integrate First Data Payment Gateway with Apache OFBiz + +* Checkout or install the "firstdatapaymentgateway" plugin from the Apache OFBiz repository. +https://github.com/apache/ofbiz-plugins.git +* Make sure you load the data from following files manually or using loadAll command. +** FirstDataTypeData.xml +** FirstDataSecurityPermissionSeedData.xml +** FirstDataSecurityGroupDemoData.xml +** FirstDataDemoData.xml +* Make sure you have created your test account on First Data and you have enabled REST APIs for your test merchant account. +Also you have got following configuration parameters from the First Data against your merchant account. +** App Name +** API Key +** API Secret +* Now build and start the server. +* Hit following URL and use admin credentials for login. +`https://localhost:8443/firstdata/control/main` +* Fill in the configuration parameters which you have got from First Data in appropriate fields. +Transaction URL to be entered should be of sandbox server. +`https://cert.api.firstdata.com/gateway/v2` +* Now you can place order and check transactions like Auth, Capture, Refund and Release. \ No newline at end of file diff --git a/firstdatapaymentgateway/build.gradle b/firstdatapaymentgateway/build.gradle new file mode 100644 index 0000000..3ebcfec --- /dev/null +++ b/firstdatapaymentgateway/build.gradle @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF 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. + */ + +dependencies { + //Examples of compile-time and runtime dependencies + + //pluginLibsCompile 'junit:junit-dep:4.10' + //pluginLibsRuntime 'junit:junit-dep:4.10' +} \ No newline at end of file diff --git a/firstdatapaymentgateway/config/FirstDataUiLabels.xml b/firstdatapaymentgateway/config/FirstDataUiLabels.xml new file mode 100644 index 0000000..93ec755 --- /dev/null +++ b/firstdatapaymentgateway/config/FirstDataUiLabels.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF 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. +--> + +<resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/ofbiz-properties.xsd"> + <property key="FirstDataApplication"> + <value xml:lang="en">FirstData Application</value> + <value xml:lang="zh">FirstData应用程序</value> + <value xml:lang="zh-TW">FirstData應用程式</value> + </property> + <property key="FirstDataCompanyName"> + <value xml:lang="en">OFBiz: FirstData</value> + <value xml:lang="zh-TW">OFBiz: FirstData</value> + </property> + <property key="FirstDataCompanySubtitle"> + <value xml:lang="en">Part of the Apache OFBiz Family of Open Source Software</value> + <value xml:lang="it">Un modulo della famiglia di software open source Apache OFBiz</value> + <value xml:lang="zh">开源软件OFBiz的组成部分</value> + <value xml:lang="zh-TW">開源軟體OFBiz的組成部分</value> + </property> + <property key="FirstDataViewPermissionError"> + <value xml:lang="en">You are not allowed to view this page.</value> + <value xml:lang="zh">不允许你浏览这个页面。</value> + <value xml:lang="zh-TW">不允許您檢視這個頁面.</value> + </property> + <property key="FirstDataConfigurations"> + <value xml:lang="en">First Data Configurations</value> + </property> + <property key="FirstDataEditConfigurations"> + <value xml:lang="en">Edit Configurations</value> + </property> + <property key="FormFieldTitle_appName"> + <value xml:lang="en">App Name</value> + </property> + <property key="FormFieldTitle_apiKey"> + <value xml:lang="en">API Key</value> + </property> + <property key="FormFieldTitle_apiSecret"> + <value xml:lang="en">API Secret</value> + </property> + <property key="FormFieldTitle_transactionUrl"> + <value xml:lang="en">Transaction URL</value> + </property> + <property key="FormFieldTitle_enableDataVault"> + <value xml:lang="en">Enable Data Vault</value> + </property> +</resource> diff --git a/firstdatapaymentgateway/config/firstdata.properties b/firstdatapaymentgateway/config/firstdata.properties new file mode 100644 index 0000000..82dc3d2 --- /dev/null +++ b/firstdatapaymentgateway/config/firstdata.properties @@ -0,0 +1,23 @@ +############################################################################### +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF 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. +############################################################################### + +paymentgateway.firstdata.template.preauth.location=component://firstdatapaymentgateway/template/FirstDataPreAuthTemplate.json.ftl +paymentgateway.firstdata.template.postauth.location=component://firstdatapaymentgateway/template/FirstDataPostAuthTemplate.json.ftl +paymentgateway.firstdata.template.refund.location=component://firstdatapaymentgateway/template/FirstDataRefundTemplate.json.ftl +paymentgateway.firstdata.template.release.location=component://firstdatapaymentgateway/template/FirstDataReleaseTemplate.json.ftl \ No newline at end of file diff --git a/firstdatapaymentgateway/data/FirstDataDemoData.xml b/firstdatapaymentgateway/data/FirstDataDemoData.xml new file mode 100644 index 0000000..e73b58a --- /dev/null +++ b/firstdatapaymentgateway/data/FirstDataDemoData.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF 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. +--> + +<entity-engine-xml> + <PaymentGatewayConfig paymentGatewayConfigId="FIRST_DATA_CONFIG" paymentGatewayConfigTypeId="PAY_GATWY_FIRSTDATA" /> + <PaymentGatewayFirstData paymentGatewayConfigId="FIRST_DATA_CONFIG" appName="[AppName]" appId="[AppID]" apiKey="[ApiKey]" apiSecret="[ApiSecret]" transactionUrl="[TransactionUrl]" enableDataVault="N" /> + + <ProductStorePaymentSetting productStoreId="9000" paymentMethodTypeId="CREDIT_CARD" paymentServiceTypeEnumId="PRDS_PAY_AUTH" paymentService="" paymentCustomMethodId="CC_AUTH_FD" paymentGatewayConfigId="FIRST_DATA_CONFIG"/> + <ProductStorePaymentSetting productStoreId="9000" paymentMethodTypeId="CREDIT_CARD" paymentServiceTypeEnumId="PRDS_PAY_CAPTURE" paymentService="" paymentCustomMethodId="CC_CAPTURE_FD" paymentGatewayConfigId="FIRST_DATA_CONFIG"/> + <ProductStorePaymentSetting productStoreId="9000" paymentMethodTypeId="CREDIT_CARD" paymentServiceTypeEnumId="PRDS_PAY_REAUTH" paymentService="" paymentCustomMethodId="CC_AUTH_FD" paymentGatewayConfigId="FIRST_DATA_CONFIG"/> + <ProductStorePaymentSetting productStoreId="9000" paymentMethodTypeId="CREDIT_CARD" paymentServiceTypeEnumId="PRDS_PAY_REFUND" paymentService="" paymentCustomMethodId="CC_REFUND_FD" paymentGatewayConfigId="FIRST_DATA_CONFIG"/> + <ProductStorePaymentSetting productStoreId="9000" paymentMethodTypeId="CREDIT_CARD" paymentServiceTypeEnumId="PRDS_PAY_RELEASE" paymentService="" paymentCustomMethodId="CC_RELEASE_FD" paymentGatewayConfigId="FIRST_DATA_CONFIG"/> +</entity-engine-xml> \ No newline at end of file diff --git a/firstdatapaymentgateway/data/FirstDataSecurityGroupDemoData.xml b/firstdatapaymentgateway/data/FirstDataSecurityGroupDemoData.xml new file mode 100644 index 0000000..ee7d7c2 --- /dev/null +++ b/firstdatapaymentgateway/data/FirstDataSecurityGroupDemoData.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF 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. +--> + +<entity-engine-xml> + <SecurityGroupPermission fromDate="2001-05-13 12:00:00.0" groupId="FULLADMIN" permissionId="FDSECURITY_ADMIN"/> + <SecurityGroupPermission fromDate="2001-05-13 12:00:00.0" groupId="FLEXADMIN" permissionId="FDSECURITY_CREATE"/> + <SecurityGroupPermission fromDate="2001-05-13 12:00:00.0" groupId="FLEXADMIN" permissionId="FDSECURITY_DELETE"/> + <SecurityGroupPermission fromDate="2001-05-13 12:00:00.0" groupId="FLEXADMIN" permissionId="FDSECURITY_UPDATE"/> + <SecurityGroupPermission fromDate="2001-05-13 12:00:00.0" groupId="FLEXADMIN" permissionId="FDSECURITY_VIEW"/> + <SecurityGroupPermission fromDate="2001-05-13 12:00:00.0" groupId="VIEWADMIN" permissionId="FDSECURITY_VIEW"/> + <SecurityGroupPermission fromDate="2001-05-13 12:00:00.0" groupId="BIZADMIN" permissionId="FDSECURITY_ADMIN"/> +</entity-engine-xml> diff --git a/firstdatapaymentgateway/data/FirstDataSecurityPermissionSeedData.xml b/firstdatapaymentgateway/data/FirstDataSecurityPermissionSeedData.xml new file mode 100644 index 0000000..3d6e7b7 --- /dev/null +++ b/firstdatapaymentgateway/data/FirstDataSecurityPermissionSeedData.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF 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. +--> + +<entity-engine-xml> + <SecurityPermission description="View operations in the FirstData Component." permissionId="FDSECURITY_VIEW"/> + <SecurityPermission description="Create operations in the FirstData Component." permissionId="FDSECURITY_CREATE"/> + <SecurityPermission description="Update operations in the FirstData Component." permissionId="FDSECURITY_UPDATE"/> + <SecurityPermission description="Delete operations in the FirstData Component." permissionId="FDSECURITY_DELETE"/> + <SecurityPermission description="ALL operations in the FirstData Component." permissionId="FDSECURITY_ADMIN"/> + + <SecurityGroupPermission fromDate="2001-05-13 12:00:00.0" groupId="SUPER" permissionId="FDSECURITY_ADMIN"/> + +</entity-engine-xml> diff --git a/firstdatapaymentgateway/data/FirstDataTypeData.xml b/firstdatapaymentgateway/data/FirstDataTypeData.xml new file mode 100644 index 0000000..c2abb7d --- /dev/null +++ b/firstdatapaymentgateway/data/FirstDataTypeData.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF 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. +--> + +<entity-engine-xml> + <PaymentGatewayConfigType paymentGatewayConfigTypeId="PAY_GATWY_FIRSTDATA" hasTable="Y" description="Payment Gateway FirstData"/> + <CustomMethod customMethodId="CC_AUTH_FD" customMethodTypeId="CC_AUTH" customMethodName="firstDataCCAuth" description="CC Authorize First Data"/> + <CustomMethod customMethodId="CC_CAPTURE_FD" customMethodTypeId="CC_CAPTURE" customMethodName="firstDataCCCapture" description="CC Capture First Data"/> + <CustomMethod customMethodId="CC_REFUND_FD" customMethodTypeId="CC_REFUND" customMethodName="firstDataCCRefund" description="CC Refund First Data"/> + <CustomMethod customMethodId="CC_RELEASE_FD" customMethodTypeId="CC_RELEASE" customMethodName="firstDataCCRelease" description="CC Release First Data"/> +</entity-engine-xml> \ No newline at end of file diff --git a/firstdatapaymentgateway/entitydef/entitymodel.xml b/firstdatapaymentgateway/entitydef/entitymodel.xml new file mode 100644 index 0000000..57c9cfc --- /dev/null +++ b/firstdatapaymentgateway/entitydef/entitymodel.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF 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. +--> + +<entitymodel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/entitymodel.xsd"> + <!-- ========================================================= --> + <!-- ======================== Defaults ======================= --> + <!-- ========================================================= --> + <title>Entity of FirstData Component</title> + <description>None</description> + <copyright></copyright> + <version></version> + + <entity entity-name="PaymentGatewayFirstData" + package-name="org.apache.ofbiz.accounting.payment" + title="First Data Payment Gateway Config"> + <field name="paymentGatewayConfigId" type="id"></field> + <field name="appName" type="value"><description>App Name</description></field> + <field name="apiKey" type="value" encrypt="true"><description>API Key</description></field> + <field name="apiSecret" type="value" encrypt="true"><description>API Secret</description></field> + <field name="transactionUrl" type="value"><description>Transaction URL Test or Live</description></field> + <field name="enableDataVault" type="indicator"><description>Enable Data Vault</description></field> + <prim-key field="paymentGatewayConfigId"/> + <relation type="one" fk-name="PGFD_PGC" rel-entity-name="PaymentGatewayConfig"> + <key-map field-name="paymentGatewayConfigId"/> + </relation> + </entity> + +</entitymodel> \ No newline at end of file diff --git a/firstdatapaymentgateway/ofbiz-component.xml b/firstdatapaymentgateway/ofbiz-component.xml new file mode 100644 index 0000000..10cec1a --- /dev/null +++ b/firstdatapaymentgateway/ofbiz-component.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF 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. +--> + +<ofbiz-component name="firstdatapaymentgateway" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/ofbiz-component.xsd"> + <!-- define resource loaders; most common is to use the component resource loader --> + <resource-loader name="main" type="component"/> + + <!-- place the config directory on the classpath to access configuration files --> + <classpath type="dir" location="config"/> + <!-- entity resources: model(s), eca(s), group, and data definitions --> + <entity-resource type="model" reader-name="main" loader="main" location="entitydef/entitymodel.xml"/> + <!-- <entity-resource type="eca" reader-name="main" loader="main" location="entitydef/eecas.xml"/> --> + <entity-resource type="data" reader-name="seed" loader="main" location="data/FirstDataTypeData.xml"/> + <entity-resource type="data" reader-name="seed" loader="main" location="data/FirstDataSecurityPermissionSeedData.xml"/> + <entity-resource type="data" reader-name="demo" loader="main" location="data/FirstDataSecurityGroupDemoData.xml"/> + <entity-resource type="data" reader-name="demo" loader="main" location="data/FirstDataDemoData.xml"/> + + <!-- service resources: model(s), eca(s) and group definitions --> + <service-resource type="model" loader="main" location="servicedef/services.xml"/> + <!-- + <service-resource type="eca" loader="main" location="servicedef/secas.xml"/> + <service-resource type="group" loader="main" location="servicedef/groups.xml"/> + --> + + <!-- web applications; will be mounted when using the embedded container --> + <webapp name="firstdata" + title="FirstData" + server="default-server" + location="webapp/firstdata" + base-permission="OFBTOOLS,FDSECURITY" + mount-point="/firstdata"/> +</ofbiz-component> diff --git a/firstdatapaymentgateway/servicedef/services.xml b/firstdatapaymentgateway/servicedef/services.xml new file mode 100644 index 0000000..b552fd9 --- /dev/null +++ b/firstdatapaymentgateway/servicedef/services.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF 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. +--> + +<services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/services.xsd"> + <description>FirstData Services</description> + <vendor></vendor> + <version>1.0</version> + + <service name="updatePaymentGatewayFirstData" default-entity-name="PaymentGatewayFirstData" engine="entity-auto" invoke="update" auth="true"> + <description>Update a PaymentGatwayFirstData</description> + <auto-attributes include="pk" mode="IN" optional="false"/> + <auto-attributes include="nonpk" mode="IN" optional="true"/> + </service> + + <!-- First Data Implementations --> + <service name="firstDataCCAuth" engine="java" + location="org.apache.ofbiz.firstdatapaymentgateway.FirstDataPaymentServices" invoke="ccAuth"> + <description>First Data Payment Authorization Service</description> + <implements service="ccAuthInterface"/> + </service> + <service name="firstDataCCCapture" engine="java" + location="org.apache.ofbiz.firstdatapaymentgateway.FirstDataPaymentServices" invoke="ccCapture"> + <description>First Data Payment Capture Service</description> + <implements service="ccCaptureInterface"/> + </service> + <service name="firstDataCCRelease" engine="java" + location="org.apache.ofbiz.firstdatapaymentgateway.FirstDataPaymentServices" invoke="ccRelease"> + <description>First Data Payment Release Service</description> + <implements service="paymentReleaseInterface"/> + </service> + <service name="firstDataCCRefund" engine="java" + location="org.apache.ofbiz.firstdatapaymentgateway.FirstDataPaymentServices" invoke="ccRefund"> + <description>First Data Payment Refund Service</description> + <implements service="paymentRefundInterface"/> + </service> +</services> \ No newline at end of file diff --git a/firstdatapaymentgateway/src/main/java/org/apache/ofbiz/firstdatapaymentgateway/FirstDataPaymentServices.java b/firstdatapaymentgateway/src/main/java/org/apache/ofbiz/firstdatapaymentgateway/FirstDataPaymentServices.java new file mode 100644 index 0000000..a3e6347 --- /dev/null +++ b/firstdatapaymentgateway/src/main/java/org/apache/ofbiz/firstdatapaymentgateway/FirstDataPaymentServices.java @@ -0,0 +1,422 @@ +package org.apache.ofbiz.firstdatapaymentgateway; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import freemarker.template.TemplateException; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.binary.Hex; +import org.apache.commons.codec.digest.HmacAlgorithms; +import org.apache.commons.codec.digest.HmacUtils; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.apache.ofbiz.base.util.Debug; +import org.apache.ofbiz.base.util.UtilValidate; +import org.apache.ofbiz.base.util.template.FreeMarkerWorker; +import org.apache.ofbiz.entity.Delegator; +import org.apache.ofbiz.entity.GenericEntityException; +import org.apache.ofbiz.entity.GenericValue; +import org.apache.ofbiz.entity.util.EntityQuery; +import org.apache.ofbiz.entity.util.EntityUtilProperties; +import org.apache.ofbiz.service.DispatchContext; +import org.apache.ofbiz.service.ModelService; +import org.apache.ofbiz.service.ServiceUtil; + +import java.io.IOException; +import java.io.StringWriter; +import java.math.BigDecimal; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; + +public class FirstDataPaymentServices { + private static final String MODULE = FirstDataPaymentServices.class.getName(); + + private static Properties FDProperties = null; + + public static Map<String, Object> ccAuth(DispatchContext ctx, Map<String, Object> context) { + Delegator delegator = ctx.getDelegator(); + BigDecimal processAmount = (BigDecimal) context.get("processAmount"); + String orderId = (String) context.get("orderId"); + String currency = (String) context.get("currency"); + String cardSecurityCode = (String) context.get("cardSecurityCode"); + GenericValue creditCard = (GenericValue) context.get("creditCard"); + String paymentGatewayConfigId = (String) context.get("paymentGatewayConfigId"); + Map<String, Object> result = ServiceUtil.returnSuccess(); + result.put("processAmount", processAmount); + Boolean isSuccess = Boolean.FALSE; + String cardNumber = creditCard.getString("cardNumber"); + + try { + String clientRequestId = UUID.randomUUID().toString(); + String epochTime = String.valueOf(System.currentTimeMillis()); + Date expireDate = new SimpleDateFormat("MM/yyyy").parse(creditCard.getString("expireDate")); + SimpleDateFormat df = new SimpleDateFormat("MM"); + String strMonth = df.format(expireDate); + df = new SimpleDateFormat("yy"); + String strYear = df.format(expireDate); + + Map<String, Object> ccAuthReqContext = new HashMap<String, Object>(); + ccAuthReqContext.put("amount", processAmount); + ccAuthReqContext.put("currency", currency); + ccAuthReqContext.put("cardSecurityCode", cardSecurityCode); + ccAuthReqContext.put("cardNumber", cardNumber); + ccAuthReqContext.put("expireMonth", strMonth); + ccAuthReqContext.put("expireYear", strYear); + + StringWriter outWriter = new StringWriter(); + String firstDataPreAuthTemplate = EntityUtilProperties.getPropertyValue("firstdata", "paymentgateway.firstdata.template.preauth.location", delegator); + FreeMarkerWorker.renderTemplate(firstDataPreAuthTemplate, ccAuthReqContext, outWriter); + String requestBody = outWriter.toString(); + + String messageSignature = buildMessageSignature(paymentGatewayConfigId, requestBody, clientRequestId, epochTime, delegator); + + CloseableHttpClient httpClient = HttpClients.createDefault(); + StringEntity stringEntity = new StringEntity(requestBody); + HttpPost httpPost = new HttpPost(FDProperties.getProperty("transactionUrl") + "/payments"); + httpPost.setEntity(stringEntity); + httpPost.setHeader("Client-Request-Id", clientRequestId); + httpPost.setHeader("Api-Key", FDProperties.getProperty("apiKey")); + httpPost.setHeader("Timestamp", epochTime); + httpPost.setHeader("Message-Signature", messageSignature); + httpPost.setHeader("Content-Type", "application/json"); + + CloseableHttpResponse response = httpClient.execute(httpPost); + + HttpEntity entity = response.getEntity(); + String responseString = EntityUtils.toString(entity); + + ObjectMapper objectMapper = new ObjectMapper(); + Map<String, Object> convertedMap = objectMapper.readValue(responseString, new TypeReference<Map<String, Object>>(){}); + + String transactionStatus = (String) convertedMap.get("transactionStatus"); + String transactionId = (String) convertedMap.get("ipgTransactionId"); + String fdOrderId = (String) convertedMap.get("orderId"); + Map<String, Object> processor = objectMapper.convertValue(convertedMap.get("processor"), new TypeReference<Map<String, Object>>(){}); + String gatewayMessage = (String) processor.get("responseMessage"); + int statusCode = response.getStatusLine().getStatusCode(); + result.put("authCode", String.valueOf(statusCode)); + result.put("authMessage", gatewayMessage); + if (UtilValidate.isNotEmpty(transactionId)) { + result.put("authRefNum", transactionId); + result.put("authAltRefNum", fdOrderId); + if ("approved".equalsIgnoreCase(transactionStatus)) { + isSuccess = Boolean.TRUE; + } + } + if (!isSuccess) { + String errorMessage = "Transaction Type:" + (String) convertedMap.get("transactionType") + " Transaction Id: " + transactionId + " Transaction Status: " + transactionStatus; + errorMessage = errorMessage + " Message: " + statusCode + "-" + gatewayMessage; + result.put(ModelService.ERROR_MESSAGE, errorMessage); + } + } catch (ParseException | TemplateException | IOException e) { + Debug.logError(e, "Could not complete First Data transaction: " + e.toString(), MODULE); + } + result.put("authResult", isSuccess); + return result; + } + + public static Map<String, Object> ccCapture(DispatchContext dctx, Map<String, ? extends Object> context) { + Delegator delegator = dctx.getDelegator(); + BigDecimal captureAmount = (BigDecimal) context.get("captureAmount"); + String paymentGatewayConfigId = (String) context.get("paymentGatewayConfigId"); + String currency = (String) context.get("currency"); + GenericValue orderPaymentPreference = (GenericValue) context.get("orderPaymentPreference"); + + Map<String, Object> result = ServiceUtil.returnSuccess(); + result.put("captureAmount", captureAmount); + Boolean isSuccess = Boolean.FALSE; + + try { + String clientRequestId = UUID.randomUUID().toString(); + String epochTime = String.valueOf(System.currentTimeMillis()); + + Map<String, Object> ccPostAuthReqContext = new HashMap<String, Object>(); + ccPostAuthReqContext.put("amount", captureAmount); + ccPostAuthReqContext.put("currency", currency); + + StringWriter outWriter = new StringWriter(); + String firstDataPreAuthTemplate = EntityUtilProperties.getPropertyValue("firstdata", "paymentgateway.firstdata.template.postauth.location", delegator); + FreeMarkerWorker.renderTemplate(firstDataPreAuthTemplate, ccPostAuthReqContext, outWriter); + String requestBody = outWriter.toString(); + + String messageSignature = buildMessageSignature(paymentGatewayConfigId, requestBody, clientRequestId, epochTime, delegator); + + GenericValue paymentGatewayResponse = EntityQuery.use(delegator).from("PaymentGatewayResponse") + .where("orderPaymentPreferenceId", orderPaymentPreference.getString("orderPaymentPreferenceId"), "paymentMethodId", orderPaymentPreference.getString("paymentMethodId"), "transCodeEnumId", "PGT_AUTHORIZE", "paymentServiceTypeEnumId", "PRDS_PAY_AUTH") + .queryFirst(); + String authTransactionId = null; + if (UtilValidate.isNotEmpty(paymentGatewayResponse.getString("referenceNum"))) { + authTransactionId = paymentGatewayResponse.getString("referenceNum"); + } else { + authTransactionId = paymentGatewayResponse.getString("altReference"); + } + + CloseableHttpClient httpClient = HttpClients.createDefault(); + StringEntity stringEntity = new StringEntity(requestBody); + HttpPost httpPost = new HttpPost(FDProperties.getProperty("transactionUrl") + "/payments/" + authTransactionId); + httpPost.setEntity(stringEntity); + httpPost.setHeader("Client-Request-Id", clientRequestId); + httpPost.setHeader("Api-Key", FDProperties.getProperty("apiKey")); + httpPost.setHeader("Timestamp", epochTime); + httpPost.setHeader("Message-Signature", messageSignature); + httpPost.setHeader("Content-Type", "application/json"); + + CloseableHttpResponse response = httpClient.execute(httpPost); + + HttpEntity entity = response.getEntity(); + String responseString = EntityUtils.toString(entity); + + ObjectMapper objectMapper = new ObjectMapper(); + Map<String, Object> convertedMap = objectMapper.readValue(responseString, new TypeReference<Map<String, Object>>(){}); + + String transactionStatus = (String) convertedMap.get("transactionStatus"); + String transactionId = (String) convertedMap.get("ipgTransactionId"); + String fdOrderId = (String) convertedMap.get("orderId"); + Map<String, Object> processor = objectMapper.convertValue(convertedMap.get("processor"), new TypeReference<Map<String, Object>>(){}); + String gatewayMessage = (String) processor.get("responseMessage"); + int statusCode = response.getStatusLine().getStatusCode(); + result.put("captureCode", String.valueOf(statusCode)); + result.put("captureMessage", gatewayMessage); + if (UtilValidate.isNotEmpty(transactionId)) { + result.put("captureRefNum", transactionId); + result.put("captureAltRefNum", fdOrderId); + if ("approved".equalsIgnoreCase(transactionStatus)) { + isSuccess = Boolean.TRUE; + } + } + if (!isSuccess) { + String errorMessage = "Transaction Type:" + (String) convertedMap.get("transactionType") + " Transaction Id: " + transactionId + " Transaction Status: " + transactionStatus; + errorMessage = errorMessage + " Message: " + statusCode + "-" + gatewayMessage; + result.put(ModelService.ERROR_MESSAGE, errorMessage); + } + } catch (TemplateException | IOException | GenericEntityException e) { + Debug.logError(e, "Could not complete First Data transaction: " + e.toString(), MODULE); + } + result.put("captureResult", isSuccess); + return result; + } + + public static Map<String, Object> ccRefund(DispatchContext dctx, Map<String, ? extends Object> context) { + Delegator delegator = dctx.getDelegator(); + BigDecimal refundAmount = (BigDecimal) context.get("refundAmount"); + String paymentGatewayConfigId = (String) context.get("paymentGatewayConfigId"); + String currency = (String) context.get("currency"); + GenericValue orderPaymentPreference = (GenericValue) context.get("orderPaymentPreference"); + + Map<String, Object> result = ServiceUtil.returnSuccess(); + result.put("refundAmount", refundAmount); + Boolean isSuccess = Boolean.FALSE; + + try { + String clientRequestId = UUID.randomUUID().toString(); + String epochTime = String.valueOf(System.currentTimeMillis()); + + Map<String, Object> ccRefundReqContext = new HashMap<String, Object>(); + ccRefundReqContext.put("amount", refundAmount); + ccRefundReqContext.put("currency", currency); + + StringWriter outWriter = new StringWriter(); + String firstDataPreAuthTemplate = EntityUtilProperties.getPropertyValue("firstdata", "paymentgateway.firstdata.template.refund.location", delegator); + FreeMarkerWorker.renderTemplate(firstDataPreAuthTemplate, ccRefundReqContext, outWriter); + String requestBody = outWriter.toString(); + + String messageSignature = buildMessageSignature(paymentGatewayConfigId, requestBody, clientRequestId, epochTime, delegator); + + GenericValue paymentGatewayResponse = EntityQuery.use(delegator) + .from("PaymentGatewayResponse") + .where("orderPaymentPreferenceId", orderPaymentPreference.getString("orderPaymentPreferenceId"), "paymentMethodId", + orderPaymentPreference.getString("paymentMethodId"), "transCodeEnumId", "PGT_CAPTURE", + "paymentServiceTypeEnumId", "PRDS_PAY_CAPTURE") + .queryFirst(); + String captureTransactionId = null; + if (UtilValidate.isNotEmpty(paymentGatewayResponse.getString("referenceNum"))) { + captureTransactionId = paymentGatewayResponse.getString("referenceNum"); + } else { + captureTransactionId = paymentGatewayResponse.getString("altReference"); + } + + CloseableHttpClient httpClient = HttpClients.createDefault(); + StringEntity stringEntity = new StringEntity(requestBody); + HttpPost httpPost = new HttpPost(FDProperties.getProperty("transactionUrl") + "/payments/" + captureTransactionId); + httpPost.setEntity(stringEntity); + httpPost.setHeader("Client-Request-Id", clientRequestId); + httpPost.setHeader("Api-Key", FDProperties.getProperty("apiKey")); + httpPost.setHeader("Timestamp", epochTime); + httpPost.setHeader("Message-Signature", messageSignature); + httpPost.setHeader("Content-Type", "application/json"); + + CloseableHttpResponse response = httpClient.execute(httpPost); + + HttpEntity entity = response.getEntity(); + String responseString = EntityUtils.toString(entity); + + ObjectMapper objectMapper = new ObjectMapper(); + Map<String, Object> convertedMap = objectMapper.readValue(responseString, new TypeReference<Map<String, Object>>(){}); + + String transactionStatus = (String) convertedMap.get("transactionStatus"); + String transactionId = (String) convertedMap.get("ipgTransactionId"); + String fdOrderId = (String) convertedMap.get("orderId"); + Map<String, Object> processor = objectMapper.convertValue(convertedMap.get("processor"), new TypeReference<Map<String, Object>>(){}); + String gatewayMessage = (String) processor.get("responseMessage"); + int statusCode = response.getStatusLine().getStatusCode(); + result.put("refundCode", String.valueOf(statusCode)); + result.put("refundMessage", gatewayMessage); + if (UtilValidate.isNotEmpty(transactionId)) { + result.put("refundRefNum", transactionId); + result.put("refundAltRefNum", fdOrderId); + if ("approved".equalsIgnoreCase(transactionStatus)) { + isSuccess = Boolean.TRUE; + } + } + if (!isSuccess) { + String errorMessage = "Transaction Type:" + (String) convertedMap.get("transactionType") + " Transaction Id: " + transactionId + " Transaction Status: " + transactionStatus; + errorMessage = errorMessage + " Message: " + statusCode + "-" + gatewayMessage; + result.put(ModelService.ERROR_MESSAGE, errorMessage); + } + } catch (TemplateException | IOException | GenericEntityException e) { + Debug.logError(e, "Could not complete First Data transaction: " + e.toString(), MODULE); + } + result.put("refundResult", isSuccess); + return result; + } + + public static Map<String, Object> ccRelease(DispatchContext dctx, Map<String, ? extends Object> context) { + Delegator delegator = dctx.getDelegator(); + BigDecimal releaseAmount = (BigDecimal) context.get("releaseAmount"); + String paymentGatewayConfigId = (String) context.get("paymentGatewayConfigId"); + String currency = (String) context.get("currency"); + GenericValue orderPaymentPreference = (GenericValue) context.get("orderPaymentPreference"); + + Map<String, Object> result = ServiceUtil.returnSuccess(); + result.put("releaseAmount", releaseAmount); + Boolean isSuccess = Boolean.FALSE; + + try { + String clientRequestId = UUID.randomUUID().toString(); + String epochTime = String.valueOf(System.currentTimeMillis()); + + Map<String, Object> ccReleaseReqContext = new HashMap<String, Object>(); + ccReleaseReqContext.put("comments", "The amount " + currency + " " + releaseAmount + " against OrderPaymentPreferenceId " + orderPaymentPreference.getString("orderPaymentPreferenceId") + " is released."); + + StringWriter outWriter = new StringWriter(); + String firstDataPreAuthTemplate = EntityUtilProperties.getPropertyValue("firstdata", "paymentgateway.firstdata.template.release.location", delegator); + FreeMarkerWorker.renderTemplate(firstDataPreAuthTemplate, ccReleaseReqContext, outWriter); + String requestBody = outWriter.toString(); + + String messageSignature = buildMessageSignature(paymentGatewayConfigId, requestBody, clientRequestId, epochTime, delegator); + + GenericValue paymentGatewayResponse = EntityQuery.use(delegator).from("PaymentGatewayResponse") + .where("orderPaymentPreferenceId", orderPaymentPreference.getString("orderPaymentPreferenceId"), "paymentMethodId", orderPaymentPreference.getString("paymentMethodId"), "transCodeEnumId", "PGT_AUTHORIZE", "paymentServiceTypeEnumId", "PRDS_PAY_AUTH") + .queryFirst(); + String releaseTransactionId = null; + if (UtilValidate.isNotEmpty(paymentGatewayResponse.getString("referenceNum"))) { + releaseTransactionId = paymentGatewayResponse.getString("referenceNum"); + } else { + releaseTransactionId = paymentGatewayResponse.getString("altReference"); + } + + CloseableHttpClient httpClient = HttpClients.createDefault(); + StringEntity stringEntity = new StringEntity(requestBody); + HttpPost httpPost = new HttpPost(FDProperties.getProperty("transactionUrl") + "/payments/" + releaseTransactionId); + httpPost.setEntity(stringEntity); + httpPost.setHeader("Client-Request-Id", clientRequestId); + httpPost.setHeader("Api-Key", FDProperties.getProperty("apiKey")); + httpPost.setHeader("Timestamp", epochTime); + httpPost.setHeader("Message-Signature", messageSignature); + httpPost.setHeader("Content-Type", "application/json"); + + CloseableHttpResponse response = httpClient.execute(httpPost); + + HttpEntity entity = response.getEntity(); + String responseString = EntityUtils.toString(entity); + + ObjectMapper objectMapper = new ObjectMapper(); + Map<String, Object> convertedMap = objectMapper.readValue(responseString, new TypeReference<Map<String, Object>>(){}); + + String transactionStatus = (String) convertedMap.get("transactionStatus"); + String transactionId = (String) convertedMap.get("ipgTransactionId"); + String fdOrderId = (String) convertedMap.get("orderId"); + Map<String, Object> processor = objectMapper.convertValue(convertedMap.get("processor"), new TypeReference<Map<String, Object>>(){}); + String gatewayMessage = (String) processor.get("responseMessage"); + int statusCode = response.getStatusLine().getStatusCode(); + result.put("releaseCode", String.valueOf(statusCode)); + result.put("releaseMessage", gatewayMessage); + if (UtilValidate.isNotEmpty(transactionId)) { + result.put("releaseRefNum", transactionId); + result.put("releaseAltRefNum", fdOrderId); + if ("approved".equalsIgnoreCase(transactionStatus)) { + isSuccess = Boolean.TRUE; + } + } + if (!isSuccess) { + String errorMessage = "Transaction Type:" + (String) convertedMap.get("transactionType") + " Transaction Id: " + transactionId + " Transaction Status: " + transactionStatus; + errorMessage = errorMessage + " Message: " + statusCode + "-" + gatewayMessage; + result.put(ModelService.ERROR_MESSAGE, errorMessage); + } + } catch (TemplateException | IOException | GenericEntityException e) { + Debug.logError(e, "Could not complete First Data transaction: " + e.toString(), MODULE); + } + result.put("releaseResult", isSuccess); + return result; + } + + private static Properties buildFDProperties(String paymentGatewayConfigId, Delegator delegator) { + String transactionUrl = getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "transactionUrl"); + String appName = getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "appName"); + String apiKey = getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "apiKey"); + String apiSecret = getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "apiSecret"); + //String enableDataVault = getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "enableDataVault"); + + Properties props = new Properties(); + props.put("transactionUrl", transactionUrl); + props.put("appName", appName); + props.put("apiKey", apiKey); + props.put("apiSecret", apiSecret); + //props.put("enableDataVault", enableDataVault); + + if (FDProperties == null) { + FDProperties = props; + } + + return props; + } + + private static String getPaymentGatewayConfigValue(Delegator delegator, String paymentGatewayConfigId, String paymentGatewayConfigParameterName) { + String returnValue = null; + if (UtilValidate.isNotEmpty(paymentGatewayConfigId)) { + try { + GenericValue paymentGatewayFirstData = EntityQuery.use(delegator).from("PaymentGatewayFirstData").where("paymentGatewayConfigId", paymentGatewayConfigId).queryOne(); + if (paymentGatewayFirstData != null) { + Object payflowProField = paymentGatewayFirstData.get(paymentGatewayConfigParameterName); + if (payflowProField != null) { + returnValue = payflowProField.toString().trim(); + } + } + } catch (GenericEntityException e) { + Debug.logError(e, MODULE); + } + } + return returnValue; + } + + private static String buildMessageSignature(String paymentGatewayConfigId, String requestBody, String clientRequestId, String epochTime, Delegator delegator) { + String messageSignature = null; + if (FDProperties == null) { + buildFDProperties(paymentGatewayConfigId, delegator); + } + + String apiKey = FDProperties.getProperty("apiKey"); + final HmacUtils hmacHelper = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, FDProperties.getProperty("apiSecret")); + final Hex hexHelper = new Hex(); + final String msg = apiKey + clientRequestId + epochTime + requestBody; + final byte[] raw = hmacHelper.hmac(msg); + final byte[] hex = hexHelper.encode(raw); + messageSignature = Base64.encodeBase64String(hex); + return messageSignature; + } +} diff --git a/firstdatapaymentgateway/template/FirstDataPostAuthTemplate.json.ftl b/firstdatapaymentgateway/template/FirstDataPostAuthTemplate.json.ftl new file mode 100644 index 0000000..16ddaa3 --- /dev/null +++ b/firstdatapaymentgateway/template/FirstDataPostAuthTemplate.json.ftl @@ -0,0 +1,7 @@ +{ + "requestType": "PostAuthTransaction", + "transactionAmount": { + "total": "${amount}", + "currency": "${currency}" + } +} \ No newline at end of file diff --git a/firstdatapaymentgateway/template/FirstDataPreAuthTemplate.json.ftl b/firstdatapaymentgateway/template/FirstDataPreAuthTemplate.json.ftl new file mode 100644 index 0000000..dbf7a04 --- /dev/null +++ b/firstdatapaymentgateway/template/FirstDataPreAuthTemplate.json.ftl @@ -0,0 +1,19 @@ +{ + "transactionAmount": { + "total": "${amount}", + "currency": "${currency}" + }, + "requestType": "PaymentCardPreAuthTransaction", + "paymentMethod": { + "paymentCard": { + "number": "${cardNumber}", + <#if cardSecurityCode?has_content> + "securityCode": "${cardSecurityCode}", + </#if> + "expiryDate": { + "month": "${expireMonth}", + "year": "${expireYear}" + } + } + } +} \ No newline at end of file diff --git a/firstdatapaymentgateway/template/FirstDataRefundTemplate.json.ftl b/firstdatapaymentgateway/template/FirstDataRefundTemplate.json.ftl new file mode 100644 index 0000000..fcfca65 --- /dev/null +++ b/firstdatapaymentgateway/template/FirstDataRefundTemplate.json.ftl @@ -0,0 +1,7 @@ +{ + "requestType": "ReturnTransaction", + "transactionAmount": { + "total": "${amount}", + "currency": "${currency}" + } +} \ No newline at end of file diff --git a/firstdatapaymentgateway/template/FirstDataReleaseTemplate.json.ftl b/firstdatapaymentgateway/template/FirstDataReleaseTemplate.json.ftl new file mode 100644 index 0000000..d192979 --- /dev/null +++ b/firstdatapaymentgateway/template/FirstDataReleaseTemplate.json.ftl @@ -0,0 +1,4 @@ +{ + "requestType": "VoidTransaction", + "comments": "${comments}" +} \ No newline at end of file diff --git a/firstdatapaymentgateway/template/FirstDataSaleTemplate.json.ftl b/firstdatapaymentgateway/template/FirstDataSaleTemplate.json.ftl new file mode 100644 index 0000000..06a0625 --- /dev/null +++ b/firstdatapaymentgateway/template/FirstDataSaleTemplate.json.ftl @@ -0,0 +1,19 @@ +{ + "transactionAmount": { + "total": "${amount}", + "currency": "${currency}" + }, + "requestType": "PaymentCardSaleTransaction", + "paymentMethod": { + "paymentCard": { + "number": "${cardNumber}", + <#if cardSecurityCode?has_content> + "securityCode": "${cardSecurityCode}", + </#if> + "expiryDate": { + "month": "${expireMonth}", + "year": "${expireYear}" + } + } + } +} \ No newline at end of file diff --git a/firstdatapaymentgateway/webapp/firstdata/WEB-INF/controller.xml b/firstdatapaymentgateway/webapp/firstdata/WEB-INF/controller.xml new file mode 100644 index 0000000..2fe151c --- /dev/null +++ b/firstdatapaymentgateway/webapp/firstdata/WEB-INF/controller.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF 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. +--> + +<site-conf xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="http://ofbiz.apache.org/Site-Conf" xsi:schemaLocation="http://ofbiz.apache.org/Site-Conf http://ofbiz.apache.org/dtds/site-conf.xsd"> + <!-- The controller elements that are common to all OFBiz components + can be found in the following xml file. A component can override the + elements found in the common-controller.xml file. --> + <include location="component://common/webcommon/WEB-INF/common-controller.xml"/> + + <description>FirstData Component Site Configuration File</description> + + <!-- Events to run on every request before security (chains exempt) --> + <!-- + <preprocessor> + </preprocessor> + --> + <!-- Events to run on every request after all other processing (chains exempt) --> + <!-- + <postprocessor> + <event name="test" type="java" path="org.apache.ofbiz.webapp.event.TestEvent" invoke="test"/> + </postprocessor> + --> + + <!-- Request Mappings --> + <request-map uri="main"><security https="true" auth="true"/><response name="success" type="view" value="main"/></request-map> + <request-map uri="updatePaymentGatewayFirstData"> + <security https="true" auth="true"/> + <event type="service" invoke="updatePaymentGatewayFirstData"/> + <response name="success" type="request-redirect" value="main"/> + <response name="error" type="view" value="main"/> + </request-map> + + <!-- View Mappings --> + <view-map name="main" type="screen" page="component://firstdatapaymentgateway/widget/FirstDataScreens.xml#main"/> +</site-conf> \ No newline at end of file diff --git a/firstdatapaymentgateway/webapp/firstdata/WEB-INF/web.xml b/firstdatapaymentgateway/webapp/firstdata/WEB-INF/web.xml new file mode 100644 index 0000000..94554ae --- /dev/null +++ b/firstdatapaymentgateway/webapp/firstdata/WEB-INF/web.xml @@ -0,0 +1,96 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF 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. +--> + +<web-app version="4.0" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"> + <display-name>Apache OFBiz - FirstData Component</display-name> + <description>FirstData Component of the Apache OFBiz Project</description> + + <!-- context-param> + <param-name>webSiteId</param-name> + <param-value>firstdatapaymentgatewaySite</param-value> + <description>A unique ID used to look up the WebSite entity. Only for component using a WebSite entity, like ecommerce</description> + </context-param--> + <context-param> + <description>A unique name used to identify/recognize the local dispatcher for the Service Engine</description> + <param-name>localDispatcherName</param-name><param-value>firstdatapaymentgateway</param-value> + </context-param> + <context-param> + <description>The Name of the Entity Delegator to use, defined in entityengine.xml</description> + <param-name>entityDelegatorName</param-name><param-value>default</param-value> + </context-param> + <context-param> + <description>The location of the main-decorator screen to use for this webapp; referred to as a context variable in screen def XML files.</description> + <param-name>mainDecoratorLocation</param-name> + <param-value>component://firstdatapaymentgateway/widget/CommonScreens.xml</param-value> + </context-param> + <context-param> + <description>Remove unnecessary whitespace from HTML output.</description> + <param-name>compressHTML</param-name> + <param-value>false</param-value> + </context-param> + + <filter> + <display-name>ControlFilter</display-name> + <filter-name>ControlFilter</filter-name> + <filter-class>org.apache.ofbiz.webapp.control.ControlFilter</filter-class> + <init-param> + <param-name>allowedPaths</param-name> + <param-value>/error:/control:/select:/index.html:/index.jsp:/default.html:/default.jsp:/images</param-value> + </init-param> + <init-param><param-name>redirectPath</param-name><param-value>/control/main</param-value></init-param> + </filter> + <filter> + <display-name>ContextFilter</display-name> + <filter-name>ContextFilter</filter-name> + <filter-class>org.apache.ofbiz.webapp.control.ContextFilter</filter-class> + </filter> + <filter> + <display-name>SameSiteFilter</display-name> + <filter-name>SameSiteFilter</filter-name> + <filter-class>org.apache.ofbiz.webapp.control.SameSiteFilter</filter-class> + </filter> + <filter-mapping><filter-name>ControlFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping> + <filter-mapping><filter-name>ContextFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping> + <filter-mapping><filter-name>SameSiteFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping> + + <listener><listener-class>org.apache.ofbiz.webapp.control.ControlEventListener</listener-class></listener> + <listener><listener-class>org.apache.ofbiz.webapp.control.LoginEventListener</listener-class></listener> + <!-- NOTE: not all app servers support mounting implementations of the HttpSessionActivationListener interface --> + <!-- <listener><listener-class>org.apache.ofbiz.webapp.control.ControlActivationEventListener</listener-class></listener> --> + + <servlet> + <description>Main Control Servlet</description> + <display-name>ControlServlet</display-name> + <servlet-name>ControlServlet</servlet-name> + <servlet-class>org.apache.ofbiz.webapp.control.ControlServlet</servlet-class> + <load-on-startup>1</load-on-startup> + </servlet> + <servlet-mapping><servlet-name>ControlServlet</servlet-name><url-pattern>/control/*</url-pattern></servlet-mapping> + + <session-config> + <session-timeout>60</session-timeout><!-- in minutes --> + </session-config> + + <welcome-file-list> + <welcome-file>index.jsp</welcome-file> + <welcome-file>index.html</welcome-file> + <welcome-file>index.htm</welcome-file> + </welcome-file-list> +</web-app> diff --git a/firstdatapaymentgateway/webapp/firstdata/index.jsp b/firstdatapaymentgateway/webapp/firstdata/index.jsp new file mode 100644 index 0000000..4ea7d0c --- /dev/null +++ b/firstdatapaymentgateway/webapp/firstdata/index.jsp @@ -0,0 +1,20 @@ +<%-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF 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. +--%> + +<%response.sendRedirect("control/main");%> \ No newline at end of file diff --git a/firstdatapaymentgateway/widget/CommonScreens.xml b/firstdatapaymentgateway/widget/CommonScreens.xml new file mode 100644 index 0000000..b91abec --- /dev/null +++ b/firstdatapaymentgateway/widget/CommonScreens.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF 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. +--> + +<screens xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="http://ofbiz.apache.org/Widget-Screen" xsi:schemaLocation="http://ofbiz.apache.org/Widget-Screen http://ofbiz.apache.org/dtds/widget-screen.xsd"> + + <screen name="main-decorator"> + <section> + <actions> + <property-map resource="FirstDataUiLabels" map-name="uiLabelMap" global="true"/> + <property-map resource="CommonUiLabels" map-name="uiLabelMap" global="true"/> + + <set field="layoutSettings.companyName" from-field="uiLabelMap.FirstDataCompanyName" global="true"/> + <set field="layoutSettings.companySubtitle" from-field="uiLabelMap.FirstDataCompanySubtitle" global="true"/> + + <set field="activeApp" value="firstdata" global="true"/> + <set field="applicationMenuName" value="MainAppBar" global="true"/> + <set field="applicationMenuLocation" value="component://firstdatapaymentgateway/widget/FirstDataMenus.xml" global="true"/> + <set field="applicationTitle" from-field="uiLabelMap.FirstDataApplication" global="true"/> + </actions> + <widgets> + <include-screen name="GlobalDecorator" location="component://common/widget/CommonScreens.xml"/> + </widgets> + </section> + </screen> + + <screen name="FirstDataCommonDecorator"> + <section> + <actions> + </actions> + <widgets> + <decorator-screen name="main-decorator" location="${parameters.mainDecoratorLocation}"> + <decorator-section name="body"> + <section> + <condition> + <if-has-permission permission="FDSECURITY" action="_VIEW"/> + </condition> + <widgets> + <decorator-section-include name="body"/> + </widgets> + <fail-widgets> + <label style="h3">${uiLabelMap.FirstDataViewPermissionError}</label> + </fail-widgets> + </section> + </decorator-section> + </decorator-screen> + </widgets> + </section> + </screen> +</screens> \ No newline at end of file diff --git a/firstdatapaymentgateway/widget/FirstDataForms.xml b/firstdatapaymentgateway/widget/FirstDataForms.xml new file mode 100644 index 0000000..9219800 --- /dev/null +++ b/firstdatapaymentgateway/widget/FirstDataForms.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF 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. +--> + +<forms xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="http://ofbiz.apache.org/Widget-Form" xsi:schemaLocation="http://ofbiz.apache.org/Widget-Form http://ofbiz.apache.org/dtds/widget-form.xsd"> + + <form name="EditPaymentGatewayFirstData" type="single" target="updatePaymentGatewayFirstData" default-entity-name="PaymentGatewayFirstData"> + <field name="paymentGatewayConfigId"><hidden value="${paymentGatewayFirstData.paymentGatewayConfigId}"/></field> + <field name="appName" title="${uiLabelMap.FormFieldTitle_appName}"><text default-value="${paymentGatewayFirstData.appName}" size="30"/></field> + <field name="apiKey" title="${uiLabelMap.FormFieldTitle_apiKey}"><text default-value="${paymentGatewayFirstData.apiKey}" size="30"/></field> + <field name="apiSecret" title="${uiLabelMap.FormFieldTitle_apiSecret}"><password default-value="${paymentGatewayFirstData.apiSecret}" size="30"/></field> + <field name="transactionUrl" title="${uiLabelMap.FormFieldTitle_transactionUrl}"><text default-value="${paymentGatewayFirstData.transactionUrl}" size="30"/></field> + <field name="enableDataVault" title="${uiLabelMap.FormFieldTitle_enableDataVault}"> + <drop-down allow-empty="false" current="selected" no-current-selected-key="${paymentGatewayFirstData.enableDataVault}"> + <option key="Y" description="${uiLabelMap.CommonYes}"/> + <option key="N" description="${uiLabelMap.CommonNo}"/> + </drop-down> + </field> + <field name="submitButton" use-when="paymentGatewayFirstData!=null" title="${uiLabelMap.CommonUpdate}"><submit button-type="button"/></field> + </form> +</forms> \ No newline at end of file diff --git a/firstdatapaymentgateway/widget/FirstDataMenus.xml b/firstdatapaymentgateway/widget/FirstDataMenus.xml new file mode 100644 index 0000000..93614db --- /dev/null +++ b/firstdatapaymentgateway/widget/FirstDataMenus.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF 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. +--> + +<menus xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://ofbiz.apache.org/Widget-Menu" xsi:schemaLocation="http://ofbiz.apache.org/Widget-Menu http://ofbiz.apache.org/dtds/widget-menu.xsd"> + <menu name="MainAppBar" title="${uiLabelMap.FirstDataApplication}" extends="CommonAppBarMenu" extends-resource="component://common/widget/CommonMenus.xml"> + <menu-item name="main" title="${uiLabelMap.CommonMain}"><link target="main"/></menu-item> + </menu> +</menus> \ No newline at end of file diff --git a/firstdatapaymentgateway/widget/FirstDataScreens.xml b/firstdatapaymentgateway/widget/FirstDataScreens.xml new file mode 100644 index 0000000..e5b43f2 --- /dev/null +++ b/firstdatapaymentgateway/widget/FirstDataScreens.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF 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. +--> + +<screens xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="http://ofbiz.apache.org/Widget-Screen" xsi:schemaLocation="http://ofbiz.apache.org/Widget-Screen http://ofbiz.apache.org/dtds/widget-screen.xsd"> + + <screen name="main"> + <section> + <actions> + <set field="headerItem" value="main"/><!-- this highlights the selected menu-item with name "main" --> + <property-map resource="FirstDataUiLabels" map-name="uiLabelMap" global="true"/> + <property-map resource="CommonUiLabels" map-name="uiLabelMap" global="true"/> + <set field="titleProperty" value="FirstDataEditConfigurations"/> + <set field="tabButtonItem" value="FirstDataEditConfigurations"/> + </actions> + <widgets> + <decorator-screen name="FirstDataCommonDecorator" location="${parameters.mainDecoratorLocation}"> + <decorator-section name="body"> + <section> + <actions> + <set field="paymentGatewayConfigId" from-field="parameters.paymentGatewayConfigId" default-value="FIRST_DATA_CONFIG"/> + <entity-one entity-name="PaymentGatewayFirstData" value-field="paymentGatewayFirstData"/> + </actions> + <widgets> + <container style="h1"><label>${uiLabelMap.FirstDataConfigurations}</label></container> + <include-form name="EditPaymentGatewayFirstData" location="component://firstdatapaymentgateway/widget/FirstDataForms.xml"/> + </widgets> + </section> + </decorator-section> + </decorator-screen> + </widgets> + </section> + </screen> + +</screens> \ No newline at end of file