PluginProbe
WooCommerce Square / 4.3.2
WooCommerce Square v4.3.2
5.5.0 5.4.3 5.4.2 5.4.1 5.4.0 trunk 1.0.25 1.0.26 1.0.27 1.0.28 1.0.29 1.0.30 1.0.31 1.0.32 1.0.33 1.0.34 1.0.35 1.0.36 1.0.37 1.0.38 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 All 132 releases
woocommerce-square / includes / Gateway / API.php
API.php
782 lines 20.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * WooCommerce Square
4 *
5 * This source file is subject to the GNU General Public License v3.0
6 * that is bundled with this package in the file license.txt.
7 * It is also available through the world-wide-web at this URL:
8 * http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0 or later
9 * If you did not receive a copy of the license and are unable to
10 * obtain it through the world-wide-web, please send an email
11 * to license@woocommerce.com so we can send you a copy immediately.
12 *
13 * DISCLAIMER
14 *
15 * Do not edit or add to this file if you wish to upgrade WooCommerce Square to newer
16 * versions in the future. If you wish to customize WooCommerce Square for your
17 * needs please refer to https://docs.woocommerce.com/document/woocommerce-square/
18 *
19 * @author WooCommerce
20 * @copyright Copyright: (c) 2019, Automattic, Inc.
21 * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0 or later
22 */
23
24 namespace WooCommerce\Square\Gateway;
25
26 defined( 'ABSPATH' ) || exit;
27
28 use Square\Models\Order;
29 use WooCommerce\Square\WC_Order_Square;
30
31 /**
32 * The base Square gateway API class.
33 *
34 * @since 2.0.0
35 */
36 class API extends \WooCommerce\Square\API {
37
38
39 /** @var string location ID to use for requests */
40 protected $location_id;
41
42 /** @var \WC_Order order object associated with a request, if any */
43 protected $order;
44
45
46 /**
47 * Constructs the class.
48 *
49 * @since 2.0.0
50 *
51 * @param string $access_token the API access token
52 * @param string $location_id location ID to use for requests
53 */
54 public function __construct( $access_token, $location_id, $is_sandbox = null ) {
55
56 parent::__construct( $access_token, $is_sandbox );
57
58 $this->location_id = $location_id;
59 }
60
61
62 /** Transaction methods *******************************************************************************************/
63
64
65 /**
66 * Performs a credit card authorization for the given order.
67 *
68 * @since 2.0.0
69 *
70 * @param \WC_Order $order order object
71 * @return \WooCommerce\Square\API\Response
72 * @throws \Exception
73 */
74 public function credit_card_authorization( \WC_Order $order ) {
75
76 $request = new API\Requests\Payments( $this->get_location_id(), $this->client );
77
78 $request->set_authorization_data( $order );
79
80 $this->set_response_handler( API\Responses\Create_Payment::class );
81
82 return $this->perform_request( $request );
83 }
84
85
86 /**
87 * Performs a credit card charge for the given order.
88 *
89 * @since 2.0.0
90 *
91 * @param \WC_Order $order order object
92 * @return \WooCommerce\Square\API\Response
93 * @throws \Exception
94 */
95 public function credit_card_charge( \WC_Order $order ) {
96
97 $request = new API\Requests\Payments( $this->get_location_id(), $this->client );
98
99 $request->set_charge_data( $order );
100
101 $this->set_response_handler( API\Responses\Create_Payment::class );
102
103 return $this->perform_request( $request );
104 }
105
106
107 /**
108 * Performs a credit card capture for a given authorized order.
109 *
110 * @since 2.0.0
111 *
112 * @param \WC_Order $order order object
113 * @return \WooCommerce\Square\API\Response
114 * @throws \Exception
115 */
116 public function credit_card_capture( \WC_Order $order ) {
117
118 $location_id = ! empty( $order->capture->location_id ) ? $order->capture->location_id : $this->get_location_id();
119
120 // use the Payments API to capture orders that were processed with Square v2.2+
121 if ( ! empty( $order->square_version ) && version_compare( $order->square_version, '2.2', '>=' ) ) {
122 $request = new API\Requests\Payments( $location_id, $this->client );
123 } else {
124 $request = new API\Requests\Transactions( $location_id, $this->client );
125 }
126
127 $request->set_capture_data( $order );
128
129 $this->set_response_handler( API\Response::class );
130
131 return $this->perform_request( $request );
132 }
133
134 /**
135 * Performs a gift card charge for a given order.
136 *
137 * @param \WC_Order $order order object
138 * @since 3.7.0
139 * @return \WooCommerce\Square\API\Response
140 */
141 public function gift_card_charge( \WC_Order $order ) {
142 $request = new API\Requests\Payments( $this->get_location_id(), $this->client );
143
144 $request->set_gift_card_charge_data( $order );
145
146 $this->set_response_handler( API\Responses\Create_Payment::class );
147
148 return $this->perform_request( $request );
149 }
150
151
152 /**
153 * Performs a refund for the given order.
154 *
155 * @since 2.0.0
156 *
157 * @param \WC_Order $order WooCommerce order object.
158 * @param array $payment_data Array of payment information necessary for a refund.
159 * @return \WooCommerce\Square\API\Response
160 * @throws \Exception
161 */
162 public function refund( \WC_Order $order, $payment_data = array() ) {
163
164 $location_id = ! empty( $order->refund->location_id ) ? $order->refund->location_id : $this->get_location_id();
165
166 // only use the Refunds API to refund orders that took payment after Square v2.2
167 if ( ! empty( $order->square_version ) && version_compare( $order->square_version, '2.2', '>=' ) ) {
168 $request = new API\Requests\Refunds( $this->client );
169 } else {
170 $request = new API\Requests\Transactions( $location_id, $this->client );
171 }
172
173 $request->set_refund_data( $order, $payment_data );
174
175 $this->set_response_handler( API\Responses\Refund::class );
176
177 return $this->perform_request( $request );
178 }
179
180
181 /**
182 * Performs a void for the given order.
183 *
184 * @since 2.0.0
185 *
186 * @param \WC_Order $order order object
187 * @return \WooCommerce\Square\API\Response
188 * @throws \Exception
189 */
190 public function void( \WC_Order $order ) {
191
192 $location_id = ! empty( $order->refund->location_id ) ? $order->refund->location_id : $this->get_location_id();
193
194 // use the Payments API to void/cancel orders that were processed after Square v2.2
195 if ( ! empty( $order->square_version ) && version_compare( $order->square_version, '2.2', '>=' ) ) {
196 $request = new API\Requests\Payments( $location_id, $this->client );
197 } else {
198 $request = new API\Requests\Transactions( $location_id, $this->client );
199 }
200
201 $request->set_void_data( $order );
202
203 $this->set_response_handler( API\Response::class );
204
205 return $this->perform_request( $request );
206 }
207
208
209 /**
210 * Creates a payment token for the given order.
211 *
212 * @since 2.0.0
213 *
214 * @param \WC_Order|WC_Order_Square $order the order object
215 * @return API\Responses\Create_Customer_Card|API\Responses\Create_Customer
216 * @throws \Exception
217 */
218 public function tokenize_payment_method( $order ) {
219
220 // a customer ID should've already been created, but there may be cases where the customer id is deleted/corrupted at Square
221 if ( ! empty( $order->customer_id ) ) {
222
223 $response = $this->create_customer_card( $order );
224
225 if ( $response->has_error_code( 'NOT_FOUND' ) ) {
226 $order->customer_id = '';
227 } else {
228 return $response;
229 }
230 }
231
232 $response = $this->create_customer( $order );
233
234 if ( ! $response->transaction_approved() ) {
235 return $response;
236 }
237
238 // Update the user meta with the new customer id created for further API requests
239 update_user_meta( $order->get_user_id(), 'wc_square_customer_id', $response->get_customer_id(), $order->customer_id );
240
241 // Update the customer id on the order as well
242 $order->square_customer_id = $order->customer_id = $response->get_customer_id();
243
244 return $this->create_customer_card( $order );
245 }
246
247
248 /**
249 * Creates a payment token for the given order.
250 *
251 * @since 2.0.0
252 *
253 * @param \WC_Order $order the order object
254 * @return API\Responses\Create_Customer_Card
255 * @throws \Exception
256 */
257 public function create_customer_card( \WC_Order $order ) {
258
259 $request = new API\Requests\Card( $this->client );
260
261 $request->set_create_card_data( $order );
262
263 $this->set_response_handler( API\Responses\Create_Customer_Card::class );
264
265 return $this->perform_request( $request );
266 }
267
268
269 /**
270 * Creates a new customer based on the given order.
271 *
272 * @since 2.0.0
273 *
274 * @param \WC_Order $order order object
275 * @return API\Responses\Create_Customer
276 * @throws \Exception
277 */
278 public function create_customer( \WC_Order $order ) {
279
280 $request = new API\Requests\Customers( $this->client );
281
282 $request->set_create_customer_data( $order );
283
284 $this->set_response_handler( API\Responses\Create_Customer::class );
285
286 return $this->perform_request( $request );
287 }
288
289
290 /**
291 * Gets all tokenized payment methods for the customer.
292 *
293 * @since 2.0.0
294 *
295 * @param string $customer_id unique customer id
296 * @return API\Responses\Get_Customer
297 * @throws \Exception
298 */
299 public function get_tokenized_payment_methods( $customer_id ) {
300
301 $request = new API\Requests\Customers( $this->client );
302
303 $request->set_get_customer_data( $customer_id );
304
305 $this->set_response_handler( API\Responses\Get_Customer::class );
306
307 return $this->perform_request( $request );
308 }
309
310
311 /**
312 * Removes the tokenized payment method.
313 *
314 * @since 2.0.0
315 *
316 * @param string $token the payment method token
317 * @param string $customer_id unique customer id
318 * @return API\Response
319 * @throws \Exception
320 */
321 public function remove_tokenized_payment_method( $token, $customer_id ) {
322
323 $request = new API\Requests\Card( $this->client );
324
325 $request->set_delete_card_data( $token );
326
327 $this->set_response_handler( API\Response::class );
328
329 return $this->perform_request( $request );
330 }
331
332
333 /**
334 * Creates a new Square order from a WooCommerce order.
335 *
336 * @since 2.0.0
337 *
338 * @param string $location_id location ID
339 * @param \WC_Order $order
340 * @return Order
341 * @throws \Exception
342 */
343 public function create_order( $location_id, \WC_Order $order ) {
344
345 $request = new API\Requests\Orders( $this->client );
346
347 $request->set_create_order_data( $location_id, $order );
348
349 $this->set_response_handler( \WooCommerce\Square\API\Response::class );
350
351 $response = $this->perform_request( $request );
352
353 if ( $response->get_data() instanceof \Square\Models\CreateOrderResponse ) {
354 return $response->get_data()->getOrder();
355 }
356
357 throw new \Exception( esc_html__( 'Failed to make request createOrder.', 'woocommerce-square' ) );
358 }
359
360 /**
361 * Retrieves a Square order.
362 *
363 * @param string $order_id The Square order ID.
364 *
365 * @return \Square\Models\Order
366 */
367 public function retrieve_order( $order_id ) {
368 $request = new API\Requests\Orders( $this->client );
369
370 $request->set_retrieve_order_data( $order_id );
371
372 $this->set_response_handler( \WooCommerce\Square\API\Response::class );
373
374 $response = $this->perform_request( $request );
375
376 return $response->get_data()->getOrder();
377 }
378
379 /**
380 * Calculates a Square order without creating one.
381 *
382 * @param \WC_Order $order Woo order object.
383 * @param \Square\Models\Order $square_order Square order object.
384 *
385 * @return \Square\Models\Order
386 */
387 public function calculate_order( \WC_Order $order, \Square\Models\Order $square_order ) {
388 $request = new API\Requests\Orders( $this->client );
389
390 $request->set_calculate_order_data( $order, $square_order );
391
392 $this->set_response_handler( \WooCommerce\Square\API\Response::class );
393
394 $response = $this->perform_request( $request );
395
396 return $response->get_data()->getOrder();
397 }
398
399 /**
400 * Updates a Square order.
401 *
402 * @param \WC_Order $order Woo order object.
403 * @param \Square\Models\Order $square_order Square order object.
404 */
405 public function update_order( \WC_Order $order, \Square\Models\Order $square_order ) {
406 $request = new API\Requests\Orders( $this->client );
407
408 $request->set_update_order_data( $order, $square_order );
409
410 $this->set_response_handler( \WooCommerce\Square\API\Response::class );
411
412 $response = $this->perform_request( $request );
413
414 return $response->get_data()->getOrder();
415 }
416
417 /**
418 * Updates the payment total of an existing payment.
419 *
420 * @param \WC_Order $order The WooCommerce order object.
421 * @param float $amount The new payment total.
422 *
423 * @return \Square\Models\Payment
424 */
425 public function update_payment( \WC_Order $order, float $amount ) {
426 $request = new API\Requests\Payments( $this->get_location_id(), $this->client );
427
428 $request->set_update_payment_data( $order, $amount );
429
430 $this->set_response_handler( \WooCommerce\Square\API\Response::class );
431
432 $response = $this->perform_request( $request );
433
434 return $response->get_data()->getPayment();
435 }
436
437 /**
438 * Adjusts an existing Square order by amount.
439 *
440 * @since 2.0.4
441 *
442 * @param string $location_id location ID
443 * @param \WC_Order $order
444 * @param int $version Current 'version' value of Square order
445 * @param int $amount Amount of adjustment in smallest unit
446 * @return Order
447 * @throws \Exception
448 */
449 public function adjust_order( $location_id, \WC_Order $order, $version, $amount ) {
450
451 $request = new API\Requests\Orders( $this->client );
452
453 if ( $amount > 0 ) {
454 $request->add_line_item_order_data( $location_id, $order, $version, $amount );
455 } else {
456 $request->add_discount_order_data( $location_id, $order, $version, -1 * $amount );
457 }
458 $this->set_response_handler( \WooCommerce\Square\API\Response::class );
459
460 $response = $this->perform_request( $request );
461
462 if ( $response->get_data() instanceof \Square\Models\UpdateOrderResponse ) {
463 return $response->get_data()->getOrder();
464 }
465
466 throw new \Exception( esc_html__( 'Failed to make request updateOrder.', 'woocommerce-square' ) );
467 }
468
469 /**
470 * Performs payments when a transaction is done using multiple payment methods.
471 * For example: Gift Card + Square Credit Card.
472 *
473 * @param array $payment_ids Array of payment IDs.
474 * @param string $order_id Square order ID.
475 * @since x.x.x
476 */
477 public function pay_order( $payment_ids, $order_id ) {
478 $request = new API\Requests\Orders( $this->client );
479
480 $request->set_pay_order_data( $payment_ids, $order_id );
481
482 $this->set_response_handler( \WooCommerce\Square\Gateway\API\Responses\Create_PayOrder::class );
483
484 return $this->perform_request( $request );
485 }
486
487
488 /**
489 * Gets an existing transaction.
490 *
491 * @since 2.0.0
492 *
493 * @param string $transaction_id transaction ID
494 * @param string $location_id location ID
495 * @return API\Responses\Charge
496 * @throws \Exception
497 */
498 public function get_transaction( $transaction_id, $location_id = '' ) {
499
500 if ( ! $location_id ) {
501 $location_id = $this->get_location_id();
502 }
503
504 $request = new API\Requests\Transactions( $location_id, $this->client );
505
506 $request->set_get_transaction_data( $transaction_id );
507
508 $this->set_response_handler( API\Responses\Charge::class );
509
510 return $this->perform_request( $request );
511 }
512
513
514 /**
515 * Creates a Gift Card.
516 *
517 * @since x.x.x
518 *
519 * @param $order_id Line item order ID.
520 * @return API\Responses\Get_Gift_Card
521 */
522 public function create_gift_card( $order_id ) {
523 $request = new API\Requests\Gift_Card( $this->location_id, $this->client );
524
525 $request->set_create_gift_card_data( $order_id );
526
527 $this->set_response_handler( API\Responses\Get_Gift_Card::class );
528
529 return $this->perform_request( $request );
530 }
531
532 /**
533 * Activates a Gift Card which is in a pending state.
534 *
535 * @since x.x.x
536 *
537 * @param string $gift_card_id The ID of the inactive Gift Card.
538 * @param string $order_id Square Order ID associated with the Gift Card.
539 * @param string $line_item_id Line Item ID for the Gift Card.
540 */
541 public function activate_gift_card( $gift_card_id, $order_id, $line_item_id ) {
542 $request = new API\Requests\Gift_Card_Activities( $this->location_id, $this->client );
543
544 $request->set_activate_gift_card_data( $gift_card_id, $order_id, $line_item_id );
545
546 $this->set_response_handler( \WooCommerce\Square\API\Response::class );
547
548 return $this->perform_request( $request );
549 }
550
551 /**
552 * Loads an existing gift card with an amount.
553 *
554 * @since x.x.x
555 *
556 * @param string $gan The gift card number.
557 * @param string $order_id The Square order ID.
558 * @param string $line_item_id The line item order ID for the gift card.
559 */
560 public function load_gift_card( $gan, $order ) {
561 $request = new API\Requests\Gift_Card_Activities( $this->location_id, $this->client );
562
563 $request->set_load_gift_card_data( $gan, $order );
564
565 $this->set_response_handler( \WooCommerce\Square\API\Response::class );
566
567 return $this->perform_request( $request );
568 }
569
570 /**
571 * Sets data to refund/adjust decrement funds in a gift card.
572 *
573 * @since x.x.x
574 *
575 * @param string $gan Gift card number.
576 * @param \Square\Models\Money $amount_money The amount to be refunded.
577 * @param \WC_Order $order WooCommerce order.
578 */
579 public function refund_gift_card( $gan, $amount_money, $order ) {
580 $request = new API\Requests\Gift_Card_Activities( $this->location_id, $this->client );
581
582 $request->set_gift_card_refund_data( $gan, $amount_money, $order );
583
584 $this->set_response_handler( \WooCommerce\Square\API\Response::class );
585
586 return $this->perform_request( $request );
587 }
588
589 /**
590 * Gets an existing payment.
591 *
592 * @since 2.2.0
593 *
594 * @param string $payment_id transaction ID
595 * @return API\Responses\Create_Payment
596 * @throws \Exception
597 */
598 public function get_payment( $payment_id ) {
599
600 $request = new API\Requests\Payments( $this->get_location_id(), $this->client );
601
602 $request->set_get_payment_data( $payment_id );
603
604 $this->set_response_handler( API\Responses\Create_Payment::class );
605
606 return $this->perform_request( $request );
607 }
608
609 /**
610 * Retrieves a gift card using nonce.
611 *
612 * @since 3.7.0
613 *
614 * @param string $gan Gift card number.
615 *
616 * @return API\Responses\Get_Gift_Card
617 */
618 public function retrieve_gift_card( $nonce = '' ) {
619
620 $request = new API\Requests\Gift_Card( $this->get_location_id(), $this->client );
621
622 $request->set_retrieve_gift_card_data( $nonce );
623
624 $this->set_response_handler( API\Responses\Get_Gift_Card::class );
625
626 return $this->perform_request( $request );
627 }
628
629 /**
630 * Retrieves a gift card using GAN.
631 *
632 * @since x.x.x
633 *
634 * @param string $gan Gift card number.
635 *
636 * @return API\Responses\Get_Gift_Card
637 */
638 public function retrieve_gift_card_by_gan( $gan = '' ) {
639
640 $request = new API\Requests\Gift_Card( $this->get_location_id(), $this->client );
641
642 $request->set_retrieve_gift_card_from_gan_data( $gan );
643
644 $this->set_response_handler( API\Responses\Get_Gift_Card::class );
645
646 return $this->perform_request( $request );
647 }
648
649
650 /**
651 * Validates the parsed response.
652 *
653 * @since 2.0.0
654 *
655 * @return bool
656 * @throws \Exception
657 */
658 protected function do_post_parse_response_validation() {
659
660 // gateway responses need to get through to check API\Response::transaction_approved()
661 if ( $this->get_response() instanceof API\Response ) {
662 return true;
663 }
664
665 return parent::do_post_parse_response_validation();
666 }
667
668
669 /** Conditional methods *******************************************************************************************/
670
671
672 /**
673 * Determines if this API supports getting a customer's tokenized payment methods.
674 *
675 * @since 2.0.0
676 *
677 * @return bool
678 */
679 public function supports_get_tokenized_payment_methods() {
680
681 return true;
682 }
683
684
685 /**
686 * Determines if this API supports updating tokenized payment methods.
687 *
688 * @see Payment_Gateway_API::update_tokenized_payment_method()
689 *
690 * @since 2.0.0
691 *
692 * @return bool
693 */
694 public function supports_update_tokenized_payment_method() {
695
696 return false;
697 }
698
699
700 /**
701 * Determines if this API supports removing a tokenized payment method.
702 *
703 * @since 2.0.0
704 *
705 * @return bool
706 */
707 public function supports_remove_tokenized_payment_method() {
708
709 return true;
710 }
711
712
713 /** Getter methods ************************************************************************************************/
714
715
716 /**
717 * Gets the location ID to be used for requests.
718 *
719 * @since 2.0.0
720 *
721 * @return string
722 */
723 protected function get_location_id() {
724
725 return $this->location_id;
726 }
727
728
729 /**
730 * Gets the object associated with the request, if any.
731 *
732 * @since 2.0.0
733 *
734 * @return \WC_Order
735 */
736 public function get_order() {
737
738 return $this->order;
739 }
740
741
742 /**
743 * Gets the API ID.
744 *
745 * @since 2.0.0
746 *
747 * @return string
748 */
749 protected function get_api_id() {
750
751 return $this->get_plugin()->get_gateway()->get_id();
752 }
753
754
755 /** No-op methods *************************************************************************************************/
756
757
758 /**
759 * The gateway API does not support check debits.
760 *
761 * @since 2.0.0
762 *
763 * @param \WC_Order $order order object
764 */
765 public function check_debit( \WC_Order $order ) {}
766
767
768 /**
769 * Updates a tokenized payment method.
770 *
771 * Square API does not allow updating a stored card's address, and instead recommends deleting and re-adding a new
772 * card. This isn't an option for us since subscriptions would break any time an address is updated.
773 *
774 * @since 2.0.0
775 *
776 * @param \WC_Order $order order object
777 */
778 public function update_tokenized_payment_method( \WC_Order $order ) {}
779
780
781 }
782