PluginProbe ʕ •ᴥ•ʔ
LatePoint – Calendar Booking Plugin for Appointments and Events / 5.6.6
LatePoint – Calendar Booking Plugin for Appointments and Events v5.6.6
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 / razorpay_connect_controller.php
latepoint / lib / controllers Last commit date
activities_controller.php 2 months ago auth_controller.php 3 months ago booking_form_settings_controller.php 3 months ago bookings_controller.php 4 days ago calendars_controller.php 3 months ago carts_controller.php 4 days ago controller.php 3 months ago customer_cabinet_controller.php 2 months ago customers_controller.php 4 days ago dashboard_controller.php 2 months ago default_agent_controller.php 3 months ago events_controller.php 3 months ago form_fields_controller.php 1 week ago integrations_controller.php 3 months ago invoices_controller.php 4 days 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 4 days ago pro_controller.php 3 weeks ago process_jobs_controller.php 3 months ago processes_controller.php 1 month ago razorpay_connect_controller.php 1 week ago search_controller.php 3 months ago services_controller.php 3 months ago settings_controller.php 2 months ago steps_controller.php 3 weeks ago stripe_connect_controller.php 1 week ago support_topics_controller.php 3 months ago todos_controller.php 3 months ago transactions_controller.php 4 days ago wizard_controller.php 1 week ago
razorpay_connect_controller.php
346 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 if ( ! class_exists( 'OsRazorpayConnectController' ) ) :
11
12 class OsRazorpayConnectController extends OsController {
13
14 function __construct() {
15 parent::__construct();
16 $this->action_access['public'] = array_merge( $this->action_access['public'], [ 'webhook', 'create_razorpay_order', 'create_razorpay_order_for_transaction' ] );
17 $this->views_folder = LATEPOINT_VIEWS_ABSPATH . 'razorpay_connect/';
18 }
19
20 private function get_env_from_params(): string {
21 return ( ! empty( $this->params['env'] ) && in_array( $this->params['env'], [ LATEPOINT_PAYMENTS_ENV_LIVE, LATEPOINT_PAYMENTS_ENV_DEV ] ) )
22 ? $this->params['env']
23 : OsSettingsHelper::get_payments_environment();
24 }
25
26 public function create_razorpay_order() {
27 try {
28 OsStepsHelper::set_required_objects( $this->params );
29
30 $booking_form_page_url = $this->params['booking_form_page_url'] ?? OsUtilHelper::get_referrer();
31 $order_intent = OsOrderIntentHelper::create_or_update_order_intent(
32 OsStepsHelper::$cart_object,
33 OsStepsHelper::$restrictions,
34 OsStepsHelper::$presets,
35 $booking_form_page_url,
36 OsStepsHelper::get_customer_object_id()
37 );
38
39 if ( ! $order_intent->is_bookable() ) {
40 throw new Exception( empty( $order_intent->get_error_messages() ) ? __( 'Booking slot is not available anymore.', 'latepoint' ) : implode( ', ', $order_intent->get_error_messages() ) );
41 }
42
43 if ( ! OsSettingsHelper::get_settings_value( OsSettingsHelper::append_payment_env_key( 'razorpay_connect_account_id' ) ) ) {
44 throw new Exception( __( 'Razorpay connect account ID not set', 'latepoint' ) );
45 }
46
47 $order_data = OsRazorpayConnectHelper::generate_razorpay_order_for_order_intent( $order_intent );
48
49 $order_data['options']['name'] = OsSettingsHelper::get_settings_value( 'razorpay_connect_company_name', 'RazorPay' );
50 $order_data['options']['description'] = 'LatePoint Order Intent Key: ' . $order_intent->intent_key;
51 $order_data['options']['image'] = OsImageHelper::get_image_url_by_id(
52 OsSettingsHelper::get_settings_value( 'razorpay_connect_logo_image_id', false ),
53 'thumbnail',
54 get_site_icon_url()
55 );
56 $order_data['options']['theme'] = [
57 'color' => OsSettingsHelper::get_settings_value( 'razorpay_connect_theme_color', '#4366ff' ),
58 ];
59 $order_data['options']['notes'] = [
60 'order_intent_key' => $order_intent->intent_key,
61 ];
62 $customer = OsStepsHelper::get_customer_object();
63 if ( $customer ) {
64 $order_data['options']['prefill'] = [
65 'name' => $customer->full_name,
66 'email' => $customer->email,
67 'contact' => $customer->phone,
68 ];
69 }
70
71 if ( $this->get_return_format() === 'json' ) {
72 $this->send_json(
73 [
74 'status' => LATEPOINT_STATUS_SUCCESS,
75 'continue_order_intent_url' => OsOrderIntentHelper::generate_continue_intent_url( $order_intent->intent_key ),
76 'order_intent_key' => $order_intent->intent_key,
77 'razorpay_order_id' => $order_data['order_id'],
78 'amount' => $order_data['amount'],
79 'currency' => $order_data['currency'],
80 'options' => $order_data['options'],
81 ]
82 );
83 }
84 } catch ( Exception $e ) {
85 if ( $this->get_return_format() === 'json' ) {
86 $this->send_json(
87 [
88 'status' => LATEPOINT_STATUS_ERROR,
89 'message' => $e->getMessage(),
90 ]
91 );
92 }
93 }
94 }
95
96 public function create_razorpay_order_for_transaction() {
97 try {
98 $invoice_access_key = sanitize_text_field( $this->params['key'] ?? '' );
99 if ( empty( $invoice_access_key ) ) {
100 throw new Exception( __( 'Invoice not found', 'latepoint' ) );
101 }
102 $invoice = OsInvoicesHelper::get_invoice_by_key( $invoice_access_key );
103 if ( ! ( $invoice instanceof OsInvoiceModel ) || $invoice->is_new_record() ) {
104 throw new Exception( __( 'Invoice not found', 'latepoint' ) );
105 }
106
107 $transaction_intent = OsTransactionIntentHelper::create_or_update_transaction_intent( $invoice, $this->params );
108
109 if ( ! OsSettingsHelper::get_settings_value( OsSettingsHelper::append_payment_env_key( 'razorpay_connect_account_id' ) ) ) {
110 throw new Exception( __( 'Razorpay connect account ID not set', 'latepoint' ) );
111 }
112
113 $order_data = OsRazorpayConnectHelper::generate_razorpay_order_for_transaction_intent( $transaction_intent );
114
115 $order_data['options']['name'] = OsSettingsHelper::get_settings_value( 'razorpay_connect_company_name', 'RazorPay' );
116 $order_data['options']['description'] = 'LatePoint Transaction Intent Key: ' . $transaction_intent->intent_key;
117 $order_data['options']['image'] = OsImageHelper::get_image_url_by_id(
118 OsSettingsHelper::get_settings_value( 'razorpay_connect_logo_image_id', false ),
119 'thumbnail',
120 get_site_icon_url()
121 );
122 $order_data['options']['theme'] = [
123 'color' => OsSettingsHelper::get_settings_value( 'razorpay_connect_theme_color', '#4366ff' ),
124 ];
125 $order_data['options']['notes'] = [
126 'transaction_intent_key' => $transaction_intent->intent_key,
127 ];
128 if ( ! empty( $transaction_intent->customer_id ) ) {
129 $customer = new OsCustomerModel( $transaction_intent->customer_id );
130 $order_data['options']['prefill'] = [
131 'name' => $customer->full_name,
132 'email' => $customer->email,
133 'contact' => $customer->phone,
134 ];
135 }
136
137 if ( $this->get_return_format() === 'json' ) {
138 $this->send_json(
139 [
140 'status' => LATEPOINT_STATUS_SUCCESS,
141 'continue_transaction_intent_url' => OsTransactionIntentHelper::generate_continue_intent_url( $transaction_intent->intent_key ),
142 'transaction_intent_key' => $transaction_intent->intent_key,
143 'razorpay_order_id' => $order_data['order_id'],
144 'amount' => $order_data['amount'],
145 'currency' => $order_data['currency'],
146 'options' => $order_data['options'],
147 ]
148 );
149 }
150 } catch ( Exception $e ) {
151 if ( $this->get_return_format() === 'json' ) {
152 $this->send_json(
153 [
154 'status' => LATEPOINT_STATUS_ERROR,
155 'message' => $e->getMessage(),
156 ]
157 );
158 }
159 }
160 }
161
162 public function webhook() {
163 $payload = @file_get_contents( 'php://input' );
164 $data = json_decode( $payload, true );
165
166 if ( empty( $data['server_token'] ) || empty( $data['razorpay_account_id'] ) || $data['server_token'] !== OsRazorpayConnectHelper::get_server_token() || $data['razorpay_account_id'] !== OsRazorpayConnectHelper::get_connect_account_id() ) {
167 http_response_code( 400 );
168 echo 'Validation issue with webhook';
169 exit();
170 }
171
172 if ( empty( $data['event'] ) || empty( $data['event']['type'] ) ) {
173 http_response_code( 400 );
174 exit();
175 }
176
177 $event = $data['event'];
178 switch ( $event['type'] ) {
179 case 'payment.captured':
180 if ( ! empty( $event['data']['order_intent_key'] ) ) {
181 $order_intent = OsOrderIntentHelper::get_order_intent_by_intent_key( $event['data']['order_intent_key'] );
182 if ( $order_intent->is_new_record() ) {
183 OsDebugHelper::log( 'Error processing Razorpay connect webhook: Order intent not found' );
184 http_response_code( 400 );
185 exit();
186 }
187 // Store the payment ID so process_payment() can verify it
188 $payment_data = json_decode( $order_intent->payment_data, true ) ?? [];
189 $payment_data['token'] = sanitize_text_field( $event['data']['payment_id'] ?? '' );
190 $order_intent->update_attributes( [ 'payment_data' => wp_json_encode( $payment_data ) ] );
191
192 if ( $order_intent->convert_to_order() ) {
193 http_response_code( 200 );
194 } else {
195 http_response_code( 400 );
196 OsDebugHelper::log( 'Error converting order intent', 'razorpay_connect_webhook', $order_intent->get_error_messages() );
197 }
198 }
199 if ( ! empty( $event['data']['transaction_intent_key'] ) ) {
200 $transaction_intent = OsTransactionIntentHelper::get_transaction_intent_by_intent_key( $event['data']['transaction_intent_key'] );
201 if ( $transaction_intent->is_new_record() ) {
202 OsDebugHelper::log( 'Error processing Razorpay connect webhook: Transaction intent not found' );
203 http_response_code( 400 );
204 exit();
205 }
206 $payment_data = json_decode( $transaction_intent->payment_data, true ) ?? [];
207 $payment_data['token'] = sanitize_text_field( $event['data']['payment_id'] ?? '' );
208 $transaction_intent->update_attributes( [ 'payment_data' => wp_json_encode( $payment_data ) ] );
209
210 if ( $transaction_intent->convert_to_transaction() ) {
211 http_response_code( 200 );
212 } else {
213 http_response_code( 400 );
214 OsDebugHelper::log( 'Error converting transaction intent', 'razorpay_connect_webhook' );
215 }
216 }
217 break;
218 }
219 exit();
220 }
221
222 public function start_connect_process() {
223 $env = $this->get_env_from_params();
224 OsSettingsHelper::save_setting_by_name( OsSettingsHelper::append_payment_env_key( 'enable_payment_processor_razorpay_connect', $env ), LATEPOINT_VALUE_ON );
225 $url = OsRazorpayConnectHelper::get_connect_url( $env );
226 $this->send_json(
227 [
228 'status' => LATEPOINT_STATUS_SUCCESS,
229 'url' => $url,
230 'message' => __( 'Redirecting to Razorpay', 'latepoint' ),
231 ]
232 );
233 }
234
235 public function disconnect_connect_account() {
236 $this->check_nonce( 'razorpay_disconnect_account' );
237 $env = $this->get_env_from_params();
238 try {
239 $account_id = OsRazorpayConnectHelper::get_connect_account_id( $env );
240 $path = $account_id . '/server-tokens/' . OsRazorpayConnectHelper::get_server_token( $env ) . '/disconnect/';
241 $response = OsRazorpayConnectHelper::do_request( $path, '', 'DELETE', [], [], $env );
242 if ( $response['status']['code'] === 200 ) {
243 OsSettingsHelper::remove_setting_by_name( OsSettingsHelper::append_payment_env_key( 'razorpay_connect_charges_enabled', $env ) );
244 OsSettingsHelper::remove_setting_by_name( OsSettingsHelper::append_payment_env_key( 'razorpay_connect_account_id', $env ) );
245 OsSettingsHelper::remove_setting_by_name( OsSettingsHelper::append_payment_env_key( 'razorpay_connect_public_token', $env ) );
246 OsRazorpayConnectHelper::reset_server_token( $env );
247 } else {
248 OsDebugHelper::log( 'Razorpay Connect Error', 'razorpay_connect_disconnect_error', $response );
249 }
250 } catch ( Exception $e ) {
251 OsDebugHelper::log( 'Error disconnecting Razorpay account', 'razorpay_connect_error', [ 'error_message' => $e->getMessage() ] );
252 $this->send_json(
253 [
254 'status' => LATEPOINT_STATUS_ERROR,
255 'message' => $e->getMessage(),
256 ]
257 );
258 }
259 $this->send_json(
260 [
261 'status' => LATEPOINT_STATUS_SUCCESS,
262 'message' => OsRazorpayConnectHelper::get_connection_buttons_and_status( $env ),
263 ]
264 );
265 }
266
267 public function check_connect_status() {
268 $env = $this->get_env_from_params();
269 try {
270 $response = OsRazorpayConnectHelper::do_request( 'server-tokens/' . OsRazorpayConnectHelper::get_server_token( $env ) . '/status', '', 'GET', [], [], $env );
271 if ( $env === LATEPOINT_PAYMENTS_ENV_LIVE ) {
272 $fee_info = empty( $response['data']['transaction_fee_info'] ) ? '0' : $response['data']['transaction_fee_info'];
273 OsSettingsHelper::save_setting_by_name( 'razorpay_connect_transaction_fee_info', $fee_info );
274 }
275 if ( ! empty( $response['data'] ) && ! empty( $response['data']['account_id'] ) ) {
276 OsSettingsHelper::save_setting_by_name( OsSettingsHelper::append_payment_env_key( 'razorpay_connect_account_id', $env ), $response['data']['account_id'] );
277 OsSettingsHelper::save_setting_by_name( OsSettingsHelper::append_payment_env_key( 'razorpay_connect_public_token', $env ), $response['data']['public_token'] ?? '' );
278 if ( ! empty( $response['data']['charges_enabled'] ) ) {
279 OsSettingsHelper::save_setting_by_name( OsSettingsHelper::append_payment_env_key( 'razorpay_connect_charges_enabled', $env ), LATEPOINT_VALUE_ON );
280 } else {
281 OsSettingsHelper::remove_setting_by_name( OsSettingsHelper::append_payment_env_key( 'razorpay_connect_charges_enabled', $env ) );
282 }
283 } else {
284 OsSettingsHelper::remove_setting_by_name( OsSettingsHelper::append_payment_env_key( 'razorpay_connect_charges_enabled', $env ) );
285 OsSettingsHelper::remove_setting_by_name( OsSettingsHelper::append_payment_env_key( 'razorpay_connect_account_id', $env ) );
286 OsSettingsHelper::remove_setting_by_name( OsSettingsHelper::append_payment_env_key( 'razorpay_connect_public_token', $env ) );
287 }
288 if ( ! empty( $response['data']['active_site_urls'] ) ) {
289 OsSettingsHelper::save_setting_by_name( OsSettingsHelper::append_payment_env_key( 'razorpay_connect_duplicate_token_activations', $env ), $response['data']['active_site_urls'] );
290 } else {
291 OsSettingsHelper::remove_setting_by_name( OsSettingsHelper::append_payment_env_key( 'razorpay_connect_duplicate_token_activations', $env ) );
292 }
293 if ( ! empty( $response['data']['error'] ) ) {
294 OsDebugHelper::log( 'Error checking Razorpay connect status', 'razorpay_connect_error', [ 'error_message' => $response['data']['error'] ] );
295 }
296 } catch ( Exception $e ) {
297 OsDebugHelper::log( 'Error getting Razorpay connection status', 'razorpay_connect_error', [ 'error_message' => $e->getMessage() ] );
298 $this->send_json(
299 [
300 'status' => LATEPOINT_STATUS_ERROR,
301 'message' => $e->getMessage(),
302 ]
303 );
304 }
305 $this->send_json(
306 [
307 'status' => LATEPOINT_STATUS_SUCCESS,
308 'message' => OsRazorpayConnectHelper::get_connection_buttons_and_status( $env ),
309 ]
310 );
311 }
312
313 public function heartbeat() {
314 $payload = @file_get_contents( 'php://input' );
315 $data = json_decode( $payload, true );
316
317 if ( empty( $data['wp_latepoint_server_token'] ) ) {
318 $this->send_json(
319 [
320 'status' => LATEPOINT_STATUS_ERROR,
321 'message' => 'Token is missing',
322 ],
323 404
324 );
325 }
326 if ( $data['wp_latepoint_server_token'] !== OsRazorpayConnectHelper::get_server_token() ) {
327 $this->send_json(
328 [
329 'status' => LATEPOINT_STATUS_ERROR,
330 'message' => 'Invalid Token',
331 ],
332 404
333 );
334 }
335 $this->send_json(
336 [
337 'status' => LATEPOINT_STATUS_SUCCESS,
338 'message' => 'Heartbeat detected',
339 ],
340 200
341 );
342 }
343 }
344
345 endif;
346