diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..62e7820
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+# Created by .ignore support plugin (hsz.mobi)
+.idea
\ No newline at end of file
diff --git a/README.md b/README.md
index 991f90f..42ea532 100644
--- a/README.md
+++ b/README.md
@@ -1,25 +1,28 @@
# Integrate Gravity Forms with Braintree
-Braintree Payments is a payment gateway provider owned by eBAY Inc, which allows you to proces credit card payments without the need for a bank merchant account and full PCI-compliance. No sensitive data such as credit card numbers are stored on your server, Braintree takes care of everything.
-
-#### If you have found this plugin useful, consider taking a moment to rate it, or perhaps even a small donation.
+Braintree Payments is a payment gateway provider owned by PayPal which allows you to process credit card payments without the need for a bank merchant account and full PCI-compliance. No sensitive data such as credit card numbers are stored on your server, Braintree takes care of everything.
## Installation
-1. Upload the `gravity-forms-braintree` folder to the `/wp-content/plugins/` directory.
-2. Activate the plugin through the 'Plugins' menu in WordPress.
-3. Navigate to the Form you wish to setup with a Braintree feed.
-4. Under Form Settings, choose the Braintree option.
+### Automatic installation
-## Features
+Automatic installation is the easiest option as WordPress handles the file transfers itself and you don't need to leave your web browser. To do an automatic install of Gravity Forms Braintree Payments, log in to your WordPress dashboard, navigate to the Plugins menu and click Add New.
+
+In the search field type Gravity Forms Braintree Payments and click Search Plugins. Once you've found our plugin (make sure it says "by Angell EYE") you can view details about it such as the the rating and description. Most importantly, of course, you can install it by simply clicking Install Now.
+
+### Manual Installation
-* Seamlessly integrates your Gravity Forms credit card forms with Braintree Payments
-* Supports both production and sandbox environments, enabling you to test payments before going live
-* Form entries will only be created when payment is successful
-* Quick and easy setup
+1. Unzip the files and upload the folder into your plugins folder (/wp-content/plugins/) overwriting older versions if they exist
+2. Activate the plugin in your WordPress admin area.
-## Subscriptions
-The plugin does not currently support Braintree Subscriptions. Keep a look out for it in a future version
+### Usage
+
+1. Navigate to the Form you wish to setup with a Braintree feed.
+2. Under Form Settings, choose the Braintree option.
+
+## Features
-## Upgrade Notice
-If you are updating from a version previous to 1.0, your existing feeds will not work. Please make sure you check all your feeds and ensure they function correctly.
+* Seamlessly integrates your Gravity Forms credit card forms with Braintree Payments.
+* Supports both production and sandbox environments, enabling you to test payments before going live.
+* Form entries will only be created when payment is successful.
+* Quick and easy setup.
\ No newline at end of file
diff --git a/angelleye-gravity-forms-braintree.php b/angelleye-gravity-forms-braintree.php
new file mode 100644
index 0000000..544b6e3
--- /dev/null
+++ b/angelleye-gravity-forms-braintree.php
@@ -0,0 +1,138 @@
+setPHP('7.2');
+ $checker->setRequiredClasses(['GFForms' => 'The Gravity Forms plugin is required in order to run Gravity Forms Braintree Payments.']);
+ $checker->setRequiredExtensions(['xmlwriter', 'openssl', 'dom', 'hash', 'curl']);
+ $checker->setRequiredPlugins(['gravityforms/gravityforms.php'=>['min_version'=>'2.4', 'install_link'=>'https://rocketgenius.pxf.io/c/1331556/445235/7938', 'name'=>'Gravity Forms']]);
+ //$checker->setDeactivatePlugins([self::$plugin_base_file]);
+ if($checker->check()===true) {
+ $this->init();
+ }
+ }
+
+ public function init()
+ {
+ $path = trailingslashit( dirname( __FILE__ ) );
+
+ // Ensure Gravity Forms (payment addon framework) is installed and good to go
+ if( is_callable( array( 'GFForms', 'include_payment_addon_framework' ) ) ) {
+
+ // Bootstrap payment addon framework
+ GFForms::include_payment_addon_framework();
+ GFForms::include_addon_framework();
+
+ // Require Braintree Payments core
+ if(!class_exists('Braintree')) {
+ require_once $path . 'lib/Braintree.php';
+ }
+
+ // Require plugin entry point
+ require_once $path . 'includes/angelleye-gravity-braintree-helper.php';
+ require_once $path . 'lib/class.plugify-gform-braintree.php';
+ require_once $path . 'includes/class-angelleye-gravity-braintree-ach-field.php';
+ require_once $path . 'includes/class-angelleye-gravity-braintree-ach-toggle-field.php';
+ require_once $path . 'lib/angelleye-gravity-forms-payment-logger.php';
+ require_once $path . 'includes/angelleye-gravity-braintree-field-mapping.php';
+ require_once $path . 'includes/class-angelleye-gravity-braintree-creditcard.php';
+
+ /**
+ * Required functions
+ */
+ if (!function_exists('angelleye_queue_update')) {
+ require_once( 'includes/angelleye-functions.php' );
+ }
+
+ // Fire off entry point
+ new Plugify_GForm_Braintree();
+ new AngelleyeGravityBraintreeFieldMapping();
+
+ /**
+ * Register the ACH form field and Payment Method toggle field
+ */
+ GF_Fields::register( new Angelleye_Gravity_Braintree_ACH_Field() );
+ GF_Fields::register( new Angelleye_Gravity_Braintree_ACH_Toggle_Field() );
+ GF_Fields::register( new Angelleye_Gravity_Braintree_CreditCard_Field() );
+ AngellEYE_GForm_Braintree_Payment_Logger::instance();
+
+ }
+ }
+
+ public static function isBraintreeFeedActive()
+ {
+ global $wpdb;
+ $addon_feed_table_name = $wpdb->prefix . 'gf_addon_feed';
+ $is_active = $wpdb->get_var("select is_active from ".$addon_feed_table_name." where addon_slug='gravity-forms-braintree' and is_active=1");
+
+ return $is_active=='1';
+ }
+}
+
+AngelleyeGravityFormsBraintree::getInstance();
\ No newline at end of file
diff --git a/assets/css/gravity-forms-braintree-admin.css b/assets/css/gravity-forms-braintree-admin.css
new file mode 100644
index 0000000..ff5e739
--- /dev/null
+++ b/assets/css/gravity-forms-braintree-admin.css
@@ -0,0 +1,88 @@
+.notice.notice-success.angelleye-notice {
+ padding: 0 !important;
+ margin: 5px 0 10px;
+ background: #FFF;
+ overflow: hidden;
+ -webkit-border-radius: 6px;
+ border-radius: 6px;
+ -webkit-box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.05);
+ box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.05);
+ position: relative;
+ z-index: 1;
+ min-height: 80px;
+ display: table; /* The magic ingredient! */
+ font: 13px "Open Sans", sans-serif;
+}
+.angelleye-notice > div {
+ display: table-cell;
+ vertical-align: middle;
+ cursor: default;
+ line-height: 1.5;
+}
+.angelleye-notice-logo-push {
+ background-repeat: no-repeat;
+ background-position: 50% 50%;
+}
+.angelleye-notice-logo-push span {
+ display: block;
+ margin: 0px 10px 0px 10px;
+}
+.notice.notice-success.angelleye-notice {
+ font: 13px "Open Sans", sans-serif;
+ line-height: normal;
+}
+.angelleye-notice-message {
+ color: #23282D;
+ font-size: 13px;
+ font-weight: normal;
+ line-height: 20px;
+ padding: 3px 5px;
+ -webkit-font-smoothing: antialiased;
+ width: 100%;
+}
+.angelleye-notice-message h3 {
+ margin: 4px 0px !important;
+}
+.angelleye-notice-message-inner {
+ margin-bottom: 10px;
+}
+.angelleye-notice-message p {
+ margin: 3px 0px !important;
+ padding: 0px;
+}
+.angelleye-notice-action {
+ padding-top: 5px;
+}
+.angelleye-notice-cta {
+ border-left: 1px solid #E5E5E5;
+ background: #F8F8F8;
+ padding: 0 30px;
+ position: relative;
+ white-space: nowrap;
+}
+.wp-core-ui .angelleye-notice-cta button,
+.wp-core-ui .angelleye-notice-cta .button-primary:active {
+ vertical-align: middle;
+}
+.angelleye-notice-dismiss {
+ background: transparent;
+ border: 0;
+ cursor: pointer;
+ color: #C5C5C5;
+ -webkit-font-smoothing: antialiased;
+}
+.updater-dismissible {
+ padding-right: 38px;
+ position: relative;
+}
+
+.alert-notification-custom-fields:after,.alert-notification-custom-fields:before {
+ content:"";display:table;clear:both;
+}
+.alert-notification-custom-fields{
+ padding:0.01em 16px;color:#000!important;background-color:#ffffcc!important;margin-top:16px;
+}
+
+#gform_braintree_mapping table{
+ width: 800px;
+}
\ No newline at end of file
diff --git a/assets/css/styles.css b/assets/css/styles.css
index 73216a6..0efd233 100644
--- a/assets/css/styles.css
+++ b/assets/css/styles.css
@@ -14,3 +14,77 @@ table.feeds th#id {
body {
display: none;
}
+
+.notice.notice-success.angelleye-notice {
+ padding: 0 !important;
+ margin: 5px 0 10px;
+ background: #FFF;
+ overflow: hidden;
+ -webkit-border-radius: 6px;
+ border-radius: 6px;
+ -webkit-box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.05);
+ box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.05);
+ position: relative;
+ z-index: 1;
+ min-height: 80px;
+ display: table; /* The magic ingredient! */
+ font: 13px "Open Sans", sans-serif;
+}
+.angelleye-notice > div {
+ display: table-cell;
+ vertical-align: middle;
+ cursor: default;
+ line-height: 1.5;
+}
+.angelleye-notice-logo-push {
+ background-repeat: no-repeat;
+ background-position: 50% 50%;
+}
+.angelleye-notice-logo-push span {
+ display: block;
+ margin: 0px 10px 0px 10px;
+}
+.notice.notice-success.angelleye-notice {
+ font: 13px "Open Sans", sans-serif;
+ line-height: normal;
+}
+.angelleye-notice-message {
+ color: #23282D;
+ font-size: 13px;
+ font-weight: normal;
+ line-height: 20px;
+ padding: 3px 5px;
+ -webkit-font-smoothing: antialiased;
+ width: 100%;
+}
+.angelleye-notice-message h3 {
+ margin: 4px 0px !important;
+}
+.angelleye-notice-message-inner {
+ margin-bottom: 10px;
+}
+.angelleye-notice-message p {
+ margin: 3px 0px !important;
+ padding: 0px;
+}
+.angelleye-notice-action {
+ padding-top: 5px;
+}
+.angelleye-notice-cta {
+ border-left: 1px solid #E5E5E5;
+ background: #F8F8F8;
+ padding: 0 30px;
+ position: relative;
+ white-space: nowrap;
+}
+.wp-core-ui .angelleye-notice-cta button,
+.wp-core-ui .angelleye-notice-cta .button-primary:active {
+ vertical-align: middle;
+}
+.angelleye-notice-dismiss {
+ background: transparent;
+ border: 0;
+ cursor: pointer;
+ color: #C5C5C5;
+ -webkit-font-smoothing: antialiased;
+}
\ No newline at end of file
diff --git a/assets/js/angelleye-braintree-ach-cc.js b/assets/js/angelleye-braintree-ach-cc.js
new file mode 100644
index 0000000..29efbe3
--- /dev/null
+++ b/assets/js/angelleye-braintree-ach-cc.js
@@ -0,0 +1,271 @@
+jQuery(document).ready(function ($) {
+ if ($('.gform_payment_method_options').length) {
+ var payment_methods = {};
+ $('.gform_payment_method_options input[type=radio]').each(function () {
+ var targetdiv = $(this).attr('targetdiv');
+ var value = $(this).val();
+ payment_methods[value] = targetdiv;
+ });
+
+ $('.gform_payment_method_options').on('click', 'input[type=radio]', function () {
+ var selectedradio = $(this).val();
+ for (var i in payment_methods)
+ if (i !== selectedradio)
+ $(this).closest('form').find('#' + payment_methods[i]).slideUp()
+
+ var targetdiv = $(this).attr('targetdiv');
+ $(this).closest('form').find('#' + targetdiv).slideDown();
+ });
+
+ var selectedradio = $('.gform_payment_method_options input[type=radio]:checked').val();
+
+ switch (selectedradio) {
+ case 'braintree_ach':
+ $('.gform_payment_method_options input[value=braintree_ach]').trigger('click');
+ break;
+ default:
+ case 'creditcard':
+ $('.gform_payment_method_options input[value=creditcard]').trigger('click');
+ break;
+ }
+ }
+
+
+
+ $('.custom_ach_form_submit_btn').click(function (e) {
+ window[ 'gf_submitting_' + $("input[name='gform_submit']").val() ] = true;
+ $('#gform_ajax_spinner_' + $("input[name='gform_submit']").val()).remove();
+ e.preventDefault();
+ var curlabel = $(this).html();
+ var form = $(this).closest('form');
+
+ var selectedradio = form.find('.gform_payment_method_options input[type=radio]:checked').val();
+
+ var check_if_ach_form = form.find('.ginput_ach_form_container');
+ if (check_if_ach_form.length && (selectedradio === 'braintree_ach' || check_if_ach_form.closest('.gfield').css('display') !== 'none')) {
+ if (form.find('.ginput_container_address').length == 0) {
+ alert('ACH payment requires billing address fields, so please include Billing Address field in your Gravity form.');
+ return;
+ }
+
+ var account_number = form.find('.ginput_account_number').val();
+ var account_number_verification = form.find('.ginput_account_number_verification').val();
+ var account_type = form.find('.ginput_account_type').val();
+ var routing_number = form.find('.ginput_routing_number').val();
+ var account_holdername = form.find('.ginput_account_holdername').val();
+
+ var streetAddress = form.find('.ginput_container_address .address_line_1 input[type=text]').val();
+ var extendedAddress = form.find('.ginput_container_address .address_line_2 input[type=text]').val();
+ var locality = form.find('.ginput_container_address .address_city input[type=text]').val();
+ var region = form.find('.ginput_container_address .address_state input[type=text], .ginput_container_address .address_state select').val();
+ var postalCode = form.find('.ginput_container_address .address_zip input[type=text]').val();
+
+ if (region.length > 2) {
+ region = stateNameToAbbreviation(region);
+ }
+
+ var address_validation_errors = [];
+ if (streetAddress == '') {
+ address_validation_errors.push('Please enter a street address.');
+ }
+
+ if (locality == '') {
+ address_validation_errors.push('Please enter your city.');
+ }
+
+ if (region == '') {
+ address_validation_errors.push('Please enter your state.');
+ }
+
+ if (postalCode == '') {
+ address_validation_errors.push('Please enter your postal code.');
+ }
+
+ if (address_validation_errors.length) {
+ alert(address_validation_errors.join('\n'));
+ return;
+ }
+
+ var achform_validation_errors = [];
+ if (routing_number == '' || isNaN(routing_number) || account_number == '' || isNaN(account_number)) {
+ achform_validation_errors.push('Please enter a valid routing and account number.')
+ }
+
+ if (account_type == '') {
+ achform_validation_errors.push('Please select your account type.')
+ }
+
+ if (account_holdername == '') {
+ achform_validation_errors.push('Please enter the account holder name.');
+ } else {
+ var account_holder_namebreak = account_holdername.split(' ');
+ if (account_type == 'S' && account_holder_namebreak.length < 2) {
+ achform_validation_errors.push('Please enter the account holder first and last name.');
+ }
+ }
+
+ if (account_number !== account_number_verification) {
+ achform_validation_errors.push('Account Number and Account Number Verification field should be same.');
+ }
+
+ if (achform_validation_errors.length) {
+ alert(achform_validation_errors.join('\n'));
+ return;
+ }
+
+ var submitbtn = $(this);
+ // submitbtn.attr('disabled', true).html('Please wait...').css('opacity', '0.4');
+
+ braintree.client.create({
+ authorization: angelleye_gravity_form_braintree_ach_handler_strings.ach_bt_token
+ }, function (clientErr, clientInstance) {
+ if (clientErr) {
+ alert('There was an error creating the Client, Please check your Braintree Settings.');
+ console.error('clientErr', clientErr);
+ return;
+ }
+
+ braintree.dataCollector.create({
+ client: clientInstance,
+ paypal: true
+ }, function (err, dataCollectorInstance) {
+ if (err) {
+ alert('We are unable to validate your system, please try again.');
+ resetButtonLoading(submitbtn, curlabel);
+ console.error('dataCollectorError', err);
+ return;
+ }
+
+ var deviceData = dataCollectorInstance.deviceData;
+
+ braintree.usBankAccount.create({
+ client: clientInstance
+ }, function (usBankAccountErr, usBankAccountInstance) {
+ if (usBankAccountErr) {
+ alert('There was an error initiating the bank request. Please try again.');
+ resetButtonLoading(submitbtn, curlabel);
+ console.error('usBankAccountErr', usBankAccountErr);
+ return;
+ }
+
+ var bankDetails = {
+ accountNumber: account_number, //'1000000000',
+ routingNumber: routing_number, //'011000015',
+ accountType: account_type == 'S' ? 'savings' : 'checking',
+ ownershipType: account_type == 'S' ? 'personal' : 'business',
+ billingAddress: {
+ streetAddress: streetAddress, //'1111 Thistle Ave',
+ extendedAddress: extendedAddress,
+ locality: locality, //'Fountain Valley',
+ region: region, //'CA',
+ postalCode: postalCode //'92708'
+ }
+ };
+
+ if (bankDetails.ownershipType === 'personal') {
+ bankDetails.firstName = account_holder_namebreak[0];
+ bankDetails.lastName = account_holder_namebreak[1];
+ } else {
+ bankDetails.businessName = account_holdername;
+ }
+
+ usBankAccountInstance.tokenize({
+ bankDetails: bankDetails,
+ mandateText: 'By clicking ["Submit"], I authorize Braintree, a service of PayPal, on behalf of ' + angelleye_gravity_form_braintree_ach_handler_strings.ach_business_name + ' (i) to verify my bank account information using bank information and consumer reports and (ii) to debit my bank account.'
+ }, function (tokenizeErr, tokenizedPayload) {
+ if (tokenizeErr) {
+ var errormsg = tokenizeErr['details']['originalError']['details']['originalError'][0]['message'];
+ if (errormsg.indexOf("Variable 'zipCode' has an invalid value") != -1)
+ alert('Please enter valid postal code.');
+ else if (errormsg.indexOf("Variable 'state' has an invalid value") != -1)
+ alert('Please enter valid state code. (e.g.: CA)');
+ else
+ alert(errormsg);
+
+ resetButtonLoading(submitbtn, curlabel);
+ console.error('tokenizeErr', tokenizeErr);
+ return;
+ }
+
+ form.append("");
+ form.append('');
+
+
+ form.submit();
+ });
+ });
+ });
+ });
+
+ } else {
+ form.submit();
+ }
+ });
+});
+
+function stateNameToAbbreviation(name) {
+ let states = {
+ "Alabama": "AL",
+ "Alaska": "AK",
+ "Arizona": "AZ",
+ "Arkansas": "AR",
+ "California": "CA",
+ "Colorado": "CO",
+ "Connecticut": "CT",
+ "Delaware": "DE",
+ "District of Columbia": "DC",
+ "Florida": "FL",
+ "Georgia": "GA",
+ "Hawaii": "HI",
+ "Idaho": "ID",
+ "Illinois": "IL",
+ "Indiana": "IN",
+ "Iowa": "IA",
+ "Kansas": "KS",
+ "Kentucky": "KY",
+ "Louisiana": "LA",
+ "Maine": "ME",
+ "Maryland": "MD",
+ "Massachusetts": "MA",
+ "Michigan": "MI",
+ "Minnesota": "MN",
+ "Mississippi": "MS",
+ "Missouri": "MO",
+ "Montana": "MT",
+ "Nebraska": "NE",
+ "Nevada": "NV",
+ "New Hampshire": "NH",
+ "New Jersey": "NJ",
+ "New Mexico": "NM",
+ "New York": "NY",
+ "North Carolina": "NC",
+ "North Dakota": "ND",
+ "Ohio": "OH",
+ "Oklahoma": "OK",
+ "Oregon": "OR",
+ "Pennsylvania": "PA",
+ "Rhode Island": "RI",
+ "South Carolina": "SC",
+ "South Dakota": "SD",
+ "Tennessee": "TN",
+ "Texas": "TX",
+ "Utah": "UT",
+ "Vermont": "VT",
+ "Virginia": "VA",
+ "Washington": "WA",
+ "West Virginia": "WV",
+ "Wisconsin": "WI",
+ "Wyoming": "WY",
+ "Armed Forces Americas": "AA",
+ "Armed Forces Europe": "AE",
+ "Armed Forces Pacific": "AP"
+ }
+ if (states[name] !== null) {
+ return states[name];
+ }
+ return name;
+}
+
+function resetButtonLoading(submitbtn, curlabel) {
+ // submitbtn.attr('disabled', false).html(curlabel).css('opacity', '1');
+}
diff --git a/assets/js/gravity-forms-braintree-admin.js b/assets/js/gravity-forms-braintree-admin.js
new file mode 100644
index 0000000..5eff35f
--- /dev/null
+++ b/assets/js/gravity-forms-braintree-admin.js
@@ -0,0 +1,76 @@
+jQuery(function () {
+ jQuery('[id^=angelleye_notification]').each(function (i) {
+ jQuery('[id="' + this.id + '"]').slice(1).remove();
+ });
+ var el_notice = jQuery(".angelleye-notice");
+ el_notice.fadeIn(750);
+ jQuery(".angelleye-notice-dismiss").click(function(e){
+ e.preventDefault();
+ jQuery( this ).parent().parent(".angelleye-notice").fadeOut(600, function () {
+ jQuery( this ).parent().parent(".angelleye-notice").remove();
+ });
+ notify_wordpress(jQuery( this ).data("msg"));
+ });
+ function notify_wordpress(message) {
+ var param = {
+ action: 'angelleye_gform_braintree_adismiss_notice',
+ data: message
+ };
+ jQuery.post(ajaxurl, param);
+ }
+ jQuery(document).off('click', '#angelleye-updater-notice .notice-dismiss').on('click', '#angelleye-updater-notice .notice-dismiss',function(event) {
+ var r = confirm("If you do not install the Updater plugin you will not receive automated updates for Angell EYE products going forward!");
+ if (r == true) {
+ var data = {
+ action : 'angelleye_updater_dismissible_admin_notice'
+ };
+ jQuery.post(ajaxurl, data, function (response) {
+ var $el = jQuery( '#angelleye-updater-notice' );
+ event.preventDefault();
+ $el.fadeTo( 100, 0, function() {
+ $el.slideUp( 100, function() {
+ $el.remove();
+ });
+ });
+ });
+ }
+ });
+});
+
+jQuery(document).ready(function ($) {
+ $('.addmorecustomfield').click(function () {
+ $('.custom_field_row:last').after('
| '+$('.custom_fields_template').html()+' Remove |
');
+ if($('.custom_field_row').length>1){
+ $('.alert-notification-custom-fields').removeClass('hide');
+ }
+ });
+
+ $('body').on('click','.remove_custom_field', function () {
+ $(this).closest('tr.custom_field_row') .remove();
+ });
+
+ $('#gform_braintree_mapping').submit(function (e) {
+ e.preventDefault();
+
+ var data = $(this).serialize();
+ var url = $(this).attr('action');
+ $('.successful_message').html('');
+ $('.updatemappingbtn').html('Saving...').attr('disabled','disabled');
+ $.ajax({
+ url:url,
+ method: 'post',
+ 'data': data,
+ 'dataType': 'json'
+ }).done(function (response) {
+ if(response.status){
+ $('.successful_message').html('')
+ }else {
+ console.log('error', response);
+ }
+
+ }).complete(function () {
+ $('.updatemappingbtn').html('Update Mapping').removeAttr('disabled');
+ });
+
+ })
+});
\ No newline at end of file
diff --git a/assets/js/scripts.js b/assets/js/scripts.js
index e1fcb85..6145dea 100644
--- a/assets/js/scripts.js
+++ b/assets/js/scripts.js
@@ -148,4 +148,4 @@ jQuery( function($) {
});
-});
+});
\ No newline at end of file
diff --git a/gravity-forms-braintree.php b/gravity-forms-braintree.php
deleted file mode 100644
index 45534e9..0000000
--- a/gravity-forms-braintree.php
+++ /dev/null
@@ -1,35 +0,0 @@
-
diff --git a/includes/angelleye-functions.php b/includes/angelleye-functions.php
new file mode 100644
index 0000000..1d33b50
--- /dev/null
+++ b/includes/angelleye-functions.php
@@ -0,0 +1,91 @@
+file = $file;
+ $plugin->file_id = $file_id;
+ $plugin->product_id = $product_id;
+
+ $angelleye_queued_updates[] = $plugin;
+ }
+
+}
+
+
+/**
+ * Load installer for the AngellEYE Updater.
+ * @return $api Object
+ */
+if (!class_exists('AngellEYE_Updater') && !function_exists('angell_updater_install')) {
+
+ function angell_updater_install($api, $action, $args) {
+ $download_url = AEU_ZIP_URL;
+
+ if ('plugin_information' != $action ||
+ false !== $api ||
+ !isset($args->slug) ||
+ 'angelleye-updater' != $args->slug
+ )
+ return $api;
+
+ $api = new stdClass();
+ $api->name = 'AngellEYE Updater';
+ $api->version = '';
+ $api->download_link = esc_url($download_url);
+ return $api;
+ }
+
+ add_filter('plugins_api', 'angell_updater_install', 10, 3);
+}
+
+/**
+ * AngellEYE Installation Prompts
+ */
+if (!class_exists('AngellEYE_Updater') && !function_exists('angell_updater_notice')) {
+
+ /**
+ * Display a notice if the "AngellEYE Updater" plugin hasn't been installed.
+ * @return void
+ */
+ function angell_updater_notice() {
+ $active_plugins = apply_filters('active_plugins', get_option('active_plugins'));
+ if (in_array('angelleye-updater/angelleye-updater.php', $active_plugins))
+ return;
+
+ $slug = 'angelleye-updater';
+ $install_url = wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=' . $slug), 'install-plugin_' . $slug);
+ $activate_url = 'plugins.php?action=activate&plugin=' . urlencode('angelleye-updater/angelleye-updater.php') . '&plugin_status=all&paged=1&s&_wpnonce=' . urlencode(wp_create_nonce('activate-plugin_angelleye-updater/angelleye-updater.php'));
+
+ $message = 'Install the Angell EYE Updater plugin to get updates for your Angell EYE plugins.';
+ $is_downloaded = false;
+ $plugins = array_keys(get_plugins());
+ foreach ($plugins as $plugin) {
+ if (strpos($plugin, 'angelleye-updater.php') !== false) {
+ $is_downloaded = true;
+ $message = ' Activate the Angell EYE Updater plugin to get updates for your Angell EYE plugins.';
+ }
+ }
+ echo '' . $message . '
' . "\n";
+ }
+
+ function angelleye_updater_dismissible_admin_notice() {
+ set_transient( 'angelleye_updater_notice_hide', 'yes', MONTH_IN_SECONDS );
+ }
+ if ( false === ( $angelleye_updater_notice_hide = get_transient( 'angelleye_updater_notice_hide' ) ) ) {
+ add_action('admin_notices', 'angell_updater_notice');
+ }
+ add_action( 'wp_ajax_angelleye_updater_dismissible_admin_notice', 'angelleye_updater_dismissible_admin_notice' );
+}
\ No newline at end of file
diff --git a/includes/angelleye-gravity-braintree-activator.php b/includes/angelleye-gravity-braintree-activator.php
new file mode 100755
index 0000000..d7524f2
--- /dev/null
+++ b/includes/angelleye-gravity-braintree-activator.php
@@ -0,0 +1,24 @@
+isCreditCardFieldExist($form_id)) {
+ $menu_items[] = array(
+ 'name' => 'braintree_mapping_settings_page',
+ 'label' => __('Braintree Field Mapping')
+ );
+ }
+ }
+ return $menu_items;
+ }
+
+ public function braintreeFieldMapping()
+ {
+ GFFormSettings::page_header();
+ require dirname(__FILE__).'/pages/angelleye-braintree-field-map-form.php';
+ GFFormSettings::page_footer();
+ }
+
+ public function isCreditCardFieldExist($id)
+ {
+ $get_form = GFAPI::get_form($id);
+ if(isset($get_form['fields'])) {
+ foreach ($get_form['fields'] as $single_field) {
+ if ($single_field->type == 'creditcard' || $single_field->type=='braintree_ach' || $single_field->type=='braintree_credit_card' ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public function saveMapping()
+ {
+ $form_id = $_POST['gform_id'];
+ //sanitize input values
+ $final_mapping = [];
+ foreach ($_POST['gravity_form_field'] as $key=>$field_id){
+ if(empty($field_id)) continue;
+ $final_mapping[$key] = $field_id;
+ }
+
+ $custom_fields=[];
+ if(isset($_POST['gravity_form_custom_field_name'])){
+ $mapped_field_ids = $_POST['gravity_form_custom_field'];
+ foreach ($_POST['gravity_form_custom_field_name'] as $key => $single_custom_field_name){
+ if(!isset($mapped_field_ids[$key]) || empty($mapped_field_ids[$key]))
+ continue;
+
+ $custom_fields[$single_custom_field_name] = $mapped_field_ids[$key];
+ }
+ }
+ if(count($custom_fields))
+ $final_mapping['custom_fields'] = $custom_fields;
+
+ $get_form = GFAPI::get_form($form_id);
+ $get_form['braintree_fields_mapping'] = $final_mapping;
+ GFAPI::update_form($get_form, $form_id);
+
+ die(json_encode(['status'=>true,'message'=>'Mapping has been updated successfully.']));
+ }
+
+ function assignArrayByPath(&$arr, $path, $value, $separator='.') {
+ $keys = explode($separator, $path);
+
+ foreach ($keys as $key) {
+ $arr = &$arr[$key];
+ }
+
+ $arr = $value;
+ }
+
+ public function mapGravityBraintreeFields($args, $submission_data, $form, $entry)
+ {
+
+ $braintree_mapping = isset($form['braintree_fields_mapping'])?$form['braintree_fields_mapping']:[];
+ $final_array = [];
+
+ if(count($braintree_mapping)){
+ foreach ($braintree_mapping as $key_name => $single_mapid)
+ {
+ if(is_array($single_mapid)){
+ if($key_name=='custom_fields') {
+ foreach ($single_mapid as $subkey_name => $sub_mapid) {
+ if (isset($entry[$sub_mapid])) {
+ $this->assignArrayByPath($final_array, 'customFields.' . $subkey_name, $entry[$sub_mapid]);
+ }
+ }
+ }
+ }else {
+ if (isset($entry[$single_mapid])) {
+ $this->assignArrayByPath($final_array, $key_name, $entry[$single_mapid]);
+ }
+ }
+ }
+ }
+ if(count($final_array)){
+ $args = array_merge($args, $final_array);
+ }
+ //var_dump($args); die;
+ return $args;
+ }
+
+ function addNoticeToCreditCardForm( $field_content, $field, $value, $lead_id, $form_id ) {
+ if(is_admin()) {
+ if ($field->type == 'creditcard' || $field->type == 'braintree_credit_card') {
+ //echo ($field_content); die;
+ $first_label_position = strpos($field_content, '