Failed Conditions
Push — develop ( 8c1843...7824fe )
by Reüel
07:49
created

src/NotificationsController.php (1 issue)

Labels
Severity
1
<?php
2
/**
3
 * Notifications controller
4
 *
5
 * @author    Pronamic <[email protected]>
6
 * @copyright 2005-2019 Pronamic
7
 * @license   GPL-3.0-or-later
8
 * @package   Pronamic\WordPress\Pay\Gateways\Adyen
9
 */
10
11
namespace Pronamic\WordPress\Pay\Gateways\Adyen;
12
13
use InvalidArgumentException;
14
use Pronamic\WordPress\Pay\Core\Statuses as PaymentStatus;
15
use WP_Error;
16
use WP_REST_Request;
17
18
/**
19
 * Notification controller
20
 *
21
 * @link    https://docs.adyen.com/developers/api-reference/notifications-api#notificationrequest
22
 * @author  Remco Tolsma
23
 * @version 1.0.0
24
 * @since   1.0.0
25
 */
26
class NotificationsController {
27
	/**
28
	 * REST route namespace.
29
	 *
30
	 * @var string
31
	 */
32
	const REST_ROUTE_NAMESPACE = 'pronamic-pay/adyen/v1';
33
34
	/**
35
	 * Setup.
36
	 */
37 6
	public function setup() {
38 6
		add_action( 'rest_api_init', array( $this, 'rest_api_init' ) );
39 6
	}
40
41
	/**
42
	 * REST API init.
43
	 *
44
	 * @link https://developer.wordpress.org/rest-api/extending-the-rest-api/adding-custom-endpoints/
45
	 * @link https://developer.wordpress.org/reference/hooks/rest_api_init/
46
	 */
47 1
	public function rest_api_init() {
48 1
		register_rest_route(
49 1
			self::REST_ROUTE_NAMESPACE,
50 1
			'/notifications',
51
			array(
52 1
				'methods'             => 'POST',
53 1
				'callback'            => array( $this, 'rest_api_adyen_notifications' ),
54 1
				'permission_callback' => array( $this, 'rest_api_adyen_permissions_check' ),
55
			)
56
		);
57 1
	}
58
59
	/**
60
	 * REST API Adyen permissions check.
61
	 *
62
	 * @link https://developer.wordpress.org/rest-api/extending-the-rest-api/adding-custom-endpoints/#permissions-callback
63
	 *
64
	 * @param WP_REST_Request $request Request.
65
	 */
66 5
	public function rest_api_adyen_permissions_check( WP_REST_Request $request ) {
67 5
		$username = get_option( 'pronamic_pay_adyen_notification_authentication_username' );
68 5
		$password = get_option( 'pronamic_pay_adyen_notification_authentication_password' );
69
70 5
		if ( empty( $username ) && empty( $password ) ) {
71 4
			return true;
72
		}
73
74 1
		$authorization = $request->get_header( 'Authorization' );
75
76 1
		if ( 'Basic ' . base64_encode( $username . ':' . $password ) === $authorization ) {
77 1
			return true;
78
		}
79
80
		return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to post Adyen notifications.' ), array( 'status' => rest_authorization_required_code() ) );
81
	}
82
83
	/**
84
	 * REST API Adyen notifications handler.
85
	 *
86
	 * @param WP_REST_Request $request Request.
87
	 */
88 5
	public function rest_api_adyen_notifications( WP_REST_Request $request ) {
89 5
		$json = $request->get_body();
90
91 5
		$data = json_decode( $json );
92
93
		try {
94 5
			$notification_request = NotificationRequest::from_object( $data );
95 2
		} catch ( InvalidArgumentException $e ) {
96 2
			return new WP_Error( 'adyen_invalid_notification', __( 'Cannot parse JSON notification.' ), array( 'status' => 500 ) );
97
		}
98
99 3
		foreach ( $notification_request->get_items() as $item ) {
100 3
			$payment = get_pronamic_payment( $item->get_merchant_reference() );
101
102 3
			if ( null === $payment ) {
103 2
				continue;
104
			}
105
106
			// Add note.
107 1
			$note = sprintf(
108 1
				'<p>%1$s</p><pre>%2$s</pre>',
109 1
				sprintf(
110
					/* translators: %s: payment provider name */
111 1
					__( 'Webhook requested by %s.', 'pronamic_ideal' ),
112 1
					__( 'Adyen', 'pronamic_ideal' )
113
				),
114 1
				wp_json_encode( $item->get_json(), JSON_PRETTY_PRINT )
0 ignored issues
show
It seems like wp_json_encode($item->ge...dyen\JSON_PRETTY_PRINT) can also be of type false; however, parameter $args of sprintf() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

114
				/** @scrutinizer ignore-type */ wp_json_encode( $item->get_json(), JSON_PRETTY_PRINT )
Loading history...
115
			);
116
117 1
			$payment->add_note( $note );
118
119
			// Authorization.
120 1
			if ( EventCode::AUTHORIZATION === $item->get_event_code() ) {
121 1
				$payment->set_status( $item->is_success() ? PaymentStatus::SUCCESS : PaymentStatus::FAILURE );
122
123 1
				$payment->save();
124
			}
125
		}
126
127
		$response = (object) array(
128 3
			'notificationResponse' => '[accepted]',
129
		);
130
131 3
		return $response;
132
	}
133
}
134