PluginProbe
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell / 3.12.9
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell v3.12.9
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-authorize-net.php

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

883 lines 35.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPFunnels\Gateway;
4
5 use WpFluent\Exception;
6 use WPFunnels\Wpfnl_functions;
7
8 /**
9 * Class Wpfnl_Pro_Gateway_Authorize_Net
10 * @package WPFunnelsPro\Frontend\Gateways
11 */
12 class Wpfnl_Gateway_Authorize_Net {
13
14 /**
15 * @var $key string
16 */
17 public $key = 'authorize_net_cim_credit_card';
18
19
20 /**
21 * @var $is_api_refund bool
22 */
23 public $refund_support;
24
25
26 /**
27 * @var $extra_data
28 */
29 public $extra_data;
30
31
32 public $unset_opaque_value = false;
33
34
35 public $offer_product;
36
37
38 const MB_ENCODING = 'UTF-8';
39
40
41 public function __construct() {
42
43 $this->refund_support = true;
44
45 /**
46 * force tokenization and do not ask user for an option
47 */
48 add_filter( 'wc_payment_gateway_' . $this->key . '_tokenization_forced', array( $this, 'maybe_force_tokenization' ) );
49
50 /**
51 * create token for non logged in user and accept js is turned on.
52 * force tokenization for guest when needed
53 */
54 add_filter( 'wc_payment_gateway_' . $this->key . '_process_payment', array( $this, 'create_token_process_payment' ), 10, 3 );
55
56 /**
57 * modify refund request data
58 */
59 add_filter( 'wc_authorize_net_cim_api_request_data', array( $this, 'modify_offer_refund_request_data' ), 10, 3 );
60
61 add_action( 'wpfunnels/subscription_created', array( $this, 'add_offer_subscription_meta' ), 9999, 3 );
62 }
63
64
65 /**
66 * force tokenization for upsell/downsell
67 *
68 * @param $force_tokenization
69 * @return mixed
70 */
71 public function maybe_force_tokenization( $force_tokenization ) {
72 if( isset( $_POST['post_data'] ) ) {
73 $post_data = array();
74 parse_str( $_POST['post_data'],$post_data );
75 $checkout_id = Wpfnl_functions::get_checkout_id_from_post_data( $post_data );
76 $funnel_id = Wpfnl_functions::get_funnel_id_from_post_data( $post_data );
77 if ( $checkout_id && $funnel_id ) {
78 if ( Wpfnl_functions::is_offer_exists_in_funnel($funnel_id) ) {
79 $force_tokenization = true;
80 }
81 }
82 }
83 return $force_tokenization;
84 }
85
86
87 /**
88 * create token and process payment for non-logged in user
89 *
90 * @param $result
91 * @param $order_id
92 * @param $auth_net_obj
93 * @return mixed
94 */
95 public function create_token_process_payment( $result, $order_id, $auth_net_obj ) {
96 $create_token = false;
97 $checkout_id = Wpfnl_functions::get_checkout_id_from_post_data();
98 $funnel_id = Wpfnl_functions::get_funnel_id_from_post_data();
99 if ( $checkout_id && $funnel_id ) {
100 if ( Wpfnl_functions::is_offer_exists_in_funnel($funnel_id) ) {
101 $create_token = true;
102 }
103 }
104 $order = $this->get_wc_gateway()->get_order( $order_id );
105
106 if( $create_token && empty( $order->get_user_id() ) ) {
107 try {
108 // check if token is already exists for the order
109 if( isset( $order->payment->token ) && $order->payment->token ) {
110 $this->get_wc_gateway()->add_transaction_data( $order );
111 } else {
112 // create new token
113 $order_for_shipping = $order;
114 try {
115 $order = $this->get_wc_gateway()->get_payment_tokens_handler()->create_token($order);
116 } catch ( \Exception $e ) {
117 $re = '/[0-9]+/';
118 $str = $e->getMessage();
119 preg_match_all( $re, $str, $matches, PREG_SET_ORDER, 0 );
120
121 if ( $matches && is_array( $matches ) && isset( $matches[0][0] ) && '00039' === $matches[0][0] ) {
122 $get_order_by_meta = new \WP_Query( array(
123 'post_type' => 'shop_order',
124 'post_status' => 'any',
125 'meta_query' => array(
126 array(
127 'key' => '_wc_authorize_net_cim_credit_card_customer_id',
128 'value' => $matches[1][0],
129 'compare' => '=',
130 ),
131 ),
132 'fields' => 'ids',
133 'order' => 'ASC',
134 ) );
135
136 if ( is_array( $get_order_by_meta->posts ) && count( $get_order_by_meta->posts ) > 0 ) {
137 $this->extra_data['authorize_net_cim_order_id'] = $get_order_by_meta->posts[0];
138 $order_for_shipping = $this->get_wc_gateway()->get_order( $get_order_by_meta->posts[0] );
139 $this->extra_data['authorize_net_cim_customer_id'] = $matches[1][0];
140 }
141 }
142 }
143 $this->unset_opaque_value = true;
144 $order = $this->get_order( $order );
145 $this->get_wc_gateway()->add_transaction_data( $order );
146
147 /**
148 * We need to create shipping ID for the current user on Authorize.Net CIM API
149 * As ShippingAddressID is important for the cases when business owner has shipping-filters enabled in their merchant account.
150 *
151 */
152
153 try {
154
155 /**
156 * When we are in a case when there is a returning user & not logged in then in this case there are chances that shipping API request might fail.
157 * In this case we need to try and get shipping ID from the order meta and set this up for further.
158 */
159 $response = $this->get_wc_gateway()->get_api()->create_shipping_address( $order );
160
161 } catch ( \Exception $e) {
162 $response = intval( $order_for_shipping->get_meta( '_authorize_cim_shipping_address_id', true ) );
163 }
164 $shipping_address_id = is_numeric( $response ) ? $response : $response->get_shipping_address_id();
165 $order->payment->shipping_address_id = $shipping_address_id;
166 WC()->session->set( 'authorize_net_cim_shipping_id', $order->payment->shipping_address_id );
167 $this->get_wc_gateway()->add_transaction_data( $order );
168 $this->do_main_transaction( $order );
169 }
170 $result = array(
171 'result' => 'success',
172 'redirect' => $this->get_wc_gateway()->get_return_url( $order ),
173 );
174 }
175 catch ( \Exception $e ) {
176 $result = array(
177 'result' => 'failure',
178 'message' => $e->getMessage(),
179 );
180 }
181 }
182 return $result;
183 }
184
185
186 /**
187 * process the offer payment
188 *
189 * @param $order
190 * @param $offer_product
191 * @return array
192 */
193 public function process_payment( $order, $offer_product ) {
194 $_response = array(
195 'is_success' => false,
196 'message' => ''
197 );
198
199 $this->offer_product = $offer_product;
200 try {
201 $gateway = $this->get_wc_gateway();
202 $api = $gateway->get_api();
203 $environment = $gateway->get_environment();
204 $url = ( 'production' === $environment ) ? $api::PRODUCTION_ENDPOINT : $api::TEST_ENDPOINT;
205
206 /**
207 * modify order object and populate it as per the scenario (offer transaction)
208 */
209 add_filter( 'wc_payment_gateway_' . $this->key . '_get_order', array( $this, 'get_modified_order' ), 999 );
210 $new_order = $gateway->get_order( $order );
211 $request = $this->create_transaction_request( 'capture', $new_order );
212 $response = wp_safe_remote_request( $url, $this->get_request_attributes( $request ) );
213 $body = wp_remote_retrieve_body( $response );
214 $body = preg_replace( '/[\x00-\x1F\x80-\xFF]/', '', $body );
215 $result = json_decode( $body, true );
216
217 if ( is_wp_error( $response ) ) {
218 $result['is_success'] = false;
219 }
220 else {
221 if ( isset( $result['messages'] ) && isset( $result['messages']['message'][0]['code'] ) && 'I00001' === $result['messages']['message'][0]['code'] ) {
222 $_response['is_success'] = true;
223 $transaction_id = $this->get_transaction_id( $result['directResponse'] );
224 $response_data = array(
225 'id' => $transaction_id,
226 );
227 $this->store_offer_transaction( $order, $response_data, $offer_product );
228 } else {
229 $order_note = sprintf( __( 'Authorize.net CIM Transaction Failed (%s)', 'wpfnl-pro' ), $result['messages']['message'][0]['text'] );
230 $_response['is_success'] = false;
231 $_response['message'] = $order_note;
232 $order->add_order_note( $order_note );
233 }
234 }
235 } catch (\Exception $e) {
236 $order_note = sprintf( __( 'Authorize.net CIM Transaction Failed (%s)', 'wpfnl-pro' ), $e->getMessage() );
237 $_response['is_success'] = false;
238 $_response['message'] = $order_note;
239 $order->add_order_note( $order_note );
240 }
241 return $_response;
242 }
243
244
245 /**
246 * create transaction request for offer
247 * product
248 *
249 * @param $type
250 * @param $new_order
251 * @return array[]
252 */
253 private function create_transaction_request( $type, $new_order ) {
254 $order = $new_order;
255 $transaction_type = ( 'auth_only' === $type ) ? 'profileTransAuthOnly' : 'profileTransAuthCapture';
256 $offer_product = $this->offer_product;
257
258 /**
259 * We need to create shipping ID for the current user on Authorize.Net CIM API
260 * As ShippingAddressID is important for the cases when business owner has shipping-filters enabled in their merchant account.
261 */
262 $maybe_get_shipping_id_from_session = WC()->session->get( 'authorize_net_cim_shipping_id' );
263 if ( isset( $order->payment ) && isset( $order->payment->shipping_address_id ) && ! empty( $order->payment->shipping_address_id ) ) {
264 $shipping_address_id = $order->payment->shipping_address_id;
265 } elseif ( ! empty( $maybe_get_shipping_id_from_session ) ) {
266 $shipping_address_id = $maybe_get_shipping_id_from_session;
267 } else {
268 $response = $this->get_wc_gateway()->get_api()->create_shipping_address( $order );
269 $shipping_address_id = is_numeric( $response ) ? $response : $response->get_shipping_address_id();
270 }
271 return array(
272 'createCustomerProfileTransactionRequest' => array(
273 'merchantAuthentication' => array(
274 'name' => wc_clean( $this->get_wc_gateway()->get_api_login_id() ),
275 'transactionKey' => wc_clean( $this->get_wc_gateway()->get_api_transaction_key() ),
276 ),
277 'refId' => $order->get_id() . '_' . $offer_product['step_id'],
278 'transaction' => array(
279 $transaction_type => array(
280 'amount' => $offer_product['total'],
281 'tax' => array(),
282 'shipping' => array(),
283 'lineItems' => $this->get_line_items(),
284 'customerProfileId' => $this->get_customer_id( $order ),
285 'customerPaymentProfileId' => $this->get_token( $order ),
286 'customerShippingAddressId' => $shipping_address_id,
287 'order' => array(
288 'invoiceNumber' => $order->get_id() . '_' . $offer_product['step_id'],
289 'description' => $this->string_truncate( $offer_product['desc'], 255 ),
290 'purchaseOrderNumber' => $this->string_truncate( preg_replace( '/\W/', '', $order->payment->po_number ), 25 ),
291 ),
292 ),
293 ),
294 )
295 );
296 }
297
298
299 /**
300 * do main transaction
301 *
302 * @param \WC_Order $order
303 */
304 private function do_main_transaction( \WC_Order $order ) {
305
306 try{
307 $order->description = sprintf( __( '%1$s - Release Payment for Order %2$s', 'wpfnl-pro' ), esc_html( $this->get_current_site_name() ), $order->get_order_number() );
308
309 // token is required.
310 if ( ! $order->payment->token ) {
311 throw new Exception( __( 'Payment token missing/invalid.', 'wpfnl-pro' ) );
312 }
313
314 // perform the main transaction
315 if ( $this->get_wc_gateway()->is_credit_card_gateway() ) {
316 if ( $this->get_wc_gateway()->perform_credit_card_charge( $order ) ) {
317 $response = $this->get_wc_gateway()->get_api()->credit_card_charge( $order );
318 } else {
319 $response = $this->get_wc_gateway()->get_api()->credit_card_authorization( $order );
320 }
321 } elseif ( $this->get_wc_gateway()->is_echeck_gateway() ) {
322 $response = $this->get_wc_gateway()->get_api()->check_debit( $order );
323 }
324
325 // success! update order record
326 if ( $response->transaction_approved() ) {
327 $last_four = substr( $order->payment->account_number, - 4 );
328 // order note based on gateway type
329 if ( $this->get_wc_gateway()->is_credit_card_gateway() ) {
330 $message = sprintf( __( '%1$s %2$s Release Payment Approved: %3$s ending in %4$s (expires %5$s)', 'wpfnl-pro' ), $this->get_wc_gateway()->get_method_title(), $this->get_wc_gateway()->perform_credit_card_authorization( $order ) ? 'Authorization' : 'Charge', ! isset( $order->payment->card_type ) ? $order->payment->card_type : 'card', $last_four, ( isset( $order->payment->exp_month ) && isset( $order->payment->exp_year ) ? $order->payment->exp_month . '/' . substr( $order->payment->exp_year, - 2 ) : 'n/a' ) );
331 }
332 // adds the transaction id (if any) to the order note
333 if ( $response->get_transaction_id() ) {
334 $message .= ' ' . sprintf( __( '(Transaction ID %s)', 'wpfnl-pro' ), $response->get_transaction_id() );
335 }
336 $order->add_order_note( $message );
337 }
338
339
340 if ( $response->transaction_approved() || $response->transaction_held() ) {
341 // add the standard transaction data.
342 $this->get_wc_gateway()->add_transaction_data( $order, $response );
343
344 // allow the concrete class to add any gateway-specific transaction data to the order.
345 $this->get_wc_gateway()->add_payment_gateway_transaction_data( $order, $response );
346
347 // if the transaction was held (ie fraud validation failure) mark it as such.
348 if ( $response->transaction_held() || ( $this->get_wc_gateway()->supports( 'authorization' ) && $this->get_wc_gateway()->perform_credit_card_authorization( $order ) ) ) {
349 $this->get_wc_gateway()->mark_order_as_held( $order, $this->get_wc_gateway()->supports( 'authorization' ) && $this->get_wc_gateway()->perform_credit_card_authorization( $order ) ? __( 'Authorization only transaction', 'wpfnl-pro' ) : $response->get_status_message(), $response );
350 wc_reduce_stock_levels( $order->get_id() );
351 } else {
352 // otherwise complete the order.
353 $order->payment_complete();
354 }
355 } else {
356 // failure.
357 throw new Exception( sprintf( '%s: %s', $response->get_status_code(), $response->get_status_message() ) );
358 }
359 } catch ( \Exception $e ) {
360 if ( isset( $response ) ) {
361 $this->get_wc_gateway()->mark_order_as_failed( $order, sprintf( __( 'Release Payment Failed: %s', 'wpfnl-pro' ), $e->getMessage() ), $response );
362 } else {
363 $this->get_wc_gateway()->mark_order_as_failed( $order, sprintf( __( 'Release Payment Failed: %s', 'wpfnl-pro' ), $e->getMessage() ) );
364 }
365 }
366 }
367
368
369 /**
370 * get modified order
371 *
372 * @param $order
373 * @return mixed|\WC_Order
374 */
375 public function get_modified_order( $order ) {
376 if ( $order instanceof \WC_Order && $this->key === $order->get_payment_method() ) {
377
378 if ( $this->has_token( $order ) && ! is_checkout_pay_page() ) {
379
380 $order_id = $order->get_id();
381
382 // retrieve the payment token.
383 $order->payment->token = $this->get_wc_gateway()->get_order_meta( $order_id, 'payment_token' );
384
385 $token_from_gateway = $this->get_token( $order );
386 if ( empty( $order->payment->token ) && ! empty( $token_from_gateway ) ) {
387 $order->payment->token = $token_from_gateway;
388 }
389
390 // retrieve the optional customer id.
391 $order->customer_id = $this->get_wc_gateway()->get_order_meta( $order_id, 'customer_id' );
392
393 // set token data on order.
394 if ( $this->get_wc_gateway()->get_payment_tokens_handler()->user_has_token( $order->get_user_id(), $order->payment->token ) ) {
395
396 // an existing registered user with a saved payment token.
397 $token = $this->get_wc_gateway()->get_payment_tokens_handler()->get_token( $order->get_user_id(), $order->payment->token );
398
399 // account last four.
400 $order->payment->account_number = $token->get_last_four();
401
402 if ( $this->get_wc_gateway()->is_credit_card_gateway() ) {
403
404 // card type.
405 $order->payment->card_type = $token->get_card_type();
406
407 // exp month/year.
408 $order->payment->exp_month = $token->get_exp_month();
409 $order->payment->exp_year = $token->get_exp_year();
410
411 } elseif ( $this->get_wc_gateway()->is_echeck_gateway() ) {
412
413 // account type (checking/savings).
414 $order->payment->account_type = $token->get_account_type();
415 }
416 } else {
417
418 // a guest user means that token data must be set from the original order.
419
420 // account number.
421 $order->payment->account_number = $this->get_wc_gateway()->get_order_meta( $order_id, 'account_four' );
422
423 if ( $this->get_wc_gateway()->is_credit_card_gateway() ) {
424
425 // card type.
426 $order->payment->card_type = $this->get_wc_gateway()->get_order_meta( $order_id, 'card_type' );
427
428 // expiry date.
429 $expiry_date = $this->get_wc_gateway()->get_order_meta( $order_id, 'card_expiry_date' );
430
431 if ( ! empty( $expiry_date ) ) {
432 list( $exp_year, $exp_month ) = explode( '-', $expiry_date );
433 $order->payment->exp_month = $exp_month;
434 $order->payment->exp_year = $exp_year;
435 }
436 } elseif ( $this->get_wc_gateway()->is_echeck_gateway() ) {
437
438 // account type.
439 $order->payment->account_type = $this->get_wc_gateway()->get_order_meta( $order_id, 'account_type' );
440 }
441 }
442 }
443
444 $response = intval( $order->get_meta( '_authorize_cim_shipping_address_id', true ) );
445 if ( ! empty( $response ) ) {
446 $order->payment->shipping_address_id = $response;
447 }
448 if ( true === $this->unset_opaque_value && isset( $order->payment->opaque_value ) ) {
449 unset( $order->payment->opaque_value );
450 }
451 }
452 return $order;
453 }
454
455
456 /**
457 * modify offer refund request data
458 *
459 * @param $request_data
460 * @param $order
461 * @param $gateway
462 * @return mixed
463 */
464 public function modify_offer_refund_request_data( $request_data, $order, $gateway ) {
465 if ( isset( $_POST['wpfnl_refund'] ) ) {
466 $refund_data = $_POST;
467 $order_id = $order->get_id();
468 $step_id = isset( $_POST['step_id'] ) ? intval( $_POST['step_id'] ) : 0;
469 if ( isset( $request_data['createCustomerProfileTransactionRequest'] ) && isset( $request_data['createCustomerProfileTransactionRequest']['refId'] ) ) {
470 $request_data['createCustomerProfileTransactionRequest']['refId'] = $order_id . '_' . $step_id;
471 }
472
473 if ( isset( $request_data['createCustomerProfileTransactionRequest'] ) && isset( $request_data['createCustomerProfileTransactionRequest']['transaction'] ) && isset( $request_data['createCustomerProfileTransactionRequest']['transaction']['profileTransRefund'] ) && isset( $request_data['createCustomerProfileTransactionRequest']['transaction']['profileTransRefund']['order'] ) && isset( $request_data['createCustomerProfileTransactionRequest']['transaction']['profileTransRefund']['order']['invoiceNumber'] ) ) {
474 $request_data['createCustomerProfileTransactionRequest']['transaction']['profileTransRefund']['order']['invoiceNumber'] = $order_id . '_' . $step_id;
475 }
476 }
477 return $request_data;
478 }
479
480
481 /**
482 * @param $order
483 * @param $data
484 * @return mixed
485 */
486 public function process_refund_offer( $order, $data ) {
487 $transaction_id = $data['transaction_id'];
488 $refund_amount = $data['refund_amount'];
489 $refund_reason = $data['refund_reason'];
490 $gateway = $this->get_wc_gateway();
491 $api = $gateway->get_api();
492 $order->refund = new \stdClass();
493 $order->refund->trans_id = $transaction_id;
494 $order->refund->amount = number_format( $refund_amount, 2, '.', '' );
495 $order->refund->reason = $refund_reason;
496 $order->refund->customer_profile_id = $gateway->get_order_meta( $order, 'customer_id' );
497 $order->refund->customer_payment_profile_id = $gateway->get_order_meta( $order, 'payment_token' );
498
499 $response = $api->refund( $order );
500
501 $response_id = $response->get_transaction_id();
502
503 if ( ! $response_id ) {
504 $response = $api->void( $order );
505 $response_id = $response->get_transaction_id();
506 }
507
508 return $response_id;
509 }
510
511 /**
512 * update the meta data for WooCommerce subscription
513 *
514 * @param $subscription
515 * @param $offer_product
516 * @param $order
517 */
518 public function add_offer_subscription_meta( $subscription, $offer_product, $order ) {
519 if ( 'authorize_net_cim_credit_card' === $order->get_payment_method() ) {
520 $subscription_id = $subscription->get_id();
521 update_post_meta( $subscription_id, '_wc_authorize_net_cim_credit_card_customer_id', $order->get_meta( '_wc_authorize_net_cim_credit_card_customer_id', true ) );
522 update_post_meta( $subscription_id, '_wc_authorize_net_cim_credit_card_payment_token', $order->get_meta( '_wc_authorize_net_cim_credit_card_payment_token', true ) );
523 }
524 }
525
526
527
528 /**
529 * gert order
530 *
531 * @param $order
532 * @return mixed
533 */
534 public function get_order( $order ) {
535
536 if ( $order instanceof \WC_Order && $this->key === $order->get_payment_method() ) {
537
538 if ( $this->has_token( $order ) && ! is_checkout_pay_page() ) {
539
540 $order_id = $order->get_id();
541
542 // retrieve the payment token.
543 $order->payment->token = $this->get_wc_gateway()->get_order_meta( $order_id, 'payment_token' );
544 $token_from_gateway = $this->get_token( $order );
545 if ( empty( $order->payment->token ) && ! empty( $token_from_gateway ) ) {
546 $order->payment->token = $token_from_gateway;
547 }
548 // retrieve the optional customer id.
549 $order->customer_id = $this->get_wc_gateway()->get_order_meta( $order_id, 'customer_id' );
550
551 /* May be we need customer id from session */
552 $customer_id_from_session = isset( $this->extra_data['authorize_net_cim_customer_id'] ) ? $this->extra_data['authorize_net_cim_customer_id'] : '';
553
554 if ( empty( $order->customer_id ) && ! empty( $customer_id_from_session ) ) {
555 $order->customer_id = $customer_id_from_session;
556 }
557
558 // set token data on order.
559 if ( $this->get_wc_gateway()->get_payment_tokens_handler()->user_has_token( $order->get_user_id(), $order->payment->token ) ) {
560
561 // an existing registered user with a saved payment token.
562 $token = $this->get_wc_gateway()->get_payment_tokens_handler()->get_token( $order->get_user_id(), $order->payment->token );
563
564 // account last four.
565 $order->payment->account_number = $token->get_last_four();
566
567 if ( $this->get_wc_gateway()->is_credit_card_gateway() ) {
568
569 // card type.
570 $order->payment->card_type = $token->get_card_type();
571
572 // exp month/year.
573 $order->payment->exp_month = $token->get_exp_month();
574 $order->payment->exp_year = $token->get_exp_year();
575
576 } elseif ( $this->get_wc_gateway()->is_echeck_gateway() ) {
577
578 // account type (checking/savings).
579 $order->payment->account_type = $token->get_account_type();
580 }
581 } else {
582
583 // a guest user means that token data must be set from the original order.
584
585 // account number.
586 $order->payment->account_number = $this->get_wc_gateway()->get_order_meta( $order_id, 'account_four' );
587
588 if ( $this->get_wc_gateway()->is_credit_card_gateway() ) {
589
590 // card type.
591 $order->payment->card_type = $this->get_wc_gateway()->get_order_meta( $order_id, 'card_type' );
592
593 // expiry date.
594 $expiry_date = $this->get_wc_gateway()->get_order_meta( $order_id, 'card_expiry_date' );
595
596 if ( ! empty( $expiry_date ) ) {
597 list( $exp_year, $exp_month ) = explode( '-', $expiry_date );
598 $order->payment->exp_month = $exp_month;
599 $order->payment->exp_year = $exp_year;
600 }
601 } elseif ( $this->get_wc_gateway()->is_echeck_gateway() ) {
602
603 // account type.
604 $order->payment->account_type = $this->get_wc_gateway()->get_order_meta( $order_id, 'account_type' );
605 }
606 }
607 }
608
609 $response = intval( $order->get_meta( '_authorize_cim_shipping_address_id' ) );
610 if ( ! empty( $response ) ) {
611 $order->payment->shipping_address_id = $response;
612 }
613
614 if ( true === $this->unset_opaque_value && isset( $order->payment->opaque_value ) ) {
615 unset( $order->payment->opaque_value );
616 }
617 }
618
619 return $order;
620 }
621
622
623 /**
624 * check if the order has any payment
625 * token
626 *
627 * @param $order
628 * @return bool
629 */
630 private function has_token( $order ) {
631 $order_id = $order->get_id();
632 $token = $order->get_meta('_wc_' . $this->key . '_payment_token' );
633 if ( ! empty( $token ) ) {
634 return true;
635 }
636
637 /**
638 * if token is not present in order fallback
639 */
640 if ( isset( $this->extra_data['authorize_net_cim_order_id'] ) ) {
641 $fallback_order_id = $this->extra_data['authorize_net_cim_order_id'];
642 $token = $order->get_meta('_wc_' . $this->key . '_payment_token' );
643 if ( ! empty( $token ) ) {
644 update_post_meta( $order_id, '_wc_' . $this->key . '_payment_token', $token );
645 return true;
646 }
647 }
648 return false;
649 }
650
651
652 /**
653 * get token from order
654 *
655 * @param $order
656 * @return array|false|mixed|string
657 */
658 private function get_token( $order ) {
659 if( false === is_a( $order, 'WC_Order' ) ){
660 return false;
661 }
662
663 $token = $order->get_meta('_wc_' . $this->key . '_payment_token' );
664 if ( ! empty( $token ) ) {
665 return $token;
666 }
667 return false;
668 }
669
670 /**
671 * get next step id
672 *
673 * @param $funnel_id
674 * @param $step_id
675 * @return false|int
676 */
677 public function get_next_step( $funnel_id, $step_id ) {
678 $next_step_id = false;
679 if( $step_id ) {
680 $steps = Wpfnl_functions::get_steps($funnel_id);
681 if ( is_array( $steps ) ) {
682 foreach ( $steps as $index => $step ) {
683 if ( intval( $step['id'] ) === $step_id ) {
684 $next_step_index = $index + 1;
685 if ( isset( $steps[ $next_step_index ] ) ) {
686 $next_step_id = intval( $steps[ $next_step_index ]['id'] );
687 }
688 break;
689 }
690 }
691 }
692 }
693 return $next_step_id;
694 }
695
696
697 /**
698 * get wc payment gateway
699 *
700 * @return mixed
701 */
702 private function get_wc_gateway() {
703 global $woocommerce;
704 $gateways = $woocommerce->payment_gateways->payment_gateways();
705 return $gateways[ $this->key ];
706 }
707
708
709 /**
710 * get line items of the order
711 *
712 * @return array
713 */
714 private function get_line_items() {
715 $line_items = array();
716 $offer_product = $this->offer_product;
717 if ( isset( $offer_product['id'] ) && $offer_product['id'] > 0 ) {
718
719 $line_items[] = array(
720 'itemId' => $this->string_truncate( $offer_product['id'], 31 ),
721 'name' => $this->string_truncate( $offer_product['name'], 31 ),
722 'description' => $this->string_truncate( $offer_product['desc'], 255 ),
723 'quantity' => $offer_product['qty'],
724 'unitPrice' => number_format( (float) $offer_product['total'], 2, '.', '' ),
725 );
726 }
727
728 return $line_items;
729 }
730
731
732 /**
733 * Truncates a given string. The total length of return string will not exceed the given length.
734 * The last characters will be replaced with the $omission string
735 * for a total length not exceeding $length
736 *
737 * @param $string
738 * @param $length
739 * @param string $omission
740 * @return mixed|string
741 */
742 private function string_truncate( $string, $length, $omission = '...' ) {
743 if ( extension_loaded( 'mbstring' ) ) {
744 if ( mb_strlen( $string, self::MB_ENCODING ) <= $length ) {
745 return $string;
746 }
747 $length -= mb_strlen( $omission, self::MB_ENCODING );
748 return mb_substr( $string, 0, $length, self::MB_ENCODING ) . $omission;
749 } else {
750 $string = $this->str_to_ascii( $string );
751 if ( strlen( $string ) <= $length ) {
752 return $string;
753 }
754 $length -= strlen( $omission );
755 return substr( $string, 0, $length ) . $omission;
756 }
757 }
758
759
760 /**
761 * returns a string with all non ascii characters
762 * removed
763 *
764 * @param $string
765 * @return mixed
766 */
767 private function str_to_ascii( $string ) {
768 // strip ASCII chars 32 and under
769 $string = filter_var( $string, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW );
770
771 // strip ASCII chars 127 and higher
772 return filter_var( $string, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH );
773 }
774
775
776 /**
777 * get customer id from order
778 *
779 * @param $order
780 * @return array|false|mixed|string
781 */
782 private function get_customer_id( $order ) {
783 $customer_id = $order->get_meta('_wc_' . $this->key . '_customer_id', );
784 if ( ! empty( $customer_id ) ) {
785 return $customer_id;
786 }
787 return '';
788 }
789
790
791 /**
792 * get request attributes
793 *
794 * @param $request
795 * @return array
796 */
797 public function get_request_attributes( $request ) {
798 return array(
799 'method' => 'POST',
800 'timeout' => MINUTE_IN_SECONDS,
801 'redirection' => 0,
802 'httpversion' => '1.0',
803 'sslverify' => true,
804 'blocking' => true,
805 'headers' => array(
806 'content-type' => 'application/json',
807 'accept' => 'application/json',
808 ),
809 'body' => wp_json_encode( $request ),
810 'cookies' => array(),
811 );
812 }
813
814
815 /**
816 * get transaction id
817 *
818 * @param $response
819 * @return mixed|string
820 */
821 private function get_transaction_id( $response ) {
822
823 // parse response
824 $response = explode( ',', $response );
825
826 if ( empty( $response ) ) {
827 return '';
828 }
829
830 // offset array by 1 to match Authorize.Net's order, mainly for readability
831 array_unshift( $response, null );
832
833 $new_direct_response = array();
834
835 // direct response fields are URL encoded, but we currently do not use any fields
836 // (e.g. billing/shipping details) that would be affected by that
837 $response_fields = array(
838 'response_code' => 1,
839 'response_subcode' => 2,
840 'response_reason_code' => 3,
841 'response_reason_text' => 4,
842 'authorization_code' => 5,
843 'avs_response' => 6,
844 'transaction_id' => 7,
845 'amount' => 10,
846 'account_type' => 11, // CC or ECHECK
847 'transaction_type' => 12, // AUTH_ONLY or AUTH_CAPTUREVOID probably
848 'csc_response' => 39,
849 'cavv_response' => 40,
850 'account_last_four' => 51,
851 'card_type' => 52,
852 );
853
854 foreach ( $response_fields as $field => $order ) {
855 $new_direct_response[ $field ] = ( isset( $response[ $order ] ) ) ? $response[ $order ] : '';
856 }
857 return isset( $new_direct_response['transaction_id'] ) && '' !== $new_direct_response['transaction_id'] ? $new_direct_response['transaction_id'] : '';
858 }
859
860
861 /**
862 * store offer transaction data
863 *
864 * @param $order
865 * @param $response
866 * @param $product
867 */
868 public function store_offer_transaction( $order, $response, $product ) {
869 $order->update_meta_data( '_wpfunnels_offer_txn_resp_' . $product['step_id'], $response['id'] );
870 $order->save();
871 }
872
873
874
875 /**
876 * Get current site name.
877 *
878 * @return string
879 */
880 public function get_current_site_name() {
881 return ( is_multisite() ) ? get_blog_details()->blogname : get_bloginfo( 'name' );
882 }
883 }