diff --git a/CHANGELOG.md b/CHANGELOG.md index d7123fc408..be58bf75cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,18 +6,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Releases -### [5.0.32] +### [5.0.33] #### Fixed + - [Fix Registration Refunds (#1638)](https://github.com/eventespresso/cafe/pull/1638) + - [PPC. Fix amount rounding issue (#1622)](https://github.com/eventespresso/cafe/pull/1622) + - [PPC. Fix double payments created (#1667)](https://github.com/eventespresso/cafe/pull/1667) + + + + + + +### [5.0.32] + +#### Added -#### Changed - [Move PM Deprecation Dates (#1676)](https://github.com/eventespresso/cafe/pull/1676) + ### [5.0.31] @@ -33,6 +45,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 + ### [5.0.30] #### Added diff --git a/PaymentMethods/PayPalCommerce/PayPalCheckout/EEG_PayPalCheckout.gateway.php b/PaymentMethods/PayPalCommerce/PayPalCheckout/EEG_PayPalCheckout.gateway.php index 022604ac71..dc51ddabaf 100644 --- a/PaymentMethods/PayPalCommerce/PayPalCheckout/EEG_PayPalCheckout.gateway.php +++ b/PaymentMethods/PayPalCommerce/PayPalCheckout/EEG_PayPalCheckout.gateway.php @@ -71,7 +71,7 @@ public function do_direct_payment($payment, $billing_info = null) if (! $order_id) { return EEG_PayPalCheckout::updatePaymentStatus( $payment, - EEM_Payment::status_id_failed, + EEM_Payment::status_id_declined, $post_parameters, esc_html__('Can\'t charge the Order. The Order ID is missing.', 'event_espresso') ); @@ -83,7 +83,7 @@ public function do_direct_payment($payment, $billing_info = null) if (! $order_status['completed']) { return EEG_PayPalCheckout::updatePaymentStatus( $payment, - EEM_Payment::status_id_failed, + EEM_Payment::status_id_declined, $order_status, $order_status['message'] ?? '' ); @@ -151,31 +151,6 @@ public static function isOrderCompleted( } - /** - * Create an EE Payment. - * - * @param EE_Transaction $transaction - * @param EE_Payment_Method $payment_method - * @return EE_Payment - * @throws EE_Error - * @throws ReflectionException - */ - public static function createPayment(EE_Transaction $transaction, EE_Payment_Method $payment_method): EE_Payment - { - // No payment for this transaction was created at this point. - $payment = EE_Payment::new_instance([ - 'PAY_timestamp' => time(), - 'TXN_ID' => $transaction->ID(), - 'PMD_ID' => $payment_method->ID(), - 'PAY_po_number' => null, - 'PAY_extra_accntng' => null, - 'PAY_details' => null, - ]); - $payment->save(); - return $payment; - } - - /** * Set a payment error and log the data. * diff --git a/PaymentMethods/PayPalCommerce/api/orders/CreateOrder.php b/PaymentMethods/PayPalCommerce/api/orders/CreateOrder.php index 60cd047e6c..71a991a49b 100644 --- a/PaymentMethods/PayPalCommerce/api/orders/CreateOrder.php +++ b/PaymentMethods/PayPalCommerce/api/orders/CreateOrder.php @@ -101,7 +101,7 @@ public function __construct(PayPalApi $api, EE_Transaction $transaction, array $ */ public function sanitizeRequestParameters(array $billing_info): void { - $sanitizer = new RequestSanitizer(new Basic()); + $sanitizer = new RequestSanitizer(new Basic()); foreach ($billing_info as $item => $value) { $this->billing_info[ $item ] = $sanitizer->clean($value); } @@ -149,7 +149,7 @@ protected function getParameters(): array 'description' => substr(wp_strip_all_tags($description), 0, 125), 'items' => $this->getLineItems(), 'amount' => [ - 'value' => $this->transaction->remaining(), + 'value' => (string) CurrencyManager::normalizeValue($this->transaction->remaining()), 'currency_code' => $this->currency_code, 'breakdown' => $this->getBreakdown(), ], @@ -183,7 +183,7 @@ protected function getParameters(): array && ! empty($scopes) && in_array('partnerfee', $scopes) ) { /** @var PartnerPaymentFees $payment_fees */ - $payment_fees = LoaderFactory::getShared(PartnerPaymentFees::class); + $payment_fees = LoaderFactory::getShared(PartnerPaymentFees::class); $parameters['purchase_units'][0]['payment_instruction'] = [ 'platform_fees' => [ [ @@ -217,7 +217,7 @@ protected function getLineItems(): array && $line_item->OBJ_type() !== 'Promotion' && $line_item->quantity() > 0 ) { - $item_money = $line_item->unit_price(); + $item_money = CurrencyManager::normalizeValue($line_item->unit_price()); $li_description = $line_item->desc() ?? esc_html__('Event Ticket', 'event_espresso'); $line_items [] = [ 'name' => substr(wp_strip_all_tags($line_item->name()), 0, 126), @@ -225,7 +225,7 @@ protected function getLineItems(): array 'description' => substr(wp_strip_all_tags($li_description), 0, 125), 'unit_amount' => [ 'currency_code' => $this->currency_code, - 'value' => $item_money, + 'value' => (string) $item_money, ], 'category' => 'DIGITAL_GOODS', ]; @@ -275,15 +275,15 @@ protected function getBreakdown(): array { $breakdown['item_total'] = [ 'currency_code' => $this->currency_code, - 'value' => $this->items_total, + 'value' => (string) $this->items_total, ]; $breakdown['tax_total'] = [ 'currency_code' => $this->currency_code, - 'value' => $this->tax_total, + 'value' => (string) $this->tax_total, ]; $breakdown['discount'] = [ 'currency_code' => $this->currency_code, - 'value' => abs($this->promos_total), + 'value' => (string) abs($this->promos_total), ]; return $breakdown; } diff --git a/PaymentMethods/PayPalCommerce/modules/EED_PayPalCommerce.module.php b/PaymentMethods/PayPalCommerce/modules/EED_PayPalCommerce.module.php index 9aa12f9ab0..9f7b5f3e94 100644 --- a/PaymentMethods/PayPalCommerce/modules/EED_PayPalCommerce.module.php +++ b/PaymentMethods/PayPalCommerce/modules/EED_PayPalCommerce.module.php @@ -145,10 +145,22 @@ public static function createOrder( 'message' => esc_html__('The Create Order API request fault.', 'event_espresso'), ]; } - $payment = EEG_PayPalCheckout::createPayment($transaction, $paypal_pm); - $order = $create_order_api->create(); + // Make sure we have a payment method saved. + $payment_method = EED_PayPalCommerce::getPaymentMethod(); + if ($payment_method->ID()) { + $transaction->set_payment_method_ID($payment_method->ID()); + } + $order = $create_order_api->create(); if (isset($order['error'])) { - EEG_PayPalCheckout::updatePaymentStatus($payment, EEM_Payment::status_id_failed, $order, $order['error']); + $last_payment = $transaction->last_payment(); + if ($last_payment instanceof EE_Payment) { + EEG_PayPalCheckout::updatePaymentStatus( + $last_payment, + EEM_Payment::status_id_failed, + $order, + $order['error'] + ); + } return [ 'error' => 'CREATE_ORDER_API_RESPONSE_ERROR', 'message' => $order['message'], diff --git a/PaymentMethods/PayPalCommerce/tools/currency/CurrencyManager.php b/PaymentMethods/PayPalCommerce/tools/currency/CurrencyManager.php index d3a10d5553..6178170d19 100644 --- a/PaymentMethods/PayPalCommerce/tools/currency/CurrencyManager.php +++ b/PaymentMethods/PayPalCommerce/tools/currency/CurrencyManager.php @@ -49,20 +49,6 @@ public static function getDecimalPlaces(string $currency = ''): int } - /** - * Converts an amount into the currency's subunits. - * Some currencies have no subunits, so leave them in the currency's main units. - * - * @param float $amount - * @return float in the currency's smallest unit (e.g., pennies) - */ - public static function convertToSubunits(float $amount): float - { - $decimals = self::getDecimalPlaces(); - return round($amount * pow(10, $decimals), $decimals); - } - - /** * Make sure the value is an absolute number with only two decimal places. * @@ -71,8 +57,12 @@ public static function convertToSubunits(float $amount): float */ public static function normalizeValue(float $amount): float { - $decimals = self::getDecimalPlaces(); - return abs(number_format($amount, $decimals, '.', '')); + // Make sure we get a positive value. + // Don't use abs() because of the possible issues with rounding if 'serialize_precision' is not set to -1. + if ($amount < 0) { + $amount = $amount * -1; + } + return number_format($amount, self::getDecimalPlaces(), '.', ''); } diff --git a/espresso.php b/espresso.php index 1953bdec20..9224e0a528 100644 --- a/espresso.php +++ b/espresso.php @@ -3,7 +3,7 @@ Plugin Name: Event Espresso Plugin URI: https://eventespresso.com/pricing/?ee_ver=ee4&utm_source=ee4_plugin_admin&utm_medium=link&utm_campaign=wordpress_plugins_page&utm_content=support_link Description: Manage events, sell tickets, and receive payments from your WordPress website. Reduce event administration time, cut-out ticketing fees, and own your customer data. | Extensions | Sales | Support - Version: 5.0.33.rc.000 + Version: 5.0.33.rc.002 Author: Event Espresso Author URI: https://eventespresso.com/?ee_ver=ee4&utm_source=ee4_plugin_admin&utm_medium=link&utm_campaign=wordpress_plugins_page&utm_content=support_link License: GPLv3 @@ -104,7 +104,7 @@ function espresso_minimum_php_version_error() */ function espresso_version(): string { - return apply_filters('FHEE__espresso__espresso_version', '5.0.33.rc.000'); + return apply_filters('FHEE__espresso__espresso_version', '5.0.33.rc.002'); } /** diff --git a/info.json b/info.json index d218390083..53a6e8e6c3 100644 --- a/info.json +++ b/info.json @@ -1 +1 @@ -{"awsbucket":"","awsregion":"","decafFilesRemove":["src\/.babelrc","src\/.editorconfig","src\/.github\/**","src\/.travis.yml","src\/bin\/**","src\/caffeinated","src\/docs\/**","src\/info.json","src\/tests\/**","src\/wp-assets\/**"],"jsBuildDirectory":".\/","name":"Event Espresso Core","releaseFilesRemove":["src\/.babelrc","src\/.editorconfig","src\/.github\/**","src\/.travis.yml","src\/bin\/**","src\/docs\/**","src\/info.json","src\/readme.txt","src\/tests\/**","src\/wp-assets\/**"],"remoteNamesToPushTo":[],"slug":"event-espresso-core-reg","srcBuildFolderName":"event-espresso-core","textDomain":"event_espresso","versionFile":"espresso.php","wpi18nJsPotFilePath":".\/languages\/ee-js.pot","wpOrgMainFileSlug":"espresso","wpOrgPluginName":"Event Espresso 4 Decaf","wpOrgPluginUrl":"https:\/\/eventespresso.com\/pricing\/?ee_ver=ee4&utm_source=ee4_decaf_plugin_admin&utm_medium=link&utm_campaign=wordpress_plugins_page&utm_content=support_link","wpOrgRelease":"5.0.32.p","wpOrgSlug":"event-espresso-decaf","wpOrgUser":"eventespresso"} \ No newline at end of file +{"awsbucket":"","awsregion":"","decafFilesRemove":["src\/.babelrc","src\/.editorconfig","src\/.github\/**","src\/.travis.yml","src\/bin\/**","src\/caffeinated","src\/docs\/**","src\/info.json","src\/tests\/**","src\/wp-assets\/**"],"jsBuildDirectory":".\/","name":"Event Espresso Core","releaseFilesRemove":["src\/.babelrc","src\/.editorconfig","src\/.github\/**","src\/.travis.yml","src\/bin\/**","src\/docs\/**","src\/info.json","src\/readme.txt","src\/tests\/**","src\/wp-assets\/**"],"remoteNamesToPushTo":[],"slug":"event-espresso-core-reg","srcBuildFolderName":"event-espresso-core","textDomain":"event_espresso","versionFile":"espresso.php","wpi18nJsPotFilePath":".\/languages\/ee-js.pot","wpOrgMainFileSlug":"espresso","wpOrgPluginName":"Event Espresso 4 Decaf","wpOrgPluginUrl":"https:\/\/eventespresso.com\/pricing\/?ee_ver=ee4&utm_source=ee4_decaf_plugin_admin&utm_medium=link&utm_campaign=wordpress_plugins_page&utm_content=support_link","wpOrgRelease":"5.0.32.p","wpOrgSlug":"event-espresso-decaf","wpOrgUser":"eventespresso"}