From 92415491eb39f2a257b2c0d20d0c039078b319ed Mon Sep 17 00:00:00 2001 From: Remco Tolsma <869674+remcotolsma@users.noreply.github.com> Date: Wed, 13 Jul 2022 09:56:48 +0200 Subject: [PATCH 1/8] Use payment methods register methods. --- src/Gateway.php | 48 +++++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/src/Gateway.php b/src/Gateway.php index da229c2..227ce98 100644 --- a/src/Gateway.php +++ b/src/Gateway.php @@ -13,6 +13,7 @@ use Pronamic\WordPress\Money\Money; use Pronamic\WordPress\Money\TaxedMoney; use Pronamic\WordPress\Pay\Core\Gateway as Core_Gateway; +use Pronamic\WordPress\Pay\Core\PaymentMethod; use Pronamic\WordPress\Pay\Core\PaymentMethods; use Pronamic\WordPress\Pay\Payments\Payment; @@ -57,28 +58,9 @@ public function __construct( Config $config ) { // Client. $this->client = new Client( $config ); - } - /** - * Get supported payment methods - * - * @see Core_Gateway::get_supported_payment_methods() - * @return array - */ - public function get_supported_payment_methods() { - return array( - PaymentMethods::PAYPAL, - ); - } - - /** - * Is payment method required to start transaction? - * - * @see Core_Gateway::payment_method_is_required() - * @return true - */ - public function payment_method_is_required() { - return true; + // Methods. + $this->register_payment_method( new PaymentMethod( PaymentMethods::PAYPAL ) ); } /** @@ -90,6 +72,30 @@ public function payment_method_is_required() { * @see Plugin::start() */ public function start( Payment $payment ) { + /** + * If the payment method of the payment is unknown (`null`), we will turn it into + * an PayPal payment. + */ + $payment_method = $payment->get_payment_method(); + + if ( null === $payment_method ) { + $payment->set_payment_method( PaymentMethods::PAYPAL ); + } + + /** + * This gateway can only process payments for the payment method PayPal. + */ + $payment_method = $payment->get_payment_method(); + + if ( PaymentMethods::PAYPAL !== $payment_method ) { + throw new \Exception( + \sprintf( + 'The PayPal cannot process `%s` payments, only PayPal payments.', + $payment_method + ) + ); + } + /** * HTML Variables for PayPal Payments Standard * From c5a4b1747550e3f1086fc315cf219bf22ca47ae8 Mon Sep 17 00:00:00 2001 From: Remco Tolsma <869674+remcotolsma@users.noreply.github.com> Date: Wed, 13 Jul 2022 11:58:13 +0200 Subject: [PATCH 2/8] Mark PayPal payment method as active. --- src/Gateway.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Gateway.php b/src/Gateway.php index 227ce98..94c6dae 100644 --- a/src/Gateway.php +++ b/src/Gateway.php @@ -60,7 +60,10 @@ public function __construct( Config $config ) { $this->client = new Client( $config ); // Methods. - $this->register_payment_method( new PaymentMethod( PaymentMethods::PAYPAL ) ); + $payment_method_paypal = new PaymentMethod( PaymentMethods::PAYPAL ); + $payment_method_paypal->set_status( 'active' ); + + $this->register_payment_method( $payment_method_paypal ); } /** From 9ebed040399d17e7b5e1b2fec46766a0e21441fe Mon Sep 17 00:00:00 2001 From: Remco Tolsma <869674+remcotolsma@users.noreply.github.com> Date: Mon, 22 Aug 2022 14:09:53 +0200 Subject: [PATCH 3/8] Rename `$paypal_config` to just `$config`. --- src/Gateway.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Gateway.php b/src/Gateway.php index 94c6dae..0d6d2d5 100644 --- a/src/Gateway.php +++ b/src/Gateway.php @@ -30,7 +30,7 @@ class Gateway extends Core_Gateway { * * @var Config */ - protected $paypal_config; + protected $config; /** * Client. @@ -45,9 +45,9 @@ class Gateway extends Core_Gateway { * @param Config $config Config. */ public function __construct( Config $config ) { - parent::__construct( $config ); + parent::__construct(); - $this->paypal_config = $config; + $this->config = $config; $this->set_method( self::METHOD_HTTP_REDIRECT ); @@ -105,11 +105,11 @@ public function start( Payment $payment ) { * @link https://developer.paypal.com/docs/paypal-payments-standard/integration-guide/Appx-websitestandard-htmlvariables/ * @link https://github.com/easydigitaldownloads/easy-digital-downloads/blob/2.9.26/includes/gateways/paypal-standard.php */ - $url = $this->paypal_config->get_webscr_url(); + $url = $this->config->get_webscr_url(); $variables = new Variables(); - $variables->set_business( $this->paypal_config->get_email() ); + $variables->set_business( $this->config->get_email() ); $variables->set_cmd( '_cart' ); $variables->set_upload( true ); From 49adf0db257ec91084e538f757bc7d4cf8da23fe Mon Sep 17 00:00:00 2001 From: Remco Tolsma <869674+remcotolsma@users.noreply.github.com> Date: Wed, 24 Aug 2022 16:17:50 +0200 Subject: [PATCH 4/8] Remove support for `PaymentStatus::RESERVED`. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I think the PayPal `REVERSED` status did not have the same meaning as a Sisow `REVERSED` status. > "A ‘reversed’ payment is when your money is refunded as the sale could not be completed by the seller. You should be able to get your money back in 48 hours and depending on the Payment Source this may be delayed further like in the case of credit cards. In some cases, the refunds have taken longer and only after following up with Papal and the seller." https://www.quora.com/What-is-reversed-state-in-Paypal-payment-status --- src/NotificationsController.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/NotificationsController.php b/src/NotificationsController.php index 87e4338..2351beb 100644 --- a/src/NotificationsController.php +++ b/src/NotificationsController.php @@ -277,10 +277,6 @@ public function rest_api_paypal_ipn( WP_REST_Request $request ) { $payment->set_transaction_id( $transaction_id ); } - break; - case Statuses::REVERSED: - $payment->set_status( PaymentStatus::RESERVED ); - break; case Statuses::PROCESSED: break; From 4fe6aff82d7c4cf0791233d598ffbfa9dfa252e7 Mon Sep 17 00:00:00 2001 From: Remco Tolsma <869674+remcotolsma@users.noreply.github.com> Date: Fri, 2 Sep 2022 15:06:02 +0200 Subject: [PATCH 5/8] Add wp-env. --- .wp-env.json | 14 ++++++++++++++ package.json | 10 +++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 .wp-env.json diff --git a/.wp-env.json b/.wp-env.json new file mode 100644 index 0000000..3be6550 --- /dev/null +++ b/.wp-env.json @@ -0,0 +1,14 @@ +{ + "core": null, + "plugins": [ + ".", + "../../../", + "pronamic/wp-pronamic-pay-test-helper", + "https://downloads.wordpress.org/plugin/pronamic-client.zip", + "https://downloads.wordpress.org/plugin/query-monitor.zip", + "https://downloads.wordpress.org/plugin/one-time-login.zip" + ], + "config": { + "PRONAMIC_PAY_DEBUG": true + } +} diff --git a/package.json b/package.json index ea3c101..2722506 100644 --- a/package.json +++ b/package.json @@ -36,10 +36,18 @@ "eslint": "eslint . --ext .json --ext .js" }, "devDependencies": { + "@wordpress/env": "^5.2.0", "@babel/cli": "^7.12.8", "@babel/core": "^7.12.9", "@babel/preset-env": "^7.12.7", "eslint": "^7.14.0", - "eslint-plugin-json": "^2.1.2" + "eslint-plugin-json": "^2.1.2", + "npm-run-all": "^4.1.5" + }, + "scripts": { + "start": "wp-env start && npm run setup && npm run login", + "setup": "npm-run-all setup-*", + "setup-mollie": "wp-env run cli wp config set PRONAMIC_PAY_PAYPAL_EMAIL $PRONAMIC_PAY_PAYPAL_EMAIL", + "login": "wp-env run cli wp user one-time-login admin" } } From aea3cd5645b85c022b264163b8ec84e2250163f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reu=CC=88el=20van=20der=20Steege?= Date: Mon, 26 Sep 2022 10:28:26 +0200 Subject: [PATCH 6/8] Disable Xdebug in `phpcbf` Composer command. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 78eb780..46dc005 100644 --- a/composer.json +++ b/composer.json @@ -68,7 +68,7 @@ "@psalm" ], "coveralls": "vendor/bin/php-coveralls -v", - "phpcbf": "vendor/bin/phpcbf", + "phpcbf": "XDEBUG_MODE=off vendor/bin/phpcbf", "phpcs": "XDEBUG_MODE=off vendor/bin/phpcs -s -v", "phplint": "vendor/bin/phplint", "phpmd": "vendor/bin/phpmd src,tests text phpmd.ruleset.xml --suffixes php", From 967a302c55ca27d4800762c93db92ae7d83997dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reu=CC=88el=20van=20der=20Steege?= Date: Mon, 26 Sep 2022 13:53:45 +0200 Subject: [PATCH 7/8] Coding standards. --- phpcs.xml.dist | 7 ++- pronamic-pay-paypal.php | 8 +-- src/Config.php | 4 +- src/Gateway.php | 7 +-- src/Integration.php | 20 ++++---- src/NotificationsController.php | 90 ++++++++++++++++----------------- src/Variables.php | 2 +- 7 files changed, 72 insertions(+), 66 deletions(-) diff --git a/phpcs.xml.dist b/phpcs.xml.dist index d1b4436..31f41f0 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -6,9 +6,14 @@ tests/bootstrap.php tests/wp-config.php - + + + + + + diff --git a/pronamic-pay-paypal.php b/pronamic-pay-paypal.php index f37fd8b..729a90f 100644 --- a/pronamic-pay-paypal.php +++ b/pronamic-pay-paypal.php @@ -34,23 +34,23 @@ 'pronamic_pay_gateways', function( $gateways ) { $gateways[] = new \Pronamic\WordPress\Pay\Gateways\PayPal\Integration( - array( + [ 'id' => 'paypal', 'name' => 'PayPal', 'mode' => 'live', 'webscr_url' => 'https://www.paypal.com/cgi-bin/webscr', 'ipn_pb_url' => 'https://ipnpb.paypal.com/cgi-bin/webscr', - ) + ] ); $gateways[] = new \Pronamic\WordPress\Pay\Gateways\PayPal\Integration( - array( + [ 'id' => 'paypal-sandbox', 'name' => 'PayPal - Sandbox', 'mode' => 'test', 'webscr_url' => 'https://www.sandbox.paypal.com/cgi-bin/webscr', 'ipn_pb_url' => 'https://ipnpb.sandbox.paypal.com/cgi-bin/webscr', - ) + ] ); return $gateways; diff --git a/src/Config.php b/src/Config.php index e17b169..85000b9 100644 --- a/src/Config.php +++ b/src/Config.php @@ -89,8 +89,8 @@ public function get_email() { * @return object */ public function jsonSerialize() { - return (object) array( + return (object) [ 'email' => $this->email, - ); + ]; } } diff --git a/src/Gateway.php b/src/Gateway.php index 0d6d2d5..e9c7c72 100644 --- a/src/Gateway.php +++ b/src/Gateway.php @@ -52,9 +52,9 @@ public function __construct( Config $config ) { $this->set_method( self::METHOD_HTTP_REDIRECT ); // Supported features. - $this->supports = array( + $this->supports = [ 'payment_status_request', - ); + ]; // Client. $this->client = new Client( $config ); @@ -72,6 +72,7 @@ public function __construct( Config $config ) { * @param Payment $payment Payment. * @return void * @throws \InvalidArgumentException Throws exception if payment ID or currency is empty. + * @throws \Exception Throws exception Throws exception on unsupported payment method. * @see Plugin::start() */ public function start( Payment $payment ) { @@ -281,7 +282,7 @@ private function format_amount( Money $amount ) { * @return array */ private function get_shopping_cart_variables( Payment $payment ) { - $variables = array(); + $variables = []; $lines = $payment->get_lines(); diff --git a/src/Integration.php b/src/Integration.php index f9ff82c..fe3933a 100644 --- a/src/Integration.php +++ b/src/Integration.php @@ -47,10 +47,10 @@ class Integration extends AbstractGatewayIntegration { * * @param array> $args Arguments. */ - public function __construct( $args = array() ) { + public function __construct( $args = [] ) { $args = \wp_parse_args( $args, - array( + [ 'id' => 'paypal', 'name' => 'PayPal', 'mode' => 'live', @@ -64,8 +64,8 @@ public function __construct( $args = array() ) { 'https://www.pronamic.eu/manuals/using-paypal-pronamic-pay/', 'pronamic_ideal' ), - 'supports' => array(), - ) + 'supports' => [], + ] ); parent::__construct( $args ); @@ -80,12 +80,12 @@ public function __construct( $args = array() ) { public function setup() { \add_filter( 'pronamic_gateway_configuration_display_value_' . $this->get_id(), - array( $this, 'gateway_configuration_display_value' ), + [ $this, 'gateway_configuration_display_value' ], 10, 2 ); - \add_filter( 'pronamic_payment_provider_url_paypal', array( $this, 'payment_provider_url' ), 10, 2 ); + \add_filter( 'pronamic_payment_provider_url_paypal', [ $this, 'payment_provider_url' ], 10, 2 ); // Notifications controller. $notifications_controller = new NotificationsController( $this ); @@ -129,18 +129,18 @@ public function payment_provider_url( $url, Payment $payment ) { * @return array>> */ public function get_settings_fields() { - $fields = array(); + $fields = []; // Business Id. - $fields[] = array( + $fields[] = [ 'section' => 'general', 'filter' => \FILTER_SANITIZE_STRING, 'meta_key' => '_pronamic_gateway_paypal_email', 'title' => \_x( 'Email', 'paypal', 'pronamic_ideal' ), 'type' => 'text', - 'classes' => array( 'regular-text', 'code' ), + 'classes' => [ 'regular-text', 'code' ], 'tooltip' => \__( 'Enter your PayPal account\'s email.', 'pronamic_ideal' ), - ); + ]; // Return fields. return $fields; diff --git a/src/NotificationsController.php b/src/NotificationsController.php index 2351beb..edf3250 100644 --- a/src/NotificationsController.php +++ b/src/NotificationsController.php @@ -47,7 +47,7 @@ public function __construct( Integration $integration ) { * @return void */ public function setup() { - \add_action( 'rest_api_init', array( $this, 'rest_api_init' ) ); + \add_action( 'rest_api_init', [ $this, 'rest_api_init' ] ); } /** @@ -61,80 +61,80 @@ public function rest_api_init() { \register_rest_route( Integration::REST_ROUTE_NAMESPACE, '/ipn-listener', - array( + [ /** * IPN and PDT variables. * * @link https://developer.paypal.com/docs/api-basics/notifications/ipn/IPNandPDTVariables/ */ - 'args' => array( - 'custom' => array( + 'args' => [ + 'custom' => [ 'description' => \__( 'Custom.', 'pronamic_ideal' ), 'type' => 'string', - ), - 'payment_status' => array( + ], + 'payment_status' => [ 'description' => \__( 'The status of the payment.', 'pronamic_ideal' ), 'type' => 'string', - ), - 'txn_id' => array( + ], + 'txn_id' => [ 'description' => \__( 'The merchant\'s original transaction identification number for the payment from the buyer, against which the case was registered.', 'pronamic_ideal' ), 'type' => 'string', - ), - 'parent_txn_id' => array( + ], + 'parent_txn_id' => [ 'description' => \__( 'In the case of a refund, reversal, or canceled reversal, this variable contains the `txn_id` of the original transaction.', 'pronamic_ideal' ), 'type' => 'string', - ), - 'mc_currency' => array( + ], + 'mc_currency' => [ 'description' => \__( 'For payment IPN notifications, this is the currency of the payment.', 'pronamic_ideal' ), 'type' => 'string', - ), - 'mc_gross' => array( + ], + 'mc_gross' => [ 'description' => \__( 'Full amount of the customer\'s payment, before transaction fee is subtracted. Equivalent to payment_gross for USD payments. If this amount is negative, it signifies a refund or reversal, and either of those payment statuses can be for the full or partial amount of the original transaction.', 'pronamic_ideal' ), 'type' => 'string', - ), - ), + ], + ], 'methods' => 'POST', - 'callback' => array( $this, 'rest_api_paypal_ipn' ), + 'callback' => [ $this, 'rest_api_paypal_ipn' ], 'permission_callback' => '__return_true', - ) + ] ); \register_rest_route( Integration::REST_ROUTE_NAMESPACE, '/cancel-return/(?P\d+)', - array( + [ /** * IPN and PDT variables. * * @link https://developer.paypal.com/docs/api-basics/notifications/ipn/IPNandPDTVariables/ */ - 'args' => array( - 'hash' => array( + 'args' => [ + 'hash' => [ 'description' => \__( 'Hash.', 'pronamic_ideal' ), 'type' => 'string', - ), - 'payment_id' => array( + ], + 'payment_id' => [ 'description' => \__( 'Payment ID.', 'pronamic_ideal' ), 'type' => 'string', - ), - ), + ], + ], 'methods' => 'GET', - 'callback' => array( $this, 'rest_api_paypal_cancel_return' ), - 'permission_callback' => array( $this, 'rest_api_paypal_cancel_return_permission' ), - ) + 'callback' => [ $this, 'rest_api_paypal_cancel_return' ], + 'permission_callback' => [ $this, 'rest_api_paypal_cancel_return_permission' ], + ] ); } @@ -153,9 +153,9 @@ public function rest_api_paypal_ipn( WP_REST_Request $request ) { return new \WP_Error( 'rest_paypal_empty_custom_variable', \__( 'Empty `custom` PayPal variable.', 'pronamic_ideal ' ), - array( + [ 'status' => 200, - ) + ] ); } @@ -169,9 +169,9 @@ public function rest_api_paypal_ipn( WP_REST_Request $request ) { \__( 'No payment found by `custom` variable: %s.', 'pronamic_ideal ' ), $custom ), - array( + [ 'status' => 200, - ) + ] ); } @@ -197,17 +197,17 @@ public function rest_api_paypal_ipn( WP_REST_Request $request ) { */ $response = Http::post( $ipn_pb_url, - array( - 'headers' => array( + [ + 'headers' => [ /** * Please ensure you provide a User-Agent header value that * describes your IPN listener, such as, * `PHP-IPN-VerificationScript`. */ 'User-Agent' => 'Pronamic-Pay-IPN-VerificationScript', - ), + ], 'body' => $pb_body, - ) + ] ); $result = $response->body(); @@ -216,9 +216,9 @@ public function rest_api_paypal_ipn( WP_REST_Request $request ) { return new \WP_Error( 'rest_paypal_ipn_invalid', \__( 'IPN request invalid.', 'pronamic_ideal ' ), - array( + [ 'status' => 200, - ) + ] ); } @@ -226,9 +226,9 @@ public function rest_api_paypal_ipn( WP_REST_Request $request ) { return new \WP_Error( 'rest_paypal_ipn_not_verified', \__( 'IPN request not verified.', 'pronamic_ideal ' ), - array( + [ 'status' => 200, - ) + ] ); } @@ -297,11 +297,11 @@ public function rest_api_paypal_ipn( WP_REST_Request $request ) { /** * Result. */ - $result = (object) array( + $result = (object) [ 'body' => $request->get_body(), 'custom' => $request->get_param( 'custom' ), 'result' => $result, - ); + ]; return $result; } @@ -347,9 +347,9 @@ public function rest_api_paypal_cancel_return( WP_REST_Request $request ) { \__( 'No payment found by `payment_id` variable: %s.', 'pronamic_ideal ' ), (string) $payment_id ), - array( + [ 'status' => 404, - ) + ] ); } @@ -369,6 +369,6 @@ public function rest_api_paypal_cancel_return( WP_REST_Request $request ) { * * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/303 */ - return new \WP_REST_Response( null, 303, array( 'Location' => $payment->get_return_redirect_url() ) ); + return new \WP_REST_Response( null, 303, [ 'Location' => $payment->get_return_redirect_url() ] ); } } diff --git a/src/Variables.php b/src/Variables.php index ac781ce..591f722 100644 --- a/src/Variables.php +++ b/src/Variables.php @@ -29,7 +29,7 @@ class Variables { * Construct variables object. */ public function __construct() { - $this->variables = array(); + $this->variables = []; } /** From 4d3c775cca47118e8f9d0249358ccc71887dee4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reu=CC=88el=20van=20der=20Steege?= Date: Mon, 26 Sep 2022 13:54:29 +0200 Subject: [PATCH 8/8] Getting ready for version 2.2.0. --- CHANGELOG.md | 6 +++++- package.json | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a66e94d..2d0e674 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased][unreleased] +## [2.2.0] - 2022-09-26 +- Updated payment methods registration. + ## [2.1.0] - 2022-04-11 - No longer use global core mode. @@ -22,7 +25,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [1.0.0] - 2021-08-05 - First release. -[unreleased]: https://github.com/wp-pay-gateways/paypal/compare/2.1.0...HEAD +[unreleased]: https://github.com/wp-pay-gateways/paypal/compare/2.2.0...HEAD +[2.2.0]: https://github.com/pronamic/wp-pronamic-pay-paypal/compare/2.1.0...2.2.0 [2.1.0]: https://github.com/wp-pay-gateways/paypal/compare/2.0.0...2.1.0 [2.0.0]: https://github.com/wp-pay-gateways/paypal/compare/1.0.2...2.0.0 [1.0.2]: https://github.com/wp-pay-gateways/paypal/compare/1.0.1...1.0.2 diff --git a/package.json b/package.json index 2722506..8ee69b1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "paypal", - "version": "2.1.0", + "version": "2.2.0", "description": "PayPal driver for the WordPress payment processing library.", "repository": { "type": "git",