Test Failed
Push — master ( 315839...9b266f )
by Devin
05:39
created

Give_Stripe_Webhooks   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 176
Duplicated Lines 14.2 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
dl 25
loc 176
rs 10
c 0
b 0
f 0
wmc 17
lcom 1
cbo 3

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A listen() 0 46 4
C process() 25 88 12

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * Give - Stripe Core | Process Webhooks
4
 *
5
 * @since 2.5.0
6
 *
7
 * @package    Give
8
 * @subpackage Stripe Core
9
 * @copyright  Copyright (c) 2019, GiveWP
10
 * @license    https://opensource.org/licenses/gpl-license GNU Public License
11
 */
12
13
// Exit if accessed directly.
14
if ( ! defined( 'ABSPATH' ) ) {
15
	exit;
16
}
17
18
if ( ! class_exists( 'Give_Stripe_Webhooks' ) ) {
19
20
	/**
21
	 * Class Give_Stripe_Webhooks
22
	 *
23
	 * @since 2.5.0
24
	 */
25
	class Give_Stripe_Webhooks {
26
27
		/**
28
		 * Stripe Gateway
29
		 *
30
		 * @since  2.5.0
31
		 * @access public
32
		 *
33
		 * @var $stripe_gateway
34
		 */
35
		public $stripe_gateway;
36
37
		/**
38
		 * Give_Stripe_Webhooks constructor.
39
		 *
40
		 * @since 2.5.0
41
		 */
42
		public function __construct() {
43
44
			$this->stripe_gateway = new Give_Stripe_Gateway();
45
46
			add_action( 'init', array( $this, 'listen' ) );
47
		}
48
49
		/**
50
		 * Listen for Stripe events.
51
		 *
52
		 * @access public
53
		 * @since  2.5.0
54
		 *
55
		 * @return void
56
		 */
57
		public function listen() {
58
59
			$give_listener = give_clean( filter_input( INPUT_GET, 'give-listener' ) );
60
61
			// Must be a stripe listener to proceed.
62
			if ( ! isset( $give_listener ) || 'stripe' !== $give_listener ) {
63
				return;
64
			}
65
66
			// Get the Stripe SDK autoloader.
67
			require_once GIVE_PLUGIN_DIR . 'vendor/autoload.php';
68
69
			// Set App Info, API Key, and API Version.
70
			give_stripe_set_app_info();
71
			$this->stripe_gateway->set_api_version();
72
73
			// Retrieve the request's body and parse it as JSON.
74
			$body  = @file_get_contents( 'php://input' );
75
			$event = json_decode( $body );
76
77
			$processed_event = $this->process( $event );
78
79
			if ( false === $processed_event ) {
80
				$message = __( 'Something went wrong with processing the payment gateway event.', 'give' );
81
			} else {
82
				$message = sprintf(
83
					/* translators: 1. Processing result. */
84
					__( 'Processed event: %s', 'give' ),
85
					$processed_event
86
				);
87
			}
88
89
			give_stripe_record_log(
90
				__( 'Stripe - Webhook Received', 'give' ),
91
				sprintf(
92
					/* translators: 1. Event ID 2. Event Type 3. Message */
93
					__( 'Webhook received with ID %1$s and TYPE %2$s which processed and returned a message %3$s.', 'give' ),
94
					$event_json->id,
95
					$event_json->type,
96
					$message
97
				)
98
			);
99
100
			status_header( 200 );
101
			exit( $message );
102
		}
103
104
		/**
105
		 * Process Stripe Webhooks.
106
		 *
107
		 * @since  2.5.0
108
		 * @access public
109
		 *
110
		 * @param \Stripe\Event $event_json Stripe Event.
111
		 */
112
		public function process( $event_json ) {
113
114
			// Next, proceed with additional webhooks.
115
			if ( isset( $event_json->id ) ) {
116
117
				status_header( 200 );
118
119
				try {
120
121
					$event = \Stripe\Event::retrieve( $event_json->id );
122
123
					// Update time of webhook received whenever the event is retrieved.
124
					give_update_option( 'give_stripe_last_webhook_received_timestamp', current_time( 'timestamp', 1 ) );
125
126
				} catch ( \Stripe\Error\Authentication $e ) {
127
128
					if ( strpos( $e->getMessage(), 'Platform access may have been revoked' ) !== false ) {
129
						give_stripe_connect_delete_options();
130
					}
131
				} catch ( Exception $e ) {
132
					die( 'Invalid event ID' );
133
				}
134
135
				// Bailout, if event type doesn't exists.
136
				if ( empty( $event->type ) ) {
137
					return false;
138
				}
139
140
				switch ( $event->type ) {
141
142 View Code Duplication
					case 'payment_intent.succeeded':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
143
						$intent = $event->data->object;
144
145
						if ( 'succeeded' === $intent->status ) {
146
							$donation_id = give_get_purchase_id_by_transaction_id( $intent->id );
147
148
							// Update payment status to donation.
149
							give_update_payment_status( $donation_id, 'publish' );
150
151
							// Insert donation note to inform admin that charge succeeded.
152
							give_insert_payment_note( $donation_id, __( 'Charge succeeded in Stripe.', 'give' ) );
153
						}
154
155
						break;
156
157 View Code Duplication
					case 'payment_intent.payment_failed':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
158
							$intent      = $event->data->object;
159
							$donation_id = give_get_purchase_id_by_transaction_id( $intent->id );
160
161
							// Update payment status to donation.
162
							give_update_payment_status( $donation_id, 'failed' );
163
164
							// Insert donation note to inform admin that charge succeeded.
165
							give_insert_payment_note( $donation_id, __( 'Charge failed in Stripe.', 'give' ) );
166
167
						break;
168
169
					case 'charge.refunded':
170
						global $wpdb;
171
172
						$charge = $event->data->object;
173
174
						if ( $charge->refunded ) {
175
176
							$payment_id = $wpdb->get_var( $wpdb->prepare( "SELECT donation_id FROM {$wpdb->donationmeta} WHERE meta_key = '_give_payment_transaction_id' AND meta_value = %s LIMIT 1", $charge->id ) );
177
178
							if ( $payment_id ) {
179
180
								give_update_payment_status( $payment_id, 'refunded' );
181
								give_insert_payment_note( $payment_id, __( 'Charge refunded in Stripe.', 'give' ) );
182
183
							}
184
						}
185
186
						break;
187
				}
188
189
				do_action( 'give_stripe_event_' . $event->type, $event );
190
191
				return $event->type;
192
193
			} else {
194
				status_header( 500 );
195
				// Something went wrong outside of Stripe.
196
				give_record_gateway_error( __( 'Stripe Error', 'give' ), sprintf( __( 'An error occurred while processing a webhook.', 'give' ) ) );
197
				die( '-1' ); // Failed.
198
			} // End if().
199
		}
200
	}
201
}
202
203
new Give_Stripe_Webhooks();
204