PluginProbe ʕ •ᴥ•ʔ
LatePoint – Calendar Booking Plugin for Appointments and Events / 5.1.7
LatePoint – Calendar Booking Plugin for Appointments and Events v5.1.7
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 1 year ago auth_controller.php 1 year ago booking_form_settings_controller.php 1 year ago bookings_controller.php 1 year ago calendars_controller.php 1 year ago carts_controller.php 1 year ago controller.php 1 year ago customer_cabinet_controller.php 1 year ago customers_controller.php 1 year ago dashboard_controller.php 1 year ago default_agent_controller.php 1 year ago events_controller.php 1 year ago form_fields_controller.php 1 year ago integrations_controller.php 1 year ago invoices_controller.php 1 year ago manage_booking_by_key_controller.php 1 year ago manage_order_by_key_controller.php 1 year ago notifications_controller.php 1 year ago orders_controller.php 1 year ago pro_controller.php 1 year ago process_jobs_controller.php 1 year ago processes_controller.php 1 year ago search_controller.php 1 year ago services_controller.php 1 year ago settings_controller.php 1 year ago steps_controller.php 1 year ago stripe_connect_controller.php 1 year ago support_topics_controller.php 1 year ago todos_controller.php 1 year ago transactions_controller.php 1 year ago wizard_controller.php 1 year ago
stripe_connect_controller.php
244 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' ] );
21 $this->action_access['customer'] = array_merge( $this->action_access['customer'], [ 'create_payment_intent' ] );
22 $this->views_folder = LATEPOINT_VIEWS_ABSPATH . 'stripe_connect/';
23 }
24
25 public function refund_transaction() {
26 if ( ! filter_var( $this->params['transaction_refund']['transaction_id'], FILTER_VALIDATE_INT ) ) {
27 $this->send_json( array( 'status' => LATEPOINT_STATUS_ERROR, 'message' => __( 'Invalid Transaction', 'latepoint' ) ) );
28 }
29 $transaction = new OsTransactionModel( $this->params['transaction_refund']['transaction_id'] );
30 if ( empty( $transaction ) || $transaction->is_new_record() || $transaction->processor != OsStripeConnectHelper::$processor_code ) {
31 $this->send_json( array( 'status' => LATEPOINT_STATUS_ERROR, 'message' => __( 'Invalid Transaction', 'latepoint' ) ) );
32 }
33 try {
34 $refund_amount = ( $this->params['transaction_refund']['portion'] == 'custom' ) ? $this->params['transaction_refund']['custom_amount'] : ( $transaction->amount - $transaction->get_total_refunded_amount() );
35 $refund_amount = OsParamsHelper::sanitize_param( $refund_amount, 'money' );
36 if ( empty( $refund_amount ) || $refund_amount > $transaction->amount - $transaction->get_total_refunded_amount() ) {
37 throw new Exception( __( 'Invalid Refund Amount', 'latepoint' ) );
38 }
39 $transaction_refund = OsStripeConnectHelper::refund_transaction( $transaction, $refund_amount );
40 $this->vars['transaction'] = new OsTransactionModel( $transaction->id ); # reload to get new refund info
41 $message = $this->render( LATEPOINT_VIEWS_ABSPATH . 'orders/_transaction_box', 'none' );
42 $this->send_json( array( 'status' => LATEPOINT_STATUS_SUCCESS, 'message' => $message ) );
43 } catch ( Exception $e ) {
44 $this->send_json( array( 'status' => LATEPOINT_STATUS_ERROR, 'message' => $e->getMessage() ) );
45 }
46 }
47
48 public function create_payment_intent_for_transaction() {
49 if ( ! filter_var( $this->params['invoice_id'], FILTER_VALIDATE_INT ) ) {
50 exit();
51 }
52 try {
53
54 $invoice = new OsInvoiceModel( $this->params['invoice_id'] );
55
56 $transaction_intent = OsTransactionIntentHelper::create_or_update_transaction_intent( $invoice, $this->params );
57
58 if ( OsSettingsHelper::get_settings_value( OsSettingsHelper::append_payment_env_key( 'stripe_connect_account_id' ) ) ) {
59 $payment_intent_data = OsStripeConnectHelper::generate_payment_intent_id_and_secret_for_transaction_intent( $transaction_intent );
60 $payment_intent_id = $payment_intent_data['id'];
61 $payment_intent_client_secret = $payment_intent_data['client_secret'];
62 } else {
63 throw new Exception( __( 'Stripe connect account ID not set', 'latepoint' ) );
64 }
65
66 $transaction_intent->set_payment_data_value( 'token', $payment_intent_id, false );
67 if ( ! $transaction_intent->save() ) {
68 throw new Exception( __( 'Unable to save transaction intent', 'latepoint' ) );
69 }
70
71
72 if ( $this->get_return_format() == 'json' ) {
73 $this->send_json( [
74 'status' => LATEPOINT_STATUS_SUCCESS,
75 'continue_transaction_intent_url' => OsTransactionIntentHelper::generate_continue_intent_url( $transaction_intent->intent_key ),
76 'payment_intent_id' => $payment_intent_id,
77 'payment_intent_secret' => $payment_intent_client_secret,
78 'transaction_intent_key' => $transaction_intent->intent_key
79 ] );
80 }
81 } catch ( Exception $e ) {
82 if ( $this->get_return_format() == 'json' ) {
83 $this->send_json( array( 'status' => LATEPOINT_STATUS_ERROR, 'message' => $e->getMessage() ) );
84 }
85 }
86 }
87
88 public function webhook() {
89 $payload = @file_get_contents( 'php://input' );
90 $data = json_decode( $payload, true );
91 if ( empty( $data['server_token'] ) || $data['server_token'] != OsStripeConnectHelper::get_server_token() || $data['stripe_account_id'] != OsStripeConnectHelper::get_connect_account_id() ) {
92 http_response_code( 400 );
93 echo 'Error converting order intent';
94 exit();
95 }
96 $event = $data['event'];
97 // Handle the event
98 switch ( $event['type'] ) {
99 case 'payment_intent.succeeded':
100 if ( ! empty( $event['data']['order_intent_key'] ) ) {
101 $order_intent = OsOrderIntentHelper::get_order_intent_by_intent_key( $event['data']['order_intent_key'] );
102 if ( $order_intent->is_new_record() ) {
103 OsDebugHelper::log( 'Error processing stripe connect webhook: Order intent not found for key' );
104 http_response_code( 400 );
105 exit();
106 }
107 if ( $order_intent->convert_to_order() ) {
108 http_response_code( 200 );
109 } else {
110 http_response_code( 400 );
111 OsDebugHelper::log( 'Error converting order intent' );
112 }
113 }
114 break;
115 }
116 exit();
117 }
118
119 private function get_env_from_params(): string {
120 return ( ! empty( $this->params['env'] && in_array( $this->params['env'], [
121 LATEPOINT_PAYMENTS_ENV_LIVE,
122 LATEPOINT_PAYMENTS_ENV_DEV
123 ] ) ) ) ? $this->params['env'] : OsSettingsHelper::get_payments_environment();
124 }
125
126 public function start_connect_process() {
127 $env = $this->get_env_from_params();
128 OsSettingsHelper::save_setting_by_name( OsSettingsHelper::append_payment_env_key( 'enable_payment_processor_stripe_connect', $env ), LATEPOINT_VALUE_ON );
129 $url = OsStripeConnectHelper::get_connect_url( $env );
130 $this->send_json( array( 'status' => LATEPOINT_STATUS_SUCCESS, 'url' => $url, 'message' => __( 'Redirecting to Stripe', 'latepoint' ) ) );
131 }
132
133 public function disconnect_connect_account() {
134 $env = $this->get_env_from_params();
135 try {
136 $path = 'server-tokens/' . OsStripeConnectHelper::get_server_token( $env ) . '/disconnect/';
137 $response = OsStripeConnectHelper::do_account_request( $path, $env, '', 'DELETE' );
138 if ( $response['status']['code'] == 200 ) {
139 OsSettingsHelper::remove_setting_by_name( OsSettingsHelper::append_payment_env_key( 'stripe_connect_charges_enabled' ) );
140 OsSettingsHelper::remove_setting_by_name( OsSettingsHelper::append_payment_env_key( 'stripe_connect_account_id' ) );
141 } else {
142 OsDebugHelper::log( 'Stripe Connect Error', 'stripe_connect_disconnect_error', $response );
143 }
144 } catch ( Exception $e ) {
145 OsDebugHelper::log( 'Error getting status of a stripe connection', 'stripe', [ 'error_message' => $e->getMessage() ] );
146 $this->send_json( array( 'status' => LATEPOINT_STATUS_ERROR, 'message' => $e->getMessage() ) );
147 }
148 $this->send_json( array( 'status' => LATEPOINT_STATUS_SUCCESS, 'message' => OsStripeConnectHelper::get_connection_buttons_and_status( $env ) ) );
149 }
150
151
152 public function check_connect_status() {
153 $env = $this->get_env_from_params();
154 try {
155 $response = OsStripeConnectHelper::do_request( 'server-tokens/' . OsStripeConnectHelper::get_server_token( $env ) . '/status', '', 'GET', [], [], $env );
156 if ( ! empty( $response['data'] ) && ! empty( $response['data']['account_id'] ) ) {
157 OsSettingsHelper::save_setting_by_name( OsSettingsHelper::append_payment_env_key( 'stripe_connect_account_id', $env ), $response['data']['account_id'] );
158 if ( ! empty( $response['data']['charges_enabled'] ) ) {
159 OsSettingsHelper::save_setting_by_name( OsSettingsHelper::append_payment_env_key( 'stripe_connect_charges_enabled', $env ), LATEPOINT_VALUE_ON );
160 } else {
161 OsSettingsHelper::remove_setting_by_name( OsSettingsHelper::append_payment_env_key( 'stripe_connect_charges_enabled', $env ) );
162 }
163 } else {
164 OsSettingsHelper::remove_setting_by_name( OsSettingsHelper::append_payment_env_key( 'stripe_connect_charges_enabled', $env ) );
165 OsSettingsHelper::remove_setting_by_name( OsSettingsHelper::append_payment_env_key( 'stripe_connect_account_id', $env ) );
166 }
167 if ( ! empty( $response['data']['error'] ) ) {
168 OsDebugHelper::log( 'Error checking status of server token', 'stripe_connect_error', [ 'error_message' => $response['data']['error'] ] );
169 }
170 } catch ( Exception $e ) {
171 OsDebugHelper::log( 'Error getting status of a stripe connection', 'stripe_connect_error', [ 'error_message' => $e->getMessage() ] );
172 $this->send_json( array( 'status' => LATEPOINT_STATUS_ERROR, 'message' => $e->getMessage() ) );
173 }
174 $this->send_json( array( 'status' => LATEPOINT_STATUS_SUCCESS, 'message' => OsStripeConnectHelper::get_connection_buttons_and_status( $env ) ) );
175 }
176
177
178 public function heartbeat() {
179 $payload = @file_get_contents( 'php://input' );
180 $data = json_decode( $payload, true );
181
182 if ( empty( $data['wp_latepoint_server_token'] ) ) {
183 $this->send_json( array( 'status' => LATEPOINT_STATUS_ERROR, 'message' => 'Token is missing' ), 404 );
184 }
185 if ( $data['wp_latepoint_server_token'] != OsStripeConnectHelper::get_server_token() ) {
186 $this->send_json( array( 'status' => LATEPOINT_STATUS_ERROR, 'message' => 'Invalid Token' ), 404 );
187 }
188
189 $this->send_json( array( 'status' => LATEPOINT_STATUS_SUCCESS, 'message' => 'Heartbeat detected' ), 200 );
190 }
191
192 public function create_payment_intent() {
193 try {
194 OsStepsHelper::set_required_objects( $this->params );
195
196 $booking_form_page_url = $this->params['booking_form_page_url'] ?? OsUtilHelper::get_referrer();
197 $order_intent = OsOrderIntentHelper::create_or_update_order_intent( OsStepsHelper::$cart_object, OsStepsHelper::$restrictions, OsStepsHelper::$presets, $booking_form_page_url );
198
199 if ( ! $order_intent->is_bookable() ) {
200 throw new Exception( empty( $order_intent->get_error_messages() ) ? __( 'Booking slot is not available anymore.', 'latepoint' ) : implode( ', ', $order_intent->get_error_messages() ) );
201 }
202
203 if ( OsSettingsHelper::get_settings_value( OsSettingsHelper::append_payment_env_key( 'stripe_connect_account_id' ) ) ) {
204 $payment_intent_data = OsStripeConnectHelper::generate_payment_intent_id_and_secret_for_order_intent( $order_intent );
205 $payment_intent_id = $payment_intent_data['id'];
206 $payment_intent_client_secret = $payment_intent_data['client_secret'];
207 } else {
208 throw new Exception( __( 'Stripe connect account ID not set', 'latepoint' ) );
209 }
210
211
212 // update cart with payment intent id
213 OsStepsHelper::$cart_object->payment_token = $payment_intent_id;
214
215 // cart_item_data might be changed after filters run, make sure to get the latest version
216 $cart_items_data = json_decode( $order_intent->cart_items_data, true );
217 $payment_data = json_decode( $order_intent->payment_data, true );
218
219 $payment_data['token'] = $payment_intent_id;
220 $order_intent->update_attributes( [
221 'cart_items_data' => wp_json_encode( $cart_items_data ),
222 'payment_data' => wp_json_encode( $payment_data )
223 ] );
224 if ( $this->get_return_format() == 'json' ) {
225 $this->send_json( [
226 'status' => LATEPOINT_STATUS_SUCCESS,
227 'continue_order_intent_url' => OsOrderIntentHelper::generate_continue_intent_url( $order_intent->intent_key ),
228 'payment_intent_id' => $payment_intent_id,
229 'payment_intent_secret' => $payment_intent_client_secret,
230 'order_intent_key' => $order_intent->intent_key
231 ] );
232 }
233 } catch ( Exception $e ) {
234 if ( $this->get_return_format() == 'json' ) {
235 $this->send_json( array( 'status' => LATEPOINT_STATUS_ERROR, 'message' => $e->getMessage() ) );
236 }
237 }
238
239 }
240 }
241
242
243 endif;
244