Failed Conditions
Push — develop ( 82812e...db783a )
by Reüel
37:24 queued 26:32
created

rest_api_adyen_permissions_check()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4.0218

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 3
nop 1
dl 0
loc 15
ccs 8
cts 9
cp 0.8889
crap 4.0218
rs 10
c 0
b 0
f 0
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 5
	public function setup() {
38 5
		add_action( 'rest_api_init', array( $this, 'rest_api_init' ) );
39 5
	}
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 4
	public function rest_api_adyen_permissions_check( WP_REST_Request $request ) {
67 4
		$username = get_option( 'pronamic_pay_adyen_notification_authentication_username' );
68 4
		$password = get_option( 'pronamic_pay_adyen_notification_authentication_password' );
69
70 4
		if ( empty( $username ) && empty( $password ) ) {
71 3
			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 4
	public function rest_api_adyen_notifications( WP_REST_Request $request ) {
89 4
		$json = $request->get_body();
90
91 4
		$data = json_decode( $json );
92
93
		try {
94 4
			$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 2
		foreach ( $notification_request->get_items() as $item ) {
100 2
			$payment = get_pronamic_payment( $item->get_merchant_reference() );
101
102 2
			if ( null === $payment ) {
103 2
				continue;
104
			}
105
106
			// Store notification.
107
			$payment->set_meta( 'adyen_notification', $json );
108
109
			// Add note.
110
			$note = sprintf(
111
				/* translators: %s: Adyen */
112
				__( 'Webhook requested by %s.', 'pronamic_ideal' ),
113
				__( 'Adyen', 'pronamic_ideal' )
114
			);
115
116
			$payment->add_note( $note );
117
118
			// Authorization.
119
			if ( EventCode::AUTHORIZATION === $item->get_event_code() ) {
120
				$payment->set_status( $item->is_success() ? PaymentStatus::SUCCESS : PaymentStatus::FAILURE );
121
122
				$payment->save();
123
			}
124
		}
125
126
		$response = (object) array(
127 2
			'notificationResponse' => '[accepted]',
128
		);
129
130 2
		return $response;
131
	}
132
}
133