PluginProbe
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell / 3.12.1
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell v3.12.1
3.13.3 3.13.2 3.13.1 3.13.0 3.12.13 3.12.12 3.12.11 3.12.10 3.12.9 3.12.8 3.12.7 3.12.6 3.12.5 3.12.4 3.12.3 3.12.1 3.12.2 3.12.0 3.11.1 3.11.0 3.10.9 3.10.8 3.10.7 3.10.6 2.8.16 All 261 releases
wpfunnels / includes / core / gateways / class-wpfnl-gateway-square.php

class-wpfnl-gateway-square.php in WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell 3.12.1, at includes/core/gateways/class-wpfnl-gateway-square.php

470 lines 14.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace WPFunnels\Gateway;
3
4 /**
5 * @author [Saiduzzaman Tohin]
6 * @email [[email protected]]
7 * @create date 2022-05-26 11:16:34
8 * @modify date 2022-05-26 11:16:34
9 * @desc [Supporting Square Payment Gateway with WPFunnels one-click offer]
10 */
11
12 use Square\SquareClient;
13 use WooCommerce\Square\Framework\PaymentGateway\Payment_Gateway_Helper;
14 use WooCommerce\Square\Framework\Square_Helper;
15 use WPFunnels\Wpfnl_functions;
16 use WooCommerce\Square\Gateway\Customer_Helper;
17
18 class Wpfnl_Gateway_Square {
19
20 /**
21 * @var string
22 * @since 1.6.4
23 */
24 public $key = 'square_credit_card';
25
26 /**
27 * Guest token call
28 *
29 * @var string
30 * @since 1.9.1
31 */
32 public $maybe_guest_token_call = false;
33
34 /**
35 * @var bool
36 * @since 1.6.4
37 */
38 public $refund_support;
39
40
41 public function __construct() {
42
43
44 $this->refund_support = true;
45 add_filter( 'wc_' . $this->key . '_payment_form_tokenization_forced', array( $this, 'is_square_tokenization_allowed' ), 10, 2 );
46 add_filter( 'wc_payment_gateway_' . $this->key . '_get_order', [ $this, 'get_order_by_hook' ], 10 );
47 add_filter( 'wc_payment_gateway_' . $this->key . '_process_payment', [ $this, 'is_credit_card_process_payment' ], 10, 3 );
48 add_action( 'wpfunnels/child_order_created_' . $this->key, array( $this, 'add_capture_meta_to_child_order' ), 9999, 3 );
49 add_action( 'wpfunnels/subscription_created', array( $this, 'add_offer_subscription_meta' ), 9999, 3 );
50 }
51
52 /**
53 * Get order
54 *
55 * @param $order
56 * @param WC_Payment_Gateway $gateway
57 *
58 * @since 1.9.1
59 * @return mixed
60 */
61 public function get_order_by_hook( $order ) {
62 $this->set_square_client_environment();
63 if ( ! isset( $order->payment->token ) ) {
64 $order->payment->token = $order->get_meta('_wc_square_credit_card_payment_token');
65 }
66 if ( $this->maybe_guest_token_call && isset( $order->payment->verification_token ) && ! empty( $order->payment->verification_token ) ) {
67 $order->payment->verification_token = null;
68 if ( isset( $_POST[ 'wc-' . $this->get_wc_gateway()->get_id_dasherized() . '-buyer-verification-token' ] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing
69 unset( $_POST[ 'wc-' . $this->get_wc_gateway()->get_id_dasherized() . '-buyer-verification-token' ] ); //phpcs:ignore WordPress.Security.NonceVerification.Missing
70 }
71 }
72 return $order;
73 }
74
75
76 /**
77 * Credit card payment processing
78 *
79 * @param bool $process_payment The current process payment status.
80 * @param int $order_id The ID of the order.
81 * @param object $gateway The WooCommerce payment gateway object.
82 *
83 * @return bool Returns the updated process payment status.
84 *
85 * @since 1.6.4
86 */
87 public function is_credit_card_process_payment($process_payment, $order_id, $gateway) {
88 $order = wc_get_order( $order_id );
89 if ( $order ) {
90 $this->create_token_for_offer_payment( $order );
91 }
92 return $process_payment;
93 }
94
95
96 /**
97 * Create payment token for offer product charge
98 *
99 * Creates a payment token for processing the payment of an offer product charge.
100 *
101 * @param object $order full order object.
102 *
103 * @return void
104 *
105 * @since 1.9.1
106 */
107 private function create_token_for_offer_payment( $order ) {
108 $this->set_square_client_environment();
109 $order = $this->get_wc_gateway()->get_order( $order );
110 $is_checkout_nonce_present_in_request = isset( $_REQUEST['wc_square_credit_card_checkout_validate_nonce'] ) ? wc_clean( $_REQUEST['wc_square_credit_card_checkout_validate_nonce'] ) : ''; //phpcs:ignore WordPress.Security.NonceVerification.Recommended
111 if ( empty( $order->payment->token ) && empty( $is_checkout_nonce_present_in_request ) && 1 > $order->get_customer_id() ) {
112 $create_token = true;
113 if ( class_exists( '\WooCommerce\Square\Gateway\Customer_Helper' ) ) {
114 $indexed_customers = Customer_Helper::get_customers_by_email( $order->get_billing_email() );
115 if ( is_array( $indexed_customers ) && count( $indexed_customers ) > 1 ) {
116 $create_token = false;
117 }
118 }
119 if ( $create_token ) {
120 $order = $this->get_wc_gateway()->get_payment_tokens_handler()->create_token( $order );
121 }
122 $this->maybe_guest_token_call = true;
123 if ( isset( $_POST[ 'wc-' . $this->get_wc_gateway()->get_id_dasherized() . '-buyer-verification-token' ] ) ) {
124 unset( $_POST[ 'wc-' . $this->get_wc_gateway()->get_id_dasherized() . '-buyer-verification-token' ] );
125 }
126 }
127 }
128
129
130 /**
131 * Remove underscore and add dash inside a string
132 *
133 * @return string|string[]
134 * @since 1.6.4
135 */
136 public function get_id_dasherized() {
137 return str_replace( '_', '-', $this->key );
138 }
139
140
141 /**
142 * Return order information for creating customer response
143 *
144 * @param $order
145 *
146 * @return bool|\WC_Order|\WC_Order_Refund
147 * @since 1.6.4
148 */
149 public function get_order( $order ) {
150
151 if ( is_numeric( $order ) ) {
152 $order = wc_get_order( $order );
153 }
154
155 $order->payment = new \stdClass();
156
157 if ( empty( $order->payment->token ) ) {
158 $order->payment->nonce = Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-payment-nonce' );
159 $order->payment->card_type = Payment_Gateway_Helper::normalize_card_type( Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-card-type' ) );
160 $order->payment->account_number = $order->payment->last_four = substr( Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-last-four' ), -4 );
161 $order->payment->exp_month = Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-exp-month' );
162 $order->payment->exp_year = Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-exp-year' );
163 $order->payment->postcode = Square_Helper::get_post( 'wc-' . $this->get_id_dasherized() . '-payment-postcode' );
164 }
165 return $order;
166 }
167
168
169 /**
170 * Payment Gateway Payment Form Tokenization Forced.
171 *
172 * Filters whether tokenization is forced for the payment form.
173 *
174 * @param bool $tokenization_forced The current tokenization forced status.
175 *
176 * @return bool Returns the updated tokenization forced status.
177 *
178 * @since 1.6.4
179 */
180 public function is_square_tokenization_allowed($tokenization_forced)
181 {
182 return true;
183 if(get_the_ID() === 1){
184 $post = Wpfnl_functions::get_sanitized_get_post();
185 $checkout_id = Wpfnl_functions::get_checkout_id_from_post($post);
186 }else{
187 $checkout_id = get_the_ID();
188 }
189 $funnel_id = Wpfnl_functions::get_funnel_id_from_step( $checkout_id );
190 if ( $checkout_id && $funnel_id ) {
191 $next_step = Wpfnl_functions::get_next_step($funnel_id, $checkout_id);
192
193 if ( $next_step && Wpfnl_functions::is_offer_page($next_step['step_id']) ) {
194 $tokenization_forced = true;
195 }
196 }
197 return $tokenization_forced;
198 }
199
200
201 /**
202 * Processing of the Upsell or Downsell offers
203 *
204 * @param mixed $order
205 * @param mixed $offer_product
206 *
207 * @return array
208 * @since 1.6.4
209 */
210 public function process_payment($order, $offer_product) {
211 $currency = $order->get_currency();
212 // Setup square payment configuration
213 $client = $this->set_square_client_environment();
214
215 if ( isset($offer_product['price']) && (floatval(0) === floatval( $offer_product['price'] ) || '' === trim($offer_product['price'])) ) {
216 wp_send_json(array(
217 'result' => 'fail',
218 'message' => __('Product price is less than 0', 'wpfnl-pro'),
219 ));
220 } else {
221 $money_utility_object = new \WooCommerce\Square\Utilities\Money_Utility();
222 $amount_money = $money_utility_object::amount_to_money($offer_product['total'], $currency);
223
224 $credit_card_payment_token = $order->get_meta('_wc_square_credit_card_payment_token');
225 $credit_card_customer_id = $order->get_meta('_wc_square_credit_card_customer_id');
226
227 // Prepare data structure for request
228 $body = new \Square\Models\CreatePaymentRequest(
229 $credit_card_payment_token,
230 uniqid()
231 );
232 $body->setAutocomplete(true);
233 $body->setCustomerId($credit_card_customer_id);
234 $body->setAmountMoney($amount_money);
235
236 // Handle payment request API responses
237 $api_response = $client->getPaymentsApi()->createPayment($body);
238
239 if ($api_response->isSuccess()) {
240 $transaction_id = $api_response->getResult()->getPayment()->getId();
241
242 // Store transaction ID for offer products
243 $this->store_offer_transaction( $order, $transaction_id, $offer_product );
244 // Reduce offer products from stock
245 $this->reduce_the_offer_product_from_stock($order, $offer_product);
246
247 return array(
248 'is_success' => true,
249 'message' => 'Success'
250 );
251 } else {
252 $errors = $api_response->getErrors();
253 return array(
254 'is_success' => false,
255 'message' => sprintf( __( 'Square payment transaction failed (%1$s:%2$s)', 'wpfnl-pro' ), $errors )
256 );
257 }
258
259 }
260 }
261
262
263 /**
264 * Store transaction ID for offer products
265 *
266 * @param $order
267 * @param $response
268 * @param $product
269 *
270 * @since 1.6.4
271 */
272 public function store_offer_transaction( $order, $transaction_id, $product )
273 {
274 $order->update_meta_data('_wpfunnels_offer_txn_resp_' . $product['step_id'], $transaction_id);
275 $order->save();
276 }
277
278
279 /**
280 * Set up the required configuration for payment.
281 *
282 * @return object
283 *
284 * @since 1.6.4
285 */
286 public function set_square_client_environment() {
287
288 // Set the access tokan.
289 $this->access_token = $this->get_wc_gateway()->get_plugin()->get_settings_handler()->get_access_token();
290 $this->access_token = empty( $this->access_token ) ? $this->get_wc_gateway()->get_plugin()->get_settings_handler()->get_option( 'sandbox_token' ) : $this->access_token;
291
292 // Set the location id.
293 $this->location_id = $this->get_wc_gateway()->get_plugin()->get_settings_handler()->get_location_id();
294 $client = new SquareClient([
295 'accessToken' => $this->access_token,
296 'environment' => $this->get_environment(),
297 ]);
298
299 return $client;
300 }
301
302
303 /**
304 * Get WooCommerce payment geteways.
305 *
306 * @return array
307 *
308 * @since 1.6.4
309 */
310 public function get_wc_gateway() {
311
312 global $woocommerce;
313
314 $gateways = $woocommerce->payment_gateways->payment_gateways();
315
316 return $gateways[ $this->key ];
317 }
318
319
320 /**
321 * Gets the configured environment.
322 *
323 * @since 1.6.4
324 *
325 * @return string
326 */
327 public function get_environment() {
328 $sanboxed = ( defined( 'WC_SQUARE_SANDBOX' ) && WC_SQUARE_SANDBOX ) || $this->is_sandbox_setting_enabled();
329 return $sanboxed ? 'sandbox' : 'production';
330 }
331
332
333 /**
334 * Tells is if the setting for enabling sandbox is checked.
335 *
336 * @since 1.6.4
337 *
338 * @return boolean
339 */
340 public function is_sandbox_setting_enabled() {
341 return 'yes' === $this->get_enable_sandbox();
342 }
343
344
345 /**
346 * Gets setting enabled sandbox.
347 *
348 * @since 1.6.4
349 *
350 * @return string
351 */
352 public function get_enable_sandbox() {
353 $setting = get_option('wc_square_settings');
354 return $setting['enable_sandbox'];
355 }
356
357
358 /**
359 * Determines if configured in the sandbox environment.
360 *
361 * @since 1.6.4
362 *
363 * @return bool
364 */
365 public function is_sandbox() {
366
367 return 'sandbox' === $this->get_environment();
368 }
369
370
371 /**
372 * Update post meta for refund process on upsell or downsell
373 *
374 * @param $parent_order
375 * @param $child_order
376 * @param $transaction_id
377 *
378 * @since 1.6.4
379 */
380 public function add_capture_meta_to_child_order( $parent_order, $child_order, $transaction_id ) {
381 $child_order->update_meta_data('_wc_square_credit_card_trans_id', $parent_order->data['transaction_id'] );
382 $child_order->update_meta_data('_wc_square_credit_card_square_location_id', $parent_order->get_meta( '_wc_square_credit_card_square_location_id', true ) );
383 $child_order->update_meta_data('_wc_square_credit_card_authorization_code', $parent_order->data['transaction_id'] );
384 $child_order->update_meta_data('_wc_square_credit_card_customer_id', $parent_order->get_meta( '_wc_square_credit_card_customer_id', true ) );
385 $child_order->update_meta_data('_wc_square_credit_card_square_order_id', $parent_order->data['transaction_id'] );
386 $child_order->update_meta_data('_wc_square_credit_card_charge_captured', 'yes' );
387 }
388
389
390 /**
391 * Process offer refund
392 *
393 * @param object $order Order Object.
394 * @param array $offer_data offer data.
395 *
396 * @return string/bool.
397 *
398 * @since 1.6.4
399 */
400 public function process_refund_offer( $order, $offer_data ) {
401 $payment_id = $offer_data['transaction_id'];
402
403 // set up the square payment configuration.
404 $client = $this->set_square_client_environment();
405 $money_utility_object = new \WooCommerce\Square\Utilities\Money_Utility();
406 $amount_money = $money_utility_object::amount_to_money($offer_data['amount'],'USD');
407
408 $body = new \Square\Models\RefundPaymentRequest(
409 uniqid(),
410 $amount_money,
411 $payment_id
412 );
413
414 $api_response = $client->getRefundsApi()->refundPayment($body);
415
416 if ($api_response->isSuccess()) {
417 $response_id = $api_response->getResult()->getRefund()->getId();
418 return $response_id;
419 } else {
420 $errors = $api_response->getErrors();
421 return false;
422 }
423
424 }
425
426
427 /**
428 * add subscription offer meta to order
429 *
430 * @param $subscription
431 * @param $offer_product
432 * @param $order
433 *
434 * @since 1.6.4
435 */
436 public function add_offer_subscription_meta( $subscription, $offer_product, $order ) {
437 if ( $this->key === $order->get_payment_method() ) {
438 $subscription_id = $subscription->get_id();
439 update_post_meta( $subscription_id, '_wc_square_credit_card_payment_token', $order->get_meta( '_wc_square_credit_card_payment_token', true ) );
440 update_post_meta( $subscription_id, '_wc_square_credit_card_customer_id', $order->get_meta( '_wc_square_credit_card_customer_id', true ) );
441 }
442 }
443
444
445
446 /**
447 * Reduce the offer product from the stock after upsell or downsell offer has been accepted
448 *
449 * @param object $order Object of order.
450 * @param array $offer_product array of offer product.
451 *
452 * @since 1.6.4
453 */
454 public function reduce_the_offer_product_from_stock( $order, $offer_product ) {
455
456 $product = wc_get_product( $offer_product['id'] );
457 if( $product ){
458 $new_stock = wc_update_product_stock( $offer_product['id'], $offer_product['qty'], 'decrease' );
459 $changes[] = array(
460 'product' => $product,
461 'from' => $new_stock + intval( $offer_product['qty'] ),
462 'to' => $new_stock,
463 );
464 wc_trigger_stock_change_notifications( $order, $changes );
465 }
466
467
468 }
469
470 }