You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by pa...@apache.org on 2020/06/27 05:54:50 UTC
[ofbiz-plugins] 01/03: Adding new plugin for integration of First
Data payment gateway with Apache OFBiz. (OFBIZ-11837)
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