PluginProbe ʕ •ᴥ•ʔ
LatePoint – Calendar Booking Plugin for Appointments and Events / 5.4.2
LatePoint – Calendar Booking Plugin for Appointments and Events v5.4.2
5.6.7 5.6.6 5.6.5 5.6.4 5.6.3 5.6.2 5.6.1 5.6.0 5.5.2 5.5.1 5.5.0 5.4.2 trunk 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.1.8 5.1.9 5.1.91 5.1.92 5.1.93 5.1.94 5.2.0 5.2.1 5.2.10 5.2.11 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.0 5.3.1 5.3.2 5.4.0 5.4.1
latepoint / lib / controllers / stripe_connect_controller.php
latepoint / lib / controllers Last commit date
activities_controller.php 3 months ago auth_controller.php 3 months ago booking_form_settings_controller.php 3 months ago bookings_controller.php 3 months ago calendars_controller.php 3 months ago carts_controller.php 3 months ago controller.php 3 months ago customer_cabinet_controller.php 2 months ago customers_controller.php 3 months ago dashboard_controller.php 3 months ago default_agent_controller.php 3 months ago events_controller.php 3 months ago form_fields_controller.php 3 months ago integrations_controller.php 3 months ago invoices_controller.php 2 months ago manage_booking_by_key_controller.php 3 months ago manage_order_by_key_controller.php 3 months ago notifications_controller.php 3 months ago orders_controller.php 3 months ago pro_controller.php 2 months ago process_jobs_controller.php 3 months ago processes_controller.php 3 months ago search_controller.php 3 months ago services_controller.php 3 months ago settings_controller.php 3 months ago steps_controller.php 3 months ago stripe_connect_controller.php 2 months ago support_topics_controller.php 3 months ago todos_controller.php 3 months ago transactions_controller.php 3 months ago wizard_controller.php 2 months ago
stripe_connect_controller.php
316 lines
1 <?php
2 /*
3 * Copyright (c) 2024 LatePoint LLC. All rights reserved.
4 */
5
6 if ( ! defined( 'ABSPATH' ) ) {
7 exit; // Exit if accessed directly.
8 }
9
10
11 if ( ! class_exists( 'OsStripeConnectController' ) ) :
12
13
14 class OsStripeConnectController extends OsController {
15
16
17 function __construct() {
18 parent::__construct();
19
20 $this->action_access['public'] = array_merge( $this->action_access['public'], [ 'webhook', 'create_payment_intent_for_transaction', 'create_payment_intent' ] );
21 $this->action_access['customer'] = array_merge( $this->action_access['customer'], [] );
22 $this->views_folder = LATEPOINT_VIEWS_ABSPATH . 'stripe_connect/';
23 }
24
25 public function create_payment_intent_for_transaction() {
26 try {
27 $invoice_access_key = sanitize_text_field( $this->params['key'] ?? '' );
28 if ( empty( $invoice_access_key ) ) {
29 throw new Exception( __( 'Invoice not found', 'latepoint' ) );
30 }
31 $invoice = new OsInvoiceModel();
32 $invoice = OsInvoicesHelper::get_invoice_by_key( $invoice_access_key );
33 if ( ! ( $invoice instanceof OsInvoiceModel ) || $invoice->is_new_record() ) {
34 throw new Exception( __( 'Invoice not found', 'latepoint' ) );
35 }
36
37 $transaction_intent = OsTransactionIntentHelper::create_or_update_transaction_intent( $invoice, $this->params );
38
39 if ( OsSettingsHelper::get_settings_value( OsSettingsHelper::append_payment_env_key( 'stripe_connect_account_id' ) ) ) {
40 $payment_intent_data = OsStripeConnectHelper::generate_payment_intent_id_and_secret_for_transaction_intent( $transaction_intent );
41 $payment_intent_id = $payment_intent_data['id'];
42 $payment_intent_client_secret = $payment_intent_data['client_secret'];
43 } else {
44 throw new Exception( __( 'Stripe connect account ID not set', 'latepoint' ) );
45 }
46
47 $transaction_intent->set_payment_data_value( 'token', $payment_intent_id, false );
48 if ( ! $transaction_intent->save() ) {
49 throw new Exception( __( 'Unable to save transaction intent', 'latepoint' ) );
50 }
51
52
53 if ( $this->get_return_format() == 'json' ) {
54 $this->send_json(
55 [
56 'status' => LATEPOINT_STATUS_SUCCESS,
57 'continue_transaction_intent_url' => OsTransactionIntentHelper::generate_continue_intent_url( $transaction_intent->intent_key ),
58 'payment_intent_id' => $payment_intent_id,
59 'payment_intent_secret' => $payment_intent_client_secret,
60 'transaction_intent_key' => $transaction_intent->intent_key,
61 ]
62 );
63 }
64 } catch ( Exception $e ) {
65 if ( $this->get_return_format() == 'json' ) {
66 $this->send_json(
67 array(
68 'status' => LATEPOINT_STATUS_ERROR,
69 'message' => $e->getMessage(),
70 )
71 );
72 }
73 }
74 }
75
76 public function webhook() {
77 $payload = @file_get_contents( 'php://input' );
78 $data = json_decode( $payload, true );
79 if ( empty( $data['server_token'] ) || $data['server_token'] != OsStripeConnectHelper::get_server_token() || $data['stripe_account_id'] != OsStripeConnectHelper::get_connect_account_id() ) {
80 http_response_code( 400 );
81 echo 'Validation issue with webhook';
82 exit();
83 }
84 $event = $data['event'];
85 // Handle the event
86 switch ( $event['type'] ) {
87 case 'payment_intent.succeeded':
88 if ( ! empty( $event['data']['order_intent_key'] ) ) {
89 $order_intent = OsOrderIntentHelper::get_order_intent_by_intent_key( $event['data']['order_intent_key'] );
90 if ( $order_intent->is_new_record() ) {
91 OsDebugHelper::log( 'Error processing stripe connect webhook: Order intent not found for key' );
92 http_response_code( 400 );
93 exit();
94 }
95 if ( $order_intent->convert_to_order() ) {
96 http_response_code( 200 );
97 } else {
98 http_response_code( 400 );
99 OsDebugHelper::log( 'Error converting order intent', 'stripe_connect_webhook', $order_intent->get_error_messages() );
100 }
101 }
102 if ( ! empty( $event['data']['transaction_intent_key'] ) ) {
103 $transaction_intent = OsTransactionIntentHelper::get_transaction_intent_by_intent_key( $event['data']['transaction_intent_key'] );
104 if ( $transaction_intent->is_new_record() ) {
105 OsDebugHelper::log( 'Error processing stripe connect webhook: Transaction intent not found for key' );
106 http_response_code( 400 );
107 exit();
108 }
109 if ( $transaction_intent->convert_to_transaction() ) {
110 http_response_code( 200 );
111 } else {
112 http_response_code( 400 );
113 OsDebugHelper::log( 'Error converting transaction intent' );
114 }
115 }
116 break;
117 }
118 exit();
119 }
120
121 private function get_env_from_params(): string {
122 return ( ! empty(
123 $this->params['env'] && in_array(
124 $this->params['env'],
125 [
126 LATEPOINT_PAYMENTS_ENV_LIVE,
127 LATEPOINT_PAYMENTS_ENV_DEV,
128 ]
129 )
130 ) ) ? $this->params['env'] : OsSettingsHelper::get_payments_environment();
131 }
132
133 public function start_connect_process() {
134 $env = $this->get_env_from_params();
135 OsSettingsHelper::save_setting_by_name( OsSettingsHelper::append_payment_env_key( 'enable_payment_processor_stripe_connect', $env ), LATEPOINT_VALUE_ON );
136 $url = OsStripeConnectHelper::get_connect_url( $env );
137 $this->send_json(
138 array(
139 'status' => LATEPOINT_STATUS_SUCCESS,
140 'url' => $url,
141 'message' => __( 'Redirecting to Stripe', 'latepoint' ),
142 )
143 );
144 }
145
146 public function disconnect_connect_account() {
147 $env = $this->get_env_from_params();
148 try {
149 $path = 'server-tokens/' . OsStripeConnectHelper::get_server_token( $env ) . '/disconnect/';
150 $response = OsStripeConnectHelper::do_account_request( $path, $env, '', 'DELETE' );
151 if ( $response['status']['code'] == 200 ) {
152 OsSettingsHelper::remove_setting_by_name( OsSettingsHelper::append_payment_env_key( 'stripe_connect_charges_enabled' ) );
153 OsSettingsHelper::remove_setting_by_name( OsSettingsHelper::append_payment_env_key( 'stripe_connect_account_id' ) );
154 OsStripeConnectHelper::reset_server_token( $env );
155 } else {
156 OsDebugHelper::log( 'Stripe Connect Error', 'stripe_connect_disconnect_error', $response );
157 }
158 } catch ( Exception $e ) {
159 OsDebugHelper::log( 'Error getting status of a stripe connection', 'stripe', [ 'error_message' => $e->getMessage() ] );
160 $this->send_json(
161 array(
162 'status' => LATEPOINT_STATUS_ERROR,
163 'message' => $e->getMessage(),
164 )
165 );
166 }
167 $this->send_json(
168 array(
169 'status' => LATEPOINT_STATUS_SUCCESS,
170 'message' => OsStripeConnectHelper::get_connection_buttons_and_status( $env ),
171 )
172 );
173 }
174
175
176 public function check_connect_status() {
177 $env = $this->get_env_from_params();
178 try {
179 $response = OsStripeConnectHelper::do_request( 'server-tokens/' . OsStripeConnectHelper::get_server_token( $env ) . '/status', '', 'GET', [], [], $env );
180 if ( $env == 'live' ) {
181 if ( empty( $response['data']['transaction_fee_info'] ) ) {
182 OsSettingsHelper::save_setting_by_name( 'stripe_connect_transaction_fee_info', '0' );
183 } else {
184 OsSettingsHelper::save_setting_by_name( 'stripe_connect_transaction_fee_info', $response['data']['transaction_fee_info'] );
185 }
186 }
187 if ( ! empty( $response['data'] ) && ! empty( $response['data']['account_id'] ) ) {
188 OsSettingsHelper::save_setting_by_name( OsSettingsHelper::append_payment_env_key( 'stripe_connect_account_id', $env ), $response['data']['account_id'] );
189 if ( ! empty( $response['data']['charges_enabled'] ) ) {
190 OsSettingsHelper::save_setting_by_name( OsSettingsHelper::append_payment_env_key( 'stripe_connect_charges_enabled', $env ), LATEPOINT_VALUE_ON );
191 } else {
192 OsSettingsHelper::remove_setting_by_name( OsSettingsHelper::append_payment_env_key( 'stripe_connect_charges_enabled', $env ) );
193 }
194 } else {
195 OsSettingsHelper::remove_setting_by_name( OsSettingsHelper::append_payment_env_key( 'stripe_connect_charges_enabled', $env ) );
196 OsSettingsHelper::remove_setting_by_name( OsSettingsHelper::append_payment_env_key( 'stripe_connect_account_id', $env ) );
197 }
198 if ( ! empty( $response['data']['active_site_urls'] ) ) {
199 OsSettingsHelper::save_setting_by_name( OsSettingsHelper::append_payment_env_key( 'stripe_connect_duplicate_token_activations', $env ), $response['data']['active_site_urls'] );
200 } else {
201 OsSettingsHelper::remove_setting_by_name( OsSettingsHelper::append_payment_env_key( 'stripe_connect_duplicate_token_activations', $env ) );
202 }
203 if ( ! empty( $response['data']['error'] ) ) {
204 OsDebugHelper::log( 'Error checking status of server token', 'stripe_connect_error', [ 'error_message' => $response['data']['error'] ] );
205 }
206 } catch ( Exception $e ) {
207 OsDebugHelper::log( 'Error getting status of a stripe connection', 'stripe_connect_error', [ 'error_message' => $e->getMessage() ] );
208 $this->send_json(
209 array(
210 'status' => LATEPOINT_STATUS_ERROR,
211 'message' => $e->getMessage(),
212 )
213 );
214 }
215 $this->send_json(
216 array(
217 'status' => LATEPOINT_STATUS_SUCCESS,
218 'message' => OsStripeConnectHelper::get_connection_buttons_and_status( $env ),
219 )
220 );
221 }
222
223
224 public function heartbeat() {
225 $payload = @file_get_contents( 'php://input' );
226 $data = json_decode( $payload, true );
227
228 if ( empty( $data['wp_latepoint_server_token'] ) ) {
229 $this->send_json(
230 array(
231 'status' => LATEPOINT_STATUS_ERROR,
232 'message' => 'Token is missing',
233 ),
234 404
235 );
236 }
237 if ( $data['wp_latepoint_server_token'] != OsStripeConnectHelper::get_server_token() ) {
238 $this->send_json(
239 array(
240 'status' => LATEPOINT_STATUS_ERROR,
241 'message' => 'Invalid Token',
242 ),
243 404
244 );
245 }
246
247 $this->send_json(
248 array(
249 'status' => LATEPOINT_STATUS_SUCCESS,
250 'message' => 'Heartbeat detected',
251 ),
252 200
253 );
254 }
255
256 public function create_payment_intent() {
257 try {
258 OsStepsHelper::set_required_objects( $this->params );
259
260 $booking_form_page_url = $this->params['booking_form_page_url'] ?? OsUtilHelper::get_referrer();
261 $order_intent = OsOrderIntentHelper::create_or_update_order_intent( OsStepsHelper::$cart_object, OsStepsHelper::$restrictions, OsStepsHelper::$presets, $booking_form_page_url, OsStepsHelper::get_customer_object_id() );
262
263 if ( ! $order_intent->is_bookable() ) {
264 throw new Exception( empty( $order_intent->get_error_messages() ) ? __( 'Booking slot is not available anymore.', 'latepoint' ) : implode( ', ', $order_intent->get_error_messages() ) );
265 }
266
267 if ( OsSettingsHelper::get_settings_value( OsSettingsHelper::append_payment_env_key( 'stripe_connect_account_id' ) ) ) {
268 $payment_intent_data = OsStripeConnectHelper::generate_payment_intent_id_and_secret_for_order_intent( $order_intent );
269 $payment_intent_id = $payment_intent_data['id'];
270 $payment_intent_client_secret = $payment_intent_data['client_secret'];
271 } else {
272 throw new Exception( __( 'Stripe connect account ID not set', 'latepoint' ) );
273 }
274
275
276 // update cart with payment intent id
277 OsStepsHelper::$cart_object->payment_token = $payment_intent_id;
278
279 // cart_item_data might be changed after filters run, make sure to get the latest version
280 $cart_items_data = json_decode( $order_intent->cart_items_data, true );
281 $payment_data = json_decode( $order_intent->payment_data, true );
282
283 $payment_data['token'] = $payment_intent_id;
284 $order_intent->update_attributes(
285 [
286 'cart_items_data' => wp_json_encode( $cart_items_data ),
287 'payment_data' => wp_json_encode( $payment_data ),
288 ]
289 );
290 if ( $this->get_return_format() == 'json' ) {
291 $this->send_json(
292 [
293 'status' => LATEPOINT_STATUS_SUCCESS,
294 'continue_order_intent_url' => OsOrderIntentHelper::generate_continue_intent_url( $order_intent->intent_key ),
295 'payment_intent_id' => $payment_intent_id,
296 'payment_intent_secret' => $payment_intent_client_secret,
297 'order_intent_key' => $order_intent->intent_key,
298 ]
299 );
300 }
301 } catch ( Exception $e ) {
302 if ( $this->get_return_format() == 'json' ) {
303 $this->send_json(
304 array(
305 'status' => LATEPOINT_STATUS_ERROR,
306 'message' => $e->getMessage(),
307 )
308 );
309 }
310 }
311 }
312 }
313
314
315 endif;
316