PluginProbe
Stripe Payment Forms by WP Simple Pay – Accept Credit Card Payments + Subscriptions with Stripe / trunk
Stripe Payment Forms by WP Simple Pay – Accept Credit Card Payments + Subscriptions with Stripe vtrunk
4.17.3 trunk 2.2.0 2.3.0 2.3.1 2.3.2 2.3.3 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.6.0 2.6.1 2.6.2 2.6.3 4.10.0 4.11.1 4.12.2 4.14.1 4.14.2 4.14.3 4.15.0 4.16.0 All 59 releases
stripe / src / Webhook / WebhookEndpointManager.php

WebhookEndpointManager.php in Stripe Payment Forms by WP Simple Pay – Accept Credit Card Payments + Subscriptions with Stripe trunk, at src/Webhook/WebhookEndpointManager.php

295 lines 6.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Webhook: Endpoint manager
4 *
5 * @package SimplePay
6 * @subpackage Core
7 * @copyright Copyright (c) 2022, Sandhills Development, LLC
8 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9 * @since 4.4.2
10 */
11
12 namespace SimplePay\Core\Webhook;
13
14 use Exception;
15 use SimplePay\Core\Payments\Stripe_API;
16 use SimplePay\Pro\Webhooks;
17
18 /**
19 * WebhookEndpointManager class.
20 *
21 * @since 4.2.2
22 */
23 class WebhookEndpointManager {
24
25 /**
26 * Determines if the current payment mode has an up-to-date webhook endpoint.
27 *
28 * @since 4.2.2
29 *
30 * @return bool|\SimplePay\Vendor\Stripe\WebhookEndpoint
31 */
32 public function exists() {
33 $prefix = simpay_is_test_mode() ? 'test' : 'live';
34
35 /** @var string $endpoint_id */
36 $endpoint_id = simpay_get_setting(
37 "{$prefix}_webhook_endpoint_id",
38 ''
39 );
40
41 // No endpoint ID for the current mode exists.
42 if ( empty( $endpoint_id ) ) {
43 return false;
44 }
45
46 try {
47 // The endpoint is still valid in Stripe.
48 $endpoint = $this->get( $endpoint_id );
49 } catch ( Exception $e ) {
50 // The endpoint ID exists, but the endpoint no longer exists on Stripe.
51 return false;
52 }
53
54 return $endpoint;
55 }
56
57 /**
58 * Determines if a Stripe webhook endpoint is still valid.
59 *
60 * @since 4.4.2
61 *
62 * @param \SimplePay\Vendor\Stripe\WebhookEndpoint $endpoint Webhook endpoint to validate.
63 * @return bool True if the webhook does not need to be updated.
64 */
65 public function is_valid( $endpoint ) {
66 $enabled_events = $endpoint->enabled_events;
67
68 // Enabled events are not * and do not match the defined whitelist.
69 if ( ! in_array( '*', $enabled_events, true ) ) {
70 // Check if all events in the whitelist are present in the enabled events.
71 $whitelist = $this->get_event_whitelist();
72 foreach ( $whitelist as $event ) {
73 if ( ! in_array( $event, $enabled_events, true ) ) {
74 return false;
75 }
76 }
77 }
78
79 // URL mismatch.
80 if ( simpay_get_webhook_url() !== $endpoint->url ) {
81 return false;
82 }
83
84 // Disabled.
85 if ( 'enabled' !== $endpoint->status ) {
86 return false;
87 }
88
89 return true;
90 }
91
92 /**
93 * Retrieves a Stripe webhook endpoint.
94 *
95 * @since 4.4.2
96 *
97 * @param string $endpoint_id Stripe endpoint ID.
98 * @return \SimplePay\Vendor\Stripe\WebhookEndpoint
99 */
100 public function get( $endpoint_id ) {
101 return Stripe_API::request(
102 'WebhookEndpoint',
103 'retrieve',
104 $endpoint_id,
105 $this->get_api_request_args()
106 );
107 }
108
109 /**
110 * Creates a Stripe webhook endpoint with the current plugin and site settings.
111 *
112 * @since 4.4.2
113 *
114 * @return \SimplePay\Vendor\Stripe\WebhookEndpoint
115 */
116 public function create() {
117 // Use an existing endpoint if one already exists from a previous setup.
118 $endpoint = $this->get_manual_endpoint();
119
120 if ( ! $endpoint instanceof \SimplePay\Vendor\Stripe\WebhookEndpoint ) {
121 $endpoint = Stripe_API::request(
122 'WebhookEndpoint',
123 'create',
124 array(
125 'url' => simpay_get_webhook_url(),
126 'enabled_events' => $this->get_event_whitelist(),
127 'connect' => false,
128 'api_version' => SIMPLE_PAY_STRIPE_API_VERSION, // @phpstan-ignore-line
129 'description' => sprintf(
130 'WP Simple Pay (WordPress plugin) endpoint (%s Mode)',
131 simpay_is_test_mode() ? 'Test' : 'Live'
132 ),
133 ),
134 $this->get_api_request_args()
135 );
136 }
137
138 $this->persist( $endpoint );
139
140 return $endpoint;
141 }
142
143 /**
144 * Updates a Stripe webhook endpoint with the current site and plugin settings.
145 *
146 * @since 4.4.2
147 *
148 * @param \SimplePay\Vendor\Stripe\WebhookEndpoint $endpoint Webhook endpoint to update.
149 * @return \SimplePay\Vendor\Stripe\WebhookEndpoint
150 */
151 public function update( $endpoint ) {
152 $enabled_events = $endpoint->enabled_events;
153
154 // Existing webhook does not accept all events. Merge the new whitelist.
155 if ( ! in_array( '*', $enabled_events, true ) ) {
156 $enabled_events = array_values(
157 array_unique(
158 array_merge(
159 $enabled_events,
160 $this->get_event_whitelist()
161 )
162 )
163 );
164 }
165
166 $endpoint = Stripe_API::request(
167 'WebhookEndpoint',
168 'update',
169 $endpoint->id,
170 array(
171 'url' => simpay_get_webhook_url(),
172 'enabled_events' => $enabled_events,
173 'disabled' => false,
174 ),
175 $this->get_api_request_args()
176 );
177
178 $this->persist( $endpoint );
179
180 return $endpoint;
181 }
182
183 /**
184 * Returns a list of Stripe webhook events that are supported by the plugin.
185 *
186 * @since 4.4.2
187 *
188 * @return array<string>
189 */
190 public function get_event_whitelist() {
191 return array_keys( Webhooks\get_event_whitelist() );
192 }
193
194 /**
195 * Persists a Stripe webhook endpoint's information.
196 *
197 * @since 4.4.2
198 *
199 * @param \SimplePay\Vendor\Stripe\WebhookEndpoint $endpoint Webhook endpoint to persist.
200 * @return void
201 */
202 private function persist( $endpoint ) {
203 $prefix = simpay_is_test_mode() ? 'test' : 'live';
204
205 simpay_update_setting(
206 "{$prefix}_webhook_endpoint_id",
207 $endpoint->id
208 );
209
210 simpay_update_setting(
211 "{$prefix}_webhook_endpoint_events",
212 $endpoint->enabled_events
213 );
214
215 simpay_update_setting(
216 "{$prefix}_webhook_endpoint_url",
217 $endpoint->url
218 );
219
220 // Secret is only returned on initial creation.
221 if ( isset( $endpoint->secret ) ) {
222 simpay_update_setting(
223 "{$prefix}_webhook_endpoint_secret",
224 $endpoint->secret
225 );
226
227 // Clear out from a previous connection.
228 } else {
229 simpay_update_setting(
230 "{$prefix}_webhook_endpoint_secret",
231 ''
232 );
233 }
234
235 simpay_update_setting(
236 "{$prefix}_webhook_endpoint_created",
237 $endpoint->created
238 );
239 }
240
241 /**
242 * Returns per-request arguments to be passed to the Stripe API.
243 *
244 * @since 4.4.2
245 *
246 * @return array<string>
247 */
248 private function get_api_request_args() {
249 return array(
250 'api_key' => simpay_get_secret_key(),
251 );
252 }
253
254 /**
255 * Attemps to locate an endpoint that was manually created prior to 4.4.2.
256 *
257 * If we find an endpoint with an exact URL match, persist it and return it.
258 *
259 * @since 4.4.2
260 *
261 * @return bool|\SimplePay\Vendor\Stripe\WebhookEndpoint Existing webhook endpoint if one matches the expected URL.
262 * False if no endpoint matches.
263 */
264 private function get_manual_endpoint() {
265 $endpoints = Stripe_API::request(
266 'WebhookEndpoint',
267 'all',
268 array(
269 'limit' => 100,
270 ),
271 $this->get_api_request_args()
272 );
273
274 foreach ( $endpoints->data as $endpoint ) {
275 if ( simpay_get_webhook_url() === $endpoint->url ) {
276 // Ensure the remote endpoint has the expected events. Update if needed.
277 $remote_events = $endpoint->enabled_events;
278 $local_events = $this->get_event_whitelist();
279
280 if ( count( $remote_events ) < count( $local_events ) ) {
281 $endpoint = $this->update( $endpoint );
282 }
283
284 // Persist the endpoint information locally.
285 $this->persist( $endpoint );
286
287 return $endpoint;
288 }
289 }
290
291 return false;
292 }
293
294 }
295