@@ -37,138 +37,138 @@ |
||
| 37 | 37 | * @since 4.0 |
| 38 | 38 | */ |
| 39 | 39 | if (function_exists('espresso_version')) { |
| 40 | - if (! function_exists('espresso_duplicate_plugin_error')) { |
|
| 41 | - /** |
|
| 42 | - * espresso_duplicate_plugin_error |
|
| 43 | - * displays if more than one version of EE is activated at the same time. |
|
| 44 | - */ |
|
| 45 | - function espresso_duplicate_plugin_error() |
|
| 46 | - { |
|
| 47 | - ?> |
|
| 40 | + if (! function_exists('espresso_duplicate_plugin_error')) { |
|
| 41 | + /** |
|
| 42 | + * espresso_duplicate_plugin_error |
|
| 43 | + * displays if more than one version of EE is activated at the same time. |
|
| 44 | + */ |
|
| 45 | + function espresso_duplicate_plugin_error() |
|
| 46 | + { |
|
| 47 | + ?> |
|
| 48 | 48 | <div class="error"> |
| 49 | 49 | <p> |
| 50 | 50 | <?php |
| 51 | - echo esc_html__( |
|
| 52 | - 'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.', |
|
| 53 | - 'event_espresso' |
|
| 54 | - ); ?> |
|
| 51 | + echo esc_html__( |
|
| 52 | + 'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.', |
|
| 53 | + 'event_espresso' |
|
| 54 | + ); ?> |
|
| 55 | 55 | </p> |
| 56 | 56 | </div> |
| 57 | 57 | <?php |
| 58 | - espresso_deactivate_plugin(plugin_basename(__FILE__)); |
|
| 59 | - } |
|
| 60 | - } |
|
| 61 | - add_action('admin_notices', 'espresso_duplicate_plugin_error', 1); |
|
| 58 | + espresso_deactivate_plugin(plugin_basename(__FILE__)); |
|
| 59 | + } |
|
| 60 | + } |
|
| 61 | + add_action('admin_notices', 'espresso_duplicate_plugin_error', 1); |
|
| 62 | 62 | } else { |
| 63 | - define('EE_MIN_PHP_VER_REQUIRED', '7.4.0'); |
|
| 64 | - if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) { |
|
| 65 | - /** |
|
| 66 | - * espresso_minimum_php_version_error |
|
| 67 | - * |
|
| 68 | - * @return void |
|
| 69 | - */ |
|
| 70 | - function espresso_minimum_php_version_error() |
|
| 71 | - { |
|
| 72 | - ?> |
|
| 63 | + define('EE_MIN_PHP_VER_REQUIRED', '7.4.0'); |
|
| 64 | + if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) { |
|
| 65 | + /** |
|
| 66 | + * espresso_minimum_php_version_error |
|
| 67 | + * |
|
| 68 | + * @return void |
|
| 69 | + */ |
|
| 70 | + function espresso_minimum_php_version_error() |
|
| 71 | + { |
|
| 72 | + ?> |
|
| 73 | 73 | <div class="error"> |
| 74 | 74 | <p> |
| 75 | 75 | <?php |
| 76 | - printf( |
|
| 77 | - esc_html__( |
|
| 78 | - 'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.', |
|
| 79 | - 'event_espresso' |
|
| 80 | - ), |
|
| 81 | - EE_MIN_PHP_VER_REQUIRED, |
|
| 82 | - PHP_VERSION, |
|
| 83 | - '<br/>', |
|
| 84 | - '<a href="https://www.php.net/downloads.php">https://php.net/downloads.php</a>' |
|
| 85 | - ); |
|
| 86 | - ?> |
|
| 76 | + printf( |
|
| 77 | + esc_html__( |
|
| 78 | + 'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.', |
|
| 79 | + 'event_espresso' |
|
| 80 | + ), |
|
| 81 | + EE_MIN_PHP_VER_REQUIRED, |
|
| 82 | + PHP_VERSION, |
|
| 83 | + '<br/>', |
|
| 84 | + '<a href="https://www.php.net/downloads.php">https://php.net/downloads.php</a>' |
|
| 85 | + ); |
|
| 86 | + ?> |
|
| 87 | 87 | </p> |
| 88 | 88 | </div> |
| 89 | 89 | <?php |
| 90 | - espresso_deactivate_plugin(plugin_basename(__FILE__)); |
|
| 91 | - } |
|
| 90 | + espresso_deactivate_plugin(plugin_basename(__FILE__)); |
|
| 91 | + } |
|
| 92 | 92 | |
| 93 | - add_action('admin_notices', 'espresso_minimum_php_version_error', 1); |
|
| 94 | - } else { |
|
| 95 | - define('EVENT_ESPRESSO_MAIN_FILE', __FILE__); |
|
| 93 | + add_action('admin_notices', 'espresso_minimum_php_version_error', 1); |
|
| 94 | + } else { |
|
| 95 | + define('EVENT_ESPRESSO_MAIN_FILE', __FILE__); |
|
| 96 | 96 | |
| 97 | - require_once __DIR__ . '/vendor/autoload.php'; |
|
| 97 | + require_once __DIR__ . '/vendor/autoload.php'; |
|
| 98 | 98 | |
| 99 | - /** |
|
| 100 | - * espresso_version |
|
| 101 | - * Returns the plugin version |
|
| 102 | - * |
|
| 103 | - * @return string |
|
| 104 | - */ |
|
| 105 | - function espresso_version(): string |
|
| 106 | - { |
|
| 107 | - return apply_filters('FHEE__espresso__espresso_version', '5.0.29.rc.000'); |
|
| 108 | - } |
|
| 99 | + /** |
|
| 100 | + * espresso_version |
|
| 101 | + * Returns the plugin version |
|
| 102 | + * |
|
| 103 | + * @return string |
|
| 104 | + */ |
|
| 105 | + function espresso_version(): string |
|
| 106 | + { |
|
| 107 | + return apply_filters('FHEE__espresso__espresso_version', '5.0.29.rc.000'); |
|
| 108 | + } |
|
| 109 | 109 | |
| 110 | - /** |
|
| 111 | - * espresso_plugin_activation |
|
| 112 | - * adds a wp-option to indicate that EE has been activated via the WP admin plugins page |
|
| 113 | - */ |
|
| 114 | - function espresso_plugin_activation() |
|
| 115 | - { |
|
| 116 | - update_option('ee_espresso_activation', true); |
|
| 117 | - update_option('event-espresso-core_allow_tracking', 'no'); |
|
| 118 | - update_option('event-espresso-core_tracking_notice', 'hide'); |
|
| 119 | - // Run WP GraphQL activation callback |
|
| 120 | - espressoLoadWpGraphQL(); |
|
| 121 | - graphql_activation_callback(); |
|
| 122 | - } |
|
| 110 | + /** |
|
| 111 | + * espresso_plugin_activation |
|
| 112 | + * adds a wp-option to indicate that EE has been activated via the WP admin plugins page |
|
| 113 | + */ |
|
| 114 | + function espresso_plugin_activation() |
|
| 115 | + { |
|
| 116 | + update_option('ee_espresso_activation', true); |
|
| 117 | + update_option('event-espresso-core_allow_tracking', 'no'); |
|
| 118 | + update_option('event-espresso-core_tracking_notice', 'hide'); |
|
| 119 | + // Run WP GraphQL activation callback |
|
| 120 | + espressoLoadWpGraphQL(); |
|
| 121 | + graphql_activation_callback(); |
|
| 122 | + } |
|
| 123 | 123 | |
| 124 | - register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation'); |
|
| 124 | + register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation'); |
|
| 125 | 125 | |
| 126 | - /** |
|
| 127 | - * espresso_plugin_deactivation |
|
| 128 | - */ |
|
| 129 | - function espresso_plugin_deactivation() |
|
| 130 | - { |
|
| 131 | - // Run WP GraphQL deactivation callback |
|
| 132 | - espressoLoadWpGraphQL(); |
|
| 133 | - graphql_deactivation_callback(); |
|
| 134 | - delete_option('event-espresso-core_allow_tracking'); |
|
| 135 | - delete_option('event-espresso-core_tracking_notice'); |
|
| 136 | - } |
|
| 137 | - register_deactivation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_deactivation'); |
|
| 126 | + /** |
|
| 127 | + * espresso_plugin_deactivation |
|
| 128 | + */ |
|
| 129 | + function espresso_plugin_deactivation() |
|
| 130 | + { |
|
| 131 | + // Run WP GraphQL deactivation callback |
|
| 132 | + espressoLoadWpGraphQL(); |
|
| 133 | + graphql_deactivation_callback(); |
|
| 134 | + delete_option('event-espresso-core_allow_tracking'); |
|
| 135 | + delete_option('event-espresso-core_tracking_notice'); |
|
| 136 | + } |
|
| 137 | + register_deactivation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_deactivation'); |
|
| 138 | 138 | |
| 139 | - require_once __DIR__ . '/core/bootstrap_espresso.php'; |
|
| 140 | - bootstrap_espresso(); |
|
| 141 | - } |
|
| 139 | + require_once __DIR__ . '/core/bootstrap_espresso.php'; |
|
| 140 | + bootstrap_espresso(); |
|
| 141 | + } |
|
| 142 | 142 | } |
| 143 | 143 | |
| 144 | 144 | if (! function_exists('espresso_deactivate_plugin')) { |
| 145 | - /** |
|
| 146 | - * deactivate_plugin |
|
| 147 | - * usage: espresso_deactivate_plugin( plugin_basename( __FILE__ )); |
|
| 148 | - * |
|
| 149 | - * @access public |
|
| 150 | - * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file |
|
| 151 | - * @return void |
|
| 152 | - */ |
|
| 153 | - function espresso_deactivate_plugin(string $plugin_basename = '') |
|
| 154 | - { |
|
| 155 | - if (! function_exists('deactivate_plugins')) { |
|
| 156 | - require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
|
| 157 | - } |
|
| 158 | - unset($_GET['activate'], $_REQUEST['activate']); |
|
| 159 | - deactivate_plugins($plugin_basename); |
|
| 160 | - } |
|
| 145 | + /** |
|
| 146 | + * deactivate_plugin |
|
| 147 | + * usage: espresso_deactivate_plugin( plugin_basename( __FILE__ )); |
|
| 148 | + * |
|
| 149 | + * @access public |
|
| 150 | + * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file |
|
| 151 | + * @return void |
|
| 152 | + */ |
|
| 153 | + function espresso_deactivate_plugin(string $plugin_basename = '') |
|
| 154 | + { |
|
| 155 | + if (! function_exists('deactivate_plugins')) { |
|
| 156 | + require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
|
| 157 | + } |
|
| 158 | + unset($_GET['activate'], $_REQUEST['activate']); |
|
| 159 | + deactivate_plugins($plugin_basename); |
|
| 160 | + } |
|
| 161 | 161 | } |
| 162 | 162 | |
| 163 | 163 | |
| 164 | 164 | if (! function_exists('espressoLoadWpGraphQL')) { |
| 165 | - function espressoLoadWpGraphQL() |
|
| 166 | - { |
|
| 167 | - if ( |
|
| 168 | - ! class_exists('WPGraphQL') |
|
| 169 | - && is_readable(__DIR__ . '/vendor/wp-graphql/wp-graphql/wp-graphql.php') |
|
| 170 | - ) { |
|
| 171 | - require_once __DIR__ . '/vendor/wp-graphql/wp-graphql/wp-graphql.php'; |
|
| 172 | - } |
|
| 173 | - } |
|
| 165 | + function espressoLoadWpGraphQL() |
|
| 166 | + { |
|
| 167 | + if ( |
|
| 168 | + ! class_exists('WPGraphQL') |
|
| 169 | + && is_readable(__DIR__ . '/vendor/wp-graphql/wp-graphql/wp-graphql.php') |
|
| 170 | + ) { |
|
| 171 | + require_once __DIR__ . '/vendor/wp-graphql/wp-graphql/wp-graphql.php'; |
|
| 172 | + } |
|
| 173 | + } |
|
| 174 | 174 | } |
@@ -21,220 +21,220 @@ |
||
| 21 | 21 | */ |
| 22 | 22 | class Manager |
| 23 | 23 | { |
| 24 | - /** |
|
| 25 | - * List of PMs that can be replaced with PP Commerce. |
|
| 26 | - * ['payment method name' => 'settings option'] |
|
| 27 | - * |
|
| 28 | - * @var array $pms_can_hide |
|
| 29 | - */ |
|
| 30 | - protected static array $pms_can_hide = [ |
|
| 31 | - 'paypal_express' => 'api_username', |
|
| 32 | - 'paypal_pro' => 'api_username', |
|
| 33 | - 'aim' => 'login_id', |
|
| 34 | - ]; |
|
| 35 | - |
|
| 36 | - |
|
| 37 | - /** |
|
| 38 | - * Manager constructor. |
|
| 39 | - */ |
|
| 40 | - public function __construct() |
|
| 41 | - { |
|
| 42 | - if (DbStatus::isOffline()) { |
|
| 43 | - return; |
|
| 44 | - } |
|
| 45 | - $this->loadPaymentMethods(); |
|
| 46 | - if (is_admin()) { |
|
| 47 | - // Use only PayPal Commerce if it's a new setup. |
|
| 48 | - add_filter( |
|
| 49 | - 'FHEE__Payments_Admin_Page___payment_methods_list__payment_methods', |
|
| 50 | - [__CLASS__, 'hidePaymentMethods'] |
|
| 51 | - ); |
|
| 52 | - // Payment methods related admin notices. |
|
| 53 | - add_action('admin_init', [__CLASS__, 'adminNotice']); |
|
| 54 | - } |
|
| 55 | - } |
|
| 56 | - |
|
| 57 | - |
|
| 58 | - /** |
|
| 59 | - * Load all payment methods that are in PaymentMethods folder. |
|
| 60 | - * |
|
| 61 | - * @return void |
|
| 62 | - */ |
|
| 63 | - protected function loadPaymentMethods() |
|
| 64 | - { |
|
| 65 | - // Scan the PaymentMethods folder. |
|
| 66 | - $pms_list = glob(EE_PLUGIN_DIR_PATH . 'PaymentMethods/*', GLOB_ONLYDIR); |
|
| 67 | - // Filter the discovered PM list. |
|
| 68 | - $pms_list = apply_filters('FHEE__PaymentMethods__Manager__loadPaymentMethods__pms_list', $pms_list); |
|
| 69 | - // Clean from duplicates. |
|
| 70 | - $pms_list = array_unique($pms_list); |
|
| 71 | - foreach ($pms_list as $pm_path) { |
|
| 72 | - $this->registerPaymentMethod($pm_path); |
|
| 73 | - } |
|
| 74 | - } |
|
| 75 | - |
|
| 76 | - |
|
| 77 | - /** |
|
| 78 | - * Looks for the main payment method file and loads it. |
|
| 79 | - * |
|
| 80 | - * @param string $pm_path path to the payment method folder |
|
| 81 | - * @param string $file_ext |
|
| 82 | - * @param string $pm_namespace |
|
| 83 | - * @return boolean |
|
| 84 | - */ |
|
| 85 | - public function registerPaymentMethod( |
|
| 86 | - string $pm_path, |
|
| 87 | - string $file_ext = '.php', |
|
| 88 | - string $pm_namespace = 'EventEspresso\PaymentMethods' |
|
| 89 | - ): bool { |
|
| 90 | - do_action('AHEE__PaymentMethods__Manager__registerPaymentMethod__start', $pm_path); |
|
| 91 | - // Separators should match. |
|
| 92 | - $pm_path = str_replace('/\\', '/', $pm_path) . DS; |
|
| 93 | - // Sanitize PM name. |
|
| 94 | - $module_dir = basename($pm_path); |
|
| 95 | - // Get class name. |
|
| 96 | - $pm_class_name = str_replace(' ', '_', $module_dir); |
|
| 97 | - // Check if file exists. |
|
| 98 | - if (! is_readable($pm_path . $pm_class_name . $file_ext)) { |
|
| 99 | - return false; |
|
| 100 | - } |
|
| 101 | - // Load the initial PM class. |
|
| 102 | - require_once($pm_path . DS . $pm_class_name . $file_ext); |
|
| 103 | - $pm_object = "$pm_namespace\\$pm_class_name"; |
|
| 104 | - if (! class_exists($pm_object)) { |
|
| 105 | - return false; |
|
| 106 | - } |
|
| 107 | - $payment_menthod = new $pm_object(); |
|
| 108 | - $payment_menthod->initialize(); |
|
| 109 | - return true; |
|
| 110 | - } |
|
| 111 | - |
|
| 112 | - |
|
| 113 | - /** |
|
| 114 | - * Deactivate a few other PMs if it's a new setup. Use PP Commerce. |
|
| 115 | - * |
|
| 116 | - * @param array $pms_to_list |
|
| 117 | - * @return array |
|
| 118 | - * @throws EE_Error |
|
| 119 | - * @throws ReflectionException |
|
| 120 | - */ |
|
| 121 | - public static function hidePaymentMethods(array $pms_to_list): array |
|
| 122 | - { |
|
| 123 | - $pms_can_hide = apply_filters( |
|
| 124 | - 'FHEE__EventEspresso_PaymentMethods_Manager__hidePaymentMethods__pms_can_hide', |
|
| 125 | - self::$pms_can_hide |
|
| 126 | - ); |
|
| 127 | - foreach ($pms_can_hide as $pm_name => $pm_option) { |
|
| 128 | - // Can we deregister this PM ? |
|
| 129 | - if (isset($pms_to_list[ $pm_name ]) && self::pmCanBeHidden($pm_name, $pm_option)) { |
|
| 130 | - unset($pms_to_list[ $pm_name ]); |
|
| 131 | - } |
|
| 132 | - } |
|
| 133 | - return $pms_to_list; |
|
| 134 | - } |
|
| 135 | - |
|
| 136 | - |
|
| 137 | - /** |
|
| 138 | - * Deregisters the provided payment method if not used. |
|
| 139 | - * |
|
| 140 | - * @param string $pm_name |
|
| 141 | - * @param string $pm_option |
|
| 142 | - * @return bool |
|
| 143 | - * @throws EE_Error |
|
| 144 | - * @throws ReflectionException |
|
| 145 | - */ |
|
| 146 | - public static function pmCanBeHidden(string $pm_name, string $pm_option): bool |
|
| 147 | - { |
|
| 148 | - $pm_to_hide = EEM_Payment_Method::instance()->get_one_by_slug($pm_name); |
|
| 149 | - $pm_active = $pm_active_before = false; |
|
| 150 | - if ($pm_to_hide instanceof EE_Payment_Method) { |
|
| 151 | - $pm_active = $pm_to_hide->active(); |
|
| 152 | - // Payment method used before ? |
|
| 153 | - $option = $pm_to_hide->get_extra_meta($pm_option, true, false); |
|
| 154 | - $pm_active_before = ! empty($option); |
|
| 155 | - } |
|
| 156 | - // If PM not used before and not active, deregister it. |
|
| 157 | - if ( |
|
| 158 | - apply_filters( |
|
| 159 | - "FHEE__PaymentMethods__Manager__register_payment_methods__hide_$pm_name", |
|
| 160 | - ! $pm_active && ! $pm_active_before, |
|
| 161 | - $pm_name |
|
| 162 | - ) |
|
| 163 | - ) { |
|
| 164 | - return true; |
|
| 165 | - } |
|
| 166 | - return false; |
|
| 167 | - } |
|
| 168 | - |
|
| 169 | - |
|
| 170 | - /** |
|
| 171 | - * Payment methods related admin notices. |
|
| 172 | - * |
|
| 173 | - * @return void |
|
| 174 | - */ |
|
| 175 | - public static function adminNotice() |
|
| 176 | - { |
|
| 177 | - // Is this an EE admin page ? |
|
| 178 | - $request = LoaderFactory::getLoader()->getShared(RequestInterface::class); |
|
| 179 | - $page_name = $request->getRequestParam('page'); |
|
| 180 | - // Only show the notice on core EE pages |
|
| 181 | - if (! str_contains($page_name, 'espresso')) { |
|
| 182 | - return; |
|
| 183 | - } |
|
| 184 | - // Notice if one of the following payment methods is used: PayPal Express, PayPal Pro, Authorize.net AIM. |
|
| 185 | - try { |
|
| 186 | - $pp_commerce = EEM_Payment_Method::instance()->get_one_by_slug('paypalcheckout'); |
|
| 187 | - // Don't show notice if PayPal Commerce is active. |
|
| 188 | - if ($pp_commerce instanceof EE_Payment_Method && $pp_commerce->active()) { |
|
| 189 | - return; |
|
| 190 | - } |
|
| 191 | - foreach (self::$pms_can_hide as $pm_name => $pm_option) { |
|
| 192 | - $payment_method = EEM_Payment_Method::instance()->get_one_by_slug($pm_name); |
|
| 193 | - if ($payment_method instanceof EE_Payment_Method && $payment_method->active()) { |
|
| 194 | - add_action('admin_notices', [__CLASS__, 'usePayPalCommerceNotice']); |
|
| 195 | - return; |
|
| 196 | - } |
|
| 197 | - } |
|
| 198 | - } catch (EE_Error | ReflectionException $e) { |
|
| 199 | - // No handling needed right now. |
|
| 200 | - } |
|
| 201 | - } |
|
| 202 | - |
|
| 203 | - |
|
| 204 | - /** |
|
| 205 | - * Recommend PayPal Commerce notice contents. |
|
| 206 | - * |
|
| 207 | - * @return void |
|
| 208 | - */ |
|
| 209 | - public static function usePayPalCommerceNotice() |
|
| 210 | - { |
|
| 211 | - echo ' |
|
| 24 | + /** |
|
| 25 | + * List of PMs that can be replaced with PP Commerce. |
|
| 26 | + * ['payment method name' => 'settings option'] |
|
| 27 | + * |
|
| 28 | + * @var array $pms_can_hide |
|
| 29 | + */ |
|
| 30 | + protected static array $pms_can_hide = [ |
|
| 31 | + 'paypal_express' => 'api_username', |
|
| 32 | + 'paypal_pro' => 'api_username', |
|
| 33 | + 'aim' => 'login_id', |
|
| 34 | + ]; |
|
| 35 | + |
|
| 36 | + |
|
| 37 | + /** |
|
| 38 | + * Manager constructor. |
|
| 39 | + */ |
|
| 40 | + public function __construct() |
|
| 41 | + { |
|
| 42 | + if (DbStatus::isOffline()) { |
|
| 43 | + return; |
|
| 44 | + } |
|
| 45 | + $this->loadPaymentMethods(); |
|
| 46 | + if (is_admin()) { |
|
| 47 | + // Use only PayPal Commerce if it's a new setup. |
|
| 48 | + add_filter( |
|
| 49 | + 'FHEE__Payments_Admin_Page___payment_methods_list__payment_methods', |
|
| 50 | + [__CLASS__, 'hidePaymentMethods'] |
|
| 51 | + ); |
|
| 52 | + // Payment methods related admin notices. |
|
| 53 | + add_action('admin_init', [__CLASS__, 'adminNotice']); |
|
| 54 | + } |
|
| 55 | + } |
|
| 56 | + |
|
| 57 | + |
|
| 58 | + /** |
|
| 59 | + * Load all payment methods that are in PaymentMethods folder. |
|
| 60 | + * |
|
| 61 | + * @return void |
|
| 62 | + */ |
|
| 63 | + protected function loadPaymentMethods() |
|
| 64 | + { |
|
| 65 | + // Scan the PaymentMethods folder. |
|
| 66 | + $pms_list = glob(EE_PLUGIN_DIR_PATH . 'PaymentMethods/*', GLOB_ONLYDIR); |
|
| 67 | + // Filter the discovered PM list. |
|
| 68 | + $pms_list = apply_filters('FHEE__PaymentMethods__Manager__loadPaymentMethods__pms_list', $pms_list); |
|
| 69 | + // Clean from duplicates. |
|
| 70 | + $pms_list = array_unique($pms_list); |
|
| 71 | + foreach ($pms_list as $pm_path) { |
|
| 72 | + $this->registerPaymentMethod($pm_path); |
|
| 73 | + } |
|
| 74 | + } |
|
| 75 | + |
|
| 76 | + |
|
| 77 | + /** |
|
| 78 | + * Looks for the main payment method file and loads it. |
|
| 79 | + * |
|
| 80 | + * @param string $pm_path path to the payment method folder |
|
| 81 | + * @param string $file_ext |
|
| 82 | + * @param string $pm_namespace |
|
| 83 | + * @return boolean |
|
| 84 | + */ |
|
| 85 | + public function registerPaymentMethod( |
|
| 86 | + string $pm_path, |
|
| 87 | + string $file_ext = '.php', |
|
| 88 | + string $pm_namespace = 'EventEspresso\PaymentMethods' |
|
| 89 | + ): bool { |
|
| 90 | + do_action('AHEE__PaymentMethods__Manager__registerPaymentMethod__start', $pm_path); |
|
| 91 | + // Separators should match. |
|
| 92 | + $pm_path = str_replace('/\\', '/', $pm_path) . DS; |
|
| 93 | + // Sanitize PM name. |
|
| 94 | + $module_dir = basename($pm_path); |
|
| 95 | + // Get class name. |
|
| 96 | + $pm_class_name = str_replace(' ', '_', $module_dir); |
|
| 97 | + // Check if file exists. |
|
| 98 | + if (! is_readable($pm_path . $pm_class_name . $file_ext)) { |
|
| 99 | + return false; |
|
| 100 | + } |
|
| 101 | + // Load the initial PM class. |
|
| 102 | + require_once($pm_path . DS . $pm_class_name . $file_ext); |
|
| 103 | + $pm_object = "$pm_namespace\\$pm_class_name"; |
|
| 104 | + if (! class_exists($pm_object)) { |
|
| 105 | + return false; |
|
| 106 | + } |
|
| 107 | + $payment_menthod = new $pm_object(); |
|
| 108 | + $payment_menthod->initialize(); |
|
| 109 | + return true; |
|
| 110 | + } |
|
| 111 | + |
|
| 112 | + |
|
| 113 | + /** |
|
| 114 | + * Deactivate a few other PMs if it's a new setup. Use PP Commerce. |
|
| 115 | + * |
|
| 116 | + * @param array $pms_to_list |
|
| 117 | + * @return array |
|
| 118 | + * @throws EE_Error |
|
| 119 | + * @throws ReflectionException |
|
| 120 | + */ |
|
| 121 | + public static function hidePaymentMethods(array $pms_to_list): array |
|
| 122 | + { |
|
| 123 | + $pms_can_hide = apply_filters( |
|
| 124 | + 'FHEE__EventEspresso_PaymentMethods_Manager__hidePaymentMethods__pms_can_hide', |
|
| 125 | + self::$pms_can_hide |
|
| 126 | + ); |
|
| 127 | + foreach ($pms_can_hide as $pm_name => $pm_option) { |
|
| 128 | + // Can we deregister this PM ? |
|
| 129 | + if (isset($pms_to_list[ $pm_name ]) && self::pmCanBeHidden($pm_name, $pm_option)) { |
|
| 130 | + unset($pms_to_list[ $pm_name ]); |
|
| 131 | + } |
|
| 132 | + } |
|
| 133 | + return $pms_to_list; |
|
| 134 | + } |
|
| 135 | + |
|
| 136 | + |
|
| 137 | + /** |
|
| 138 | + * Deregisters the provided payment method if not used. |
|
| 139 | + * |
|
| 140 | + * @param string $pm_name |
|
| 141 | + * @param string $pm_option |
|
| 142 | + * @return bool |
|
| 143 | + * @throws EE_Error |
|
| 144 | + * @throws ReflectionException |
|
| 145 | + */ |
|
| 146 | + public static function pmCanBeHidden(string $pm_name, string $pm_option): bool |
|
| 147 | + { |
|
| 148 | + $pm_to_hide = EEM_Payment_Method::instance()->get_one_by_slug($pm_name); |
|
| 149 | + $pm_active = $pm_active_before = false; |
|
| 150 | + if ($pm_to_hide instanceof EE_Payment_Method) { |
|
| 151 | + $pm_active = $pm_to_hide->active(); |
|
| 152 | + // Payment method used before ? |
|
| 153 | + $option = $pm_to_hide->get_extra_meta($pm_option, true, false); |
|
| 154 | + $pm_active_before = ! empty($option); |
|
| 155 | + } |
|
| 156 | + // If PM not used before and not active, deregister it. |
|
| 157 | + if ( |
|
| 158 | + apply_filters( |
|
| 159 | + "FHEE__PaymentMethods__Manager__register_payment_methods__hide_$pm_name", |
|
| 160 | + ! $pm_active && ! $pm_active_before, |
|
| 161 | + $pm_name |
|
| 162 | + ) |
|
| 163 | + ) { |
|
| 164 | + return true; |
|
| 165 | + } |
|
| 166 | + return false; |
|
| 167 | + } |
|
| 168 | + |
|
| 169 | + |
|
| 170 | + /** |
|
| 171 | + * Payment methods related admin notices. |
|
| 172 | + * |
|
| 173 | + * @return void |
|
| 174 | + */ |
|
| 175 | + public static function adminNotice() |
|
| 176 | + { |
|
| 177 | + // Is this an EE admin page ? |
|
| 178 | + $request = LoaderFactory::getLoader()->getShared(RequestInterface::class); |
|
| 179 | + $page_name = $request->getRequestParam('page'); |
|
| 180 | + // Only show the notice on core EE pages |
|
| 181 | + if (! str_contains($page_name, 'espresso')) { |
|
| 182 | + return; |
|
| 183 | + } |
|
| 184 | + // Notice if one of the following payment methods is used: PayPal Express, PayPal Pro, Authorize.net AIM. |
|
| 185 | + try { |
|
| 186 | + $pp_commerce = EEM_Payment_Method::instance()->get_one_by_slug('paypalcheckout'); |
|
| 187 | + // Don't show notice if PayPal Commerce is active. |
|
| 188 | + if ($pp_commerce instanceof EE_Payment_Method && $pp_commerce->active()) { |
|
| 189 | + return; |
|
| 190 | + } |
|
| 191 | + foreach (self::$pms_can_hide as $pm_name => $pm_option) { |
|
| 192 | + $payment_method = EEM_Payment_Method::instance()->get_one_by_slug($pm_name); |
|
| 193 | + if ($payment_method instanceof EE_Payment_Method && $payment_method->active()) { |
|
| 194 | + add_action('admin_notices', [__CLASS__, 'usePayPalCommerceNotice']); |
|
| 195 | + return; |
|
| 196 | + } |
|
| 197 | + } |
|
| 198 | + } catch (EE_Error | ReflectionException $e) { |
|
| 199 | + // No handling needed right now. |
|
| 200 | + } |
|
| 201 | + } |
|
| 202 | + |
|
| 203 | + |
|
| 204 | + /** |
|
| 205 | + * Recommend PayPal Commerce notice contents. |
|
| 206 | + * |
|
| 207 | + * @return void |
|
| 208 | + */ |
|
| 209 | + public static function usePayPalCommerceNotice() |
|
| 210 | + { |
|
| 211 | + echo ' |
|
| 212 | 212 | <div class="notice ee-status-outline ee-status-outline--ok ee-status-bg--ok"> |
| 213 | 213 | <p class="big-text"> |
| 214 | 214 | <span class="dashicons dashicons-info"></span> ' |
| 215 | - . sprintf( |
|
| 216 | - esc_html__( |
|
| 217 | - 'We recommend using our latest PayPal integration - %1$sPayPal Commerce%2$s payment method in place of PayPal Standard, PayPal Express and PayPal Pro.', |
|
| 218 | - 'event_espresso' |
|
| 219 | - ), |
|
| 220 | - '<strong>', |
|
| 221 | - '</strong>' |
|
| 222 | - ) . ' |
|
| 215 | + . sprintf( |
|
| 216 | + esc_html__( |
|
| 217 | + 'We recommend using our latest PayPal integration - %1$sPayPal Commerce%2$s payment method in place of PayPal Standard, PayPal Express and PayPal Pro.', |
|
| 218 | + 'event_espresso' |
|
| 219 | + ), |
|
| 220 | + '<strong>', |
|
| 221 | + '</strong>' |
|
| 222 | + ) . ' |
|
| 223 | 223 | </p> |
| 224 | 224 | </div>'; |
| 225 | - } |
|
| 226 | - |
|
| 227 | - |
|
| 228 | - /** |
|
| 229 | - * @return bool |
|
| 230 | - * @since 5.0.20.p |
|
| 231 | - */ |
|
| 232 | - public static function verifySSL(): bool |
|
| 233 | - { |
|
| 234 | - static $verify_ssl = null; |
|
| 235 | - if ($verify_ssl === null) { |
|
| 236 | - $verify_ssl = (bool) apply_filters('FHEE__EventEspresso_PaymentMethods_Manager__verifySSL', true); |
|
| 237 | - } |
|
| 238 | - return (bool) $verify_ssl; |
|
| 239 | - } |
|
| 225 | + } |
|
| 226 | + |
|
| 227 | + |
|
| 228 | + /** |
|
| 229 | + * @return bool |
|
| 230 | + * @since 5.0.20.p |
|
| 231 | + */ |
|
| 232 | + public static function verifySSL(): bool |
|
| 233 | + { |
|
| 234 | + static $verify_ssl = null; |
|
| 235 | + if ($verify_ssl === null) { |
|
| 236 | + $verify_ssl = (bool) apply_filters('FHEE__EventEspresso_PaymentMethods_Manager__verifySSL', true); |
|
| 237 | + } |
|
| 238 | + return (bool) $verify_ssl; |
|
| 239 | + } |
|
| 240 | 240 | } |
@@ -63,7 +63,7 @@ discard block |
||
| 63 | 63 | protected function loadPaymentMethods() |
| 64 | 64 | { |
| 65 | 65 | // Scan the PaymentMethods folder. |
| 66 | - $pms_list = glob(EE_PLUGIN_DIR_PATH . 'PaymentMethods/*', GLOB_ONLYDIR); |
|
| 66 | + $pms_list = glob(EE_PLUGIN_DIR_PATH.'PaymentMethods/*', GLOB_ONLYDIR); |
|
| 67 | 67 | // Filter the discovered PM list. |
| 68 | 68 | $pms_list = apply_filters('FHEE__PaymentMethods__Manager__loadPaymentMethods__pms_list', $pms_list); |
| 69 | 69 | // Clean from duplicates. |
@@ -89,19 +89,19 @@ discard block |
||
| 89 | 89 | ): bool { |
| 90 | 90 | do_action('AHEE__PaymentMethods__Manager__registerPaymentMethod__start', $pm_path); |
| 91 | 91 | // Separators should match. |
| 92 | - $pm_path = str_replace('/\\', '/', $pm_path) . DS; |
|
| 92 | + $pm_path = str_replace('/\\', '/', $pm_path).DS; |
|
| 93 | 93 | // Sanitize PM name. |
| 94 | 94 | $module_dir = basename($pm_path); |
| 95 | 95 | // Get class name. |
| 96 | 96 | $pm_class_name = str_replace(' ', '_', $module_dir); |
| 97 | 97 | // Check if file exists. |
| 98 | - if (! is_readable($pm_path . $pm_class_name . $file_ext)) { |
|
| 98 | + if ( ! is_readable($pm_path.$pm_class_name.$file_ext)) { |
|
| 99 | 99 | return false; |
| 100 | 100 | } |
| 101 | 101 | // Load the initial PM class. |
| 102 | - require_once($pm_path . DS . $pm_class_name . $file_ext); |
|
| 102 | + require_once($pm_path.DS.$pm_class_name.$file_ext); |
|
| 103 | 103 | $pm_object = "$pm_namespace\\$pm_class_name"; |
| 104 | - if (! class_exists($pm_object)) { |
|
| 104 | + if ( ! class_exists($pm_object)) { |
|
| 105 | 105 | return false; |
| 106 | 106 | } |
| 107 | 107 | $payment_menthod = new $pm_object(); |
@@ -126,8 +126,8 @@ discard block |
||
| 126 | 126 | ); |
| 127 | 127 | foreach ($pms_can_hide as $pm_name => $pm_option) { |
| 128 | 128 | // Can we deregister this PM ? |
| 129 | - if (isset($pms_to_list[ $pm_name ]) && self::pmCanBeHidden($pm_name, $pm_option)) { |
|
| 130 | - unset($pms_to_list[ $pm_name ]); |
|
| 129 | + if (isset($pms_to_list[$pm_name]) && self::pmCanBeHidden($pm_name, $pm_option)) { |
|
| 130 | + unset($pms_to_list[$pm_name]); |
|
| 131 | 131 | } |
| 132 | 132 | } |
| 133 | 133 | return $pms_to_list; |
@@ -178,7 +178,7 @@ discard block |
||
| 178 | 178 | $request = LoaderFactory::getLoader()->getShared(RequestInterface::class); |
| 179 | 179 | $page_name = $request->getRequestParam('page'); |
| 180 | 180 | // Only show the notice on core EE pages |
| 181 | - if (! str_contains($page_name, 'espresso')) { |
|
| 181 | + if ( ! str_contains($page_name, 'espresso')) { |
|
| 182 | 182 | return; |
| 183 | 183 | } |
| 184 | 184 | // Notice if one of the following payment methods is used: PayPal Express, PayPal Pro, Authorize.net AIM. |
@@ -219,7 +219,7 @@ discard block |
||
| 219 | 219 | ), |
| 220 | 220 | '<strong>', |
| 221 | 221 | '</strong>' |
| 222 | - ) . ' |
|
| 222 | + ).' |
|
| 223 | 223 | </p> |
| 224 | 224 | </div>'; |
| 225 | 225 | } |
@@ -20,81 +20,81 @@ |
||
| 20 | 20 | */ |
| 21 | 21 | class OrderDetails extends OrdersApi |
| 22 | 22 | { |
| 23 | - /** |
|
| 24 | - * Transaction this order is for. |
|
| 25 | - * |
|
| 26 | - * @var EE_Transaction |
|
| 27 | - */ |
|
| 28 | - protected EE_Transaction $transaction; |
|
| 23 | + /** |
|
| 24 | + * Transaction this order is for. |
|
| 25 | + * |
|
| 26 | + * @var EE_Transaction |
|
| 27 | + */ |
|
| 28 | + protected EE_Transaction $transaction; |
|
| 29 | 29 | |
| 30 | - private FeatureFlags $feature; |
|
| 30 | + private FeatureFlags $feature; |
|
| 31 | 31 | |
| 32 | 32 | |
| 33 | - /** |
|
| 34 | - * OrderDetails constructor. |
|
| 35 | - * |
|
| 36 | - * @param PayPalApi $api |
|
| 37 | - * @param string $order_id |
|
| 38 | - * @param EE_Transaction $transaction |
|
| 39 | - */ |
|
| 40 | - public function __construct(PayPalApi $api, string $order_id, EE_Transaction $transaction) |
|
| 41 | - { |
|
| 42 | - parent::__construct($api); |
|
| 43 | - $this->transaction = $transaction; |
|
| 44 | - $this->request_url = $this->request_url . $order_id; |
|
| 45 | - } |
|
| 33 | + /** |
|
| 34 | + * OrderDetails constructor. |
|
| 35 | + * |
|
| 36 | + * @param PayPalApi $api |
|
| 37 | + * @param string $order_id |
|
| 38 | + * @param EE_Transaction $transaction |
|
| 39 | + */ |
|
| 40 | + public function __construct(PayPalApi $api, string $order_id, EE_Transaction $transaction) |
|
| 41 | + { |
|
| 42 | + parent::__construct($api); |
|
| 43 | + $this->transaction = $transaction; |
|
| 44 | + $this->request_url = $this->request_url . $order_id; |
|
| 45 | + } |
|
| 46 | 46 | |
| 47 | 47 | |
| 48 | - /** |
|
| 49 | - * Create PayPal Order. |
|
| 50 | - * |
|
| 51 | - * @return array |
|
| 52 | - * @throws EE_Error |
|
| 53 | - * @throws ReflectionException |
|
| 54 | - */ |
|
| 55 | - public function get(): array |
|
| 56 | - { |
|
| 57 | - $response = $this->api->sendRequest([], $this->request_url, 'GET'); |
|
| 58 | - return $this->validateResponse($response); |
|
| 59 | - } |
|
| 48 | + /** |
|
| 49 | + * Create PayPal Order. |
|
| 50 | + * |
|
| 51 | + * @return array |
|
| 52 | + * @throws EE_Error |
|
| 53 | + * @throws ReflectionException |
|
| 54 | + */ |
|
| 55 | + public function get(): array |
|
| 56 | + { |
|
| 57 | + $response = $this->api->sendRequest([], $this->request_url, 'GET'); |
|
| 58 | + return $this->validateResponse($response); |
|
| 59 | + } |
|
| 60 | 60 | |
| 61 | 61 | |
| 62 | - /** |
|
| 63 | - * Makes sure that we have received the expected Order information back from the API call. |
|
| 64 | - * |
|
| 65 | - * @param $response |
|
| 66 | - * @return array |
|
| 67 | - * @throws EE_Error |
|
| 68 | - * @throws ReflectionException |
|
| 69 | - */ |
|
| 70 | - public function validateResponse($response): array |
|
| 71 | - { |
|
| 72 | - PayPalLogger::errorLog( |
|
| 73 | - esc_html__('Validating Order Information Response:', 'event_espresso'), |
|
| 74 | - [$this->request_url, $response], |
|
| 75 | - $this->transaction->payment_method(), |
|
| 76 | - false, |
|
| 77 | - $this->transaction |
|
| 78 | - ); |
|
| 79 | - if (! empty($response['error'])) { |
|
| 80 | - return $response; |
|
| 81 | - } |
|
| 82 | - if (! isset($response['id']) || ! isset($response['status'])) { |
|
| 83 | - $message = esc_html__('No proper order information was found in this response.', 'event_espresso'); |
|
| 84 | - try { |
|
| 85 | - PayPalLogger::errorLog( |
|
| 86 | - $message, |
|
| 87 | - [$this->request_url, $response], |
|
| 88 | - $this->transaction->payment_method() |
|
| 89 | - ); |
|
| 90 | - } catch (EE_Error | ReflectionException $e) { |
|
| 91 | - error_log("PayPalLogger Error: $message: " . json_encode($response)); |
|
| 92 | - } |
|
| 93 | - return [ |
|
| 94 | - 'error' => $response['error'] ?? 'missing_order_info', |
|
| 95 | - 'message' => $response['message'] ?? $message, |
|
| 96 | - ]; |
|
| 97 | - } |
|
| 98 | - return $response; |
|
| 99 | - } |
|
| 62 | + /** |
|
| 63 | + * Makes sure that we have received the expected Order information back from the API call. |
|
| 64 | + * |
|
| 65 | + * @param $response |
|
| 66 | + * @return array |
|
| 67 | + * @throws EE_Error |
|
| 68 | + * @throws ReflectionException |
|
| 69 | + */ |
|
| 70 | + public function validateResponse($response): array |
|
| 71 | + { |
|
| 72 | + PayPalLogger::errorLog( |
|
| 73 | + esc_html__('Validating Order Information Response:', 'event_espresso'), |
|
| 74 | + [$this->request_url, $response], |
|
| 75 | + $this->transaction->payment_method(), |
|
| 76 | + false, |
|
| 77 | + $this->transaction |
|
| 78 | + ); |
|
| 79 | + if (! empty($response['error'])) { |
|
| 80 | + return $response; |
|
| 81 | + } |
|
| 82 | + if (! isset($response['id']) || ! isset($response['status'])) { |
|
| 83 | + $message = esc_html__('No proper order information was found in this response.', 'event_espresso'); |
|
| 84 | + try { |
|
| 85 | + PayPalLogger::errorLog( |
|
| 86 | + $message, |
|
| 87 | + [$this->request_url, $response], |
|
| 88 | + $this->transaction->payment_method() |
|
| 89 | + ); |
|
| 90 | + } catch (EE_Error | ReflectionException $e) { |
|
| 91 | + error_log("PayPalLogger Error: $message: " . json_encode($response)); |
|
| 92 | + } |
|
| 93 | + return [ |
|
| 94 | + 'error' => $response['error'] ?? 'missing_order_info', |
|
| 95 | + 'message' => $response['message'] ?? $message, |
|
| 96 | + ]; |
|
| 97 | + } |
|
| 98 | + return $response; |
|
| 99 | + } |
|
| 100 | 100 | } |
@@ -41,7 +41,7 @@ discard block |
||
| 41 | 41 | { |
| 42 | 42 | parent::__construct($api); |
| 43 | 43 | $this->transaction = $transaction; |
| 44 | - $this->request_url = $this->request_url . $order_id; |
|
| 44 | + $this->request_url = $this->request_url.$order_id; |
|
| 45 | 45 | } |
| 46 | 46 | |
| 47 | 47 | |
@@ -76,10 +76,10 @@ discard block |
||
| 76 | 76 | false, |
| 77 | 77 | $this->transaction |
| 78 | 78 | ); |
| 79 | - if (! empty($response['error'])) { |
|
| 79 | + if ( ! empty($response['error'])) { |
|
| 80 | 80 | return $response; |
| 81 | 81 | } |
| 82 | - if (! isset($response['id']) || ! isset($response['status'])) { |
|
| 82 | + if ( ! isset($response['id']) || ! isset($response['status'])) { |
|
| 83 | 83 | $message = esc_html__('No proper order information was found in this response.', 'event_espresso'); |
| 84 | 84 | try { |
| 85 | 85 | PayPalLogger::errorLog( |
@@ -88,7 +88,7 @@ discard block |
||
| 88 | 88 | $this->transaction->payment_method() |
| 89 | 89 | ); |
| 90 | 90 | } catch (EE_Error | ReflectionException $e) { |
| 91 | - error_log("PayPalLogger Error: $message: " . json_encode($response)); |
|
| 91 | + error_log("PayPalLogger Error: $message: ".json_encode($response)); |
|
| 92 | 92 | } |
| 93 | 93 | return [ |
| 94 | 94 | 'error' => $response['error'] ?? 'missing_order_info', |
@@ -30,301 +30,301 @@ |
||
| 30 | 30 | */ |
| 31 | 31 | class CreateOrder extends OrdersApi |
| 32 | 32 | { |
| 33 | - /** |
|
| 34 | - * Line items total. |
|
| 35 | - * |
|
| 36 | - * @var float |
|
| 37 | - */ |
|
| 38 | - protected float $items_total = 0.0; |
|
| 33 | + /** |
|
| 34 | + * Line items total. |
|
| 35 | + * |
|
| 36 | + * @var float |
|
| 37 | + */ |
|
| 38 | + protected float $items_total = 0.0; |
|
| 39 | 39 | |
| 40 | - /** |
|
| 41 | - * Promotions total. |
|
| 42 | - * |
|
| 43 | - * @var float |
|
| 44 | - */ |
|
| 45 | - protected float $promos_total = 0.0; |
|
| 40 | + /** |
|
| 41 | + * Promotions total. |
|
| 42 | + * |
|
| 43 | + * @var float |
|
| 44 | + */ |
|
| 45 | + protected float $promos_total = 0.0; |
|
| 46 | 46 | |
| 47 | - /** |
|
| 48 | - * Tax total. |
|
| 49 | - * |
|
| 50 | - * @var float |
|
| 51 | - */ |
|
| 52 | - protected float $tax_total = 0.0; |
|
| 47 | + /** |
|
| 48 | + * Tax total. |
|
| 49 | + * |
|
| 50 | + * @var float |
|
| 51 | + */ |
|
| 52 | + protected float $tax_total = 0.0; |
|
| 53 | 53 | |
| 54 | - /** |
|
| 55 | - * Currency. |
|
| 56 | - * |
|
| 57 | - * @var string |
|
| 58 | - */ |
|
| 59 | - protected string $currency_code; |
|
| 54 | + /** |
|
| 55 | + * Currency. |
|
| 56 | + * |
|
| 57 | + * @var string |
|
| 58 | + */ |
|
| 59 | + protected string $currency_code; |
|
| 60 | 60 | |
| 61 | - /** |
|
| 62 | - * Billing info. |
|
| 63 | - * |
|
| 64 | - * @var array |
|
| 65 | - */ |
|
| 66 | - protected array $billing_info; |
|
| 61 | + /** |
|
| 62 | + * Billing info. |
|
| 63 | + * |
|
| 64 | + * @var array |
|
| 65 | + */ |
|
| 66 | + protected array $billing_info; |
|
| 67 | 67 | |
| 68 | - /** |
|
| 69 | - * Transaction this order is for. |
|
| 70 | - * |
|
| 71 | - * @var EE_Transaction |
|
| 72 | - */ |
|
| 73 | - protected EE_Transaction $transaction; |
|
| 68 | + /** |
|
| 69 | + * Transaction this order is for. |
|
| 70 | + * |
|
| 71 | + * @var EE_Transaction |
|
| 72 | + */ |
|
| 73 | + protected EE_Transaction $transaction; |
|
| 74 | 74 | |
| 75 | - private FeatureFlags $feature; |
|
| 75 | + private FeatureFlags $feature; |
|
| 76 | 76 | |
| 77 | 77 | |
| 78 | - /** |
|
| 79 | - * CreateOrder constructor. |
|
| 80 | - * |
|
| 81 | - * @param PayPalApi $api |
|
| 82 | - * @param EE_Transaction $transaction |
|
| 83 | - * @param array $billing_info |
|
| 84 | - * @param FeatureFlags $feature |
|
| 85 | - */ |
|
| 86 | - public function __construct(PayPalApi $api, EE_Transaction $transaction, array $billing_info, FeatureFlags $feature) |
|
| 87 | - { |
|
| 88 | - parent::__construct($api); |
|
| 89 | - $this->transaction = $transaction; |
|
| 90 | - $this->feature = $feature; |
|
| 91 | - $this->currency_code = CurrencyManager::currencyCode(); |
|
| 92 | - $this->sanitizeRequestParameters($billing_info); |
|
| 93 | - } |
|
| 78 | + /** |
|
| 79 | + * CreateOrder constructor. |
|
| 80 | + * |
|
| 81 | + * @param PayPalApi $api |
|
| 82 | + * @param EE_Transaction $transaction |
|
| 83 | + * @param array $billing_info |
|
| 84 | + * @param FeatureFlags $feature |
|
| 85 | + */ |
|
| 86 | + public function __construct(PayPalApi $api, EE_Transaction $transaction, array $billing_info, FeatureFlags $feature) |
|
| 87 | + { |
|
| 88 | + parent::__construct($api); |
|
| 89 | + $this->transaction = $transaction; |
|
| 90 | + $this->feature = $feature; |
|
| 91 | + $this->currency_code = CurrencyManager::currencyCode(); |
|
| 92 | + $this->sanitizeRequestParameters($billing_info); |
|
| 93 | + } |
|
| 94 | 94 | |
| 95 | 95 | |
| 96 | - /** |
|
| 97 | - * Sanitize the array of billing form data. |
|
| 98 | - * |
|
| 99 | - * @param array $billing_info |
|
| 100 | - * @return void |
|
| 101 | - */ |
|
| 102 | - public function sanitizeRequestParameters(array $billing_info): void |
|
| 103 | - { |
|
| 104 | - $sanitizer = new RequestSanitizer(new Basic()); |
|
| 105 | - foreach ($billing_info as $item => $value) { |
|
| 106 | - $this->billing_info[ $item ] = $sanitizer->clean($value); |
|
| 107 | - } |
|
| 108 | - } |
|
| 96 | + /** |
|
| 97 | + * Sanitize the array of billing form data. |
|
| 98 | + * |
|
| 99 | + * @param array $billing_info |
|
| 100 | + * @return void |
|
| 101 | + */ |
|
| 102 | + public function sanitizeRequestParameters(array $billing_info): void |
|
| 103 | + { |
|
| 104 | + $sanitizer = new RequestSanitizer(new Basic()); |
|
| 105 | + foreach ($billing_info as $item => $value) { |
|
| 106 | + $this->billing_info[ $item ] = $sanitizer->clean($value); |
|
| 107 | + } |
|
| 108 | + } |
|
| 109 | 109 | |
| 110 | 110 | |
| 111 | - /** |
|
| 112 | - * Create PayPal Order. |
|
| 113 | - * |
|
| 114 | - * @return array |
|
| 115 | - * @throws EE_Error |
|
| 116 | - * @throws ReflectionException |
|
| 117 | - */ |
|
| 118 | - public function create(): array |
|
| 119 | - { |
|
| 120 | - $order_parameters = $this->getParameters(); |
|
| 121 | - // Create Order request. |
|
| 122 | - $create_response = $this->api->sendRequest($order_parameters, $this->request_url); |
|
| 123 | - return $this->validateOrder($create_response, $order_parameters); |
|
| 124 | - } |
|
| 111 | + /** |
|
| 112 | + * Create PayPal Order. |
|
| 113 | + * |
|
| 114 | + * @return array |
|
| 115 | + * @throws EE_Error |
|
| 116 | + * @throws ReflectionException |
|
| 117 | + */ |
|
| 118 | + public function create(): array |
|
| 119 | + { |
|
| 120 | + $order_parameters = $this->getParameters(); |
|
| 121 | + // Create Order request. |
|
| 122 | + $create_response = $this->api->sendRequest($order_parameters, $this->request_url); |
|
| 123 | + return $this->validateOrder($create_response, $order_parameters); |
|
| 124 | + } |
|
| 125 | 125 | |
| 126 | 126 | |
| 127 | - /** |
|
| 128 | - * Form order parameters. |
|
| 129 | - * |
|
| 130 | - * @return array |
|
| 131 | - * @throws EE_Error |
|
| 132 | - * @throws ReflectionException |
|
| 133 | - * @throws Exception |
|
| 134 | - */ |
|
| 135 | - protected function getParameters(): array |
|
| 136 | - { |
|
| 137 | - $registrant = $this->transaction->primary_registration(); |
|
| 138 | - $attendee = $registrant->attendee(); |
|
| 139 | - $event = $registrant->event(); |
|
| 140 | - $description = $event->name() ?: sprintf( |
|
| 141 | - esc_html__('Tickets for an event at %1$s', 'event_espresso'), |
|
| 142 | - get_bloginfo('name') |
|
| 143 | - ); |
|
| 144 | - $parameters = [ |
|
| 145 | - 'intent' => 'CAPTURE', |
|
| 146 | - 'purchase_units' => [ |
|
| 147 | - [ |
|
| 148 | - 'custom_id' => $this->transaction->ID(), |
|
| 149 | - 'description' => substr(wp_strip_all_tags($description), 0, 125), |
|
| 150 | - 'items' => $this->getLineItems(), |
|
| 151 | - 'amount' => [ |
|
| 152 | - 'value' => $this->transaction->remaining(), |
|
| 153 | - 'currency_code' => $this->currency_code, |
|
| 154 | - 'breakdown' => $this->getBreakdown(), |
|
| 155 | - ], |
|
| 156 | - ], |
|
| 157 | - ], |
|
| 158 | - 'application_context' => [ |
|
| 159 | - 'shipping_preference' => 'NO_SHIPPING', |
|
| 160 | - 'user_action' => 'PAY_NOW', |
|
| 161 | - ], |
|
| 162 | - 'payer' => [ |
|
| 163 | - 'email_address' => $attendee->email(), |
|
| 164 | - 'name' => [ |
|
| 165 | - 'given_name' => $attendee->fname(), |
|
| 166 | - 'surname' => $attendee->lname(), |
|
| 127 | + /** |
|
| 128 | + * Form order parameters. |
|
| 129 | + * |
|
| 130 | + * @return array |
|
| 131 | + * @throws EE_Error |
|
| 132 | + * @throws ReflectionException |
|
| 133 | + * @throws Exception |
|
| 134 | + */ |
|
| 135 | + protected function getParameters(): array |
|
| 136 | + { |
|
| 137 | + $registrant = $this->transaction->primary_registration(); |
|
| 138 | + $attendee = $registrant->attendee(); |
|
| 139 | + $event = $registrant->event(); |
|
| 140 | + $description = $event->name() ?: sprintf( |
|
| 141 | + esc_html__('Tickets for an event at %1$s', 'event_espresso'), |
|
| 142 | + get_bloginfo('name') |
|
| 143 | + ); |
|
| 144 | + $parameters = [ |
|
| 145 | + 'intent' => 'CAPTURE', |
|
| 146 | + 'purchase_units' => [ |
|
| 147 | + [ |
|
| 148 | + 'custom_id' => $this->transaction->ID(), |
|
| 149 | + 'description' => substr(wp_strip_all_tags($description), 0, 125), |
|
| 150 | + 'items' => $this->getLineItems(), |
|
| 151 | + 'amount' => [ |
|
| 152 | + 'value' => $this->transaction->remaining(), |
|
| 153 | + 'currency_code' => $this->currency_code, |
|
| 154 | + 'breakdown' => $this->getBreakdown(), |
|
| 155 | + ], |
|
| 156 | + ], |
|
| 157 | + ], |
|
| 158 | + 'application_context' => [ |
|
| 159 | + 'shipping_preference' => 'NO_SHIPPING', |
|
| 160 | + 'user_action' => 'PAY_NOW', |
|
| 161 | + ], |
|
| 162 | + 'payer' => [ |
|
| 163 | + 'email_address' => $attendee->email(), |
|
| 164 | + 'name' => [ |
|
| 165 | + 'given_name' => $attendee->fname(), |
|
| 166 | + 'surname' => $attendee->lname(), |
|
| 167 | 167 | |
| 168 | - ], |
|
| 169 | - ], |
|
| 170 | - ]; |
|
| 171 | - // Do we have the permissions for the fees ? |
|
| 172 | - $scopes = PayPalExtraMetaManager::getPmOption( |
|
| 173 | - $this->transaction->payment_method(), |
|
| 174 | - Domain::META_KEY_AUTHORIZED_SCOPES |
|
| 175 | - ); |
|
| 176 | - if ( |
|
| 177 | - ( |
|
| 178 | - (defined('EE_PPC_USE_PAYMENT_FEES') && EE_PPC_USE_PAYMENT_FEES) |
|
| 179 | - || (! defined('EE_PPC_USE_PAYMENT_FEES') |
|
| 180 | - && $this->feature->allowed(FeatureFlag::USE_PAYMENT_PROCESSOR_FEES) |
|
| 181 | - ) |
|
| 182 | - ) |
|
| 183 | - && ! empty($scopes) && in_array('partnerfee', $scopes) |
|
| 184 | - ) { |
|
| 185 | - $payment_fees = LoaderFactory::getShared(PartnerPaymentFees::class); |
|
| 186 | - $parameters['purchase_units'][0]['payment_instruction'] = [ |
|
| 187 | - 'platform_fees' => [ |
|
| 188 | - [ |
|
| 189 | - 'amount' => [ |
|
| 190 | - 'value' => (string) $payment_fees->getPartnerFee($this->transaction), |
|
| 191 | - 'currency_code' => $this->currency_code, |
|
| 192 | - ], |
|
| 193 | - ], |
|
| 194 | - ] |
|
| 195 | - ]; |
|
| 196 | - } |
|
| 197 | - return $parameters; |
|
| 198 | - } |
|
| 168 | + ], |
|
| 169 | + ], |
|
| 170 | + ]; |
|
| 171 | + // Do we have the permissions for the fees ? |
|
| 172 | + $scopes = PayPalExtraMetaManager::getPmOption( |
|
| 173 | + $this->transaction->payment_method(), |
|
| 174 | + Domain::META_KEY_AUTHORIZED_SCOPES |
|
| 175 | + ); |
|
| 176 | + if ( |
|
| 177 | + ( |
|
| 178 | + (defined('EE_PPC_USE_PAYMENT_FEES') && EE_PPC_USE_PAYMENT_FEES) |
|
| 179 | + || (! defined('EE_PPC_USE_PAYMENT_FEES') |
|
| 180 | + && $this->feature->allowed(FeatureFlag::USE_PAYMENT_PROCESSOR_FEES) |
|
| 181 | + ) |
|
| 182 | + ) |
|
| 183 | + && ! empty($scopes) && in_array('partnerfee', $scopes) |
|
| 184 | + ) { |
|
| 185 | + $payment_fees = LoaderFactory::getShared(PartnerPaymentFees::class); |
|
| 186 | + $parameters['purchase_units'][0]['payment_instruction'] = [ |
|
| 187 | + 'platform_fees' => [ |
|
| 188 | + [ |
|
| 189 | + 'amount' => [ |
|
| 190 | + 'value' => (string) $payment_fees->getPartnerFee($this->transaction), |
|
| 191 | + 'currency_code' => $this->currency_code, |
|
| 192 | + ], |
|
| 193 | + ], |
|
| 194 | + ] |
|
| 195 | + ]; |
|
| 196 | + } |
|
| 197 | + return $parameters; |
|
| 198 | + } |
|
| 199 | 199 | |
| 200 | 200 | |
| 201 | - /** |
|
| 202 | - * Itemize the payment. List all the line items, discounts and taxes. |
|
| 203 | - * |
|
| 204 | - * @return array |
|
| 205 | - * @throws EE_Error|ReflectionException |
|
| 206 | - */ |
|
| 207 | - protected function getLineItems(): array |
|
| 208 | - { |
|
| 209 | - // Order line items. |
|
| 210 | - $line_items = []; |
|
| 211 | - $event_line_items = $this->transaction->items_purchased(); |
|
| 212 | - // List actual line items. |
|
| 213 | - foreach ($event_line_items as $line_item) { |
|
| 214 | - if ( |
|
| 215 | - $line_item instanceof EE_Line_Item |
|
| 216 | - && $line_item->OBJ_type() !== 'Promotion' |
|
| 217 | - && $line_item->quantity() > 0 |
|
| 218 | - ) { |
|
| 219 | - $item_money = $line_item->unit_price(); |
|
| 220 | - $li_description = $line_item->desc() ?? esc_html__('Event Ticket', 'event_espresso'); |
|
| 221 | - $line_items [] = [ |
|
| 222 | - 'name' => substr(wp_strip_all_tags($line_item->name()), 0, 126), |
|
| 223 | - 'quantity' => $line_item->quantity(), |
|
| 224 | - 'description' => substr(wp_strip_all_tags($li_description), 0, 125), |
|
| 225 | - 'unit_amount' => [ |
|
| 226 | - 'currency_code' => $this->currency_code, |
|
| 227 | - 'value' => $item_money, |
|
| 228 | - ], |
|
| 229 | - 'category' => 'DIGITAL_GOODS', |
|
| 230 | - ]; |
|
| 231 | - // Line item total. |
|
| 232 | - $this->items_total += $line_item->pretaxTotal(); |
|
| 233 | - } elseif ($line_item->OBJ_type() === 'Promotion' && $line_item->quantity() > 0) { |
|
| 234 | - // Promotions total. |
|
| 235 | - $this->promos_total += $line_item->total(); |
|
| 236 | - } |
|
| 237 | - } |
|
| 238 | - // Make sure we have an absolute number with only two decimal laces. |
|
| 239 | - $this->items_total = CurrencyManager::normalizeValue($this->items_total); |
|
| 240 | - $this->promos_total = CurrencyManager::normalizeValue($this->promos_total); |
|
| 241 | - // If this is a partial payment, apply the paid amount as a promo. |
|
| 242 | - if ($this->transaction->paid() > 0) { |
|
| 243 | - $this->promos_total += CurrencyManager::normalizeValue($this->transaction->paid()); |
|
| 244 | - } |
|
| 245 | - $this->countTaxTotal(); |
|
| 246 | - return $line_items; |
|
| 247 | - } |
|
| 201 | + /** |
|
| 202 | + * Itemize the payment. List all the line items, discounts and taxes. |
|
| 203 | + * |
|
| 204 | + * @return array |
|
| 205 | + * @throws EE_Error|ReflectionException |
|
| 206 | + */ |
|
| 207 | + protected function getLineItems(): array |
|
| 208 | + { |
|
| 209 | + // Order line items. |
|
| 210 | + $line_items = []; |
|
| 211 | + $event_line_items = $this->transaction->items_purchased(); |
|
| 212 | + // List actual line items. |
|
| 213 | + foreach ($event_line_items as $line_item) { |
|
| 214 | + if ( |
|
| 215 | + $line_item instanceof EE_Line_Item |
|
| 216 | + && $line_item->OBJ_type() !== 'Promotion' |
|
| 217 | + && $line_item->quantity() > 0 |
|
| 218 | + ) { |
|
| 219 | + $item_money = $line_item->unit_price(); |
|
| 220 | + $li_description = $line_item->desc() ?? esc_html__('Event Ticket', 'event_espresso'); |
|
| 221 | + $line_items [] = [ |
|
| 222 | + 'name' => substr(wp_strip_all_tags($line_item->name()), 0, 126), |
|
| 223 | + 'quantity' => $line_item->quantity(), |
|
| 224 | + 'description' => substr(wp_strip_all_tags($li_description), 0, 125), |
|
| 225 | + 'unit_amount' => [ |
|
| 226 | + 'currency_code' => $this->currency_code, |
|
| 227 | + 'value' => $item_money, |
|
| 228 | + ], |
|
| 229 | + 'category' => 'DIGITAL_GOODS', |
|
| 230 | + ]; |
|
| 231 | + // Line item total. |
|
| 232 | + $this->items_total += $line_item->pretaxTotal(); |
|
| 233 | + } elseif ($line_item->OBJ_type() === 'Promotion' && $line_item->quantity() > 0) { |
|
| 234 | + // Promotions total. |
|
| 235 | + $this->promos_total += $line_item->total(); |
|
| 236 | + } |
|
| 237 | + } |
|
| 238 | + // Make sure we have an absolute number with only two decimal laces. |
|
| 239 | + $this->items_total = CurrencyManager::normalizeValue($this->items_total); |
|
| 240 | + $this->promos_total = CurrencyManager::normalizeValue($this->promos_total); |
|
| 241 | + // If this is a partial payment, apply the paid amount as a promo. |
|
| 242 | + if ($this->transaction->paid() > 0) { |
|
| 243 | + $this->promos_total += CurrencyManager::normalizeValue($this->transaction->paid()); |
|
| 244 | + } |
|
| 245 | + $this->countTaxTotal(); |
|
| 246 | + return $line_items; |
|
| 247 | + } |
|
| 248 | 248 | |
| 249 | 249 | |
| 250 | - /** |
|
| 251 | - * Count the tax total. |
|
| 252 | - * |
|
| 253 | - * @return void |
|
| 254 | - * @throws EE_Error|ReflectionException |
|
| 255 | - */ |
|
| 256 | - protected function countTaxTotal(): void |
|
| 257 | - { |
|
| 258 | - // List taxes. |
|
| 259 | - $this->tax_total = 0.0; |
|
| 260 | - $tax_items = $this->transaction->tax_items(); |
|
| 261 | - foreach ($tax_items as $tax_item) { |
|
| 262 | - $this->tax_total += $tax_item->total(); |
|
| 263 | - } |
|
| 264 | - $this->tax_total = CurrencyManager::normalizeValue($this->tax_total); |
|
| 265 | - } |
|
| 250 | + /** |
|
| 251 | + * Count the tax total. |
|
| 252 | + * |
|
| 253 | + * @return void |
|
| 254 | + * @throws EE_Error|ReflectionException |
|
| 255 | + */ |
|
| 256 | + protected function countTaxTotal(): void |
|
| 257 | + { |
|
| 258 | + // List taxes. |
|
| 259 | + $this->tax_total = 0.0; |
|
| 260 | + $tax_items = $this->transaction->tax_items(); |
|
| 261 | + foreach ($tax_items as $tax_item) { |
|
| 262 | + $this->tax_total += $tax_item->total(); |
|
| 263 | + } |
|
| 264 | + $this->tax_total = CurrencyManager::normalizeValue($this->tax_total); |
|
| 265 | + } |
|
| 266 | 266 | |
| 267 | 267 | |
| 268 | - /** |
|
| 269 | - * Itemize the payment the breakdown list. |
|
| 270 | - * |
|
| 271 | - * @return array |
|
| 272 | - */ |
|
| 273 | - protected function getBreakdown(): array |
|
| 274 | - { |
|
| 275 | - $breakdown['item_total'] = [ |
|
| 276 | - 'currency_code' => $this->currency_code, |
|
| 277 | - 'value' => $this->items_total, |
|
| 278 | - ]; |
|
| 279 | - $breakdown['tax_total'] = [ |
|
| 280 | - 'currency_code' => $this->currency_code, |
|
| 281 | - 'value' => $this->tax_total, |
|
| 282 | - ]; |
|
| 283 | - $breakdown['discount'] = [ |
|
| 284 | - 'currency_code' => $this->currency_code, |
|
| 285 | - 'value' => abs($this->promos_total), |
|
| 286 | - ]; |
|
| 287 | - return $breakdown; |
|
| 288 | - } |
|
| 268 | + /** |
|
| 269 | + * Itemize the payment the breakdown list. |
|
| 270 | + * |
|
| 271 | + * @return array |
|
| 272 | + */ |
|
| 273 | + protected function getBreakdown(): array |
|
| 274 | + { |
|
| 275 | + $breakdown['item_total'] = [ |
|
| 276 | + 'currency_code' => $this->currency_code, |
|
| 277 | + 'value' => $this->items_total, |
|
| 278 | + ]; |
|
| 279 | + $breakdown['tax_total'] = [ |
|
| 280 | + 'currency_code' => $this->currency_code, |
|
| 281 | + 'value' => $this->tax_total, |
|
| 282 | + ]; |
|
| 283 | + $breakdown['discount'] = [ |
|
| 284 | + 'currency_code' => $this->currency_code, |
|
| 285 | + 'value' => abs($this->promos_total), |
|
| 286 | + ]; |
|
| 287 | + return $breakdown; |
|
| 288 | + } |
|
| 289 | 289 | |
| 290 | 290 | |
| 291 | - /** |
|
| 292 | - * Makes sure that we have received an Order back from the API call. |
|
| 293 | - * |
|
| 294 | - * @param $response |
|
| 295 | - * @param $parameters |
|
| 296 | - * @return array |
|
| 297 | - * @throws EE_Error |
|
| 298 | - * @throws ReflectionException |
|
| 299 | - */ |
|
| 300 | - public function validateOrder($response, $parameters): array |
|
| 301 | - { |
|
| 302 | - PayPalLogger::errorLog( |
|
| 303 | - esc_html__('Validating Order Create:', 'event_espresso'), |
|
| 304 | - [$this->request_url, $response], |
|
| 305 | - $this->transaction->payment_method(), |
|
| 306 | - false, |
|
| 307 | - $this->transaction |
|
| 308 | - ); |
|
| 309 | - if (! empty($response['error'])) { |
|
| 310 | - return $response; |
|
| 311 | - } |
|
| 312 | - if (! isset($response['id'])) { |
|
| 313 | - $message = esc_html__('Unexpected response. Unable to find the order.', 'event_espresso'); |
|
| 314 | - try { |
|
| 315 | - PayPalLogger::errorLog( |
|
| 316 | - $message, |
|
| 317 | - [$this->request_url, $parameters, $response], |
|
| 318 | - $this->transaction->payment_method() |
|
| 319 | - ); |
|
| 320 | - } catch (EE_Error | ReflectionException $e) { |
|
| 321 | - error_log("PayPalLogger Error: $message: " . json_encode($response)); |
|
| 322 | - } |
|
| 323 | - return [ |
|
| 324 | - 'error' => $response['error'] ?? 'missing_order', |
|
| 325 | - 'message' => $response['message'] ?? $message, |
|
| 326 | - ]; |
|
| 327 | - } |
|
| 328 | - return $response; |
|
| 329 | - } |
|
| 291 | + /** |
|
| 292 | + * Makes sure that we have received an Order back from the API call. |
|
| 293 | + * |
|
| 294 | + * @param $response |
|
| 295 | + * @param $parameters |
|
| 296 | + * @return array |
|
| 297 | + * @throws EE_Error |
|
| 298 | + * @throws ReflectionException |
|
| 299 | + */ |
|
| 300 | + public function validateOrder($response, $parameters): array |
|
| 301 | + { |
|
| 302 | + PayPalLogger::errorLog( |
|
| 303 | + esc_html__('Validating Order Create:', 'event_espresso'), |
|
| 304 | + [$this->request_url, $response], |
|
| 305 | + $this->transaction->payment_method(), |
|
| 306 | + false, |
|
| 307 | + $this->transaction |
|
| 308 | + ); |
|
| 309 | + if (! empty($response['error'])) { |
|
| 310 | + return $response; |
|
| 311 | + } |
|
| 312 | + if (! isset($response['id'])) { |
|
| 313 | + $message = esc_html__('Unexpected response. Unable to find the order.', 'event_espresso'); |
|
| 314 | + try { |
|
| 315 | + PayPalLogger::errorLog( |
|
| 316 | + $message, |
|
| 317 | + [$this->request_url, $parameters, $response], |
|
| 318 | + $this->transaction->payment_method() |
|
| 319 | + ); |
|
| 320 | + } catch (EE_Error | ReflectionException $e) { |
|
| 321 | + error_log("PayPalLogger Error: $message: " . json_encode($response)); |
|
| 322 | + } |
|
| 323 | + return [ |
|
| 324 | + 'error' => $response['error'] ?? 'missing_order', |
|
| 325 | + 'message' => $response['message'] ?? $message, |
|
| 326 | + ]; |
|
| 327 | + } |
|
| 328 | + return $response; |
|
| 329 | + } |
|
| 330 | 330 | } |
@@ -101,9 +101,9 @@ discard block |
||
| 101 | 101 | */ |
| 102 | 102 | public function sanitizeRequestParameters(array $billing_info): void |
| 103 | 103 | { |
| 104 | - $sanitizer = new RequestSanitizer(new Basic()); |
|
| 104 | + $sanitizer = new RequestSanitizer(new Basic()); |
|
| 105 | 105 | foreach ($billing_info as $item => $value) { |
| 106 | - $this->billing_info[ $item ] = $sanitizer->clean($value); |
|
| 106 | + $this->billing_info[$item] = $sanitizer->clean($value); |
|
| 107 | 107 | } |
| 108 | 108 | } |
| 109 | 109 | |
@@ -141,7 +141,7 @@ discard block |
||
| 141 | 141 | esc_html__('Tickets for an event at %1$s', 'event_espresso'), |
| 142 | 142 | get_bloginfo('name') |
| 143 | 143 | ); |
| 144 | - $parameters = [ |
|
| 144 | + $parameters = [ |
|
| 145 | 145 | 'intent' => 'CAPTURE', |
| 146 | 146 | 'purchase_units' => [ |
| 147 | 147 | [ |
@@ -176,7 +176,7 @@ discard block |
||
| 176 | 176 | if ( |
| 177 | 177 | ( |
| 178 | 178 | (defined('EE_PPC_USE_PAYMENT_FEES') && EE_PPC_USE_PAYMENT_FEES) |
| 179 | - || (! defined('EE_PPC_USE_PAYMENT_FEES') |
|
| 179 | + || ( ! defined('EE_PPC_USE_PAYMENT_FEES') |
|
| 180 | 180 | && $this->feature->allowed(FeatureFlag::USE_PAYMENT_PROCESSOR_FEES) |
| 181 | 181 | ) |
| 182 | 182 | ) |
@@ -276,11 +276,11 @@ discard block |
||
| 276 | 276 | 'currency_code' => $this->currency_code, |
| 277 | 277 | 'value' => $this->items_total, |
| 278 | 278 | ]; |
| 279 | - $breakdown['tax_total'] = [ |
|
| 279 | + $breakdown['tax_total'] = [ |
|
| 280 | 280 | 'currency_code' => $this->currency_code, |
| 281 | 281 | 'value' => $this->tax_total, |
| 282 | 282 | ]; |
| 283 | - $breakdown['discount'] = [ |
|
| 283 | + $breakdown['discount'] = [ |
|
| 284 | 284 | 'currency_code' => $this->currency_code, |
| 285 | 285 | 'value' => abs($this->promos_total), |
| 286 | 286 | ]; |
@@ -306,10 +306,10 @@ discard block |
||
| 306 | 306 | false, |
| 307 | 307 | $this->transaction |
| 308 | 308 | ); |
| 309 | - if (! empty($response['error'])) { |
|
| 309 | + if ( ! empty($response['error'])) { |
|
| 310 | 310 | return $response; |
| 311 | 311 | } |
| 312 | - if (! isset($response['id'])) { |
|
| 312 | + if ( ! isset($response['id'])) { |
|
| 313 | 313 | $message = esc_html__('Unexpected response. Unable to find the order.', 'event_espresso'); |
| 314 | 314 | try { |
| 315 | 315 | PayPalLogger::errorLog( |
@@ -318,7 +318,7 @@ discard block |
||
| 318 | 318 | $this->transaction->payment_method() |
| 319 | 319 | ); |
| 320 | 320 | } catch (EE_Error | ReflectionException $e) { |
| 321 | - error_log("PayPalLogger Error: $message: " . json_encode($response)); |
|
| 321 | + error_log("PayPalLogger Error: $message: ".json_encode($response)); |
|
| 322 | 322 | } |
| 323 | 323 | return [ |
| 324 | 324 | 'error' => $response['error'] ?? 'missing_order', |
@@ -20,101 +20,101 @@ |
||
| 20 | 20 | */ |
| 21 | 21 | class CaptureOrder extends OrdersApi |
| 22 | 22 | { |
| 23 | - /** |
|
| 24 | - * Currency. |
|
| 25 | - * |
|
| 26 | - * @var string |
|
| 27 | - */ |
|
| 28 | - protected string $currency_code; |
|
| 23 | + /** |
|
| 24 | + * Currency. |
|
| 25 | + * |
|
| 26 | + * @var string |
|
| 27 | + */ |
|
| 28 | + protected string $currency_code; |
|
| 29 | 29 | |
| 30 | - /** |
|
| 31 | - * Transaction this order is for. |
|
| 32 | - * |
|
| 33 | - * @var EE_Transaction |
|
| 34 | - */ |
|
| 35 | - protected EE_Transaction $transaction; |
|
| 30 | + /** |
|
| 31 | + * Transaction this order is for. |
|
| 32 | + * |
|
| 33 | + * @var EE_Transaction |
|
| 34 | + */ |
|
| 35 | + protected EE_Transaction $transaction; |
|
| 36 | 36 | |
| 37 | 37 | |
| 38 | - /** |
|
| 39 | - * CaptureOrder constructor. |
|
| 40 | - * |
|
| 41 | - * @param PayPalApi $api |
|
| 42 | - * @param EE_Transaction $transaction |
|
| 43 | - * @param string $order_id |
|
| 44 | - */ |
|
| 45 | - public function __construct(PayPalApi $api, EE_Transaction $transaction, string $order_id) |
|
| 46 | - { |
|
| 47 | - parent::__construct($api); |
|
| 48 | - $this->transaction = $transaction; |
|
| 49 | - $this->order_id = $order_id; |
|
| 50 | - $this->currency_code = CurrencyManager::currencyCode(); |
|
| 51 | - $this->request_url = $this->request_url . $order_id . '/capture'; |
|
| 52 | - } |
|
| 38 | + /** |
|
| 39 | + * CaptureOrder constructor. |
|
| 40 | + * |
|
| 41 | + * @param PayPalApi $api |
|
| 42 | + * @param EE_Transaction $transaction |
|
| 43 | + * @param string $order_id |
|
| 44 | + */ |
|
| 45 | + public function __construct(PayPalApi $api, EE_Transaction $transaction, string $order_id) |
|
| 46 | + { |
|
| 47 | + parent::__construct($api); |
|
| 48 | + $this->transaction = $transaction; |
|
| 49 | + $this->order_id = $order_id; |
|
| 50 | + $this->currency_code = CurrencyManager::currencyCode(); |
|
| 51 | + $this->request_url = $this->request_url . $order_id . '/capture'; |
|
| 52 | + } |
|
| 53 | 53 | |
| 54 | 54 | |
| 55 | - /** |
|
| 56 | - * Capture payment for PayPal Order. |
|
| 57 | - * |
|
| 58 | - * @return array |
|
| 59 | - * @throws EE_Error |
|
| 60 | - * @throws ReflectionException |
|
| 61 | - */ |
|
| 62 | - public function capture(): array |
|
| 63 | - { |
|
| 64 | - // Create Order request. |
|
| 65 | - $capture_response = $this->api->sendRequest([], $this->request_url); |
|
| 66 | - return $this->validateOrder($capture_response); |
|
| 67 | - } |
|
| 55 | + /** |
|
| 56 | + * Capture payment for PayPal Order. |
|
| 57 | + * |
|
| 58 | + * @return array |
|
| 59 | + * @throws EE_Error |
|
| 60 | + * @throws ReflectionException |
|
| 61 | + */ |
|
| 62 | + public function capture(): array |
|
| 63 | + { |
|
| 64 | + // Create Order request. |
|
| 65 | + $capture_response = $this->api->sendRequest([], $this->request_url); |
|
| 66 | + return $this->validateOrder($capture_response); |
|
| 67 | + } |
|
| 68 | 68 | |
| 69 | 69 | |
| 70 | - /** |
|
| 71 | - * Makes sure that we have received an Order back from the API call. |
|
| 72 | - * |
|
| 73 | - * @param $response |
|
| 74 | - * @return array |
|
| 75 | - * @throws EE_Error |
|
| 76 | - * @throws ReflectionException |
|
| 77 | - */ |
|
| 78 | - public function validateOrder($response): array |
|
| 79 | - { |
|
| 80 | - $message = esc_html__('Validating Order Capture:', 'event_espresso'); |
|
| 81 | - PayPalLogger::errorLog( |
|
| 82 | - $message, |
|
| 83 | - [$this->request_url, $response], |
|
| 84 | - $this->transaction->payment_method(), |
|
| 85 | - false, |
|
| 86 | - $this->transaction |
|
| 87 | - ); |
|
| 88 | - // We got a direct error response. Not valid. Return that error. |
|
| 89 | - if (! empty($response['error'])) { |
|
| 90 | - return $response; |
|
| 91 | - } |
|
| 92 | - // This also could be a retry capture, so consider this valid, if order already captured. |
|
| 93 | - if ( |
|
| 94 | - ! empty($response['message']['details']['issue']) |
|
| 95 | - && $response['message']['details']['issue'] === 'ORDER_ALREADY_CAPTURED' |
|
| 96 | - ) { |
|
| 97 | - // Need to make sure we pass on the order ID. |
|
| 98 | - if (empty($response['id'])) { |
|
| 99 | - $response['id'] = $this->order_id; |
|
| 100 | - } |
|
| 101 | - $response['status'] = 'ORDER_ALREADY_CAPTURED'; |
|
| 102 | - return $response; |
|
| 103 | - } |
|
| 104 | - // A success capture should return the order ID. |
|
| 105 | - if (! isset($response['id'])) { |
|
| 106 | - $message = esc_html__('Unexpected response. No order returned.', 'event_espresso'); |
|
| 107 | - try { |
|
| 108 | - PayPalLogger::errorLog($message, [$this->request_url, $response], $this->transaction->payment_method()); |
|
| 109 | - } catch (EE_Error | ReflectionException $e) { |
|
| 110 | - error_log("PayPalLogger Error: $message: " . json_encode($response)); |
|
| 111 | - } |
|
| 112 | - return [ |
|
| 113 | - 'error' => $response['error'] ?? 'missing_order', |
|
| 114 | - 'message' => $response['message'] ?? $message, |
|
| 115 | - 'name' => $response['name'] ?? 'UNKNOWN_ERROR', |
|
| 116 | - ]; |
|
| 117 | - } |
|
| 118 | - return $response; |
|
| 119 | - } |
|
| 70 | + /** |
|
| 71 | + * Makes sure that we have received an Order back from the API call. |
|
| 72 | + * |
|
| 73 | + * @param $response |
|
| 74 | + * @return array |
|
| 75 | + * @throws EE_Error |
|
| 76 | + * @throws ReflectionException |
|
| 77 | + */ |
|
| 78 | + public function validateOrder($response): array |
|
| 79 | + { |
|
| 80 | + $message = esc_html__('Validating Order Capture:', 'event_espresso'); |
|
| 81 | + PayPalLogger::errorLog( |
|
| 82 | + $message, |
|
| 83 | + [$this->request_url, $response], |
|
| 84 | + $this->transaction->payment_method(), |
|
| 85 | + false, |
|
| 86 | + $this->transaction |
|
| 87 | + ); |
|
| 88 | + // We got a direct error response. Not valid. Return that error. |
|
| 89 | + if (! empty($response['error'])) { |
|
| 90 | + return $response; |
|
| 91 | + } |
|
| 92 | + // This also could be a retry capture, so consider this valid, if order already captured. |
|
| 93 | + if ( |
|
| 94 | + ! empty($response['message']['details']['issue']) |
|
| 95 | + && $response['message']['details']['issue'] === 'ORDER_ALREADY_CAPTURED' |
|
| 96 | + ) { |
|
| 97 | + // Need to make sure we pass on the order ID. |
|
| 98 | + if (empty($response['id'])) { |
|
| 99 | + $response['id'] = $this->order_id; |
|
| 100 | + } |
|
| 101 | + $response['status'] = 'ORDER_ALREADY_CAPTURED'; |
|
| 102 | + return $response; |
|
| 103 | + } |
|
| 104 | + // A success capture should return the order ID. |
|
| 105 | + if (! isset($response['id'])) { |
|
| 106 | + $message = esc_html__('Unexpected response. No order returned.', 'event_espresso'); |
|
| 107 | + try { |
|
| 108 | + PayPalLogger::errorLog($message, [$this->request_url, $response], $this->transaction->payment_method()); |
|
| 109 | + } catch (EE_Error | ReflectionException $e) { |
|
| 110 | + error_log("PayPalLogger Error: $message: " . json_encode($response)); |
|
| 111 | + } |
|
| 112 | + return [ |
|
| 113 | + 'error' => $response['error'] ?? 'missing_order', |
|
| 114 | + 'message' => $response['message'] ?? $message, |
|
| 115 | + 'name' => $response['name'] ?? 'UNKNOWN_ERROR', |
|
| 116 | + ]; |
|
| 117 | + } |
|
| 118 | + return $response; |
|
| 119 | + } |
|
| 120 | 120 | } |
@@ -48,7 +48,7 @@ discard block |
||
| 48 | 48 | $this->transaction = $transaction; |
| 49 | 49 | $this->order_id = $order_id; |
| 50 | 50 | $this->currency_code = CurrencyManager::currencyCode(); |
| 51 | - $this->request_url = $this->request_url . $order_id . '/capture'; |
|
| 51 | + $this->request_url = $this->request_url.$order_id.'/capture'; |
|
| 52 | 52 | } |
| 53 | 53 | |
| 54 | 54 | |
@@ -80,13 +80,13 @@ discard block |
||
| 80 | 80 | $message = esc_html__('Validating Order Capture:', 'event_espresso'); |
| 81 | 81 | PayPalLogger::errorLog( |
| 82 | 82 | $message, |
| 83 | - [$this->request_url, $response], |
|
| 83 | + [$this->request_url, $response], |
|
| 84 | 84 | $this->transaction->payment_method(), |
| 85 | 85 | false, |
| 86 | 86 | $this->transaction |
| 87 | 87 | ); |
| 88 | 88 | // We got a direct error response. Not valid. Return that error. |
| 89 | - if (! empty($response['error'])) { |
|
| 89 | + if ( ! empty($response['error'])) { |
|
| 90 | 90 | return $response; |
| 91 | 91 | } |
| 92 | 92 | // This also could be a retry capture, so consider this valid, if order already captured. |
@@ -102,12 +102,12 @@ discard block |
||
| 102 | 102 | return $response; |
| 103 | 103 | } |
| 104 | 104 | // A success capture should return the order ID. |
| 105 | - if (! isset($response['id'])) { |
|
| 105 | + if ( ! isset($response['id'])) { |
|
| 106 | 106 | $message = esc_html__('Unexpected response. No order returned.', 'event_espresso'); |
| 107 | 107 | try { |
| 108 | 108 | PayPalLogger::errorLog($message, [$this->request_url, $response], $this->transaction->payment_method()); |
| 109 | 109 | } catch (EE_Error | ReflectionException $e) { |
| 110 | - error_log("PayPalLogger Error: $message: " . json_encode($response)); |
|
| 110 | + error_log("PayPalLogger Error: $message: ".json_encode($response)); |
|
| 111 | 111 | } |
| 112 | 112 | return [ |
| 113 | 113 | 'error' => $response['error'] ?? 'missing_order', |
@@ -17,171 +17,171 @@ |
||
| 17 | 17 | */ |
| 18 | 18 | class Domain |
| 19 | 19 | { |
| 20 | - /** |
|
| 21 | - * Name of the extra meta key that stores this PM options as one meta. |
|
| 22 | - */ |
|
| 23 | - public const META_KEY_PAYPAL_DATA = 'paypal_data'; |
|
| 24 | - /** |
|
| 25 | - * Name of the extra meta key that stores this PM options as one meta. |
|
| 26 | - */ |
|
| 27 | - public const META_KEY_PAYPAL_DATA_SANDBOX = 'paypal_data_sandbox'; |
|
| 28 | - |
|
| 29 | - /** |
|
| 30 | - * Name of the extra meta that stores whether the credentials were for the sandbox or live mode. |
|
| 31 | - */ |
|
| 32 | - public const META_KEY_SANDBOX_MODE = 'sandbox_mode'; |
|
| 33 | - |
|
| 34 | - /** |
|
| 35 | - * Name of the extra meta that stores the Access Token that is used to auth in API requests to PayPal. |
|
| 36 | - */ |
|
| 37 | - public const META_KEY_ACCESS_TOKEN = 'access_token'; |
|
| 38 | - |
|
| 39 | - /** |
|
| 40 | - * Name of the extra meta that stores the last request tracking ID. |
|
| 41 | - */ |
|
| 42 | - public const META_KEY_TRACKING_ID = 'tracking_id'; |
|
| 43 | - |
|
| 44 | - /** |
|
| 45 | - * Name of the extra meta that stores the Event Espresso PayPal Account's merchant id. |
|
| 46 | - */ |
|
| 47 | - public const META_KEY_APP_ID = 'app_id'; |
|
| 48 | - |
|
| 49 | - /** |
|
| 50 | - * Name of the extra meta that holds the seller client ID. |
|
| 51 | - */ |
|
| 52 | - public const META_KEY_CLIENT_ID = 'client_id'; |
|
| 53 | - |
|
| 54 | - /** |
|
| 55 | - * Name of the extra meta that holds the seller secret. |
|
| 56 | - */ |
|
| 57 | - public const META_KEY_CLIENT_SECRET = 'client_secret'; |
|
| 58 | - |
|
| 59 | - /** |
|
| 60 | - * Name of the extra meta that stores the expiration date of the Access Token. |
|
| 61 | - */ |
|
| 62 | - public const META_KEY_TOKEN_EXPIRES_IN = 'expires_in'; |
|
| 63 | - |
|
| 64 | - /** |
|
| 65 | - * Name of the extra meta that holds the partner client ID. |
|
| 66 | - */ |
|
| 67 | - public const META_KEY_PARTNER_CLIENT_ID = 'partner_client_id'; |
|
| 68 | - |
|
| 69 | - /** |
|
| 70 | - * Name of the extra meta that holds the partner merchant ID. |
|
| 71 | - */ |
|
| 72 | - public const META_KEY_PARTNER_MERCHANT_ID = 'partner_merchant_id'; |
|
| 73 | - |
|
| 74 | - /** |
|
| 75 | - * Name of the extra meta that holds the seller merchant ID. |
|
| 76 | - */ |
|
| 77 | - public const META_KEY_SELLER_MERCHANT_ID = 'merchantIdInPayPal'; |
|
| 78 | - |
|
| 79 | - /** |
|
| 80 | - * Name of the extra meta that holds the BN / request tracking code. |
|
| 81 | - */ |
|
| 82 | - public const META_KEY_BN_CODE = 'bn_code'; |
|
| 83 | - |
|
| 84 | - /** |
|
| 85 | - * Name of the extra meta that stores the merchant authorized scopes for our app to work within. |
|
| 86 | - */ |
|
| 87 | - public const META_KEY_AUTHORIZED_SCOPES = 'authorized_scopes'; |
|
| 88 | - |
|
| 89 | - /** |
|
| 90 | - * Name of the extra meta that stores the PP checkout type selected by merchant after onboarding. |
|
| 91 | - */ |
|
| 92 | - public const META_KEY_CHECKOUT_TYPE = 'checkout_type'; |
|
| 93 | - |
|
| 94 | - /** |
|
| 95 | - * Name of the extra meta that stores the allowed PP checkout type selected by merchant while onboarding. |
|
| 96 | - */ |
|
| 97 | - public const META_KEY_ALLOWED_CHECKOUT_TYPE = 'allowed_checkout_type'; |
|
| 98 | - |
|
| 99 | - /** |
|
| 100 | - * Name of the extra meta that stores the selected PP function options. |
|
| 101 | - */ |
|
| 102 | - public const META_KEY_FUNDING_OPTIONS = 'funding_options'; |
|
| 103 | - |
|
| 104 | - /** |
|
| 105 | - * Name of the PayPal API parameter that holds the auth code. |
|
| 106 | - */ |
|
| 107 | - public const API_KEY_AUTH_CODE = 'authCode'; |
|
| 108 | - |
|
| 109 | - /** |
|
| 110 | - * Name of the PayPal API parameter that holds the client token. |
|
| 111 | - */ |
|
| 112 | - public const API_KEY_CLIENT_TOKEN = 'client_token'; |
|
| 113 | - |
|
| 114 | - /** |
|
| 115 | - * Name of the extra meta that holds the seller payer ID. |
|
| 116 | - */ |
|
| 117 | - public const META_KEY_PAYER_ID = 'payer_id'; |
|
| 118 | - |
|
| 119 | - /** |
|
| 120 | - * Name of the PayPal API parameter that holds the client token expiration time. |
|
| 121 | - */ |
|
| 122 | - public const API_KEY_EXPIRES_IN = 'expires_in'; |
|
| 123 | - |
|
| 124 | - /** |
|
| 125 | - * Name of the PayPal API parameter that holds the list of oAuth integrations related to the merchant. |
|
| 126 | - */ |
|
| 127 | - public const API_PARAM_OAUTH_INTEGRATIONS = 'oauth_integrations'; |
|
| 128 | - |
|
| 129 | - /** |
|
| 130 | - * Name of the PayPal API parameter that holds the list of third party permissions that were granted. |
|
| 131 | - */ |
|
| 132 | - public const API_PARAM_PERMISSIONS_GRANTED = 'oauth_third_party'; |
|
| 133 | - |
|
| 134 | - /** |
|
| 135 | - * Name of the PayPal API parameter that holds the bool of if the primary email was confirmed. |
|
| 136 | - */ |
|
| 137 | - public const API_PARAM_PRIM_EMAIL_CONFIRMED = 'primary_email_confirmed'; |
|
| 138 | - |
|
| 139 | - /** |
|
| 140 | - * Name of the PayPal API parameter that holds the bool of if email was confirmed. |
|
| 141 | - */ |
|
| 142 | - public const API_PARAM_EMAIL_CONFIRMED = 'isEmailConfirmed'; |
|
| 143 | - |
|
| 144 | - /** |
|
| 145 | - * Name of the PayPal API parameter that holds the partner ID. |
|
| 146 | - */ |
|
| 147 | - public const API_PARAM_PARTNER_ID = 'merchantId'; |
|
| 148 | - |
|
| 149 | - /** |
|
| 150 | - * Name of the PayPal API parameter that holds the merchant ID in the Track seller onboarding status request. |
|
| 151 | - */ |
|
| 152 | - public const API_PARAM_TRACK_MERCHANT_ID = 'merchant_id'; |
|
| 153 | - |
|
| 154 | - /** |
|
| 155 | - * Name of the PayPal API parameter that holds the payments_receivable status. |
|
| 156 | - */ |
|
| 157 | - public const API_PARAM_PAYMENTS_RECEIVABLE = 'payments_receivable'; |
|
| 158 | - |
|
| 159 | - /** |
|
| 160 | - * Name of the nonce used in the capture order request. |
|
| 161 | - */ |
|
| 162 | - public const CAPTURE_ORDER_NONCE_NAME = 'eea_pp_commerce_capture_order_payment'; |
|
| 163 | - |
|
| 164 | - /** |
|
| 165 | - * Name of the nonce used in the onboarding process. |
|
| 166 | - */ |
|
| 167 | - public const NONCE_NAME_ONBOARDING_RETURN = 'eea_pp_commerce_onboarding_return'; |
|
| 168 | - |
|
| 169 | - /** |
|
| 170 | - * Holds this payment method slug. |
|
| 171 | - */ |
|
| 172 | - public const PM_SLUG = 'paypalcheckout'; |
|
| 173 | - |
|
| 174 | - |
|
| 175 | - /** |
|
| 176 | - * Returns the base PayPal API URL. |
|
| 177 | - * |
|
| 178 | - * @param EE_Payment_Method $payment_method |
|
| 179 | - * @return string |
|
| 180 | - * @throws EE_Error |
|
| 181 | - * @throws ReflectionException |
|
| 182 | - */ |
|
| 183 | - public static function getPayPalApiUrl(EE_Payment_Method $payment_method): string |
|
| 184 | - { |
|
| 185 | - return $payment_method->debug_mode() ? 'https://api-m.sandbox.paypal.com' : 'https://api-m.paypal.com'; |
|
| 186 | - } |
|
| 20 | + /** |
|
| 21 | + * Name of the extra meta key that stores this PM options as one meta. |
|
| 22 | + */ |
|
| 23 | + public const META_KEY_PAYPAL_DATA = 'paypal_data'; |
|
| 24 | + /** |
|
| 25 | + * Name of the extra meta key that stores this PM options as one meta. |
|
| 26 | + */ |
|
| 27 | + public const META_KEY_PAYPAL_DATA_SANDBOX = 'paypal_data_sandbox'; |
|
| 28 | + |
|
| 29 | + /** |
|
| 30 | + * Name of the extra meta that stores whether the credentials were for the sandbox or live mode. |
|
| 31 | + */ |
|
| 32 | + public const META_KEY_SANDBOX_MODE = 'sandbox_mode'; |
|
| 33 | + |
|
| 34 | + /** |
|
| 35 | + * Name of the extra meta that stores the Access Token that is used to auth in API requests to PayPal. |
|
| 36 | + */ |
|
| 37 | + public const META_KEY_ACCESS_TOKEN = 'access_token'; |
|
| 38 | + |
|
| 39 | + /** |
|
| 40 | + * Name of the extra meta that stores the last request tracking ID. |
|
| 41 | + */ |
|
| 42 | + public const META_KEY_TRACKING_ID = 'tracking_id'; |
|
| 43 | + |
|
| 44 | + /** |
|
| 45 | + * Name of the extra meta that stores the Event Espresso PayPal Account's merchant id. |
|
| 46 | + */ |
|
| 47 | + public const META_KEY_APP_ID = 'app_id'; |
|
| 48 | + |
|
| 49 | + /** |
|
| 50 | + * Name of the extra meta that holds the seller client ID. |
|
| 51 | + */ |
|
| 52 | + public const META_KEY_CLIENT_ID = 'client_id'; |
|
| 53 | + |
|
| 54 | + /** |
|
| 55 | + * Name of the extra meta that holds the seller secret. |
|
| 56 | + */ |
|
| 57 | + public const META_KEY_CLIENT_SECRET = 'client_secret'; |
|
| 58 | + |
|
| 59 | + /** |
|
| 60 | + * Name of the extra meta that stores the expiration date of the Access Token. |
|
| 61 | + */ |
|
| 62 | + public const META_KEY_TOKEN_EXPIRES_IN = 'expires_in'; |
|
| 63 | + |
|
| 64 | + /** |
|
| 65 | + * Name of the extra meta that holds the partner client ID. |
|
| 66 | + */ |
|
| 67 | + public const META_KEY_PARTNER_CLIENT_ID = 'partner_client_id'; |
|
| 68 | + |
|
| 69 | + /** |
|
| 70 | + * Name of the extra meta that holds the partner merchant ID. |
|
| 71 | + */ |
|
| 72 | + public const META_KEY_PARTNER_MERCHANT_ID = 'partner_merchant_id'; |
|
| 73 | + |
|
| 74 | + /** |
|
| 75 | + * Name of the extra meta that holds the seller merchant ID. |
|
| 76 | + */ |
|
| 77 | + public const META_KEY_SELLER_MERCHANT_ID = 'merchantIdInPayPal'; |
|
| 78 | + |
|
| 79 | + /** |
|
| 80 | + * Name of the extra meta that holds the BN / request tracking code. |
|
| 81 | + */ |
|
| 82 | + public const META_KEY_BN_CODE = 'bn_code'; |
|
| 83 | + |
|
| 84 | + /** |
|
| 85 | + * Name of the extra meta that stores the merchant authorized scopes for our app to work within. |
|
| 86 | + */ |
|
| 87 | + public const META_KEY_AUTHORIZED_SCOPES = 'authorized_scopes'; |
|
| 88 | + |
|
| 89 | + /** |
|
| 90 | + * Name of the extra meta that stores the PP checkout type selected by merchant after onboarding. |
|
| 91 | + */ |
|
| 92 | + public const META_KEY_CHECKOUT_TYPE = 'checkout_type'; |
|
| 93 | + |
|
| 94 | + /** |
|
| 95 | + * Name of the extra meta that stores the allowed PP checkout type selected by merchant while onboarding. |
|
| 96 | + */ |
|
| 97 | + public const META_KEY_ALLOWED_CHECKOUT_TYPE = 'allowed_checkout_type'; |
|
| 98 | + |
|
| 99 | + /** |
|
| 100 | + * Name of the extra meta that stores the selected PP function options. |
|
| 101 | + */ |
|
| 102 | + public const META_KEY_FUNDING_OPTIONS = 'funding_options'; |
|
| 103 | + |
|
| 104 | + /** |
|
| 105 | + * Name of the PayPal API parameter that holds the auth code. |
|
| 106 | + */ |
|
| 107 | + public const API_KEY_AUTH_CODE = 'authCode'; |
|
| 108 | + |
|
| 109 | + /** |
|
| 110 | + * Name of the PayPal API parameter that holds the client token. |
|
| 111 | + */ |
|
| 112 | + public const API_KEY_CLIENT_TOKEN = 'client_token'; |
|
| 113 | + |
|
| 114 | + /** |
|
| 115 | + * Name of the extra meta that holds the seller payer ID. |
|
| 116 | + */ |
|
| 117 | + public const META_KEY_PAYER_ID = 'payer_id'; |
|
| 118 | + |
|
| 119 | + /** |
|
| 120 | + * Name of the PayPal API parameter that holds the client token expiration time. |
|
| 121 | + */ |
|
| 122 | + public const API_KEY_EXPIRES_IN = 'expires_in'; |
|
| 123 | + |
|
| 124 | + /** |
|
| 125 | + * Name of the PayPal API parameter that holds the list of oAuth integrations related to the merchant. |
|
| 126 | + */ |
|
| 127 | + public const API_PARAM_OAUTH_INTEGRATIONS = 'oauth_integrations'; |
|
| 128 | + |
|
| 129 | + /** |
|
| 130 | + * Name of the PayPal API parameter that holds the list of third party permissions that were granted. |
|
| 131 | + */ |
|
| 132 | + public const API_PARAM_PERMISSIONS_GRANTED = 'oauth_third_party'; |
|
| 133 | + |
|
| 134 | + /** |
|
| 135 | + * Name of the PayPal API parameter that holds the bool of if the primary email was confirmed. |
|
| 136 | + */ |
|
| 137 | + public const API_PARAM_PRIM_EMAIL_CONFIRMED = 'primary_email_confirmed'; |
|
| 138 | + |
|
| 139 | + /** |
|
| 140 | + * Name of the PayPal API parameter that holds the bool of if email was confirmed. |
|
| 141 | + */ |
|
| 142 | + public const API_PARAM_EMAIL_CONFIRMED = 'isEmailConfirmed'; |
|
| 143 | + |
|
| 144 | + /** |
|
| 145 | + * Name of the PayPal API parameter that holds the partner ID. |
|
| 146 | + */ |
|
| 147 | + public const API_PARAM_PARTNER_ID = 'merchantId'; |
|
| 148 | + |
|
| 149 | + /** |
|
| 150 | + * Name of the PayPal API parameter that holds the merchant ID in the Track seller onboarding status request. |
|
| 151 | + */ |
|
| 152 | + public const API_PARAM_TRACK_MERCHANT_ID = 'merchant_id'; |
|
| 153 | + |
|
| 154 | + /** |
|
| 155 | + * Name of the PayPal API parameter that holds the payments_receivable status. |
|
| 156 | + */ |
|
| 157 | + public const API_PARAM_PAYMENTS_RECEIVABLE = 'payments_receivable'; |
|
| 158 | + |
|
| 159 | + /** |
|
| 160 | + * Name of the nonce used in the capture order request. |
|
| 161 | + */ |
|
| 162 | + public const CAPTURE_ORDER_NONCE_NAME = 'eea_pp_commerce_capture_order_payment'; |
|
| 163 | + |
|
| 164 | + /** |
|
| 165 | + * Name of the nonce used in the onboarding process. |
|
| 166 | + */ |
|
| 167 | + public const NONCE_NAME_ONBOARDING_RETURN = 'eea_pp_commerce_onboarding_return'; |
|
| 168 | + |
|
| 169 | + /** |
|
| 170 | + * Holds this payment method slug. |
|
| 171 | + */ |
|
| 172 | + public const PM_SLUG = 'paypalcheckout'; |
|
| 173 | + |
|
| 174 | + |
|
| 175 | + /** |
|
| 176 | + * Returns the base PayPal API URL. |
|
| 177 | + * |
|
| 178 | + * @param EE_Payment_Method $payment_method |
|
| 179 | + * @return string |
|
| 180 | + * @throws EE_Error |
|
| 181 | + * @throws ReflectionException |
|
| 182 | + */ |
|
| 183 | + public static function getPayPalApiUrl(EE_Payment_Method $payment_method): string |
|
| 184 | + { |
|
| 185 | + return $payment_method->debug_mode() ? 'https://api-m.sandbox.paypal.com' : 'https://api-m.paypal.com'; |
|
| 186 | + } |
|
| 187 | 187 | } |
@@ -23,457 +23,457 @@ |
||
| 23 | 23 | */ |
| 24 | 24 | class EED_PayPalCommerce extends EED_Module |
| 25 | 25 | { |
| 26 | - /** |
|
| 27 | - * @return EED_Module |
|
| 28 | - * @throws EE_Error |
|
| 29 | - * @throws ReflectionException |
|
| 30 | - */ |
|
| 31 | - public static function instance(): EED_Module |
|
| 32 | - { |
|
| 33 | - return parent::get_instance(__CLASS__); |
|
| 34 | - } |
|
| 35 | - |
|
| 36 | - |
|
| 37 | - /** |
|
| 38 | - * Run - initial module setup. |
|
| 39 | - * |
|
| 40 | - * @param WP $WP |
|
| 41 | - * @return void |
|
| 42 | - */ |
|
| 43 | - public function run($WP) |
|
| 44 | - { |
|
| 45 | - } |
|
| 46 | - |
|
| 47 | - |
|
| 48 | - /** |
|
| 49 | - * For hooking into EE Core and other modules. |
|
| 50 | - * |
|
| 51 | - * @return void |
|
| 52 | - */ |
|
| 53 | - public static function set_hooks(): void |
|
| 54 | - { |
|
| 55 | - if (DbStatus::isOnline()) { |
|
| 56 | - // Don't load PM on the front-end if not Connected. |
|
| 57 | - add_filter( |
|
| 58 | - 'FHEE__EEM_Payment_Method__get_all_for_transaction__payment_methods', |
|
| 59 | - [__CLASS__, 'filterPaymentMethods'], |
|
| 60 | - 100 |
|
| 61 | - ); |
|
| 62 | - } |
|
| 63 | - } |
|
| 64 | - |
|
| 65 | - |
|
| 66 | - /** |
|
| 67 | - * For hooking into EE Core and other modules Admin. |
|
| 68 | - * |
|
| 69 | - * @return void |
|
| 70 | - */ |
|
| 71 | - public static function set_hooks_admin(): void |
|
| 72 | - { |
|
| 73 | - if (DbStatus::isOnline()) { |
|
| 74 | - // Create an Order. |
|
| 75 | - add_action('wp_ajax_eeaPPCCreateOrder', [__CLASS__, 'createOrderRequest']); |
|
| 76 | - add_action('wp_ajax_nopriv_eeaPPCCreateOrder', [__CLASS__, 'createOrderRequest']); |
|
| 77 | - // Log errors from the JS side. |
|
| 78 | - add_action('wp_ajax_eeaPPCommerceLogError', [__CLASS__, 'logJsError']); |
|
| 79 | - add_action('wp_ajax_nopriv_eeaPPCommerceLogError', [__CLASS__, 'logJsError']); |
|
| 80 | - // Don't load PM in the admin if not Connected. |
|
| 81 | - add_filter( |
|
| 82 | - 'FHEE__EEM_Payment_Method__get_all_for_transaction__payment_methods', |
|
| 83 | - [__CLASS__, 'filterPaymentMethods'], |
|
| 84 | - 100 |
|
| 85 | - ); |
|
| 86 | - } |
|
| 87 | - } |
|
| 88 | - |
|
| 89 | - |
|
| 90 | - /** |
|
| 91 | - * Create the order and return its data as JSON. |
|
| 92 | - * (AJAX) |
|
| 93 | - * |
|
| 94 | - * @return void |
|
| 95 | - * @throws EE_Error |
|
| 96 | - * @throws ReflectionException |
|
| 97 | - */ |
|
| 98 | - public static function createOrderRequest(): void |
|
| 99 | - { |
|
| 100 | - $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
| 101 | - $post_params = EED_Module::getRequest()->postParams(); |
|
| 102 | - if (! $paypal_pm instanceof EE_Payment_Method) { |
|
| 103 | - PayPalLogger::errorLogAndExit( |
|
| 104 | - esc_html__('Related payment method not found (create Order).', 'event_espresso'), |
|
| 105 | - $post_params |
|
| 106 | - ); |
|
| 107 | - } |
|
| 108 | - $transaction = EED_PayPalCommerce::getTransaction(); |
|
| 109 | - $billing_info = $post_params['billing_info'] ?? []; |
|
| 110 | - if ($billing_info) { |
|
| 111 | - $billing_info_decoded = json_decode(stripslashes($billing_info), true); |
|
| 112 | - $billing_info = is_array($billing_info_decoded) ? $billing_info_decoded : []; |
|
| 113 | - } |
|
| 114 | - if (! $transaction) { |
|
| 115 | - PayPalLogger::errorLogAndExit( |
|
| 116 | - esc_html__('Transaction info not found.', 'event_espresso'), |
|
| 117 | - $post_params, |
|
| 118 | - $paypal_pm |
|
| 119 | - ); |
|
| 120 | - } |
|
| 121 | - $order_data = EED_PayPalCommerce::createOrder($transaction, $billing_info, $paypal_pm); |
|
| 122 | - wp_send_json($order_data); |
|
| 123 | - } |
|
| 124 | - |
|
| 125 | - |
|
| 126 | - /** |
|
| 127 | - * Create a new Order using the PP API. |
|
| 128 | - * |
|
| 129 | - * @param EE_Transaction $transaction |
|
| 130 | - * @param array $billing_info |
|
| 131 | - * @param EE_Payment_Method $paypal_pm |
|
| 132 | - * @return array |
|
| 133 | - * @throws EE_Error |
|
| 134 | - * @throws ReflectionException |
|
| 135 | - */ |
|
| 136 | - public static function createOrder( |
|
| 137 | - EE_Transaction $transaction, |
|
| 138 | - array $billing_info, |
|
| 139 | - EE_Payment_Method $paypal_pm |
|
| 140 | - ): array { |
|
| 141 | - $create_order_api = EED_PayPalCommerce::getCreateOrderApi($transaction, $billing_info, $paypal_pm); |
|
| 142 | - if (! $create_order_api instanceof CreateOrder) { |
|
| 143 | - return [ |
|
| 144 | - 'error' => 'CREATE_ORDER_API_FAULT', |
|
| 145 | - 'message' => esc_html__('The Create Order API request fault.', 'event_espresso'), |
|
| 146 | - ]; |
|
| 147 | - } |
|
| 148 | - $payment = EEG_PayPalCheckout::createPayment($transaction, $paypal_pm); |
|
| 149 | - $order = $create_order_api->create(); |
|
| 150 | - if (isset($order['error'])) { |
|
| 151 | - EEG_PayPalCheckout::updatePaymentStatus($payment, EEM_Payment::status_id_failed, $order, $order['error']); |
|
| 152 | - return [ |
|
| 153 | - 'error' => 'CREATE_ORDER_API_RESPONSE_ERROR', |
|
| 154 | - 'message' => $order['message'], |
|
| 155 | - ]; |
|
| 156 | - } |
|
| 157 | - return [ |
|
| 158 | - 'pp_order_id' => $order['id'], |
|
| 159 | - ]; |
|
| 160 | - } |
|
| 161 | - |
|
| 162 | - |
|
| 163 | - /** |
|
| 164 | - * Create a new Order using the PP API. |
|
| 165 | - * |
|
| 166 | - * @param EE_Transaction $transaction |
|
| 167 | - * @param EE_Payment_Method $paypal_pm |
|
| 168 | - * @param string $order_id |
|
| 169 | - * @return array |
|
| 170 | - * @throws EE_Error |
|
| 171 | - * @throws ReflectionException |
|
| 172 | - */ |
|
| 173 | - public static function captureOrder( |
|
| 174 | - EE_Transaction $transaction, |
|
| 175 | - EE_Payment_Method $paypal_pm, |
|
| 176 | - string $order_id |
|
| 177 | - ): array { |
|
| 178 | - $capture_order_api = EED_PayPalCommerce::getCaptureOrderApi($transaction, $paypal_pm, $order_id); |
|
| 179 | - if (! $capture_order_api instanceof CaptureOrder) { |
|
| 180 | - return [ |
|
| 181 | - 'error' => 'CAPTURE_ORDER_API_FAULT', |
|
| 182 | - 'message' => esc_html__('A capture Order API request fault.', 'event_espresso'), |
|
| 183 | - ]; |
|
| 184 | - } |
|
| 185 | - return $capture_order_api->capture(); |
|
| 186 | - } |
|
| 187 | - |
|
| 188 | - |
|
| 189 | - /** |
|
| 190 | - * Get Order Details using the PP API. |
|
| 191 | - * |
|
| 192 | - * @param string $order_id |
|
| 193 | - * @param EE_Transaction $transaction |
|
| 194 | - * @param EE_Payment_Method $paypal_pm |
|
| 195 | - * @return array |
|
| 196 | - * @throws EE_Error |
|
| 197 | - * @throws ReflectionException |
|
| 198 | - */ |
|
| 199 | - public static function getOrderDetails( |
|
| 200 | - string $order_id, |
|
| 201 | - EE_Transaction $transaction, |
|
| 202 | - EE_Payment_Method $paypal_pm |
|
| 203 | - ): array { |
|
| 204 | - $order_details = EED_PayPalCommerce::getOrderDetailsApi($order_id, $transaction, $paypal_pm); |
|
| 205 | - if (! $order_details instanceof OrderDetails) { |
|
| 206 | - return [ |
|
| 207 | - 'error' => 'ORDER_DETAILS_API_FAULT', |
|
| 208 | - 'message' => esc_html__('Get Order Details API request fault.', 'event_espresso'), |
|
| 209 | - ]; |
|
| 210 | - } |
|
| 211 | - return $order_details->get(); |
|
| 212 | - } |
|
| 213 | - |
|
| 214 | - |
|
| 215 | - /** |
|
| 216 | - * Initialize and return Create Order API. |
|
| 217 | - * |
|
| 218 | - * @param EE_Transaction $transaction |
|
| 219 | - * @param array $billing_info |
|
| 220 | - * @param EE_Payment_Method $paypal_pm |
|
| 221 | - * @return CreateOrder|null |
|
| 222 | - * @throws EE_Error |
|
| 223 | - * @throws ReflectionException |
|
| 224 | - */ |
|
| 225 | - public static function getCreateOrderApi( |
|
| 226 | - EE_Transaction $transaction, |
|
| 227 | - array $billing_info, |
|
| 228 | - EE_Payment_Method $paypal_pm |
|
| 229 | - ): ?CreateOrder { |
|
| 230 | - $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
|
| 231 | - if (! $paypal_api instanceof PayPalApi) { |
|
| 232 | - return null; |
|
| 233 | - } |
|
| 234 | - return LoaderFactory::getNew(CreateOrder::class, [$paypal_api, $transaction, $billing_info]); |
|
| 235 | - } |
|
| 236 | - |
|
| 237 | - |
|
| 238 | - /** |
|
| 239 | - * Initialize and return Capture Order API. |
|
| 240 | - * |
|
| 241 | - * @param EE_Transaction $transaction |
|
| 242 | - * @param EE_Payment_Method $paypal_pm |
|
| 243 | - * @param string $order_id |
|
| 244 | - * @return CaptureOrder|null |
|
| 245 | - * @throws EE_Error |
|
| 246 | - * @throws ReflectionException |
|
| 247 | - */ |
|
| 248 | - public static function getCaptureOrderApi( |
|
| 249 | - EE_Transaction $transaction, |
|
| 250 | - EE_Payment_Method $paypal_pm, |
|
| 251 | - string $order_id |
|
| 252 | - ): ?CaptureOrder { |
|
| 253 | - $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
|
| 254 | - if (! $paypal_api instanceof PayPalApi) { |
|
| 255 | - return null; |
|
| 256 | - } |
|
| 257 | - return LoaderFactory::getNew(CaptureOrder::class, [$paypal_api, $transaction, $order_id]); |
|
| 258 | - } |
|
| 259 | - |
|
| 260 | - |
|
| 261 | - /** |
|
| 262 | - * Initialize and return Order Details API. |
|
| 263 | - * |
|
| 264 | - * @param EE_Transaction $transaction |
|
| 265 | - * @param EE_Payment_Method $paypal_pm |
|
| 266 | - * @param string $order_id |
|
| 267 | - * @return OrderDetails|null |
|
| 268 | - * @throws EE_Error |
|
| 269 | - * @throws ReflectionException |
|
| 270 | - */ |
|
| 271 | - public static function getOrderDetailsApi( |
|
| 272 | - string $order_id, |
|
| 273 | - EE_Transaction $transaction, |
|
| 274 | - EE_Payment_Method $paypal_pm |
|
| 275 | - ): ?OrderDetails { |
|
| 276 | - $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
|
| 277 | - if (! $paypal_api instanceof PayPalApi) { |
|
| 278 | - return null; |
|
| 279 | - } |
|
| 280 | - return LoaderFactory::getNew(OrderDetails::class, [$paypal_api, $order_id, $transaction]); |
|
| 281 | - } |
|
| 282 | - |
|
| 283 | - |
|
| 284 | - /** |
|
| 285 | - * Return a PayPal API object, or false on failure. |
|
| 286 | - * |
|
| 287 | - * @param EE_Payment_Method $paypal_pm |
|
| 288 | - * @return PayPalApi|null |
|
| 289 | - * @throws EE_Error |
|
| 290 | - * @throws ReflectionException |
|
| 291 | - */ |
|
| 292 | - public static function getPayPalApi(EE_Payment_Method $paypal_pm): ?PayPalApi |
|
| 293 | - { |
|
| 294 | - // Try getting the first party credentials to determine if this is a first party integration that's active. |
|
| 295 | - $client_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_CLIENT_ID); |
|
| 296 | - $client_secret = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_CLIENT_SECRET); |
|
| 297 | - $bn_code = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_BN_CODE); |
|
| 298 | - if ($client_id && $client_secret) { |
|
| 299 | - return new FirstPartyPayPalApi($client_id, $client_secret, $bn_code, $paypal_pm->debug_mode()); |
|
| 300 | - } |
|
| 301 | - // Third party integration credentials: |
|
| 302 | - $access_token = EED_PayPalOnboard::getPartnerAccessToken($paypal_pm); |
|
| 303 | - if (! $access_token || ! $bn_code) { |
|
| 304 | - return null; |
|
| 305 | - } |
|
| 306 | - $partner_client_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_PARTNER_CLIENT_ID) ?: ''; |
|
| 307 | - $payer_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_SELLER_MERCHANT_ID) ?: ''; |
|
| 308 | - return new ThirdPartyPayPalApi( |
|
| 309 | - $access_token, |
|
| 310 | - $bn_code, |
|
| 311 | - $partner_client_id, |
|
| 312 | - $payer_id, |
|
| 313 | - $paypal_pm->debug_mode() |
|
| 314 | - ); |
|
| 315 | - } |
|
| 316 | - |
|
| 317 | - |
|
| 318 | - /** |
|
| 319 | - * Requests a client token. |
|
| 320 | - * |
|
| 321 | - * @param EE_Payment_Method $paypal_pm |
|
| 322 | - * @return array |
|
| 323 | - * @throws EE_Error |
|
| 324 | - * @throws ReflectionException |
|
| 325 | - */ |
|
| 326 | - public static function requestClientToken(EE_Payment_Method $paypal_pm): array |
|
| 327 | - { |
|
| 328 | - $error = ['error' => 'GET_CLIENT_TOKEN_FAULT']; |
|
| 329 | - $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
|
| 330 | - if (! $paypal_api instanceof PayPalApi) { |
|
| 331 | - $error['message'] = esc_html__('Got an error while trying to get the client token.', 'event_espresso'); |
|
| 332 | - return $error; |
|
| 333 | - } |
|
| 334 | - $client_token_api = new ClientToken($paypal_api, $paypal_pm->debug_mode()); |
|
| 335 | - $client_token = $client_token_api->getToken(); |
|
| 336 | - if (isset($client_token['error'])) { |
|
| 337 | - return $client_token; |
|
| 338 | - } |
|
| 339 | - if (empty($client_token)) { |
|
| 340 | - $error['message'] = esc_html__('Client token not valid.', 'event_espresso'); |
|
| 341 | - return $error; |
|
| 342 | - } |
|
| 343 | - return $client_token; |
|
| 344 | - } |
|
| 345 | - |
|
| 346 | - |
|
| 347 | - /** |
|
| 348 | - * Retrieve the payment method from the provided data. |
|
| 349 | - * |
|
| 350 | - * @return EE_Transaction|null |
|
| 351 | - */ |
|
| 352 | - public static function getTransaction(): ?EE_Transaction |
|
| 353 | - { |
|
| 354 | - try { |
|
| 355 | - $txn_id = EED_Module::getRequest()->getRequestParam('txn_id', 0, DataType::INT); |
|
| 356 | - $transaction = EEM_Transaction::instance()->get_one_by_ID($txn_id); |
|
| 357 | - if (! $transaction instanceof EE_Transaction) { |
|
| 358 | - PayPalLogger::errorLog( |
|
| 359 | - esc_html__('No transaction found by ID:', 'event_espresso'), |
|
| 360 | - EED_Module::getRequest()->postParams() |
|
| 361 | - ); |
|
| 362 | - return null; |
|
| 363 | - } |
|
| 364 | - } catch (Exception $e) { |
|
| 365 | - return null; |
|
| 366 | - } |
|
| 367 | - return $transaction; |
|
| 368 | - } |
|
| 369 | - |
|
| 370 | - |
|
| 371 | - /** |
|
| 372 | - * Return a PayPal API object, or false on failure. |
|
| 373 | - * |
|
| 374 | - * @param EE_Payment_Method $paypal_pm |
|
| 375 | - * @return bool |
|
| 376 | - * @throws EE_Error |
|
| 377 | - * @throws ReflectionException |
|
| 378 | - */ |
|
| 379 | - public static function isThirdParty(EE_Payment_Method $paypal_pm): bool |
|
| 380 | - { |
|
| 381 | - $pp_meta_data = PayPalExtraMetaManager::getAllData($paypal_pm); |
|
| 382 | - return ! empty($pp_meta_data[ Domain::META_KEY_SELLER_MERCHANT_ID ]) |
|
| 383 | - && ! empty($pp_meta_data[ Domain::META_KEY_ACCESS_TOKEN ]); |
|
| 384 | - } |
|
| 385 | - |
|
| 386 | - |
|
| 387 | - /** |
|
| 388 | - * Retrieve the payment method from the provided data. |
|
| 389 | - * |
|
| 390 | - * @return EE_Payment_Method|null |
|
| 391 | - */ |
|
| 392 | - public static function getPaymentMethod(): ?EE_Payment_Method |
|
| 393 | - { |
|
| 394 | - try { |
|
| 395 | - // Check if all required parameters are present. |
|
| 396 | - $pm_slug = EED_Module::getRequest()->getRequestParam('payment_method'); |
|
| 397 | - $payment_method = EEM_Payment_Method::instance()->get_one_by_slug($pm_slug); |
|
| 398 | - if ($payment_method instanceof EE_Payment_Method) { |
|
| 399 | - return $payment_method; |
|
| 400 | - } |
|
| 401 | - } catch (Exception $e) { |
|
| 402 | - return null; |
|
| 403 | - } |
|
| 404 | - return null; |
|
| 405 | - } |
|
| 406 | - |
|
| 407 | - |
|
| 408 | - /** |
|
| 409 | - * Log JS error. |
|
| 410 | - * |
|
| 411 | - * @return void |
|
| 412 | - */ |
|
| 413 | - public static function logJsError(): void |
|
| 414 | - { |
|
| 415 | - // Default to the "first" PayPal checkout PM. |
|
| 416 | - $request = EED_Module::getRequest(); |
|
| 417 | - $pm_slug = $request->getRequestParam('pm_slug', Domain::PM_SLUG); |
|
| 418 | - $payment_method = null; |
|
| 419 | - $txn_id = 'unknown'; |
|
| 420 | - try { |
|
| 421 | - $payment_method = EEM_Payment_Method::instance()->get_one_of_type($pm_slug); |
|
| 422 | - $txn_id = sanitize_text_field($request->getRequestParam('txn_id', '-')); |
|
| 423 | - } catch (Exception $e) { |
|
| 424 | - // Don't throw out anything, log at least something. |
|
| 425 | - } |
|
| 426 | - $transaction = EED_PayPalCommerce::getTransaction(); |
|
| 427 | - PayPalLogger::errorLog( |
|
| 428 | - "JS Error on transaction: $txn_id", |
|
| 429 | - $request->postParams(), |
|
| 430 | - $payment_method, |
|
| 431 | - false, |
|
| 432 | - $transaction |
|
| 433 | - ); |
|
| 434 | - } |
|
| 435 | - |
|
| 436 | - |
|
| 437 | - /** |
|
| 438 | - * Filter the Payment Methods list. |
|
| 439 | - * if needed, this filter can also supply the $transaction and $scope parameters. |
|
| 440 | - * |
|
| 441 | - * @param EE_Payment_Method[] $payment_methods |
|
| 442 | - * @return array |
|
| 443 | - * @throws EE_Error |
|
| 444 | - * @throws ReflectionException |
|
| 445 | - */ |
|
| 446 | - public static function filterPaymentMethods(array $payment_methods): array |
|
| 447 | - { |
|
| 448 | - // Don't allow this PM on the checkout page if not Connected. |
|
| 449 | - foreach ($payment_methods as $key => $pm) { |
|
| 450 | - // It is a PayPal Commerce payment method. Check if it's connected. If not - remove from the list. |
|
| 451 | - if (str_contains($pm->slug(), Domain::PM_SLUG) && ! EED_PayPalOnboard::isOnboard($pm)) { |
|
| 452 | - unset($payment_methods[ $key ]); |
|
| 453 | - } |
|
| 454 | - } |
|
| 455 | - return $payment_methods; |
|
| 456 | - } |
|
| 457 | - |
|
| 458 | - |
|
| 459 | - /** |
|
| 460 | - * Get all active states. |
|
| 461 | - * |
|
| 462 | - * @return array |
|
| 463 | - * @throws EE_Error |
|
| 464 | - * @throws ReflectionException |
|
| 465 | - */ |
|
| 466 | - public static function getActiveStates(): array |
|
| 467 | - { |
|
| 468 | - $state_options = []; |
|
| 469 | - $states = EEM_State::instance()->get_all_active_states(); |
|
| 470 | - if (! empty($states)) { |
|
| 471 | - foreach ($states as $numeral => $state) { |
|
| 472 | - if ($state instanceof EE_State) { |
|
| 473 | - $state_options[ $numeral ] = $state->abbrev(); |
|
| 474 | - } |
|
| 475 | - } |
|
| 476 | - } |
|
| 477 | - return $state_options; |
|
| 478 | - } |
|
| 26 | + /** |
|
| 27 | + * @return EED_Module |
|
| 28 | + * @throws EE_Error |
|
| 29 | + * @throws ReflectionException |
|
| 30 | + */ |
|
| 31 | + public static function instance(): EED_Module |
|
| 32 | + { |
|
| 33 | + return parent::get_instance(__CLASS__); |
|
| 34 | + } |
|
| 35 | + |
|
| 36 | + |
|
| 37 | + /** |
|
| 38 | + * Run - initial module setup. |
|
| 39 | + * |
|
| 40 | + * @param WP $WP |
|
| 41 | + * @return void |
|
| 42 | + */ |
|
| 43 | + public function run($WP) |
|
| 44 | + { |
|
| 45 | + } |
|
| 46 | + |
|
| 47 | + |
|
| 48 | + /** |
|
| 49 | + * For hooking into EE Core and other modules. |
|
| 50 | + * |
|
| 51 | + * @return void |
|
| 52 | + */ |
|
| 53 | + public static function set_hooks(): void |
|
| 54 | + { |
|
| 55 | + if (DbStatus::isOnline()) { |
|
| 56 | + // Don't load PM on the front-end if not Connected. |
|
| 57 | + add_filter( |
|
| 58 | + 'FHEE__EEM_Payment_Method__get_all_for_transaction__payment_methods', |
|
| 59 | + [__CLASS__, 'filterPaymentMethods'], |
|
| 60 | + 100 |
|
| 61 | + ); |
|
| 62 | + } |
|
| 63 | + } |
|
| 64 | + |
|
| 65 | + |
|
| 66 | + /** |
|
| 67 | + * For hooking into EE Core and other modules Admin. |
|
| 68 | + * |
|
| 69 | + * @return void |
|
| 70 | + */ |
|
| 71 | + public static function set_hooks_admin(): void |
|
| 72 | + { |
|
| 73 | + if (DbStatus::isOnline()) { |
|
| 74 | + // Create an Order. |
|
| 75 | + add_action('wp_ajax_eeaPPCCreateOrder', [__CLASS__, 'createOrderRequest']); |
|
| 76 | + add_action('wp_ajax_nopriv_eeaPPCCreateOrder', [__CLASS__, 'createOrderRequest']); |
|
| 77 | + // Log errors from the JS side. |
|
| 78 | + add_action('wp_ajax_eeaPPCommerceLogError', [__CLASS__, 'logJsError']); |
|
| 79 | + add_action('wp_ajax_nopriv_eeaPPCommerceLogError', [__CLASS__, 'logJsError']); |
|
| 80 | + // Don't load PM in the admin if not Connected. |
|
| 81 | + add_filter( |
|
| 82 | + 'FHEE__EEM_Payment_Method__get_all_for_transaction__payment_methods', |
|
| 83 | + [__CLASS__, 'filterPaymentMethods'], |
|
| 84 | + 100 |
|
| 85 | + ); |
|
| 86 | + } |
|
| 87 | + } |
|
| 88 | + |
|
| 89 | + |
|
| 90 | + /** |
|
| 91 | + * Create the order and return its data as JSON. |
|
| 92 | + * (AJAX) |
|
| 93 | + * |
|
| 94 | + * @return void |
|
| 95 | + * @throws EE_Error |
|
| 96 | + * @throws ReflectionException |
|
| 97 | + */ |
|
| 98 | + public static function createOrderRequest(): void |
|
| 99 | + { |
|
| 100 | + $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
| 101 | + $post_params = EED_Module::getRequest()->postParams(); |
|
| 102 | + if (! $paypal_pm instanceof EE_Payment_Method) { |
|
| 103 | + PayPalLogger::errorLogAndExit( |
|
| 104 | + esc_html__('Related payment method not found (create Order).', 'event_espresso'), |
|
| 105 | + $post_params |
|
| 106 | + ); |
|
| 107 | + } |
|
| 108 | + $transaction = EED_PayPalCommerce::getTransaction(); |
|
| 109 | + $billing_info = $post_params['billing_info'] ?? []; |
|
| 110 | + if ($billing_info) { |
|
| 111 | + $billing_info_decoded = json_decode(stripslashes($billing_info), true); |
|
| 112 | + $billing_info = is_array($billing_info_decoded) ? $billing_info_decoded : []; |
|
| 113 | + } |
|
| 114 | + if (! $transaction) { |
|
| 115 | + PayPalLogger::errorLogAndExit( |
|
| 116 | + esc_html__('Transaction info not found.', 'event_espresso'), |
|
| 117 | + $post_params, |
|
| 118 | + $paypal_pm |
|
| 119 | + ); |
|
| 120 | + } |
|
| 121 | + $order_data = EED_PayPalCommerce::createOrder($transaction, $billing_info, $paypal_pm); |
|
| 122 | + wp_send_json($order_data); |
|
| 123 | + } |
|
| 124 | + |
|
| 125 | + |
|
| 126 | + /** |
|
| 127 | + * Create a new Order using the PP API. |
|
| 128 | + * |
|
| 129 | + * @param EE_Transaction $transaction |
|
| 130 | + * @param array $billing_info |
|
| 131 | + * @param EE_Payment_Method $paypal_pm |
|
| 132 | + * @return array |
|
| 133 | + * @throws EE_Error |
|
| 134 | + * @throws ReflectionException |
|
| 135 | + */ |
|
| 136 | + public static function createOrder( |
|
| 137 | + EE_Transaction $transaction, |
|
| 138 | + array $billing_info, |
|
| 139 | + EE_Payment_Method $paypal_pm |
|
| 140 | + ): array { |
|
| 141 | + $create_order_api = EED_PayPalCommerce::getCreateOrderApi($transaction, $billing_info, $paypal_pm); |
|
| 142 | + if (! $create_order_api instanceof CreateOrder) { |
|
| 143 | + return [ |
|
| 144 | + 'error' => 'CREATE_ORDER_API_FAULT', |
|
| 145 | + 'message' => esc_html__('The Create Order API request fault.', 'event_espresso'), |
|
| 146 | + ]; |
|
| 147 | + } |
|
| 148 | + $payment = EEG_PayPalCheckout::createPayment($transaction, $paypal_pm); |
|
| 149 | + $order = $create_order_api->create(); |
|
| 150 | + if (isset($order['error'])) { |
|
| 151 | + EEG_PayPalCheckout::updatePaymentStatus($payment, EEM_Payment::status_id_failed, $order, $order['error']); |
|
| 152 | + return [ |
|
| 153 | + 'error' => 'CREATE_ORDER_API_RESPONSE_ERROR', |
|
| 154 | + 'message' => $order['message'], |
|
| 155 | + ]; |
|
| 156 | + } |
|
| 157 | + return [ |
|
| 158 | + 'pp_order_id' => $order['id'], |
|
| 159 | + ]; |
|
| 160 | + } |
|
| 161 | + |
|
| 162 | + |
|
| 163 | + /** |
|
| 164 | + * Create a new Order using the PP API. |
|
| 165 | + * |
|
| 166 | + * @param EE_Transaction $transaction |
|
| 167 | + * @param EE_Payment_Method $paypal_pm |
|
| 168 | + * @param string $order_id |
|
| 169 | + * @return array |
|
| 170 | + * @throws EE_Error |
|
| 171 | + * @throws ReflectionException |
|
| 172 | + */ |
|
| 173 | + public static function captureOrder( |
|
| 174 | + EE_Transaction $transaction, |
|
| 175 | + EE_Payment_Method $paypal_pm, |
|
| 176 | + string $order_id |
|
| 177 | + ): array { |
|
| 178 | + $capture_order_api = EED_PayPalCommerce::getCaptureOrderApi($transaction, $paypal_pm, $order_id); |
|
| 179 | + if (! $capture_order_api instanceof CaptureOrder) { |
|
| 180 | + return [ |
|
| 181 | + 'error' => 'CAPTURE_ORDER_API_FAULT', |
|
| 182 | + 'message' => esc_html__('A capture Order API request fault.', 'event_espresso'), |
|
| 183 | + ]; |
|
| 184 | + } |
|
| 185 | + return $capture_order_api->capture(); |
|
| 186 | + } |
|
| 187 | + |
|
| 188 | + |
|
| 189 | + /** |
|
| 190 | + * Get Order Details using the PP API. |
|
| 191 | + * |
|
| 192 | + * @param string $order_id |
|
| 193 | + * @param EE_Transaction $transaction |
|
| 194 | + * @param EE_Payment_Method $paypal_pm |
|
| 195 | + * @return array |
|
| 196 | + * @throws EE_Error |
|
| 197 | + * @throws ReflectionException |
|
| 198 | + */ |
|
| 199 | + public static function getOrderDetails( |
|
| 200 | + string $order_id, |
|
| 201 | + EE_Transaction $transaction, |
|
| 202 | + EE_Payment_Method $paypal_pm |
|
| 203 | + ): array { |
|
| 204 | + $order_details = EED_PayPalCommerce::getOrderDetailsApi($order_id, $transaction, $paypal_pm); |
|
| 205 | + if (! $order_details instanceof OrderDetails) { |
|
| 206 | + return [ |
|
| 207 | + 'error' => 'ORDER_DETAILS_API_FAULT', |
|
| 208 | + 'message' => esc_html__('Get Order Details API request fault.', 'event_espresso'), |
|
| 209 | + ]; |
|
| 210 | + } |
|
| 211 | + return $order_details->get(); |
|
| 212 | + } |
|
| 213 | + |
|
| 214 | + |
|
| 215 | + /** |
|
| 216 | + * Initialize and return Create Order API. |
|
| 217 | + * |
|
| 218 | + * @param EE_Transaction $transaction |
|
| 219 | + * @param array $billing_info |
|
| 220 | + * @param EE_Payment_Method $paypal_pm |
|
| 221 | + * @return CreateOrder|null |
|
| 222 | + * @throws EE_Error |
|
| 223 | + * @throws ReflectionException |
|
| 224 | + */ |
|
| 225 | + public static function getCreateOrderApi( |
|
| 226 | + EE_Transaction $transaction, |
|
| 227 | + array $billing_info, |
|
| 228 | + EE_Payment_Method $paypal_pm |
|
| 229 | + ): ?CreateOrder { |
|
| 230 | + $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
|
| 231 | + if (! $paypal_api instanceof PayPalApi) { |
|
| 232 | + return null; |
|
| 233 | + } |
|
| 234 | + return LoaderFactory::getNew(CreateOrder::class, [$paypal_api, $transaction, $billing_info]); |
|
| 235 | + } |
|
| 236 | + |
|
| 237 | + |
|
| 238 | + /** |
|
| 239 | + * Initialize and return Capture Order API. |
|
| 240 | + * |
|
| 241 | + * @param EE_Transaction $transaction |
|
| 242 | + * @param EE_Payment_Method $paypal_pm |
|
| 243 | + * @param string $order_id |
|
| 244 | + * @return CaptureOrder|null |
|
| 245 | + * @throws EE_Error |
|
| 246 | + * @throws ReflectionException |
|
| 247 | + */ |
|
| 248 | + public static function getCaptureOrderApi( |
|
| 249 | + EE_Transaction $transaction, |
|
| 250 | + EE_Payment_Method $paypal_pm, |
|
| 251 | + string $order_id |
|
| 252 | + ): ?CaptureOrder { |
|
| 253 | + $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
|
| 254 | + if (! $paypal_api instanceof PayPalApi) { |
|
| 255 | + return null; |
|
| 256 | + } |
|
| 257 | + return LoaderFactory::getNew(CaptureOrder::class, [$paypal_api, $transaction, $order_id]); |
|
| 258 | + } |
|
| 259 | + |
|
| 260 | + |
|
| 261 | + /** |
|
| 262 | + * Initialize and return Order Details API. |
|
| 263 | + * |
|
| 264 | + * @param EE_Transaction $transaction |
|
| 265 | + * @param EE_Payment_Method $paypal_pm |
|
| 266 | + * @param string $order_id |
|
| 267 | + * @return OrderDetails|null |
|
| 268 | + * @throws EE_Error |
|
| 269 | + * @throws ReflectionException |
|
| 270 | + */ |
|
| 271 | + public static function getOrderDetailsApi( |
|
| 272 | + string $order_id, |
|
| 273 | + EE_Transaction $transaction, |
|
| 274 | + EE_Payment_Method $paypal_pm |
|
| 275 | + ): ?OrderDetails { |
|
| 276 | + $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
|
| 277 | + if (! $paypal_api instanceof PayPalApi) { |
|
| 278 | + return null; |
|
| 279 | + } |
|
| 280 | + return LoaderFactory::getNew(OrderDetails::class, [$paypal_api, $order_id, $transaction]); |
|
| 281 | + } |
|
| 282 | + |
|
| 283 | + |
|
| 284 | + /** |
|
| 285 | + * Return a PayPal API object, or false on failure. |
|
| 286 | + * |
|
| 287 | + * @param EE_Payment_Method $paypal_pm |
|
| 288 | + * @return PayPalApi|null |
|
| 289 | + * @throws EE_Error |
|
| 290 | + * @throws ReflectionException |
|
| 291 | + */ |
|
| 292 | + public static function getPayPalApi(EE_Payment_Method $paypal_pm): ?PayPalApi |
|
| 293 | + { |
|
| 294 | + // Try getting the first party credentials to determine if this is a first party integration that's active. |
|
| 295 | + $client_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_CLIENT_ID); |
|
| 296 | + $client_secret = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_CLIENT_SECRET); |
|
| 297 | + $bn_code = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_BN_CODE); |
|
| 298 | + if ($client_id && $client_secret) { |
|
| 299 | + return new FirstPartyPayPalApi($client_id, $client_secret, $bn_code, $paypal_pm->debug_mode()); |
|
| 300 | + } |
|
| 301 | + // Third party integration credentials: |
|
| 302 | + $access_token = EED_PayPalOnboard::getPartnerAccessToken($paypal_pm); |
|
| 303 | + if (! $access_token || ! $bn_code) { |
|
| 304 | + return null; |
|
| 305 | + } |
|
| 306 | + $partner_client_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_PARTNER_CLIENT_ID) ?: ''; |
|
| 307 | + $payer_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_SELLER_MERCHANT_ID) ?: ''; |
|
| 308 | + return new ThirdPartyPayPalApi( |
|
| 309 | + $access_token, |
|
| 310 | + $bn_code, |
|
| 311 | + $partner_client_id, |
|
| 312 | + $payer_id, |
|
| 313 | + $paypal_pm->debug_mode() |
|
| 314 | + ); |
|
| 315 | + } |
|
| 316 | + |
|
| 317 | + |
|
| 318 | + /** |
|
| 319 | + * Requests a client token. |
|
| 320 | + * |
|
| 321 | + * @param EE_Payment_Method $paypal_pm |
|
| 322 | + * @return array |
|
| 323 | + * @throws EE_Error |
|
| 324 | + * @throws ReflectionException |
|
| 325 | + */ |
|
| 326 | + public static function requestClientToken(EE_Payment_Method $paypal_pm): array |
|
| 327 | + { |
|
| 328 | + $error = ['error' => 'GET_CLIENT_TOKEN_FAULT']; |
|
| 329 | + $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
|
| 330 | + if (! $paypal_api instanceof PayPalApi) { |
|
| 331 | + $error['message'] = esc_html__('Got an error while trying to get the client token.', 'event_espresso'); |
|
| 332 | + return $error; |
|
| 333 | + } |
|
| 334 | + $client_token_api = new ClientToken($paypal_api, $paypal_pm->debug_mode()); |
|
| 335 | + $client_token = $client_token_api->getToken(); |
|
| 336 | + if (isset($client_token['error'])) { |
|
| 337 | + return $client_token; |
|
| 338 | + } |
|
| 339 | + if (empty($client_token)) { |
|
| 340 | + $error['message'] = esc_html__('Client token not valid.', 'event_espresso'); |
|
| 341 | + return $error; |
|
| 342 | + } |
|
| 343 | + return $client_token; |
|
| 344 | + } |
|
| 345 | + |
|
| 346 | + |
|
| 347 | + /** |
|
| 348 | + * Retrieve the payment method from the provided data. |
|
| 349 | + * |
|
| 350 | + * @return EE_Transaction|null |
|
| 351 | + */ |
|
| 352 | + public static function getTransaction(): ?EE_Transaction |
|
| 353 | + { |
|
| 354 | + try { |
|
| 355 | + $txn_id = EED_Module::getRequest()->getRequestParam('txn_id', 0, DataType::INT); |
|
| 356 | + $transaction = EEM_Transaction::instance()->get_one_by_ID($txn_id); |
|
| 357 | + if (! $transaction instanceof EE_Transaction) { |
|
| 358 | + PayPalLogger::errorLog( |
|
| 359 | + esc_html__('No transaction found by ID:', 'event_espresso'), |
|
| 360 | + EED_Module::getRequest()->postParams() |
|
| 361 | + ); |
|
| 362 | + return null; |
|
| 363 | + } |
|
| 364 | + } catch (Exception $e) { |
|
| 365 | + return null; |
|
| 366 | + } |
|
| 367 | + return $transaction; |
|
| 368 | + } |
|
| 369 | + |
|
| 370 | + |
|
| 371 | + /** |
|
| 372 | + * Return a PayPal API object, or false on failure. |
|
| 373 | + * |
|
| 374 | + * @param EE_Payment_Method $paypal_pm |
|
| 375 | + * @return bool |
|
| 376 | + * @throws EE_Error |
|
| 377 | + * @throws ReflectionException |
|
| 378 | + */ |
|
| 379 | + public static function isThirdParty(EE_Payment_Method $paypal_pm): bool |
|
| 380 | + { |
|
| 381 | + $pp_meta_data = PayPalExtraMetaManager::getAllData($paypal_pm); |
|
| 382 | + return ! empty($pp_meta_data[ Domain::META_KEY_SELLER_MERCHANT_ID ]) |
|
| 383 | + && ! empty($pp_meta_data[ Domain::META_KEY_ACCESS_TOKEN ]); |
|
| 384 | + } |
|
| 385 | + |
|
| 386 | + |
|
| 387 | + /** |
|
| 388 | + * Retrieve the payment method from the provided data. |
|
| 389 | + * |
|
| 390 | + * @return EE_Payment_Method|null |
|
| 391 | + */ |
|
| 392 | + public static function getPaymentMethod(): ?EE_Payment_Method |
|
| 393 | + { |
|
| 394 | + try { |
|
| 395 | + // Check if all required parameters are present. |
|
| 396 | + $pm_slug = EED_Module::getRequest()->getRequestParam('payment_method'); |
|
| 397 | + $payment_method = EEM_Payment_Method::instance()->get_one_by_slug($pm_slug); |
|
| 398 | + if ($payment_method instanceof EE_Payment_Method) { |
|
| 399 | + return $payment_method; |
|
| 400 | + } |
|
| 401 | + } catch (Exception $e) { |
|
| 402 | + return null; |
|
| 403 | + } |
|
| 404 | + return null; |
|
| 405 | + } |
|
| 406 | + |
|
| 407 | + |
|
| 408 | + /** |
|
| 409 | + * Log JS error. |
|
| 410 | + * |
|
| 411 | + * @return void |
|
| 412 | + */ |
|
| 413 | + public static function logJsError(): void |
|
| 414 | + { |
|
| 415 | + // Default to the "first" PayPal checkout PM. |
|
| 416 | + $request = EED_Module::getRequest(); |
|
| 417 | + $pm_slug = $request->getRequestParam('pm_slug', Domain::PM_SLUG); |
|
| 418 | + $payment_method = null; |
|
| 419 | + $txn_id = 'unknown'; |
|
| 420 | + try { |
|
| 421 | + $payment_method = EEM_Payment_Method::instance()->get_one_of_type($pm_slug); |
|
| 422 | + $txn_id = sanitize_text_field($request->getRequestParam('txn_id', '-')); |
|
| 423 | + } catch (Exception $e) { |
|
| 424 | + // Don't throw out anything, log at least something. |
|
| 425 | + } |
|
| 426 | + $transaction = EED_PayPalCommerce::getTransaction(); |
|
| 427 | + PayPalLogger::errorLog( |
|
| 428 | + "JS Error on transaction: $txn_id", |
|
| 429 | + $request->postParams(), |
|
| 430 | + $payment_method, |
|
| 431 | + false, |
|
| 432 | + $transaction |
|
| 433 | + ); |
|
| 434 | + } |
|
| 435 | + |
|
| 436 | + |
|
| 437 | + /** |
|
| 438 | + * Filter the Payment Methods list. |
|
| 439 | + * if needed, this filter can also supply the $transaction and $scope parameters. |
|
| 440 | + * |
|
| 441 | + * @param EE_Payment_Method[] $payment_methods |
|
| 442 | + * @return array |
|
| 443 | + * @throws EE_Error |
|
| 444 | + * @throws ReflectionException |
|
| 445 | + */ |
|
| 446 | + public static function filterPaymentMethods(array $payment_methods): array |
|
| 447 | + { |
|
| 448 | + // Don't allow this PM on the checkout page if not Connected. |
|
| 449 | + foreach ($payment_methods as $key => $pm) { |
|
| 450 | + // It is a PayPal Commerce payment method. Check if it's connected. If not - remove from the list. |
|
| 451 | + if (str_contains($pm->slug(), Domain::PM_SLUG) && ! EED_PayPalOnboard::isOnboard($pm)) { |
|
| 452 | + unset($payment_methods[ $key ]); |
|
| 453 | + } |
|
| 454 | + } |
|
| 455 | + return $payment_methods; |
|
| 456 | + } |
|
| 457 | + |
|
| 458 | + |
|
| 459 | + /** |
|
| 460 | + * Get all active states. |
|
| 461 | + * |
|
| 462 | + * @return array |
|
| 463 | + * @throws EE_Error |
|
| 464 | + * @throws ReflectionException |
|
| 465 | + */ |
|
| 466 | + public static function getActiveStates(): array |
|
| 467 | + { |
|
| 468 | + $state_options = []; |
|
| 469 | + $states = EEM_State::instance()->get_all_active_states(); |
|
| 470 | + if (! empty($states)) { |
|
| 471 | + foreach ($states as $numeral => $state) { |
|
| 472 | + if ($state instanceof EE_State) { |
|
| 473 | + $state_options[ $numeral ] = $state->abbrev(); |
|
| 474 | + } |
|
| 475 | + } |
|
| 476 | + } |
|
| 477 | + return $state_options; |
|
| 478 | + } |
|
| 479 | 479 | } |
@@ -99,7 +99,7 @@ discard block |
||
| 99 | 99 | { |
| 100 | 100 | $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
| 101 | 101 | $post_params = EED_Module::getRequest()->postParams(); |
| 102 | - if (! $paypal_pm instanceof EE_Payment_Method) { |
|
| 102 | + if ( ! $paypal_pm instanceof EE_Payment_Method) { |
|
| 103 | 103 | PayPalLogger::errorLogAndExit( |
| 104 | 104 | esc_html__('Related payment method not found (create Order).', 'event_espresso'), |
| 105 | 105 | $post_params |
@@ -111,7 +111,7 @@ discard block |
||
| 111 | 111 | $billing_info_decoded = json_decode(stripslashes($billing_info), true); |
| 112 | 112 | $billing_info = is_array($billing_info_decoded) ? $billing_info_decoded : []; |
| 113 | 113 | } |
| 114 | - if (! $transaction) { |
|
| 114 | + if ( ! $transaction) { |
|
| 115 | 115 | PayPalLogger::errorLogAndExit( |
| 116 | 116 | esc_html__('Transaction info not found.', 'event_espresso'), |
| 117 | 117 | $post_params, |
@@ -139,7 +139,7 @@ discard block |
||
| 139 | 139 | EE_Payment_Method $paypal_pm |
| 140 | 140 | ): array { |
| 141 | 141 | $create_order_api = EED_PayPalCommerce::getCreateOrderApi($transaction, $billing_info, $paypal_pm); |
| 142 | - if (! $create_order_api instanceof CreateOrder) { |
|
| 142 | + if ( ! $create_order_api instanceof CreateOrder) { |
|
| 143 | 143 | return [ |
| 144 | 144 | 'error' => 'CREATE_ORDER_API_FAULT', |
| 145 | 145 | 'message' => esc_html__('The Create Order API request fault.', 'event_espresso'), |
@@ -176,7 +176,7 @@ discard block |
||
| 176 | 176 | string $order_id |
| 177 | 177 | ): array { |
| 178 | 178 | $capture_order_api = EED_PayPalCommerce::getCaptureOrderApi($transaction, $paypal_pm, $order_id); |
| 179 | - if (! $capture_order_api instanceof CaptureOrder) { |
|
| 179 | + if ( ! $capture_order_api instanceof CaptureOrder) { |
|
| 180 | 180 | return [ |
| 181 | 181 | 'error' => 'CAPTURE_ORDER_API_FAULT', |
| 182 | 182 | 'message' => esc_html__('A capture Order API request fault.', 'event_espresso'), |
@@ -202,7 +202,7 @@ discard block |
||
| 202 | 202 | EE_Payment_Method $paypal_pm |
| 203 | 203 | ): array { |
| 204 | 204 | $order_details = EED_PayPalCommerce::getOrderDetailsApi($order_id, $transaction, $paypal_pm); |
| 205 | - if (! $order_details instanceof OrderDetails) { |
|
| 205 | + if ( ! $order_details instanceof OrderDetails) { |
|
| 206 | 206 | return [ |
| 207 | 207 | 'error' => 'ORDER_DETAILS_API_FAULT', |
| 208 | 208 | 'message' => esc_html__('Get Order Details API request fault.', 'event_espresso'), |
@@ -228,7 +228,7 @@ discard block |
||
| 228 | 228 | EE_Payment_Method $paypal_pm |
| 229 | 229 | ): ?CreateOrder { |
| 230 | 230 | $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
| 231 | - if (! $paypal_api instanceof PayPalApi) { |
|
| 231 | + if ( ! $paypal_api instanceof PayPalApi) { |
|
| 232 | 232 | return null; |
| 233 | 233 | } |
| 234 | 234 | return LoaderFactory::getNew(CreateOrder::class, [$paypal_api, $transaction, $billing_info]); |
@@ -251,7 +251,7 @@ discard block |
||
| 251 | 251 | string $order_id |
| 252 | 252 | ): ?CaptureOrder { |
| 253 | 253 | $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
| 254 | - if (! $paypal_api instanceof PayPalApi) { |
|
| 254 | + if ( ! $paypal_api instanceof PayPalApi) { |
|
| 255 | 255 | return null; |
| 256 | 256 | } |
| 257 | 257 | return LoaderFactory::getNew(CaptureOrder::class, [$paypal_api, $transaction, $order_id]); |
@@ -274,7 +274,7 @@ discard block |
||
| 274 | 274 | EE_Payment_Method $paypal_pm |
| 275 | 275 | ): ?OrderDetails { |
| 276 | 276 | $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
| 277 | - if (! $paypal_api instanceof PayPalApi) { |
|
| 277 | + if ( ! $paypal_api instanceof PayPalApi) { |
|
| 278 | 278 | return null; |
| 279 | 279 | } |
| 280 | 280 | return LoaderFactory::getNew(OrderDetails::class, [$paypal_api, $order_id, $transaction]); |
@@ -300,7 +300,7 @@ discard block |
||
| 300 | 300 | } |
| 301 | 301 | // Third party integration credentials: |
| 302 | 302 | $access_token = EED_PayPalOnboard::getPartnerAccessToken($paypal_pm); |
| 303 | - if (! $access_token || ! $bn_code) { |
|
| 303 | + if ( ! $access_token || ! $bn_code) { |
|
| 304 | 304 | return null; |
| 305 | 305 | } |
| 306 | 306 | $partner_client_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_PARTNER_CLIENT_ID) ?: ''; |
@@ -327,7 +327,7 @@ discard block |
||
| 327 | 327 | { |
| 328 | 328 | $error = ['error' => 'GET_CLIENT_TOKEN_FAULT']; |
| 329 | 329 | $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
| 330 | - if (! $paypal_api instanceof PayPalApi) { |
|
| 330 | + if ( ! $paypal_api instanceof PayPalApi) { |
|
| 331 | 331 | $error['message'] = esc_html__('Got an error while trying to get the client token.', 'event_espresso'); |
| 332 | 332 | return $error; |
| 333 | 333 | } |
@@ -354,7 +354,7 @@ discard block |
||
| 354 | 354 | try { |
| 355 | 355 | $txn_id = EED_Module::getRequest()->getRequestParam('txn_id', 0, DataType::INT); |
| 356 | 356 | $transaction = EEM_Transaction::instance()->get_one_by_ID($txn_id); |
| 357 | - if (! $transaction instanceof EE_Transaction) { |
|
| 357 | + if ( ! $transaction instanceof EE_Transaction) { |
|
| 358 | 358 | PayPalLogger::errorLog( |
| 359 | 359 | esc_html__('No transaction found by ID:', 'event_espresso'), |
| 360 | 360 | EED_Module::getRequest()->postParams() |
@@ -379,8 +379,8 @@ discard block |
||
| 379 | 379 | public static function isThirdParty(EE_Payment_Method $paypal_pm): bool |
| 380 | 380 | { |
| 381 | 381 | $pp_meta_data = PayPalExtraMetaManager::getAllData($paypal_pm); |
| 382 | - return ! empty($pp_meta_data[ Domain::META_KEY_SELLER_MERCHANT_ID ]) |
|
| 383 | - && ! empty($pp_meta_data[ Domain::META_KEY_ACCESS_TOKEN ]); |
|
| 382 | + return ! empty($pp_meta_data[Domain::META_KEY_SELLER_MERCHANT_ID]) |
|
| 383 | + && ! empty($pp_meta_data[Domain::META_KEY_ACCESS_TOKEN]); |
|
| 384 | 384 | } |
| 385 | 385 | |
| 386 | 386 | |
@@ -449,7 +449,7 @@ discard block |
||
| 449 | 449 | foreach ($payment_methods as $key => $pm) { |
| 450 | 450 | // It is a PayPal Commerce payment method. Check if it's connected. If not - remove from the list. |
| 451 | 451 | if (str_contains($pm->slug(), Domain::PM_SLUG) && ! EED_PayPalOnboard::isOnboard($pm)) { |
| 452 | - unset($payment_methods[ $key ]); |
|
| 452 | + unset($payment_methods[$key]); |
|
| 453 | 453 | } |
| 454 | 454 | } |
| 455 | 455 | return $payment_methods; |
@@ -467,10 +467,10 @@ discard block |
||
| 467 | 467 | { |
| 468 | 468 | $state_options = []; |
| 469 | 469 | $states = EEM_State::instance()->get_all_active_states(); |
| 470 | - if (! empty($states)) { |
|
| 470 | + if ( ! empty($states)) { |
|
| 471 | 471 | foreach ($states as $numeral => $state) { |
| 472 | 472 | if ($state instanceof EE_State) { |
| 473 | - $state_options[ $numeral ] = $state->abbrev(); |
|
| 473 | + $state_options[$numeral] = $state->abbrev(); |
|
| 474 | 474 | } |
| 475 | 475 | } |
| 476 | 476 | } |
@@ -20,736 +20,736 @@ |
||
| 20 | 20 | */ |
| 21 | 21 | class EED_PayPalOnboard extends EED_Module |
| 22 | 22 | { |
| 23 | - /** |
|
| 24 | - * @return EED_Module |
|
| 25 | - * @throws EE_Error |
|
| 26 | - * @throws ReflectionException |
|
| 27 | - */ |
|
| 28 | - public static function instance(): EED_Module |
|
| 29 | - { |
|
| 30 | - return parent::get_instance(__CLASS__); |
|
| 31 | - } |
|
| 32 | - |
|
| 33 | - |
|
| 34 | - /** |
|
| 35 | - * Run - initial module setup. |
|
| 36 | - * |
|
| 37 | - * @param WP $WP |
|
| 38 | - * @return void |
|
| 39 | - */ |
|
| 40 | - public function run($WP) |
|
| 41 | - { |
|
| 42 | - } |
|
| 43 | - |
|
| 44 | - |
|
| 45 | - /** |
|
| 46 | - * For hooking into EE Admin Core and other modules. |
|
| 47 | - * |
|
| 48 | - * @return void |
|
| 49 | - */ |
|
| 50 | - public static function set_hooks_admin(): void |
|
| 51 | - { |
|
| 52 | - // check for the most basic EE capability |
|
| 53 | - /** @var EE_Capabilities $capabilities */ |
|
| 54 | - $capabilities = LoaderFactory::getLoader()->getShared(EE_Capabilities::class); |
|
| 55 | - if ( |
|
| 56 | - DbStatus::isOffline() |
|
| 57 | - || ! $capabilities->current_user_can('ee_manage_gateways', 'manage-paypal-onboarding') |
|
| 58 | - ) { |
|
| 59 | - return; |
|
| 60 | - } |
|
| 61 | - // Get onboarding URL. |
|
| 62 | - add_action('wp_ajax_eeaPpGetOnboardingUrl', [__CLASS__, 'getOnboardingUrl']); |
|
| 63 | - // Catch the return/redirect from PayPal onboarding page. |
|
| 64 | - add_action('init', [__CLASS__, 'updateOnboardingStatus']); |
|
| 65 | - // Return the connection/onboard status. |
|
| 66 | - add_action('wp_ajax_eeaPpGetOnboardStatus', [__CLASS__, 'getOnboardStatus']); |
|
| 67 | - // Revoke access. |
|
| 68 | - add_action('wp_ajax_eeaPpOffboard', [__CLASS__, 'offboard']); |
|
| 69 | - // Clear all metadata. |
|
| 70 | - add_action('wp_ajax_eeaPpClearMetaData', [__CLASS__, 'clearMetaData']); |
|
| 71 | - // Admin notice. |
|
| 72 | - add_action('admin_init', [__CLASS__, 'adminNotice']); |
|
| 73 | - } |
|
| 74 | - |
|
| 75 | - |
|
| 76 | - /** |
|
| 77 | - * Get the onboarding URL. |
|
| 78 | - * (AJAX) |
|
| 79 | - * |
|
| 80 | - * @return void |
|
| 81 | - */ |
|
| 82 | - public static function getOnboardingUrl(): void |
|
| 83 | - { |
|
| 84 | - $signup_link = ''; |
|
| 85 | - try { |
|
| 86 | - $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
| 87 | - if (! $paypal_pm instanceof EE_Payment_Method) { |
|
| 88 | - PayPalLogger::errorLogAndExit( |
|
| 89 | - esc_html__('No payment method.', 'event_espresso'), |
|
| 90 | - EED_Module::getRequest()->postParams(), |
|
| 91 | - $paypal_pm |
|
| 92 | - ); |
|
| 93 | - } |
|
| 94 | - PayPalExtraMetaManager::updateDebugMode($paypal_pm, EED_Module::getRequest()->postParams()); |
|
| 95 | - // Just get a new onboarding URL every time. |
|
| 96 | - $signup_link = EED_PayPalOnboard::requestOnboardingUrl($paypal_pm); |
|
| 97 | - if (! $signup_link) { |
|
| 98 | - $err_msg = esc_html__('Error! Could not generate a sign-up link.', 'event_espresso'); |
|
| 99 | - PayPalLogger::errorLogAndExit($err_msg, ['signup_link' => $signup_link], $paypal_pm); |
|
| 100 | - } |
|
| 101 | - } catch (Exception $e) { |
|
| 102 | - PayPalLogger::errorLogAndExit($e->getMessage(), ['trace' => $e->getTrace()]); |
|
| 103 | - } |
|
| 104 | - // Is it empty (can happen if we didn't get the URL through the API). |
|
| 105 | - $signup_link = $signup_link ? $signup_link . '?&displayMode=minibrowser' : '#'; |
|
| 106 | - wp_send_json( |
|
| 107 | - [ |
|
| 108 | - 'signup_link' => $signup_link, |
|
| 109 | - ] |
|
| 110 | - ); |
|
| 111 | - } |
|
| 112 | - |
|
| 113 | - |
|
| 114 | - /** |
|
| 115 | - * Request the sign-up link from PayPal. |
|
| 116 | - * |
|
| 117 | - * @param EE_Payment_Method $paypal_pm |
|
| 118 | - * @param bool $one_time_request |
|
| 119 | - * @return string |
|
| 120 | - * @throws EE_Error |
|
| 121 | - * @throws Exception |
|
| 122 | - */ |
|
| 123 | - public static function requestOnboardingUrl(EE_Payment_Method $paypal_pm, bool $one_time_request = false): string |
|
| 124 | - { |
|
| 125 | - $signup_link = ''; |
|
| 126 | - // Get the access token. |
|
| 127 | - $access_token = EED_PayPalOnboard::getPartnerAccessToken($paypal_pm); |
|
| 128 | - if (! $access_token) { |
|
| 129 | - $err_msg = esc_html__('Error! No access token.', 'event_espresso'); |
|
| 130 | - PayPalLogger::errorLog($err_msg, ['access_token' => $access_token], $paypal_pm); |
|
| 131 | - return ''; |
|
| 132 | - } |
|
| 133 | - // Request the access token. |
|
| 134 | - $body_params = EED_PayPalOnboard::signupLinkRequestBody($paypal_pm); |
|
| 135 | - $bn_code = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_BN_CODE); |
|
| 136 | - $post_params = [ |
|
| 137 | - 'method' => 'POST', |
|
| 138 | - 'headers' => [ |
|
| 139 | - 'User-Agent' => sanitize_text_field($_SERVER['HTTP_USER_AGENT']), |
|
| 140 | - 'Content-Type' => 'application/json', |
|
| 141 | - 'Authorization' => 'Bearer ' . $access_token, |
|
| 142 | - 'PayPal-Partner-Attribution-Id' => $bn_code, |
|
| 143 | - ], |
|
| 144 | - 'body' => $body_params, |
|
| 145 | - ]; |
|
| 146 | - $request_url = Domain::getPayPalApiUrl($paypal_pm) . '/v2/customer/partner-referrals'; |
|
| 147 | - $response = EED_PayPalOnboard::sendRequest($paypal_pm, $request_url, $post_params); |
|
| 148 | - // Check the data we received. |
|
| 149 | - if (isset($response['error']) || empty($response['links'])) { |
|
| 150 | - // Did the original access token get replaced by any chance ? |
|
| 151 | - if ( |
|
| 152 | - ! $one_time_request |
|
| 153 | - && ! empty($response['message']) |
|
| 154 | - && $response['message'] === 'Access Token not found in cache' |
|
| 155 | - ) { |
|
| 156 | - // Clear all PM metadata and try getting the access token One more time. |
|
| 157 | - PayPalExtraMetaManager::deleteData($paypal_pm); |
|
| 158 | - PayPalLogger::errorLog( |
|
| 159 | - esc_html__('Removing old metadata before new onboarding.', 'event_espresso'), |
|
| 160 | - $response, |
|
| 161 | - $paypal_pm |
|
| 162 | - ); |
|
| 163 | - return EED_PayPalOnboard::requestOnboardingUrl($paypal_pm, true); |
|
| 164 | - } |
|
| 165 | - $err_msg = esc_html__('Incoming sign-up link parameter validation failed.', 'event_espresso'); |
|
| 166 | - PayPalLogger::errorLog($err_msg, $response, $paypal_pm); |
|
| 167 | - return ''; |
|
| 168 | - } |
|
| 169 | - // Now retrieve that sign-up link. |
|
| 170 | - foreach ($response['links'] as $link) { |
|
| 171 | - if ($link['rel'] === 'action_url') { |
|
| 172 | - $signup_link = $link['href'] ?? ''; |
|
| 173 | - } |
|
| 174 | - } |
|
| 175 | - return $signup_link; |
|
| 176 | - } |
|
| 177 | - |
|
| 178 | - |
|
| 179 | - /** |
|
| 180 | - * Get the return URL. |
|
| 181 | - * |
|
| 182 | - * @param EE_Payment_Method $paypal_pm |
|
| 183 | - * @return string |
|
| 184 | - * @throws Exception |
|
| 185 | - */ |
|
| 186 | - public static function signupLinkRequestBody(EE_Payment_Method $paypal_pm): string |
|
| 187 | - { |
|
| 188 | - $identifier_string = new OneTimeString($paypal_pm->debug_mode()); |
|
| 189 | - $tracking_id = $identifier_string->value(); |
|
| 190 | - $request = LoaderFactory::getLoader()->getShared(RequestInterface::class); |
|
| 191 | - $selected_payment = $request->getRequestParam('selected_payment', 'EXPRESS_CHECKOUT'); |
|
| 192 | - // Save the identifier for future use. |
|
| 193 | - PayPalExtraMetaManager::savePmOption($paypal_pm, Domain::META_KEY_TRACKING_ID, $tracking_id); |
|
| 194 | - // Assemble the return URL. |
|
| 195 | - $return_url = EED_PayPalOnboard::getReturnUrl($paypal_pm, $selected_payment); |
|
| 196 | - return json_encode( |
|
| 197 | - [ |
|
| 198 | - 'tracking_id' => $tracking_id, |
|
| 199 | - 'operations' => [ |
|
| 200 | - [ |
|
| 201 | - 'operation' => 'API_INTEGRATION', |
|
| 202 | - 'api_integration_preference' => [ |
|
| 203 | - 'rest_api_integration' => [ |
|
| 204 | - 'integration_method' => 'PAYPAL', |
|
| 205 | - 'integration_type' => 'THIRD_PARTY', |
|
| 206 | - 'third_party_details' => [ |
|
| 207 | - 'features' => ['PAYMENT', 'REFUND', 'PARTNER_FEE'], |
|
| 208 | - ], |
|
| 209 | - ], |
|
| 210 | - ], |
|
| 211 | - ], |
|
| 212 | - ], |
|
| 213 | - 'products' => [$selected_payment], |
|
| 214 | - 'legal_consents' => [ |
|
| 215 | - [ |
|
| 216 | - 'type' => 'SHARE_DATA_CONSENT', |
|
| 217 | - 'granted' => true, |
|
| 218 | - ], |
|
| 219 | - ], |
|
| 220 | - 'partner_config_override' => [ |
|
| 221 | - 'return_url' => $return_url, |
|
| 222 | - ], |
|
| 223 | - ] |
|
| 224 | - ); |
|
| 225 | - } |
|
| 226 | - |
|
| 227 | - |
|
| 228 | - /** |
|
| 229 | - * Get the return URL. |
|
| 230 | - * |
|
| 231 | - * @param EE_Payment_Method $paypal_pm |
|
| 232 | - * @param string $selected_payment |
|
| 233 | - * @return string |
|
| 234 | - * @throws EE_Error |
|
| 235 | - * @throws ReflectionException |
|
| 236 | - */ |
|
| 237 | - public static function getReturnUrl(EE_Payment_Method $paypal_pm, string $selected_payment = ''): string |
|
| 238 | - { |
|
| 239 | - $wp_nonce = EED_Module::getRequest()->getRequestParam('wp_nonce'); |
|
| 240 | - $nonce = wp_create_nonce(Domain::NONCE_NAME_ONBOARDING_RETURN); |
|
| 241 | - return add_query_arg( |
|
| 242 | - [ |
|
| 243 | - 'page' => 'espresso_payment_settings', |
|
| 244 | - 'webhook_action' => 'eepPpcMerchantOnboard', |
|
| 245 | - 'payment_method' => $paypal_pm->slug(), |
|
| 246 | - '_wpnonce' => $wp_nonce, |
|
| 247 | - 'nonce' => $nonce, |
|
| 248 | - 'selected_payment' => $selected_payment, |
|
| 249 | - Domain::META_KEY_SANDBOX_MODE => $paypal_pm->debug_mode() ? '1' : '0', |
|
| 250 | - ], |
|
| 251 | - admin_url('admin.php') |
|
| 252 | - ); |
|
| 253 | - } |
|
| 254 | - |
|
| 255 | - |
|
| 256 | - /** |
|
| 257 | - * Redirect to the payment method (PP) settings home page. |
|
| 258 | - * |
|
| 259 | - * @return void |
|
| 260 | - */ |
|
| 261 | - public static function redirectToPmSettingsHome(): void |
|
| 262 | - { |
|
| 263 | - $get_params = EED_Module::getRequest()->getParams(); |
|
| 264 | - if (empty($get_params['payment_method'])) { |
|
| 265 | - // Simply do not redirect. |
|
| 266 | - return; |
|
| 267 | - } |
|
| 268 | - $args_to_add = [ |
|
| 269 | - 'page' => 'espresso_payment_settings', |
|
| 270 | - 'payment_method' => $get_params['payment_method'], |
|
| 271 | - ]; |
|
| 272 | - if (isset($get_params['sandbox_mode'])) { |
|
| 273 | - $args_to_add[ Domain::META_KEY_SANDBOX_MODE ] = $get_params['sandbox_mode']; |
|
| 274 | - } |
|
| 275 | - $home_url = add_query_arg($args_to_add, admin_url('admin.php')); |
|
| 276 | - wp_redirect($home_url); |
|
| 277 | - exit; |
|
| 278 | - } |
|
| 279 | - |
|
| 280 | - |
|
| 281 | - /** |
|
| 282 | - * Check user’s onboarding status. |
|
| 283 | - * This will handle the user return from the auth page and also check the status via the API. |
|
| 284 | - * |
|
| 285 | - * @return void |
|
| 286 | - * @throws EE_Error |
|
| 287 | - * @throws ReflectionException |
|
| 288 | - */ |
|
| 289 | - public static function updateOnboardingStatus(): void |
|
| 290 | - { |
|
| 291 | - // Check if this is the webhook from PayPal. |
|
| 292 | - if ( |
|
| 293 | - ! isset($_GET['webhook_action'], $_GET['nonce']) |
|
| 294 | - || $_GET['webhook_action'] !== 'eepPpcMerchantOnboard' |
|
| 295 | - ) { |
|
| 296 | - return; // Ignore. |
|
| 297 | - } |
|
| 298 | - $get_params = EED_Module::getRequest()->getParams(); |
|
| 299 | - // Get the payment method. |
|
| 300 | - $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
| 301 | - // Check the response (GET) parameters. |
|
| 302 | - if (! EED_PayPalOnboard::onboardingStatusResponseValid($get_params, $paypal_pm)) { |
|
| 303 | - // Missing parameters. Can't proceed. |
|
| 304 | - PayPalLogger::errorLog( |
|
| 305 | - esc_html__('Missing required onboarding parameters.', 'event_espresso'), |
|
| 306 | - $get_params, |
|
| 307 | - $paypal_pm |
|
| 308 | - ); |
|
| 309 | - EED_PayPalOnboard::redirectToPmSettingsHome(); |
|
| 310 | - return; |
|
| 311 | - } |
|
| 312 | - // Check on the onboarding status (recommended by PP). |
|
| 313 | - $onboarding_status = EED_PayPalOnboard::trackSellerOnboarding( |
|
| 314 | - $paypal_pm, |
|
| 315 | - $get_params[ Domain::META_KEY_SELLER_MERCHANT_ID ] |
|
| 316 | - ); |
|
| 317 | - if (! isset($onboarding_status['valid']) || ! $onboarding_status['valid']) { |
|
| 318 | - PayPalLogger::errorLog( |
|
| 319 | - $onboarding_status['message'], |
|
| 320 | - array_merge($get_params, $onboarding_status), |
|
| 321 | - $paypal_pm |
|
| 322 | - ); |
|
| 323 | - EED_PayPalOnboard::redirectToPmSettingsHome(); |
|
| 324 | - return; |
|
| 325 | - } |
|
| 326 | - // Start saving the setup and info. |
|
| 327 | - PayPalExtraMetaManager::parseAndSaveOptions($paypal_pm, $onboarding_status, $get_params); |
|
| 328 | - // Save the credentials. |
|
| 329 | - PayPalExtraMetaManager::saveSellerApiCredentials($paypal_pm, $get_params); |
|
| 330 | - // Also clen GET params by redirecting, because PP auto redirects to the return_url on closing the onboarding window. |
|
| 331 | - EED_PayPalOnboard::redirectToPmSettingsHome(); |
|
| 332 | - } |
|
| 333 | - |
|
| 334 | - |
|
| 335 | - /** |
|
| 336 | - * Check if all required parameters for the onboarding status check are present. |
|
| 337 | - * |
|
| 338 | - * @param array $data |
|
| 339 | - * @param mixed $paypal_pm |
|
| 340 | - * @return bool |
|
| 341 | - */ |
|
| 342 | - public static function onboardingStatusResponseValid(array $data, $paypal_pm): bool |
|
| 343 | - { |
|
| 344 | - // Check that we have all the required parameters and the nonce is ok. |
|
| 345 | - if ( |
|
| 346 | - $paypal_pm instanceof EE_Payment_Method |
|
| 347 | - && wp_verify_nonce($data['nonce'], Domain::NONCE_NAME_ONBOARDING_RETURN) |
|
| 348 | - && ! empty($data[ Domain::API_PARAM_PARTNER_ID ]) |
|
| 349 | - && ! empty($data[ Domain::META_KEY_SELLER_MERCHANT_ID ]) |
|
| 350 | - && isset($data[ Domain::API_PARAM_EMAIL_CONFIRMED ]) |
|
| 351 | - ) { |
|
| 352 | - return true; |
|
| 353 | - } |
|
| 354 | - return false; |
|
| 355 | - } |
|
| 356 | - |
|
| 357 | - |
|
| 358 | - /** |
|
| 359 | - * Get partner access token. |
|
| 360 | - * |
|
| 361 | - * @param EE_Payment_Method $paypal_pm |
|
| 362 | - * @return string |
|
| 363 | - * @throws EE_Error |
|
| 364 | - * @throws ReflectionException |
|
| 365 | - */ |
|
| 366 | - public static function getPartnerAccessToken(EE_Payment_Method $paypal_pm): string |
|
| 367 | - { |
|
| 368 | - // Do we have it saved ? |
|
| 369 | - $access_token = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_ACCESS_TOKEN); |
|
| 370 | - // If we don't have it, request/update it. |
|
| 371 | - if (! $access_token) { |
|
| 372 | - return EED_PayPalOnboard::requestPartnerAccessToken($paypal_pm); |
|
| 373 | - } |
|
| 374 | - if (EED_PayPalOnboard::partnerAccessTokenExpired($paypal_pm)) { |
|
| 375 | - return EED_PayPalOnboard::requestPartnerAccessToken($paypal_pm); |
|
| 376 | - } |
|
| 377 | - // Access token is saved as encrypted, but return decrypted. |
|
| 378 | - return $access_token; |
|
| 379 | - } |
|
| 380 | - |
|
| 381 | - |
|
| 382 | - /** |
|
| 383 | - * Get partner access token. |
|
| 384 | - * |
|
| 385 | - * @param EE_Payment_Method $paypal_pm |
|
| 386 | - * @return bool |
|
| 387 | - * @throws EE_Error |
|
| 388 | - * @throws ReflectionException |
|
| 389 | - */ |
|
| 390 | - public static function partnerAccessTokenExpired(EE_Payment_Method $paypal_pm): bool |
|
| 391 | - { |
|
| 392 | - $expires_at = (int) PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_TOKEN_EXPIRES_IN); |
|
| 393 | - if (! $expires_at) { |
|
| 394 | - return true; |
|
| 395 | - } |
|
| 396 | - // Validate the token expiration date. |
|
| 397 | - $minutes_left = round(($expires_at - time()) / 60); |
|
| 398 | - // Count as expired if less than 60 minutes till expiration left. |
|
| 399 | - if ($minutes_left <= 60) { |
|
| 400 | - return true; |
|
| 401 | - } |
|
| 402 | - return false; |
|
| 403 | - } |
|
| 404 | - |
|
| 405 | - |
|
| 406 | - /** |
|
| 407 | - * Request the partner access token from PayPal and save/update it. |
|
| 408 | - * |
|
| 409 | - * @param EE_Payment_Method $paypal_pm |
|
| 410 | - * @return string |
|
| 411 | - * @throws EE_Error |
|
| 412 | - * @throws ReflectionException |
|
| 413 | - */ |
|
| 414 | - public static function requestPartnerAccessToken(EE_Payment_Method $paypal_pm): string |
|
| 415 | - { |
|
| 416 | - $nonce = wp_create_nonce('eea_pp_commerce_get_access_token'); |
|
| 417 | - // Request the access token. |
|
| 418 | - $post_args = [ |
|
| 419 | - 'method' => 'POST', |
|
| 420 | - 'body' => [ |
|
| 421 | - 'nonce' => $nonce, |
|
| 422 | - 'api_version' => 'v1', |
|
| 423 | - Domain::META_KEY_SANDBOX_MODE => $paypal_pm->debug_mode() ? '1' : '0', |
|
| 424 | - ], |
|
| 425 | - ]; |
|
| 426 | - if (defined('LOCAL_MIDDLEMAN_SERVER')) { |
|
| 427 | - $post_args['sslverify'] = Manager::verifySSL(); |
|
| 428 | - } |
|
| 429 | - $post_url = EED_PayPalOnboard::getMiddlemanBaseUrl($paypal_pm) . 'get_token'; |
|
| 430 | - $response = EED_PayPalOnboard::sendRequest($paypal_pm, $post_url, $post_args); |
|
| 431 | - if (isset($response['error'])) { |
|
| 432 | - return ''; |
|
| 433 | - } |
|
| 434 | - // Check the data we received. |
|
| 435 | - if (! EED_PayPalOnboard::partnerTokenResponseValid($response, $paypal_pm)) { |
|
| 436 | - return ''; |
|
| 437 | - } |
|
| 438 | - // If we are here all seems to be ok. Save the token and it's data. |
|
| 439 | - $saved = PayPalExtraMetaManager::savePartnerAccessToken($paypal_pm, $response); |
|
| 440 | - if (! $saved) { |
|
| 441 | - return ''; |
|
| 442 | - } |
|
| 443 | - return $response['access_token']; |
|
| 444 | - } |
|
| 445 | - |
|
| 446 | - |
|
| 447 | - /** |
|
| 448 | - * Request seller onboarding status from PayPal. |
|
| 449 | - * |
|
| 450 | - * @param EE_Payment_Method $paypal_pm |
|
| 451 | - * @param string $merchant_id |
|
| 452 | - * @return array |
|
| 453 | - * @throws EE_Error |
|
| 454 | - * @throws ReflectionException |
|
| 455 | - */ |
|
| 456 | - public static function trackSellerOnboarding(EE_Payment_Method $paypal_pm, string $merchant_id): array |
|
| 457 | - { |
|
| 458 | - $track_onboarding = EED_PayPalOnboard::getTrackOnboardingApi($paypal_pm, $merchant_id); |
|
| 459 | - if (! $track_onboarding instanceof TrackSellerOnboarding) { |
|
| 460 | - return [ |
|
| 461 | - 'error' => 'TRACK_ONBOARDING_FAILED', |
|
| 462 | - 'message' => esc_html__('Failed to track seller onboarding.', 'event_espresso') |
|
| 463 | - ]; |
|
| 464 | - } |
|
| 465 | - return $track_onboarding->isValid(); |
|
| 466 | - } |
|
| 467 | - |
|
| 468 | - |
|
| 469 | - /** |
|
| 470 | - * Returns the Track Seller Onboarding API. |
|
| 471 | - * |
|
| 472 | - * @param EE_Payment_Method $paypal_pm |
|
| 473 | - * @param string $merchant_id |
|
| 474 | - * @return TrackSellerOnboarding|null |
|
| 475 | - * @throws EE_Error |
|
| 476 | - * @throws ReflectionException |
|
| 477 | - */ |
|
| 478 | - public static function getTrackOnboardingApi( |
|
| 479 | - EE_Payment_Method $paypal_pm, |
|
| 480 | - string $merchant_id |
|
| 481 | - ): ?TrackSellerOnboarding { |
|
| 482 | - $partner_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_PARTNER_MERCHANT_ID); |
|
| 483 | - $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
|
| 484 | - if (! $paypal_api instanceof PayPalApi || ! $partner_id) { |
|
| 485 | - return null; |
|
| 486 | - } |
|
| 487 | - return new TrackSellerOnboarding($paypal_api, $partner_id, $merchant_id, $paypal_pm->debug_mode()); |
|
| 488 | - } |
|
| 489 | - |
|
| 490 | - |
|
| 491 | - /** |
|
| 492 | - * Check the onboard status and return the result. |
|
| 493 | - * (AJAX) |
|
| 494 | - * |
|
| 495 | - * @return void |
|
| 496 | - * @throws EE_Error |
|
| 497 | - * @throws ReflectionException |
|
| 498 | - */ |
|
| 499 | - public static function getOnboardStatus(): void |
|
| 500 | - { |
|
| 501 | - $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
| 502 | - if (! $paypal_pm instanceof EE_Payment_Method) { |
|
| 503 | - $err_msg = esc_html__('Could not specify the payment method.', 'event_espresso'); |
|
| 504 | - PayPalLogger::errorLog($err_msg, EED_Module::getRequest()->postParams(), $paypal_pm); |
|
| 505 | - wp_send_json(['on_board' => false]); |
|
| 506 | - } |
|
| 507 | - try { |
|
| 508 | - $seller_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_SELLER_MERCHANT_ID) ?? '--'; |
|
| 509 | - } catch (Exception $e) { |
|
| 510 | - $seller_id = '--'; |
|
| 511 | - PayPalLogger::errorLog($e->getMessage(), ['trace' => $e->getTrace()]); |
|
| 512 | - } |
|
| 513 | - wp_send_json( |
|
| 514 | - [ |
|
| 515 | - 'on_board' => EED_PayPalOnboard::isOnboard($paypal_pm), |
|
| 516 | - 'seller_id' => $seller_id, |
|
| 517 | - ] |
|
| 518 | - ); |
|
| 519 | - } |
|
| 520 | - |
|
| 521 | - |
|
| 522 | - /** |
|
| 523 | - * De-authorize the seller. Remove all API credentials. |
|
| 524 | - * (AJAX) |
|
| 525 | - * |
|
| 526 | - * @return void |
|
| 527 | - * @throws EE_Error |
|
| 528 | - * @throws ReflectionException |
|
| 529 | - */ |
|
| 530 | - public static function offboard(): void |
|
| 531 | - { |
|
| 532 | - $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
| 533 | - EED_PayPalOnboard::validatePmAjax($paypal_pm); |
|
| 534 | - PayPalExtraMetaManager::deleteData($paypal_pm); |
|
| 535 | - PayPalLogger::errorLog( |
|
| 536 | - esc_html__('Offboarding. Removing metadata.', 'event_espresso'), |
|
| 537 | - EED_Module::getRequest()->postParams(), |
|
| 538 | - $paypal_pm |
|
| 539 | - ); |
|
| 540 | - wp_send_json(['success' => true]); |
|
| 541 | - } |
|
| 542 | - |
|
| 543 | - |
|
| 544 | - /** |
|
| 545 | - * Clear all credentials metadata. |
|
| 546 | - * (AJAX) |
|
| 547 | - * |
|
| 548 | - * @return void |
|
| 549 | - * @throws EE_Error |
|
| 550 | - * @throws ReflectionException |
|
| 551 | - */ |
|
| 552 | - public static function clearMetaData(): void |
|
| 553 | - { |
|
| 554 | - $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
| 555 | - EED_PayPalOnboard::validatePmAjax($paypal_pm); |
|
| 556 | - PayPalExtraMetaManager::deleteAllData($paypal_pm); |
|
| 557 | - PayPalLogger::errorLog( |
|
| 558 | - esc_html__('Doing a Reset. Removing all PM settings metadata.', 'event_espresso'), |
|
| 559 | - EED_Module::getRequest()->postParams(), |
|
| 560 | - $paypal_pm |
|
| 561 | - ); |
|
| 562 | - wp_send_json(['success' => true]); |
|
| 563 | - } |
|
| 564 | - |
|
| 565 | - |
|
| 566 | - /** |
|
| 567 | - * Validate the PM instance, returning an ajax response on invalid. |
|
| 568 | - * |
|
| 569 | - * @param $paypal_pm |
|
| 570 | - * @return void |
|
| 571 | - */ |
|
| 572 | - public static function validatePmAjax($paypal_pm): void |
|
| 573 | - { |
|
| 574 | - if (! $paypal_pm instanceof EE_Payment_Method) { |
|
| 575 | - wp_send_json( |
|
| 576 | - [ |
|
| 577 | - 'error' => 'INVALID_PM', |
|
| 578 | - 'message' => esc_html__( |
|
| 579 | - 'Invalid payment method. Please refresh the page and try again.', |
|
| 580 | - 'event_espresso' |
|
| 581 | - ), |
|
| 582 | - ] |
|
| 583 | - ); |
|
| 584 | - } |
|
| 585 | - } |
|
| 586 | - |
|
| 587 | - |
|
| 588 | - /** |
|
| 589 | - * Checks if already onboard. |
|
| 590 | - * |
|
| 591 | - * @param EE_Payment_Method $payment_method |
|
| 592 | - * @return boolean |
|
| 593 | - * @throws EE_Error |
|
| 594 | - * @throws ReflectionException |
|
| 595 | - */ |
|
| 596 | - public static function isOnboard(EE_Payment_Method $payment_method): bool |
|
| 597 | - { |
|
| 598 | - $pp_meta_data = PayPalExtraMetaManager::getAllData($payment_method); |
|
| 599 | - return |
|
| 600 | - ( |
|
| 601 | - // onborded with a third party integration ? |
|
| 602 | - ! empty($pp_meta_data[ Domain::META_KEY_SELLER_MERCHANT_ID ]) |
|
| 603 | - && ! empty($pp_meta_data[ Domain::META_KEY_ACCESS_TOKEN ]) |
|
| 604 | - ) || ( |
|
| 605 | - // or with the first party integration ? |
|
| 606 | - ! empty($pp_meta_data[ Domain::META_KEY_CLIENT_ID ]) |
|
| 607 | - && ! empty($pp_meta_data[ Domain::META_KEY_CLIENT_SECRET ]) |
|
| 608 | - && ! empty($pp_meta_data[ Domain::META_KEY_PAYER_ID ]) |
|
| 609 | - ); |
|
| 610 | - } |
|
| 611 | - |
|
| 612 | - |
|
| 613 | - /** |
|
| 614 | - * Send a request and return a decoded response body. |
|
| 615 | - * |
|
| 616 | - * @param EE_Payment_Method $paypal_pm |
|
| 617 | - * @param string $request_url |
|
| 618 | - * @param array $request_args |
|
| 619 | - * @return array |
|
| 620 | - */ |
|
| 621 | - public static function sendRequest(EE_Payment_Method $paypal_pm, string $request_url, array $request_args): array |
|
| 622 | - { |
|
| 623 | - $error_return = ['error' => true]; |
|
| 624 | - $response = wp_remote_request($request_url, $request_args); |
|
| 625 | - if (is_wp_error($response)) { |
|
| 626 | - $message = $response->get_error_message(); |
|
| 627 | - PayPalLogger::errorLog($message, [$request_url, $request_args, $response], $paypal_pm); |
|
| 628 | - $error_return['message'] = $message; |
|
| 629 | - return $error_return; |
|
| 630 | - } |
|
| 631 | - $response_body = (isset($response['body']) && $response['body']) ? json_decode($response['body'], true) : []; |
|
| 632 | - if (empty($response_body) || isset($response_body['error'])) { |
|
| 633 | - $message = $response_body['error_description'] |
|
| 634 | - ?? sprintf( |
|
| 635 | - esc_html__('Unknown response received while sending a request to: %1$s', 'event_espresso'), |
|
| 636 | - $request_url |
|
| 637 | - ); |
|
| 638 | - PayPalLogger::errorLog($message, [$request_url, $request_args, $response], $paypal_pm); |
|
| 639 | - $error_return['message'] = $message; |
|
| 640 | - return $error_return; |
|
| 641 | - } |
|
| 642 | - return $response_body; |
|
| 643 | - } |
|
| 644 | - |
|
| 645 | - |
|
| 646 | - /** |
|
| 647 | - * Check the response for a partner token request. |
|
| 648 | - * |
|
| 649 | - * @param array $response |
|
| 650 | - * @param EE_Payment_Method $paypal_pm |
|
| 651 | - * @return bool |
|
| 652 | - */ |
|
| 653 | - public static function partnerTokenResponseValid(array $response, EE_Payment_Method $paypal_pm): bool |
|
| 654 | - { |
|
| 655 | - // Check the data we received. |
|
| 656 | - if ( |
|
| 657 | - empty($response['nonce']) |
|
| 658 | - || ! wp_verify_nonce($response['nonce'], 'eea_pp_commerce_get_access_token') |
|
| 659 | - || empty($response['access_token']) |
|
| 660 | - || empty($response['app_id']) |
|
| 661 | - || empty($response['expires_in']) |
|
| 662 | - || empty($response['partner_client_id']) |
|
| 663 | - || empty($response['partner_merchant_id']) |
|
| 664 | - ) { |
|
| 665 | - // This is an error. |
|
| 666 | - PayPalLogger::errorLog( |
|
| 667 | - esc_html__('Incoming parameter validation failed.', 'event_espresso'), |
|
| 668 | - $response, |
|
| 669 | - $paypal_pm |
|
| 670 | - ); |
|
| 671 | - return false; |
|
| 672 | - } |
|
| 673 | - return true; |
|
| 674 | - } |
|
| 675 | - |
|
| 676 | - |
|
| 677 | - /** |
|
| 678 | - * Returns the base URL to the middleman server. |
|
| 679 | - * If LOCAL_MIDDLEMAN_SERVER is defined, requests will be sent to connect.eventespresso.test |
|
| 680 | - * |
|
| 681 | - * @param EE_Payment_Method $payment_method |
|
| 682 | - * @return string |
|
| 683 | - * @throws EE_Error |
|
| 684 | - * @throws ReflectionException |
|
| 685 | - */ |
|
| 686 | - public static function getMiddlemanBaseUrl(EE_Payment_Method $payment_method): string |
|
| 687 | - { |
|
| 688 | - $target = defined('LOCAL_MIDDLEMAN_SERVER') ? 'test' : 'com'; |
|
| 689 | - // If this PM is used under different provider accounts, you might need an account indicator. |
|
| 690 | - $account = defined('EE_PAYPAL_COMMERCE_ACCOUNT_INDICATOR') ? EE_PAYPAL_COMMERCE_ACCOUNT_INDICATOR : ''; |
|
| 691 | - $postfix = $payment_method->debug_mode() ? '_sandbox' : ''; |
|
| 692 | - return "https://connect.eventespresso.$target/paypal_commerce$account$postfix/"; |
|
| 693 | - } |
|
| 694 | - |
|
| 695 | - |
|
| 696 | - /** |
|
| 697 | - * This Payment Method admin notices. |
|
| 698 | - * |
|
| 699 | - * @return void |
|
| 700 | - * @throws EE_Error |
|
| 701 | - * @throws ReflectionException |
|
| 702 | - */ |
|
| 703 | - public static function adminNotice() |
|
| 704 | - { |
|
| 705 | - // Show the notice if PayPal Commerce PM is active but merchant is not onboard. |
|
| 706 | - $pp_commerce = EEM_Payment_Method::instance()->get_one_by_slug('paypalcheckout'); |
|
| 707 | - if ( |
|
| 708 | - $pp_commerce instanceof EE_Payment_Method |
|
| 709 | - && $pp_commerce->active() |
|
| 710 | - && ! EED_PayPalOnboard::isOnboard($pp_commerce) |
|
| 711 | - ) { |
|
| 712 | - add_action('admin_notices', [EED_PayPalOnboard::class, 'notOnboardNotice']); |
|
| 713 | - } |
|
| 714 | - } |
|
| 715 | - |
|
| 716 | - |
|
| 717 | - /** |
|
| 718 | - * Contents of the not onboard admin notice. |
|
| 719 | - * |
|
| 720 | - * @return void |
|
| 721 | - * @throws EE_Error |
|
| 722 | - * @throws ReflectionException |
|
| 723 | - */ |
|
| 724 | - public static function notOnboardNotice() |
|
| 725 | - { |
|
| 726 | - $open_anchor = $close_anchor = ''; |
|
| 727 | - $pp_commerce = EEM_Payment_Method::instance()->get_one_by_slug('paypalcheckout'); |
|
| 728 | - if ($pp_commerce instanceof EE_Payment_Method) { |
|
| 729 | - $pm_page = add_query_arg( |
|
| 730 | - [ |
|
| 731 | - 'page' => 'espresso_payment_settings', |
|
| 732 | - 'webhook_action' => 'eepPpcMerchantOnboard', |
|
| 733 | - 'payment_method' => $pp_commerce->slug(), |
|
| 734 | - ], |
|
| 735 | - admin_url('admin.php') |
|
| 736 | - ); |
|
| 737 | - $open_anchor = "<a href='$pm_page'>"; |
|
| 738 | - $close_anchor = "</a>"; |
|
| 739 | - } |
|
| 740 | - $notice = sprintf( |
|
| 741 | - esc_html__( |
|
| 742 | - '%1$sPayPal Commerce%2$s payment method was activated but is not connected to PayPal. Please %3$sfinish setting up%4$s this payment method.', |
|
| 743 | - 'event_espresso' |
|
| 744 | - ), |
|
| 745 | - '<strong>', |
|
| 746 | - '</strong>', |
|
| 747 | - $open_anchor, |
|
| 748 | - $close_anchor |
|
| 749 | - ); |
|
| 750 | - echo " |
|
| 23 | + /** |
|
| 24 | + * @return EED_Module |
|
| 25 | + * @throws EE_Error |
|
| 26 | + * @throws ReflectionException |
|
| 27 | + */ |
|
| 28 | + public static function instance(): EED_Module |
|
| 29 | + { |
|
| 30 | + return parent::get_instance(__CLASS__); |
|
| 31 | + } |
|
| 32 | + |
|
| 33 | + |
|
| 34 | + /** |
|
| 35 | + * Run - initial module setup. |
|
| 36 | + * |
|
| 37 | + * @param WP $WP |
|
| 38 | + * @return void |
|
| 39 | + */ |
|
| 40 | + public function run($WP) |
|
| 41 | + { |
|
| 42 | + } |
|
| 43 | + |
|
| 44 | + |
|
| 45 | + /** |
|
| 46 | + * For hooking into EE Admin Core and other modules. |
|
| 47 | + * |
|
| 48 | + * @return void |
|
| 49 | + */ |
|
| 50 | + public static function set_hooks_admin(): void |
|
| 51 | + { |
|
| 52 | + // check for the most basic EE capability |
|
| 53 | + /** @var EE_Capabilities $capabilities */ |
|
| 54 | + $capabilities = LoaderFactory::getLoader()->getShared(EE_Capabilities::class); |
|
| 55 | + if ( |
|
| 56 | + DbStatus::isOffline() |
|
| 57 | + || ! $capabilities->current_user_can('ee_manage_gateways', 'manage-paypal-onboarding') |
|
| 58 | + ) { |
|
| 59 | + return; |
|
| 60 | + } |
|
| 61 | + // Get onboarding URL. |
|
| 62 | + add_action('wp_ajax_eeaPpGetOnboardingUrl', [__CLASS__, 'getOnboardingUrl']); |
|
| 63 | + // Catch the return/redirect from PayPal onboarding page. |
|
| 64 | + add_action('init', [__CLASS__, 'updateOnboardingStatus']); |
|
| 65 | + // Return the connection/onboard status. |
|
| 66 | + add_action('wp_ajax_eeaPpGetOnboardStatus', [__CLASS__, 'getOnboardStatus']); |
|
| 67 | + // Revoke access. |
|
| 68 | + add_action('wp_ajax_eeaPpOffboard', [__CLASS__, 'offboard']); |
|
| 69 | + // Clear all metadata. |
|
| 70 | + add_action('wp_ajax_eeaPpClearMetaData', [__CLASS__, 'clearMetaData']); |
|
| 71 | + // Admin notice. |
|
| 72 | + add_action('admin_init', [__CLASS__, 'adminNotice']); |
|
| 73 | + } |
|
| 74 | + |
|
| 75 | + |
|
| 76 | + /** |
|
| 77 | + * Get the onboarding URL. |
|
| 78 | + * (AJAX) |
|
| 79 | + * |
|
| 80 | + * @return void |
|
| 81 | + */ |
|
| 82 | + public static function getOnboardingUrl(): void |
|
| 83 | + { |
|
| 84 | + $signup_link = ''; |
|
| 85 | + try { |
|
| 86 | + $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
| 87 | + if (! $paypal_pm instanceof EE_Payment_Method) { |
|
| 88 | + PayPalLogger::errorLogAndExit( |
|
| 89 | + esc_html__('No payment method.', 'event_espresso'), |
|
| 90 | + EED_Module::getRequest()->postParams(), |
|
| 91 | + $paypal_pm |
|
| 92 | + ); |
|
| 93 | + } |
|
| 94 | + PayPalExtraMetaManager::updateDebugMode($paypal_pm, EED_Module::getRequest()->postParams()); |
|
| 95 | + // Just get a new onboarding URL every time. |
|
| 96 | + $signup_link = EED_PayPalOnboard::requestOnboardingUrl($paypal_pm); |
|
| 97 | + if (! $signup_link) { |
|
| 98 | + $err_msg = esc_html__('Error! Could not generate a sign-up link.', 'event_espresso'); |
|
| 99 | + PayPalLogger::errorLogAndExit($err_msg, ['signup_link' => $signup_link], $paypal_pm); |
|
| 100 | + } |
|
| 101 | + } catch (Exception $e) { |
|
| 102 | + PayPalLogger::errorLogAndExit($e->getMessage(), ['trace' => $e->getTrace()]); |
|
| 103 | + } |
|
| 104 | + // Is it empty (can happen if we didn't get the URL through the API). |
|
| 105 | + $signup_link = $signup_link ? $signup_link . '?&displayMode=minibrowser' : '#'; |
|
| 106 | + wp_send_json( |
|
| 107 | + [ |
|
| 108 | + 'signup_link' => $signup_link, |
|
| 109 | + ] |
|
| 110 | + ); |
|
| 111 | + } |
|
| 112 | + |
|
| 113 | + |
|
| 114 | + /** |
|
| 115 | + * Request the sign-up link from PayPal. |
|
| 116 | + * |
|
| 117 | + * @param EE_Payment_Method $paypal_pm |
|
| 118 | + * @param bool $one_time_request |
|
| 119 | + * @return string |
|
| 120 | + * @throws EE_Error |
|
| 121 | + * @throws Exception |
|
| 122 | + */ |
|
| 123 | + public static function requestOnboardingUrl(EE_Payment_Method $paypal_pm, bool $one_time_request = false): string |
|
| 124 | + { |
|
| 125 | + $signup_link = ''; |
|
| 126 | + // Get the access token. |
|
| 127 | + $access_token = EED_PayPalOnboard::getPartnerAccessToken($paypal_pm); |
|
| 128 | + if (! $access_token) { |
|
| 129 | + $err_msg = esc_html__('Error! No access token.', 'event_espresso'); |
|
| 130 | + PayPalLogger::errorLog($err_msg, ['access_token' => $access_token], $paypal_pm); |
|
| 131 | + return ''; |
|
| 132 | + } |
|
| 133 | + // Request the access token. |
|
| 134 | + $body_params = EED_PayPalOnboard::signupLinkRequestBody($paypal_pm); |
|
| 135 | + $bn_code = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_BN_CODE); |
|
| 136 | + $post_params = [ |
|
| 137 | + 'method' => 'POST', |
|
| 138 | + 'headers' => [ |
|
| 139 | + 'User-Agent' => sanitize_text_field($_SERVER['HTTP_USER_AGENT']), |
|
| 140 | + 'Content-Type' => 'application/json', |
|
| 141 | + 'Authorization' => 'Bearer ' . $access_token, |
|
| 142 | + 'PayPal-Partner-Attribution-Id' => $bn_code, |
|
| 143 | + ], |
|
| 144 | + 'body' => $body_params, |
|
| 145 | + ]; |
|
| 146 | + $request_url = Domain::getPayPalApiUrl($paypal_pm) . '/v2/customer/partner-referrals'; |
|
| 147 | + $response = EED_PayPalOnboard::sendRequest($paypal_pm, $request_url, $post_params); |
|
| 148 | + // Check the data we received. |
|
| 149 | + if (isset($response['error']) || empty($response['links'])) { |
|
| 150 | + // Did the original access token get replaced by any chance ? |
|
| 151 | + if ( |
|
| 152 | + ! $one_time_request |
|
| 153 | + && ! empty($response['message']) |
|
| 154 | + && $response['message'] === 'Access Token not found in cache' |
|
| 155 | + ) { |
|
| 156 | + // Clear all PM metadata and try getting the access token One more time. |
|
| 157 | + PayPalExtraMetaManager::deleteData($paypal_pm); |
|
| 158 | + PayPalLogger::errorLog( |
|
| 159 | + esc_html__('Removing old metadata before new onboarding.', 'event_espresso'), |
|
| 160 | + $response, |
|
| 161 | + $paypal_pm |
|
| 162 | + ); |
|
| 163 | + return EED_PayPalOnboard::requestOnboardingUrl($paypal_pm, true); |
|
| 164 | + } |
|
| 165 | + $err_msg = esc_html__('Incoming sign-up link parameter validation failed.', 'event_espresso'); |
|
| 166 | + PayPalLogger::errorLog($err_msg, $response, $paypal_pm); |
|
| 167 | + return ''; |
|
| 168 | + } |
|
| 169 | + // Now retrieve that sign-up link. |
|
| 170 | + foreach ($response['links'] as $link) { |
|
| 171 | + if ($link['rel'] === 'action_url') { |
|
| 172 | + $signup_link = $link['href'] ?? ''; |
|
| 173 | + } |
|
| 174 | + } |
|
| 175 | + return $signup_link; |
|
| 176 | + } |
|
| 177 | + |
|
| 178 | + |
|
| 179 | + /** |
|
| 180 | + * Get the return URL. |
|
| 181 | + * |
|
| 182 | + * @param EE_Payment_Method $paypal_pm |
|
| 183 | + * @return string |
|
| 184 | + * @throws Exception |
|
| 185 | + */ |
|
| 186 | + public static function signupLinkRequestBody(EE_Payment_Method $paypal_pm): string |
|
| 187 | + { |
|
| 188 | + $identifier_string = new OneTimeString($paypal_pm->debug_mode()); |
|
| 189 | + $tracking_id = $identifier_string->value(); |
|
| 190 | + $request = LoaderFactory::getLoader()->getShared(RequestInterface::class); |
|
| 191 | + $selected_payment = $request->getRequestParam('selected_payment', 'EXPRESS_CHECKOUT'); |
|
| 192 | + // Save the identifier for future use. |
|
| 193 | + PayPalExtraMetaManager::savePmOption($paypal_pm, Domain::META_KEY_TRACKING_ID, $tracking_id); |
|
| 194 | + // Assemble the return URL. |
|
| 195 | + $return_url = EED_PayPalOnboard::getReturnUrl($paypal_pm, $selected_payment); |
|
| 196 | + return json_encode( |
|
| 197 | + [ |
|
| 198 | + 'tracking_id' => $tracking_id, |
|
| 199 | + 'operations' => [ |
|
| 200 | + [ |
|
| 201 | + 'operation' => 'API_INTEGRATION', |
|
| 202 | + 'api_integration_preference' => [ |
|
| 203 | + 'rest_api_integration' => [ |
|
| 204 | + 'integration_method' => 'PAYPAL', |
|
| 205 | + 'integration_type' => 'THIRD_PARTY', |
|
| 206 | + 'third_party_details' => [ |
|
| 207 | + 'features' => ['PAYMENT', 'REFUND', 'PARTNER_FEE'], |
|
| 208 | + ], |
|
| 209 | + ], |
|
| 210 | + ], |
|
| 211 | + ], |
|
| 212 | + ], |
|
| 213 | + 'products' => [$selected_payment], |
|
| 214 | + 'legal_consents' => [ |
|
| 215 | + [ |
|
| 216 | + 'type' => 'SHARE_DATA_CONSENT', |
|
| 217 | + 'granted' => true, |
|
| 218 | + ], |
|
| 219 | + ], |
|
| 220 | + 'partner_config_override' => [ |
|
| 221 | + 'return_url' => $return_url, |
|
| 222 | + ], |
|
| 223 | + ] |
|
| 224 | + ); |
|
| 225 | + } |
|
| 226 | + |
|
| 227 | + |
|
| 228 | + /** |
|
| 229 | + * Get the return URL. |
|
| 230 | + * |
|
| 231 | + * @param EE_Payment_Method $paypal_pm |
|
| 232 | + * @param string $selected_payment |
|
| 233 | + * @return string |
|
| 234 | + * @throws EE_Error |
|
| 235 | + * @throws ReflectionException |
|
| 236 | + */ |
|
| 237 | + public static function getReturnUrl(EE_Payment_Method $paypal_pm, string $selected_payment = ''): string |
|
| 238 | + { |
|
| 239 | + $wp_nonce = EED_Module::getRequest()->getRequestParam('wp_nonce'); |
|
| 240 | + $nonce = wp_create_nonce(Domain::NONCE_NAME_ONBOARDING_RETURN); |
|
| 241 | + return add_query_arg( |
|
| 242 | + [ |
|
| 243 | + 'page' => 'espresso_payment_settings', |
|
| 244 | + 'webhook_action' => 'eepPpcMerchantOnboard', |
|
| 245 | + 'payment_method' => $paypal_pm->slug(), |
|
| 246 | + '_wpnonce' => $wp_nonce, |
|
| 247 | + 'nonce' => $nonce, |
|
| 248 | + 'selected_payment' => $selected_payment, |
|
| 249 | + Domain::META_KEY_SANDBOX_MODE => $paypal_pm->debug_mode() ? '1' : '0', |
|
| 250 | + ], |
|
| 251 | + admin_url('admin.php') |
|
| 252 | + ); |
|
| 253 | + } |
|
| 254 | + |
|
| 255 | + |
|
| 256 | + /** |
|
| 257 | + * Redirect to the payment method (PP) settings home page. |
|
| 258 | + * |
|
| 259 | + * @return void |
|
| 260 | + */ |
|
| 261 | + public static function redirectToPmSettingsHome(): void |
|
| 262 | + { |
|
| 263 | + $get_params = EED_Module::getRequest()->getParams(); |
|
| 264 | + if (empty($get_params['payment_method'])) { |
|
| 265 | + // Simply do not redirect. |
|
| 266 | + return; |
|
| 267 | + } |
|
| 268 | + $args_to_add = [ |
|
| 269 | + 'page' => 'espresso_payment_settings', |
|
| 270 | + 'payment_method' => $get_params['payment_method'], |
|
| 271 | + ]; |
|
| 272 | + if (isset($get_params['sandbox_mode'])) { |
|
| 273 | + $args_to_add[ Domain::META_KEY_SANDBOX_MODE ] = $get_params['sandbox_mode']; |
|
| 274 | + } |
|
| 275 | + $home_url = add_query_arg($args_to_add, admin_url('admin.php')); |
|
| 276 | + wp_redirect($home_url); |
|
| 277 | + exit; |
|
| 278 | + } |
|
| 279 | + |
|
| 280 | + |
|
| 281 | + /** |
|
| 282 | + * Check user’s onboarding status. |
|
| 283 | + * This will handle the user return from the auth page and also check the status via the API. |
|
| 284 | + * |
|
| 285 | + * @return void |
|
| 286 | + * @throws EE_Error |
|
| 287 | + * @throws ReflectionException |
|
| 288 | + */ |
|
| 289 | + public static function updateOnboardingStatus(): void |
|
| 290 | + { |
|
| 291 | + // Check if this is the webhook from PayPal. |
|
| 292 | + if ( |
|
| 293 | + ! isset($_GET['webhook_action'], $_GET['nonce']) |
|
| 294 | + || $_GET['webhook_action'] !== 'eepPpcMerchantOnboard' |
|
| 295 | + ) { |
|
| 296 | + return; // Ignore. |
|
| 297 | + } |
|
| 298 | + $get_params = EED_Module::getRequest()->getParams(); |
|
| 299 | + // Get the payment method. |
|
| 300 | + $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
| 301 | + // Check the response (GET) parameters. |
|
| 302 | + if (! EED_PayPalOnboard::onboardingStatusResponseValid($get_params, $paypal_pm)) { |
|
| 303 | + // Missing parameters. Can't proceed. |
|
| 304 | + PayPalLogger::errorLog( |
|
| 305 | + esc_html__('Missing required onboarding parameters.', 'event_espresso'), |
|
| 306 | + $get_params, |
|
| 307 | + $paypal_pm |
|
| 308 | + ); |
|
| 309 | + EED_PayPalOnboard::redirectToPmSettingsHome(); |
|
| 310 | + return; |
|
| 311 | + } |
|
| 312 | + // Check on the onboarding status (recommended by PP). |
|
| 313 | + $onboarding_status = EED_PayPalOnboard::trackSellerOnboarding( |
|
| 314 | + $paypal_pm, |
|
| 315 | + $get_params[ Domain::META_KEY_SELLER_MERCHANT_ID ] |
|
| 316 | + ); |
|
| 317 | + if (! isset($onboarding_status['valid']) || ! $onboarding_status['valid']) { |
|
| 318 | + PayPalLogger::errorLog( |
|
| 319 | + $onboarding_status['message'], |
|
| 320 | + array_merge($get_params, $onboarding_status), |
|
| 321 | + $paypal_pm |
|
| 322 | + ); |
|
| 323 | + EED_PayPalOnboard::redirectToPmSettingsHome(); |
|
| 324 | + return; |
|
| 325 | + } |
|
| 326 | + // Start saving the setup and info. |
|
| 327 | + PayPalExtraMetaManager::parseAndSaveOptions($paypal_pm, $onboarding_status, $get_params); |
|
| 328 | + // Save the credentials. |
|
| 329 | + PayPalExtraMetaManager::saveSellerApiCredentials($paypal_pm, $get_params); |
|
| 330 | + // Also clen GET params by redirecting, because PP auto redirects to the return_url on closing the onboarding window. |
|
| 331 | + EED_PayPalOnboard::redirectToPmSettingsHome(); |
|
| 332 | + } |
|
| 333 | + |
|
| 334 | + |
|
| 335 | + /** |
|
| 336 | + * Check if all required parameters for the onboarding status check are present. |
|
| 337 | + * |
|
| 338 | + * @param array $data |
|
| 339 | + * @param mixed $paypal_pm |
|
| 340 | + * @return bool |
|
| 341 | + */ |
|
| 342 | + public static function onboardingStatusResponseValid(array $data, $paypal_pm): bool |
|
| 343 | + { |
|
| 344 | + // Check that we have all the required parameters and the nonce is ok. |
|
| 345 | + if ( |
|
| 346 | + $paypal_pm instanceof EE_Payment_Method |
|
| 347 | + && wp_verify_nonce($data['nonce'], Domain::NONCE_NAME_ONBOARDING_RETURN) |
|
| 348 | + && ! empty($data[ Domain::API_PARAM_PARTNER_ID ]) |
|
| 349 | + && ! empty($data[ Domain::META_KEY_SELLER_MERCHANT_ID ]) |
|
| 350 | + && isset($data[ Domain::API_PARAM_EMAIL_CONFIRMED ]) |
|
| 351 | + ) { |
|
| 352 | + return true; |
|
| 353 | + } |
|
| 354 | + return false; |
|
| 355 | + } |
|
| 356 | + |
|
| 357 | + |
|
| 358 | + /** |
|
| 359 | + * Get partner access token. |
|
| 360 | + * |
|
| 361 | + * @param EE_Payment_Method $paypal_pm |
|
| 362 | + * @return string |
|
| 363 | + * @throws EE_Error |
|
| 364 | + * @throws ReflectionException |
|
| 365 | + */ |
|
| 366 | + public static function getPartnerAccessToken(EE_Payment_Method $paypal_pm): string |
|
| 367 | + { |
|
| 368 | + // Do we have it saved ? |
|
| 369 | + $access_token = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_ACCESS_TOKEN); |
|
| 370 | + // If we don't have it, request/update it. |
|
| 371 | + if (! $access_token) { |
|
| 372 | + return EED_PayPalOnboard::requestPartnerAccessToken($paypal_pm); |
|
| 373 | + } |
|
| 374 | + if (EED_PayPalOnboard::partnerAccessTokenExpired($paypal_pm)) { |
|
| 375 | + return EED_PayPalOnboard::requestPartnerAccessToken($paypal_pm); |
|
| 376 | + } |
|
| 377 | + // Access token is saved as encrypted, but return decrypted. |
|
| 378 | + return $access_token; |
|
| 379 | + } |
|
| 380 | + |
|
| 381 | + |
|
| 382 | + /** |
|
| 383 | + * Get partner access token. |
|
| 384 | + * |
|
| 385 | + * @param EE_Payment_Method $paypal_pm |
|
| 386 | + * @return bool |
|
| 387 | + * @throws EE_Error |
|
| 388 | + * @throws ReflectionException |
|
| 389 | + */ |
|
| 390 | + public static function partnerAccessTokenExpired(EE_Payment_Method $paypal_pm): bool |
|
| 391 | + { |
|
| 392 | + $expires_at = (int) PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_TOKEN_EXPIRES_IN); |
|
| 393 | + if (! $expires_at) { |
|
| 394 | + return true; |
|
| 395 | + } |
|
| 396 | + // Validate the token expiration date. |
|
| 397 | + $minutes_left = round(($expires_at - time()) / 60); |
|
| 398 | + // Count as expired if less than 60 minutes till expiration left. |
|
| 399 | + if ($minutes_left <= 60) { |
|
| 400 | + return true; |
|
| 401 | + } |
|
| 402 | + return false; |
|
| 403 | + } |
|
| 404 | + |
|
| 405 | + |
|
| 406 | + /** |
|
| 407 | + * Request the partner access token from PayPal and save/update it. |
|
| 408 | + * |
|
| 409 | + * @param EE_Payment_Method $paypal_pm |
|
| 410 | + * @return string |
|
| 411 | + * @throws EE_Error |
|
| 412 | + * @throws ReflectionException |
|
| 413 | + */ |
|
| 414 | + public static function requestPartnerAccessToken(EE_Payment_Method $paypal_pm): string |
|
| 415 | + { |
|
| 416 | + $nonce = wp_create_nonce('eea_pp_commerce_get_access_token'); |
|
| 417 | + // Request the access token. |
|
| 418 | + $post_args = [ |
|
| 419 | + 'method' => 'POST', |
|
| 420 | + 'body' => [ |
|
| 421 | + 'nonce' => $nonce, |
|
| 422 | + 'api_version' => 'v1', |
|
| 423 | + Domain::META_KEY_SANDBOX_MODE => $paypal_pm->debug_mode() ? '1' : '0', |
|
| 424 | + ], |
|
| 425 | + ]; |
|
| 426 | + if (defined('LOCAL_MIDDLEMAN_SERVER')) { |
|
| 427 | + $post_args['sslverify'] = Manager::verifySSL(); |
|
| 428 | + } |
|
| 429 | + $post_url = EED_PayPalOnboard::getMiddlemanBaseUrl($paypal_pm) . 'get_token'; |
|
| 430 | + $response = EED_PayPalOnboard::sendRequest($paypal_pm, $post_url, $post_args); |
|
| 431 | + if (isset($response['error'])) { |
|
| 432 | + return ''; |
|
| 433 | + } |
|
| 434 | + // Check the data we received. |
|
| 435 | + if (! EED_PayPalOnboard::partnerTokenResponseValid($response, $paypal_pm)) { |
|
| 436 | + return ''; |
|
| 437 | + } |
|
| 438 | + // If we are here all seems to be ok. Save the token and it's data. |
|
| 439 | + $saved = PayPalExtraMetaManager::savePartnerAccessToken($paypal_pm, $response); |
|
| 440 | + if (! $saved) { |
|
| 441 | + return ''; |
|
| 442 | + } |
|
| 443 | + return $response['access_token']; |
|
| 444 | + } |
|
| 445 | + |
|
| 446 | + |
|
| 447 | + /** |
|
| 448 | + * Request seller onboarding status from PayPal. |
|
| 449 | + * |
|
| 450 | + * @param EE_Payment_Method $paypal_pm |
|
| 451 | + * @param string $merchant_id |
|
| 452 | + * @return array |
|
| 453 | + * @throws EE_Error |
|
| 454 | + * @throws ReflectionException |
|
| 455 | + */ |
|
| 456 | + public static function trackSellerOnboarding(EE_Payment_Method $paypal_pm, string $merchant_id): array |
|
| 457 | + { |
|
| 458 | + $track_onboarding = EED_PayPalOnboard::getTrackOnboardingApi($paypal_pm, $merchant_id); |
|
| 459 | + if (! $track_onboarding instanceof TrackSellerOnboarding) { |
|
| 460 | + return [ |
|
| 461 | + 'error' => 'TRACK_ONBOARDING_FAILED', |
|
| 462 | + 'message' => esc_html__('Failed to track seller onboarding.', 'event_espresso') |
|
| 463 | + ]; |
|
| 464 | + } |
|
| 465 | + return $track_onboarding->isValid(); |
|
| 466 | + } |
|
| 467 | + |
|
| 468 | + |
|
| 469 | + /** |
|
| 470 | + * Returns the Track Seller Onboarding API. |
|
| 471 | + * |
|
| 472 | + * @param EE_Payment_Method $paypal_pm |
|
| 473 | + * @param string $merchant_id |
|
| 474 | + * @return TrackSellerOnboarding|null |
|
| 475 | + * @throws EE_Error |
|
| 476 | + * @throws ReflectionException |
|
| 477 | + */ |
|
| 478 | + public static function getTrackOnboardingApi( |
|
| 479 | + EE_Payment_Method $paypal_pm, |
|
| 480 | + string $merchant_id |
|
| 481 | + ): ?TrackSellerOnboarding { |
|
| 482 | + $partner_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_PARTNER_MERCHANT_ID); |
|
| 483 | + $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm); |
|
| 484 | + if (! $paypal_api instanceof PayPalApi || ! $partner_id) { |
|
| 485 | + return null; |
|
| 486 | + } |
|
| 487 | + return new TrackSellerOnboarding($paypal_api, $partner_id, $merchant_id, $paypal_pm->debug_mode()); |
|
| 488 | + } |
|
| 489 | + |
|
| 490 | + |
|
| 491 | + /** |
|
| 492 | + * Check the onboard status and return the result. |
|
| 493 | + * (AJAX) |
|
| 494 | + * |
|
| 495 | + * @return void |
|
| 496 | + * @throws EE_Error |
|
| 497 | + * @throws ReflectionException |
|
| 498 | + */ |
|
| 499 | + public static function getOnboardStatus(): void |
|
| 500 | + { |
|
| 501 | + $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
| 502 | + if (! $paypal_pm instanceof EE_Payment_Method) { |
|
| 503 | + $err_msg = esc_html__('Could not specify the payment method.', 'event_espresso'); |
|
| 504 | + PayPalLogger::errorLog($err_msg, EED_Module::getRequest()->postParams(), $paypal_pm); |
|
| 505 | + wp_send_json(['on_board' => false]); |
|
| 506 | + } |
|
| 507 | + try { |
|
| 508 | + $seller_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_SELLER_MERCHANT_ID) ?? '--'; |
|
| 509 | + } catch (Exception $e) { |
|
| 510 | + $seller_id = '--'; |
|
| 511 | + PayPalLogger::errorLog($e->getMessage(), ['trace' => $e->getTrace()]); |
|
| 512 | + } |
|
| 513 | + wp_send_json( |
|
| 514 | + [ |
|
| 515 | + 'on_board' => EED_PayPalOnboard::isOnboard($paypal_pm), |
|
| 516 | + 'seller_id' => $seller_id, |
|
| 517 | + ] |
|
| 518 | + ); |
|
| 519 | + } |
|
| 520 | + |
|
| 521 | + |
|
| 522 | + /** |
|
| 523 | + * De-authorize the seller. Remove all API credentials. |
|
| 524 | + * (AJAX) |
|
| 525 | + * |
|
| 526 | + * @return void |
|
| 527 | + * @throws EE_Error |
|
| 528 | + * @throws ReflectionException |
|
| 529 | + */ |
|
| 530 | + public static function offboard(): void |
|
| 531 | + { |
|
| 532 | + $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
| 533 | + EED_PayPalOnboard::validatePmAjax($paypal_pm); |
|
| 534 | + PayPalExtraMetaManager::deleteData($paypal_pm); |
|
| 535 | + PayPalLogger::errorLog( |
|
| 536 | + esc_html__('Offboarding. Removing metadata.', 'event_espresso'), |
|
| 537 | + EED_Module::getRequest()->postParams(), |
|
| 538 | + $paypal_pm |
|
| 539 | + ); |
|
| 540 | + wp_send_json(['success' => true]); |
|
| 541 | + } |
|
| 542 | + |
|
| 543 | + |
|
| 544 | + /** |
|
| 545 | + * Clear all credentials metadata. |
|
| 546 | + * (AJAX) |
|
| 547 | + * |
|
| 548 | + * @return void |
|
| 549 | + * @throws EE_Error |
|
| 550 | + * @throws ReflectionException |
|
| 551 | + */ |
|
| 552 | + public static function clearMetaData(): void |
|
| 553 | + { |
|
| 554 | + $paypal_pm = EED_PayPalCommerce::getPaymentMethod(); |
|
| 555 | + EED_PayPalOnboard::validatePmAjax($paypal_pm); |
|
| 556 | + PayPalExtraMetaManager::deleteAllData($paypal_pm); |
|
| 557 | + PayPalLogger::errorLog( |
|
| 558 | + esc_html__('Doing a Reset. Removing all PM settings metadata.', 'event_espresso'), |
|
| 559 | + EED_Module::getRequest()->postParams(), |
|
| 560 | + $paypal_pm |
|
| 561 | + ); |
|
| 562 | + wp_send_json(['success' => true]); |
|
| 563 | + } |
|
| 564 | + |
|
| 565 | + |
|
| 566 | + /** |
|
| 567 | + * Validate the PM instance, returning an ajax response on invalid. |
|
| 568 | + * |
|
| 569 | + * @param $paypal_pm |
|
| 570 | + * @return void |
|
| 571 | + */ |
|
| 572 | + public static function validatePmAjax($paypal_pm): void |
|
| 573 | + { |
|
| 574 | + if (! $paypal_pm instanceof EE_Payment_Method) { |
|
| 575 | + wp_send_json( |
|
| 576 | + [ |
|
| 577 | + 'error' => 'INVALID_PM', |
|
| 578 | + 'message' => esc_html__( |
|
| 579 | + 'Invalid payment method. Please refresh the page and try again.', |
|
| 580 | + 'event_espresso' |
|
| 581 | + ), |
|
| 582 | + ] |
|
| 583 | + ); |
|
| 584 | + } |
|
| 585 | + } |
|
| 586 | + |
|
| 587 | + |
|
| 588 | + /** |
|
| 589 | + * Checks if already onboard. |
|
| 590 | + * |
|
| 591 | + * @param EE_Payment_Method $payment_method |
|
| 592 | + * @return boolean |
|
| 593 | + * @throws EE_Error |
|
| 594 | + * @throws ReflectionException |
|
| 595 | + */ |
|
| 596 | + public static function isOnboard(EE_Payment_Method $payment_method): bool |
|
| 597 | + { |
|
| 598 | + $pp_meta_data = PayPalExtraMetaManager::getAllData($payment_method); |
|
| 599 | + return |
|
| 600 | + ( |
|
| 601 | + // onborded with a third party integration ? |
|
| 602 | + ! empty($pp_meta_data[ Domain::META_KEY_SELLER_MERCHANT_ID ]) |
|
| 603 | + && ! empty($pp_meta_data[ Domain::META_KEY_ACCESS_TOKEN ]) |
|
| 604 | + ) || ( |
|
| 605 | + // or with the first party integration ? |
|
| 606 | + ! empty($pp_meta_data[ Domain::META_KEY_CLIENT_ID ]) |
|
| 607 | + && ! empty($pp_meta_data[ Domain::META_KEY_CLIENT_SECRET ]) |
|
| 608 | + && ! empty($pp_meta_data[ Domain::META_KEY_PAYER_ID ]) |
|
| 609 | + ); |
|
| 610 | + } |
|
| 611 | + |
|
| 612 | + |
|
| 613 | + /** |
|
| 614 | + * Send a request and return a decoded response body. |
|
| 615 | + * |
|
| 616 | + * @param EE_Payment_Method $paypal_pm |
|
| 617 | + * @param string $request_url |
|
| 618 | + * @param array $request_args |
|
| 619 | + * @return array |
|
| 620 | + */ |
|
| 621 | + public static function sendRequest(EE_Payment_Method $paypal_pm, string $request_url, array $request_args): array |
|
| 622 | + { |
|
| 623 | + $error_return = ['error' => true]; |
|
| 624 | + $response = wp_remote_request($request_url, $request_args); |
|
| 625 | + if (is_wp_error($response)) { |
|
| 626 | + $message = $response->get_error_message(); |
|
| 627 | + PayPalLogger::errorLog($message, [$request_url, $request_args, $response], $paypal_pm); |
|
| 628 | + $error_return['message'] = $message; |
|
| 629 | + return $error_return; |
|
| 630 | + } |
|
| 631 | + $response_body = (isset($response['body']) && $response['body']) ? json_decode($response['body'], true) : []; |
|
| 632 | + if (empty($response_body) || isset($response_body['error'])) { |
|
| 633 | + $message = $response_body['error_description'] |
|
| 634 | + ?? sprintf( |
|
| 635 | + esc_html__('Unknown response received while sending a request to: %1$s', 'event_espresso'), |
|
| 636 | + $request_url |
|
| 637 | + ); |
|
| 638 | + PayPalLogger::errorLog($message, [$request_url, $request_args, $response], $paypal_pm); |
|
| 639 | + $error_return['message'] = $message; |
|
| 640 | + return $error_return; |
|
| 641 | + } |
|
| 642 | + return $response_body; |
|
| 643 | + } |
|
| 644 | + |
|
| 645 | + |
|
| 646 | + /** |
|
| 647 | + * Check the response for a partner token request. |
|
| 648 | + * |
|
| 649 | + * @param array $response |
|
| 650 | + * @param EE_Payment_Method $paypal_pm |
|
| 651 | + * @return bool |
|
| 652 | + */ |
|
| 653 | + public static function partnerTokenResponseValid(array $response, EE_Payment_Method $paypal_pm): bool |
|
| 654 | + { |
|
| 655 | + // Check the data we received. |
|
| 656 | + if ( |
|
| 657 | + empty($response['nonce']) |
|
| 658 | + || ! wp_verify_nonce($response['nonce'], 'eea_pp_commerce_get_access_token') |
|
| 659 | + || empty($response['access_token']) |
|
| 660 | + || empty($response['app_id']) |
|
| 661 | + || empty($response['expires_in']) |
|
| 662 | + || empty($response['partner_client_id']) |
|
| 663 | + || empty($response['partner_merchant_id']) |
|
| 664 | + ) { |
|
| 665 | + // This is an error. |
|
| 666 | + PayPalLogger::errorLog( |
|
| 667 | + esc_html__('Incoming parameter validation failed.', 'event_espresso'), |
|
| 668 | + $response, |
|
| 669 | + $paypal_pm |
|
| 670 | + ); |
|
| 671 | + return false; |
|
| 672 | + } |
|
| 673 | + return true; |
|
| 674 | + } |
|
| 675 | + |
|
| 676 | + |
|
| 677 | + /** |
|
| 678 | + * Returns the base URL to the middleman server. |
|
| 679 | + * If LOCAL_MIDDLEMAN_SERVER is defined, requests will be sent to connect.eventespresso.test |
|
| 680 | + * |
|
| 681 | + * @param EE_Payment_Method $payment_method |
|
| 682 | + * @return string |
|
| 683 | + * @throws EE_Error |
|
| 684 | + * @throws ReflectionException |
|
| 685 | + */ |
|
| 686 | + public static function getMiddlemanBaseUrl(EE_Payment_Method $payment_method): string |
|
| 687 | + { |
|
| 688 | + $target = defined('LOCAL_MIDDLEMAN_SERVER') ? 'test' : 'com'; |
|
| 689 | + // If this PM is used under different provider accounts, you might need an account indicator. |
|
| 690 | + $account = defined('EE_PAYPAL_COMMERCE_ACCOUNT_INDICATOR') ? EE_PAYPAL_COMMERCE_ACCOUNT_INDICATOR : ''; |
|
| 691 | + $postfix = $payment_method->debug_mode() ? '_sandbox' : ''; |
|
| 692 | + return "https://connect.eventespresso.$target/paypal_commerce$account$postfix/"; |
|
| 693 | + } |
|
| 694 | + |
|
| 695 | + |
|
| 696 | + /** |
|
| 697 | + * This Payment Method admin notices. |
|
| 698 | + * |
|
| 699 | + * @return void |
|
| 700 | + * @throws EE_Error |
|
| 701 | + * @throws ReflectionException |
|
| 702 | + */ |
|
| 703 | + public static function adminNotice() |
|
| 704 | + { |
|
| 705 | + // Show the notice if PayPal Commerce PM is active but merchant is not onboard. |
|
| 706 | + $pp_commerce = EEM_Payment_Method::instance()->get_one_by_slug('paypalcheckout'); |
|
| 707 | + if ( |
|
| 708 | + $pp_commerce instanceof EE_Payment_Method |
|
| 709 | + && $pp_commerce->active() |
|
| 710 | + && ! EED_PayPalOnboard::isOnboard($pp_commerce) |
|
| 711 | + ) { |
|
| 712 | + add_action('admin_notices', [EED_PayPalOnboard::class, 'notOnboardNotice']); |
|
| 713 | + } |
|
| 714 | + } |
|
| 715 | + |
|
| 716 | + |
|
| 717 | + /** |
|
| 718 | + * Contents of the not onboard admin notice. |
|
| 719 | + * |
|
| 720 | + * @return void |
|
| 721 | + * @throws EE_Error |
|
| 722 | + * @throws ReflectionException |
|
| 723 | + */ |
|
| 724 | + public static function notOnboardNotice() |
|
| 725 | + { |
|
| 726 | + $open_anchor = $close_anchor = ''; |
|
| 727 | + $pp_commerce = EEM_Payment_Method::instance()->get_one_by_slug('paypalcheckout'); |
|
| 728 | + if ($pp_commerce instanceof EE_Payment_Method) { |
|
| 729 | + $pm_page = add_query_arg( |
|
| 730 | + [ |
|
| 731 | + 'page' => 'espresso_payment_settings', |
|
| 732 | + 'webhook_action' => 'eepPpcMerchantOnboard', |
|
| 733 | + 'payment_method' => $pp_commerce->slug(), |
|
| 734 | + ], |
|
| 735 | + admin_url('admin.php') |
|
| 736 | + ); |
|
| 737 | + $open_anchor = "<a href='$pm_page'>"; |
|
| 738 | + $close_anchor = "</a>"; |
|
| 739 | + } |
|
| 740 | + $notice = sprintf( |
|
| 741 | + esc_html__( |
|
| 742 | + '%1$sPayPal Commerce%2$s payment method was activated but is not connected to PayPal. Please %3$sfinish setting up%4$s this payment method.', |
|
| 743 | + 'event_espresso' |
|
| 744 | + ), |
|
| 745 | + '<strong>', |
|
| 746 | + '</strong>', |
|
| 747 | + $open_anchor, |
|
| 748 | + $close_anchor |
|
| 749 | + ); |
|
| 750 | + echo " |
|
| 751 | 751 | <div class='error'> |
| 752 | 752 | <p>$notice</p> |
| 753 | 753 | </div>"; |
| 754 | - } |
|
| 754 | + } |
|
| 755 | 755 | } |
@@ -16,144 +16,144 @@ |
||
| 16 | 16 | */ |
| 17 | 17 | class EE_PMT_PayPalCheckout extends EE_PMT_Base |
| 18 | 18 | { |
| 19 | - /** |
|
| 20 | - * @param EE_Payment_Method|null $pm_instance |
|
| 21 | - * @throws ReflectionException |
|
| 22 | - * @throws EE_Error |
|
| 23 | - */ |
|
| 24 | - public function __construct($pm_instance = null) |
|
| 25 | - { |
|
| 26 | - $this->_template_path = dirname(__FILE__) . DS . 'templates' . DS; |
|
| 27 | - $this->_default_description = esc_html__('Please provide the following billing information.', 'event_espresso'); |
|
| 28 | - $this->_default_button_url = $this->file_url() . 'lib/default-cc-logo.png'; |
|
| 29 | - $this->_pretty_name = esc_html__('PayPal Commerce', 'event_espresso'); |
|
| 30 | - $this->_cache_billing_form = true; |
|
| 31 | - $this->_requires_https = true; |
|
| 19 | + /** |
|
| 20 | + * @param EE_Payment_Method|null $pm_instance |
|
| 21 | + * @throws ReflectionException |
|
| 22 | + * @throws EE_Error |
|
| 23 | + */ |
|
| 24 | + public function __construct($pm_instance = null) |
|
| 25 | + { |
|
| 26 | + $this->_template_path = dirname(__FILE__) . DS . 'templates' . DS; |
|
| 27 | + $this->_default_description = esc_html__('Please provide the following billing information.', 'event_espresso'); |
|
| 28 | + $this->_default_button_url = $this->file_url() . 'lib/default-cc-logo.png'; |
|
| 29 | + $this->_pretty_name = esc_html__('PayPal Commerce', 'event_espresso'); |
|
| 30 | + $this->_cache_billing_form = true; |
|
| 31 | + $this->_requires_https = true; |
|
| 32 | 32 | |
| 33 | - // Load gateway. |
|
| 34 | - require_once( |
|
| 35 | - EEP_PAYPAL_COMMERCE_PATH . 'EEG_PayPalCheckout.gateway.php' |
|
| 36 | - ); |
|
| 37 | - $this->_gateway = new EEG_PayPalCheckout(); |
|
| 33 | + // Load gateway. |
|
| 34 | + require_once( |
|
| 35 | + EEP_PAYPAL_COMMERCE_PATH . 'EEG_PayPalCheckout.gateway.php' |
|
| 36 | + ); |
|
| 37 | + $this->_gateway = new EEG_PayPalCheckout(); |
|
| 38 | 38 | |
| 39 | - // Display a refund message at transactions actions area. |
|
| 40 | - add_action( |
|
| 41 | - 'AHEE__txn_admin_details_main_meta_box_txn_details__after_actions_buttons', |
|
| 42 | - [__CLASS__, 'refundNotice'] |
|
| 43 | - ); |
|
| 39 | + // Display a refund message at transactions actions area. |
|
| 40 | + add_action( |
|
| 41 | + 'AHEE__txn_admin_details_main_meta_box_txn_details__after_actions_buttons', |
|
| 42 | + [__CLASS__, 'refundNotice'] |
|
| 43 | + ); |
|
| 44 | 44 | |
| 45 | - parent::__construct($pm_instance); |
|
| 46 | - } |
|
| 45 | + parent::__construct($pm_instance); |
|
| 46 | + } |
|
| 47 | 47 | |
| 48 | 48 | |
| 49 | - /** |
|
| 50 | - * Generate a new payment method settings form. |
|
| 51 | - * |
|
| 52 | - * @return EE_Payment_Method_Form |
|
| 53 | - * @throws EE_Error |
|
| 54 | - * @throws ReflectionException |
|
| 55 | - */ |
|
| 56 | - public function generate_new_settings_form() |
|
| 57 | - { |
|
| 58 | - // Settings form. |
|
| 59 | - $settings_form = new SettingsForm($this, $this->_pm_instance); |
|
| 60 | - // Filter the form contents. |
|
| 61 | - return apply_filters( |
|
| 62 | - 'FHEE__EE_PMT_PayPalCheckout__generate_new_settings_form__form_filtering', |
|
| 63 | - $settings_form, |
|
| 64 | - $this, |
|
| 65 | - $this->_pm_instance |
|
| 66 | - ); |
|
| 67 | - } |
|
| 49 | + /** |
|
| 50 | + * Generate a new payment method settings form. |
|
| 51 | + * |
|
| 52 | + * @return EE_Payment_Method_Form |
|
| 53 | + * @throws EE_Error |
|
| 54 | + * @throws ReflectionException |
|
| 55 | + */ |
|
| 56 | + public function generate_new_settings_form() |
|
| 57 | + { |
|
| 58 | + // Settings form. |
|
| 59 | + $settings_form = new SettingsForm($this, $this->_pm_instance); |
|
| 60 | + // Filter the form contents. |
|
| 61 | + return apply_filters( |
|
| 62 | + 'FHEE__EE_PMT_PayPalCheckout__generate_new_settings_form__form_filtering', |
|
| 63 | + $settings_form, |
|
| 64 | + $this, |
|
| 65 | + $this->_pm_instance |
|
| 66 | + ); |
|
| 67 | + } |
|
| 68 | 68 | |
| 69 | 69 | |
| 70 | - /** |
|
| 71 | - * Creates a billing form for this payment method type. |
|
| 72 | - * |
|
| 73 | - * @param EE_Transaction|null $transaction |
|
| 74 | - * @param array|null $extra_args |
|
| 75 | - * @return EE_Billing_Info_Form|null |
|
| 76 | - * @throws EE_Error |
|
| 77 | - * @throws ReflectionException |
|
| 78 | - */ |
|
| 79 | - public function generate_new_billing_form(EE_Transaction $transaction = null, ?array $extra_args = []) |
|
| 80 | - { |
|
| 81 | - $request = LoaderFactory::getShared(Request::class); |
|
| 82 | - $request_params = $request->requestParams(); |
|
| 83 | - // Return the default billing form for the postbox if this is a WP admin transaction info page. |
|
| 84 | - if (! empty($request_params['page']) && $request_params['page'] === 'espresso_transactions') { |
|
| 85 | - $default_form = new EE_Billing_Attendee_Info_Form($this->_pm_instance, $extra_args); |
|
| 86 | - $default_form->add_subsections(['credit_card' => new EE_Credit_Card_Input()]); |
|
| 87 | - return $default_form; |
|
| 88 | - } |
|
| 89 | - // Just in case this is used on other admin pages. |
|
| 90 | - if (empty($transaction) && ! empty($request_params['TXN_ID'])) { |
|
| 91 | - $txn_instance = EEM_Transaction::instance()->get_one_by_ID($request_params['TXN_ID']); |
|
| 92 | - $transaction = $txn_instance instanceof EE_Transaction ? $txn_instance : null; |
|
| 93 | - } |
|
| 94 | - $options = array_merge( |
|
| 95 | - [ |
|
| 96 | - 'transaction' => $transaction, |
|
| 97 | - 'template_path' => $this->_template_path, |
|
| 98 | - ], |
|
| 99 | - $extra_args |
|
| 100 | - ); |
|
| 101 | - return LoaderFactory::getNew(BillingForm::class, [$this->_pm_instance, $options]); |
|
| 102 | - } |
|
| 70 | + /** |
|
| 71 | + * Creates a billing form for this payment method type. |
|
| 72 | + * |
|
| 73 | + * @param EE_Transaction|null $transaction |
|
| 74 | + * @param array|null $extra_args |
|
| 75 | + * @return EE_Billing_Info_Form|null |
|
| 76 | + * @throws EE_Error |
|
| 77 | + * @throws ReflectionException |
|
| 78 | + */ |
|
| 79 | + public function generate_new_billing_form(EE_Transaction $transaction = null, ?array $extra_args = []) |
|
| 80 | + { |
|
| 81 | + $request = LoaderFactory::getShared(Request::class); |
|
| 82 | + $request_params = $request->requestParams(); |
|
| 83 | + // Return the default billing form for the postbox if this is a WP admin transaction info page. |
|
| 84 | + if (! empty($request_params['page']) && $request_params['page'] === 'espresso_transactions') { |
|
| 85 | + $default_form = new EE_Billing_Attendee_Info_Form($this->_pm_instance, $extra_args); |
|
| 86 | + $default_form->add_subsections(['credit_card' => new EE_Credit_Card_Input()]); |
|
| 87 | + return $default_form; |
|
| 88 | + } |
|
| 89 | + // Just in case this is used on other admin pages. |
|
| 90 | + if (empty($transaction) && ! empty($request_params['TXN_ID'])) { |
|
| 91 | + $txn_instance = EEM_Transaction::instance()->get_one_by_ID($request_params['TXN_ID']); |
|
| 92 | + $transaction = $txn_instance instanceof EE_Transaction ? $txn_instance : null; |
|
| 93 | + } |
|
| 94 | + $options = array_merge( |
|
| 95 | + [ |
|
| 96 | + 'transaction' => $transaction, |
|
| 97 | + 'template_path' => $this->_template_path, |
|
| 98 | + ], |
|
| 99 | + $extra_args |
|
| 100 | + ); |
|
| 101 | + return LoaderFactory::getNew(BillingForm::class, [$this->_pm_instance, $options]); |
|
| 102 | + } |
|
| 103 | 103 | |
| 104 | 104 | |
| 105 | - /** |
|
| 106 | - * Adds PM info to the help tab. |
|
| 107 | - * |
|
| 108 | - * @return array |
|
| 109 | - * @see EE_PMT_Base::help_tabs_config() |
|
| 110 | - */ |
|
| 111 | - public function help_tabs_config(): array |
|
| 112 | - { |
|
| 113 | - return [ |
|
| 114 | - $this->get_help_tab_name() => [ |
|
| 115 | - 'title' => esc_html__('PayPal Commerce settings', 'event_espresso'), |
|
| 116 | - 'filename' => 'pp-commerce-overview', |
|
| 117 | - ], |
|
| 118 | - ]; |
|
| 119 | - } |
|
| 105 | + /** |
|
| 106 | + * Adds PM info to the help tab. |
|
| 107 | + * |
|
| 108 | + * @return array |
|
| 109 | + * @see EE_PMT_Base::help_tabs_config() |
|
| 110 | + */ |
|
| 111 | + public function help_tabs_config(): array |
|
| 112 | + { |
|
| 113 | + return [ |
|
| 114 | + $this->get_help_tab_name() => [ |
|
| 115 | + 'title' => esc_html__('PayPal Commerce settings', 'event_espresso'), |
|
| 116 | + 'filename' => 'pp-commerce-overview', |
|
| 117 | + ], |
|
| 118 | + ]; |
|
| 119 | + } |
|
| 120 | 120 | |
| 121 | 121 | |
| 122 | - /** |
|
| 123 | - * Adds a refund related message section. |
|
| 124 | - * |
|
| 125 | - * @param bool $can_edit_payments Flag that tells if user can edit payments. |
|
| 126 | - * @access public |
|
| 127 | - * @return void |
|
| 128 | - */ |
|
| 129 | - public static function refundNotice(bool $can_edit_payments) |
|
| 130 | - { |
|
| 131 | - if (! $can_edit_payments) { |
|
| 132 | - return; |
|
| 133 | - } |
|
| 134 | - $request = LoaderFactory::getLoader()->getShared(RequestInterface::class); |
|
| 135 | - $txn_id = $request->getRequestParam('TXN_ID', 0, DataType::INT); |
|
| 136 | - try { |
|
| 137 | - $transaction = EEM_Transaction::instance()->get_one_by_ID($txn_id); |
|
| 138 | - if (! $transaction instanceof EE_Transaction) { |
|
| 139 | - return; |
|
| 140 | - } |
|
| 141 | - // Was this transaction paid using PayPal ? |
|
| 142 | - if (strpos((string) $transaction->payment_method(), 'PayPal Commerce') === false) { |
|
| 143 | - return; |
|
| 144 | - } |
|
| 145 | - // Try loading the template. |
|
| 146 | - EE_Registry::instance()->load_helper('Template'); |
|
| 147 | - } catch (EE_Error | ReflectionException $e) { |
|
| 148 | - // Just return, adding nothing. |
|
| 149 | - return; |
|
| 150 | - } |
|
| 151 | - $html = EEH_Template::locate_template( |
|
| 152 | - apply_filters( |
|
| 153 | - 'FHEEA__EE_PMT_PayPalCheckout__refundNotice', |
|
| 154 | - dirname(__FILE__) . DS . 'templates' . DS . 'apply-refund-notice.template.php' |
|
| 155 | - ) |
|
| 156 | - ); |
|
| 157 | - echo $html; |
|
| 158 | - } |
|
| 122 | + /** |
|
| 123 | + * Adds a refund related message section. |
|
| 124 | + * |
|
| 125 | + * @param bool $can_edit_payments Flag that tells if user can edit payments. |
|
| 126 | + * @access public |
|
| 127 | + * @return void |
|
| 128 | + */ |
|
| 129 | + public static function refundNotice(bool $can_edit_payments) |
|
| 130 | + { |
|
| 131 | + if (! $can_edit_payments) { |
|
| 132 | + return; |
|
| 133 | + } |
|
| 134 | + $request = LoaderFactory::getLoader()->getShared(RequestInterface::class); |
|
| 135 | + $txn_id = $request->getRequestParam('TXN_ID', 0, DataType::INT); |
|
| 136 | + try { |
|
| 137 | + $transaction = EEM_Transaction::instance()->get_one_by_ID($txn_id); |
|
| 138 | + if (! $transaction instanceof EE_Transaction) { |
|
| 139 | + return; |
|
| 140 | + } |
|
| 141 | + // Was this transaction paid using PayPal ? |
|
| 142 | + if (strpos((string) $transaction->payment_method(), 'PayPal Commerce') === false) { |
|
| 143 | + return; |
|
| 144 | + } |
|
| 145 | + // Try loading the template. |
|
| 146 | + EE_Registry::instance()->load_helper('Template'); |
|
| 147 | + } catch (EE_Error | ReflectionException $e) { |
|
| 148 | + // Just return, adding nothing. |
|
| 149 | + return; |
|
| 150 | + } |
|
| 151 | + $html = EEH_Template::locate_template( |
|
| 152 | + apply_filters( |
|
| 153 | + 'FHEEA__EE_PMT_PayPalCheckout__refundNotice', |
|
| 154 | + dirname(__FILE__) . DS . 'templates' . DS . 'apply-refund-notice.template.php' |
|
| 155 | + ) |
|
| 156 | + ); |
|
| 157 | + echo $html; |
|
| 158 | + } |
|
| 159 | 159 | } |