├── includes ├── Handlers │ ├── Order_Sync.php │ ├── Async_Request.php │ └── Email.php ├── Admin │ ├── Rest │ │ ├── WC_Square_REST_Base_Controller.php │ │ ├── WC_REST_Square_Gift_Cards_Settings_Controller.php │ │ └── WC_REST_Square_Cash_App_Settings_Controller.php │ ├── Analytics │ │ └── Revenue.php │ └── Privacy.php ├── Gateway │ ├── API │ │ ├── Responses │ │ │ ├── Create_Customer.php │ │ │ ├── Search_Orders.php │ │ │ ├── Refund.php │ │ │ ├── Create_Customer_Card.php │ │ │ ├── Create_PayOrder.php │ │ │ ├── Get_Gift_Card.php │ │ │ ├── Get_Customer.php │ │ │ ├── Charge.php │ │ │ └── Create_Payment.php │ │ ├── Requests │ │ │ ├── Refunds.php │ │ │ ├── Gift_Card.php │ │ │ ├── Card.php │ │ │ ├── Customers.php │ │ │ └── Gift_Card_Activities.php │ │ └── Response.php │ ├── Templates │ │ └── payment.php │ └── Customer_Helper.php ├── Functions.php ├── Framework │ ├── PaymentGateway │ │ ├── Admin │ │ │ └── views │ │ │ │ ├── html-user-profile-field-customer-id.php │ │ │ │ ├── html-user-profile-section.php │ │ │ │ ├── html-user-payment-token-editor.php │ │ │ │ ├── html-order-partial-capture.php │ │ │ │ ├── html-admin-gateway-status.php │ │ │ │ └── html-user-payment-token-editor-token.php │ │ ├── Api │ │ │ ├── Payment_Gateway_Api_Customer_Response.php │ │ │ ├── Payment_Gateway_Api_Get_Tokenized_Payment_Methods_Response.php │ │ │ ├── Payment_Gateway_Api_Create_Payment_Token_Response.php │ │ │ ├── Payment_Gateway_Api_Authorization_Response.php │ │ │ └── Payment_Gateway_API_Response.php │ │ ├── Integrations │ │ │ └── Payment_Gateway_Integration.php │ │ ├── ApplePay │ │ │ └── Api │ │ │ │ ├── Payment_Gateway_Apple_Pay_Api_Response.php │ │ │ │ ├── Payment_Gateway_Apple_Pay_Api_Request.php │ │ │ │ └── Payment_Gateway_Apple_Pay_Api.php │ │ ├── PaymentTokens │ │ │ └── Square_Credit_Card_Payment_Token.php │ │ └── Payment_Gateway_My_Payment_Methods.php │ ├── Api │ │ ├── API_Response.php │ │ ├── API_Request.php │ │ ├── API_JSON_Response.php │ │ └── API_JSON_Request.php │ ├── Plugin_Compatibility.php │ ├── Addresses │ │ └── Customer_Address.php │ └── Compatibility │ │ └── Data_Compatibility.php ├── API │ ├── Responses │ │ ├── Catalog.php │ │ ├── Locations.php │ │ ├── Inventory.php │ │ └── Connection_Refresh_Response.php │ ├── Requests │ │ ├── Locations.php │ │ └── Customers.php │ ├── Response.php │ └── Request.php ├── WC_Order_Square.php ├── WC_Payments_Compatibility.php ├── Utilities │ ├── Helper.php │ ├── Array_Utility.php │ ├── Performance_Logger.php │ ├── Money_Utility.php │ └── String_Utility.php ├── Sync │ ├── Order_Mapper.php │ ├── Catalog_Item.php │ └── Job.php └── Emails │ └── WC_Square_Access_Token_Email.php └── templates └── emails ├── plain ├── gift-card-sent.php └── square-email.php ├── square-email.php └── gift-card-sent.php /includes/Handlers/Order_Sync.php: -------------------------------------------------------------------------------- 1 | get_data() instanceof \Square\Models\CreateCustomerResponse ? $this->get_data()->getCustomer()->getId() : ''; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /includes/Gateway/API/Responses/Search_Orders.php: -------------------------------------------------------------------------------- 1 | get_data() ? $this->get_data()->getOrders() : array(); 26 | } 27 | 28 | /** 29 | * Gets the cursor for pagination. 30 | * 31 | * @since 5.0.0 32 | * 33 | * @return string 34 | */ 35 | public function get_cursor() { 36 | 37 | return $this->get_data() ? $this->get_data()->getCursor() : ''; 38 | } 39 | 40 | /** 41 | * Gets the response data as an array with orders and cursor. 42 | * 43 | * @since 5.0.0 44 | * 45 | * @return array 46 | */ 47 | public function get_response_data() { 48 | 49 | return array( 50 | 'orders' => $this->get_orders(), 51 | 'cursor' => $this->get_cursor(), 52 | ); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /includes/Admin/Analytics/Revenue.php: -------------------------------------------------------------------------------- 1 | get_items( 'line_item' ); 31 | $amount_to_deduct = 0; 32 | 33 | /** @var \WC_Order_Item_Product $line_item */ 34 | foreach ( $line_items as $line_item ) { 35 | $product = $line_item->get_product(); 36 | 37 | if ( ! Product::is_gift_card( $product ) ) { 38 | continue; 39 | } 40 | 41 | $amount_to_deduct += $line_item->get_total(); 42 | } 43 | 44 | $order_data['net_total'] = $order_data['net_total'] - $amount_to_deduct; 45 | 46 | return $order_data; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /includes/Functions.php: -------------------------------------------------------------------------------- 1 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Customer_Response.php: -------------------------------------------------------------------------------- 1 | get_status_code(), array( 'APPROVED', 'COMPLETED', 'PENDING' ), true ) ); 25 | } 26 | 27 | /** 28 | * Gets the transaction ID. 29 | * 30 | * @since 2.0.0 31 | * 32 | * @return string 33 | */ 34 | public function get_transaction_id() { 35 | 36 | return $this->get_data() && $this->get_data()->getRefund() ? $this->get_data()->getRefund()->getId() : ''; 37 | } 38 | 39 | /** 40 | * Gets the response status code. 41 | * 42 | * @since 2.0.0 43 | * 44 | * @return string 45 | */ 46 | public function get_status_code() { 47 | 48 | if ( ! $this->has_errors() && $this->get_data() ) { 49 | $code = $this->get_data()->getRefund()->getStatus(); 50 | } else { 51 | $code = parent::get_status_code(); 52 | } 53 | 54 | return $code; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /includes/Framework/Api/API_Response.php: -------------------------------------------------------------------------------- 1 | get_data() instanceof \Square\Models\CreateCardResponse ? $this->get_data()->getCard() : null; 29 | $token = null; 30 | 31 | if ( $card ) { 32 | 33 | $card_type = 'AMERICAN_EXPRESS' === $card->getCardBrand() ? Payment_Gateway_Helper::CARD_TYPE_AMEX : $card->getCardBrand(); 34 | 35 | $token = new Payment_Gateway_Payment_Token( 36 | $card->getId(), 37 | array( 38 | 'type' => 'credit_card', 39 | 'card_type' => $card_type, 40 | 'last_four' => $card->getLast4(), 41 | 'exp_month' => $card->getExpMonth(), 42 | 'exp_year' => $card->getExpYear(), 43 | ) 44 | ); 45 | } 46 | 47 | return $token; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /includes/Gateway/API/Responses/Create_PayOrder.php: -------------------------------------------------------------------------------- 1 | has_errors() && $this->get_data()->getOrder() ? $this->get_data()->getOrder() : null; 24 | } 25 | 26 | /** 27 | * Returns true if the order status is completed. 28 | * 29 | * @since 3.9.0 30 | * @return boolean 31 | */ 32 | public function transaction_approved() { 33 | return $this->get_order() && 'COMPLETED' === $this->get_order()->getState(); 34 | } 35 | 36 | /** 37 | * Returns array of trasaction IDs when payment is done using multiple payment methods. 38 | * For example, Square Gift card + Square credit card. 39 | * 40 | * @since 3.9.0 41 | * @return array 42 | */ 43 | public function get_transaction_ids() { 44 | $payments_ids = array(); 45 | 46 | if ( ! $this->get_order() ) { 47 | return $payments_ids; 48 | } 49 | 50 | $tenders = $this->get_order()->getTenders(); 51 | 52 | foreach ( $tenders as $tender ) { 53 | if ( ! $tender instanceof \Square\Models\Tender ) { 54 | continue; 55 | } 56 | 57 | $payments_ids[] = $tender->getId(); 58 | } 59 | 60 | return $payments_ids; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Get_Tokenized_Payment_Methods_Response.php: -------------------------------------------------------------------------------- 1 | has_errors() && $this->get_data()->getGiftCard() ? $this->get_data()->getGiftCard() : null; 24 | } 25 | 26 | /** 27 | * Get the gift card ID. 28 | * 29 | * @since 4.2.0 30 | * 31 | * @return string 32 | */ 33 | public function get_id() { 34 | return $this->get_gift_card() ? $this->get_gift_card()->getId() : null; 35 | } 36 | 37 | /** 38 | * Get the gift card state. 39 | * 40 | * @since 4.2.0 41 | * 42 | * @return string 43 | */ 44 | public function get_state() { 45 | return $this->get_gift_card() ? $this->get_gift_card()->getState() : null; 46 | } 47 | 48 | /** 49 | * Get the gift card number. 50 | * 51 | * @since 4.2.0 52 | * 53 | * @return string 54 | */ 55 | public function get_gan() { 56 | return $this->get_gift_card() ? $this->get_gift_card()->getGan() : null; 57 | } 58 | 59 | /** 60 | * Get the gift card amount. 61 | * 62 | * @since 4.2.0 63 | * 64 | * @return string 65 | */ 66 | public function get_amount() { 67 | return $this->get_gift_card() ? $this->get_gift_card()->getBalanceMoney()->getAmount() : null; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /includes/Framework/PaymentGateway/Admin/views/html-user-profile-section.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 23 | 24 |
25 | 26 |

27 | 28 | 29 |

30 | 31 | 32 | 33 | 34 | 35 | 36 | 44 | 45 | 46 | 47 |
48 | 49 |
50 | -------------------------------------------------------------------------------- /includes/API/Responses/Locations.php: -------------------------------------------------------------------------------- 1 | get_data() ? $this->get_data()->getLocations() : array(); 50 | } 51 | 52 | 53 | } 54 | -------------------------------------------------------------------------------- /includes/Framework/PaymentGateway/Integrations/Payment_Gateway_Integration.php: -------------------------------------------------------------------------------- 1 | gateway = $gateway; 48 | } 49 | 50 | 51 | /** 52 | * Return the gateway for the integration 53 | * 54 | * @since 3.0.0 55 | * @return Payment_Gateway 56 | */ 57 | public function get_gateway() { 58 | 59 | return $this->gateway; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /includes/API/Requests/Locations.php: -------------------------------------------------------------------------------- 1 | square_api = $api_client->getLocationsApi(); 46 | } 47 | 48 | 49 | /** 50 | * Sets API method. 51 | * 52 | * @since 2.0.0 53 | */ 54 | public function set_list_locations_data() { 55 | 56 | $this->square_api_method = 'listLocations'; 57 | } 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /includes/Gateway/API/Responses/Get_Customer.php: -------------------------------------------------------------------------------- 1 | get_data() instanceof \Square\Models\RetrieveCustomerResponse ? $this->get_data()->getCustomer()->getCards() : array(); 29 | $tokens = array(); 30 | 31 | if ( is_array( $cards ) ) { 32 | 33 | foreach ( $cards as $card ) { 34 | 35 | if ( 'SQUARE_GIFT_CARD' === $card->getCardBrand() ) { 36 | continue; 37 | } 38 | 39 | $token_id = $card->getId(); 40 | $card_type = 'AMERICAN_EXPRESS' === $card->getCardBrand() ? Payment_Gateway_Helper::CARD_TYPE_AMEX : $card->getCardBrand(); 41 | 42 | $tokens[ $token_id ] = new Payment_Gateway_Payment_Token( 43 | $token_id, 44 | array( 45 | 'type' => 'credit_card', 46 | 'card_type' => $card_type, 47 | 'last_four' => $card->getLast4(), 48 | 'exp_month' => $card->getExpMonth(), 49 | 'exp_year' => $card->getExpYear(), 50 | ) 51 | ); 52 | } 53 | } 54 | 55 | return $tokens; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /templates/emails/plain/gift-card-sent.php: -------------------------------------------------------------------------------- 1 | get_data() instanceof BatchRetrieveInventoryCountsResponse && is_array( $this->get_data()->getCounts() ) ) { 51 | $counts = $this->get_data()->getCounts(); 52 | } 53 | 54 | return $counts; 55 | } 56 | 57 | 58 | /** 59 | * Checks if there are inventory counts. 60 | * 61 | * @since 2.0.0 62 | * 63 | * @return bool 64 | */ 65 | public function has_counts() { 66 | 67 | return ! empty( $this->get_counts() ); 68 | } 69 | 70 | 71 | } 72 | -------------------------------------------------------------------------------- /templates/emails/plain/square-email.php: -------------------------------------------------------------------------------- 1 | log( 'Error in sync inventory for products: ' . implode( ',', $product_ids ) . '. ' . $exception->getMessage() ); 68 | } 69 | } 70 | } 71 | 72 | endif; 73 | -------------------------------------------------------------------------------- /includes/Framework/PaymentGateway/Api/Payment_Gateway_Api_Authorization_Response.php: -------------------------------------------------------------------------------- 1 | square_api = $api_client->getCustomersApi(); 47 | } 48 | 49 | 50 | /** 51 | * Sets the data for getting an existing customer. 52 | * 53 | * @since 2.0.0 54 | * 55 | * @param string $customer_id customer ID 56 | */ 57 | public function set_get_customer_data( $customer_id ) { 58 | 59 | $this->square_api_method = 'retrieveCustomer'; 60 | 61 | $this->square_api_args = array( $customer_id ); 62 | } 63 | 64 | 65 | /** 66 | * Sets the data for getting all existing customer. 67 | * 68 | * @since 2.0.0 69 | * 70 | * @param string $cursor pagination cursor 71 | */ 72 | public function set_get_customers_data( $cursor = '' ) { 73 | 74 | $this->square_api_method = 'listCustomers'; 75 | 76 | if ( $cursor ) { 77 | $this->square_api_args = array( $cursor ); 78 | } 79 | } 80 | 81 | 82 | } 83 | -------------------------------------------------------------------------------- /includes/WC_Payments_Compatibility.php: -------------------------------------------------------------------------------- 1 | cart ) { 64 | return $is_supported; 65 | } 66 | 67 | foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) { 68 | $product = $cart_item['data']; 69 | 70 | if ( Product::is_gift_card( $product ) ) { 71 | return false; 72 | } 73 | } 74 | 75 | return $is_supported; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /includes/Framework/Api/API_JSON_Response.php: -------------------------------------------------------------------------------- 1 | raw_response_json = $raw_response_json; 47 | $this->response_data = json_decode( $raw_response_json ); 48 | } 49 | 50 | 51 | /** 52 | * Magic accessor for response data attributes 53 | * 54 | * @since 3.0.0 55 | * @param string $name The attribute name to get. 56 | * @return mixed The attribute value 57 | */ 58 | public function __get( $name ) { 59 | // accessing the response_data object indirectly via attribute (useful when it's a class) 60 | return isset( $this->response_data->$name ) ? $this->response_data->$name : null; 61 | } 62 | 63 | 64 | /** 65 | * Get the string representation of this response. 66 | * 67 | * @since 3.0.0 68 | * @return string 69 | */ 70 | public function to_string() { 71 | return $this->raw_response_json; 72 | } 73 | 74 | 75 | /** 76 | * Get the string representation of this response with any and all sensitive elements masked 77 | * or removed. 78 | * 79 | * @since 3.0.0 80 | * @return string 81 | */ 82 | public function to_string_safe() { 83 | return $this->to_string(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /includes/API/Responses/Connection_Refresh_Response.php: -------------------------------------------------------------------------------- 1 | access_token; 48 | } 49 | 50 | /** 51 | * Gets the refresh token, if any. 52 | * 53 | * @since 2.0.0 54 | * 55 | * @return string|null 56 | */ 57 | public function get_refresh_token() { 58 | return $this->refresh_token; 59 | } 60 | 61 | 62 | /** 63 | * Gets the error message, if any. 64 | * 65 | * @since 2.0.0 66 | * 67 | * @return string|null 68 | */ 69 | public function get_error_message() { 70 | 71 | $message = $this->reason; 72 | 73 | if ( empty( $message ) ) { 74 | $message = $this->type; 75 | } 76 | 77 | if ( empty( $message ) ) { 78 | $message = 'Unknown error'; 79 | } 80 | 81 | return $message; 82 | } 83 | 84 | 85 | /** 86 | * Determines if there was an error returned. 87 | * 88 | * @since 2.0.0 89 | * 90 | * @return bool 91 | */ 92 | public function has_error() { 93 | 94 | return ! empty( $this->response_data->error ); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /includes/Utilities/Helper.php: -------------------------------------------------------------------------------- 1 | 'processing', 31 | 'COMPLETED' => 'completed', 32 | 'CANCELED' => 'cancelled', 33 | 'DRAFT' => 'pending', 34 | ); 35 | 36 | return isset( $status_map[ $square_state ] ) ? $status_map[ $square_state ] : 'processing'; 37 | } 38 | 39 | /** 40 | * Check if order status change is allowed. 41 | * 42 | * @since 5.0.0 43 | * @param string $from_status Current WooCommerce status. 44 | * @param string $to_status New status from Square. 45 | * @return bool True if status change is allowed. 46 | */ 47 | public static function is_status_change_allowed( $from_status, $to_status ) { 48 | // Don't allow status changes from terminal states unless it's a specific case. 49 | $terminal_statuses = array( 'completed', 'cancelled', 'refunded', 'failed' ); 50 | 51 | /** 52 | * Filters the allowed status changes. 53 | * 54 | * @since 5.0.0 55 | * 56 | * @param bool $allowed_status_changes True if status change is allowed. 57 | * @param string $from_status Current WooCommerce status. 58 | * @param string $to_status New status from Square. 59 | * 60 | * @return bool True if status change is allowed. 61 | */ 62 | $allowed_status_changes = apply_filters( 'wc_square_allowed_status_changes', false, $from_status, $to_status ); 63 | 64 | // Return early true if status change is allowed by filter. 65 | if ( $allowed_status_changes ) { 66 | return true; 67 | } 68 | 69 | if ( in_array( $from_status, $terminal_statuses, true ) ) { 70 | // Only allow specific transitions from terminal states. 71 | $allowed_terminal_transitions = array( 72 | 'completed' => array( 'cancelled' ), // Allow cancellation of completed orders. 73 | 'cancelled' => array(), // No transitions from cancelled. 74 | 'refunded' => array(), // No transitions from refunded. 75 | 'failed' => array( 'pending', 'processing' ), // Allow retry of failed orders. 76 | ); 77 | 78 | return in_array( $to_status, $allowed_terminal_transitions[ $from_status ] ?? array(), true ); 79 | } 80 | 81 | // Allow all other status changes. 82 | return true; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /includes/Framework/PaymentGateway/Admin/views/html-user-payment-token-editor.php: -------------------------------------------------------------------------------- 1 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | $column_title ) : 36 | ?> 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 66 | 67 | 68 | 69 | 82 | 83 | 84 | 85 | 86 | 87 |
70 | 71 | $label ) : ?> 72 | 73 | 74 | 75 | 78 | 79 | 80 | 81 |
88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /includes/Framework/PaymentGateway/ApplePay/Api/Payment_Gateway_Apple_Pay_Api_Response.php: -------------------------------------------------------------------------------- 1 | statusCode; 44 | } 45 | 46 | 47 | /** 48 | * Gets the status message. 49 | * 50 | * @since 3.0.0 51 | * 52 | * @return string 53 | */ 54 | public function get_status_message() { 55 | 56 | return $this->statusMessage; 57 | } 58 | 59 | 60 | /** 61 | * Gets the validated merchant session. 62 | * 63 | * @since 3.0.0 64 | * 65 | * @return string|array 66 | */ 67 | public function get_merchant_session() { 68 | 69 | return $this->raw_response_json; 70 | } 71 | 72 | 73 | /** 74 | * Get the string representation of this response with any and all sensitive 75 | * elements masked or removed. 76 | * 77 | * No strong indication from the Apple documentation that these _need_ to be 78 | * masked, but they don't provide any useful info and only make the debug 79 | * logs unnecessarily huge. 80 | * 81 | * @since 3.0.0 82 | * @see SquareFramework\Api\API_Response::to_string_safe() 83 | * 84 | * @return string 85 | */ 86 | public function to_string_safe() { 87 | 88 | $string = $this->to_string(); 89 | 90 | // mask the merchant session ID 91 | $string = str_replace( $this->merchantSessionIdentifier, str_repeat( '*', 10 ), $string ); 92 | 93 | // mask the merchant ID 94 | $string = str_replace( $this->merchantIdentifier, str_repeat( '*', 10 ), $string ); 95 | 96 | // mask the signature 97 | $string = str_replace( $this->signature, str_repeat( '*', 10 ), $string ); 98 | 99 | return $string; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /includes/Gateway/API/Requests/Refunds.php: -------------------------------------------------------------------------------- 1 | square_api = $api_client->getRefundsApi(); 46 | } 47 | 48 | 49 | /** 50 | * Sets the data for refund a payment. 51 | * 52 | * @since 2.2.0 53 | * 54 | * @param \WC_Order $order order object 55 | * @param array $refund_data array of data required for a refund. 56 | */ 57 | public function set_refund_data( \WC_Order $order, $refund_data = array() ) { 58 | 59 | $this->square_api_method = 'refundPayment'; 60 | 61 | // The refund objects are sorted by date DESC, so the last one created will be at the start of the array 62 | $refunds = $order->get_refunds(); 63 | $refund_obj = $refunds[0]; 64 | 65 | $refund_amount = empty( $refund_data['amount'] ) ? $order->refund->amount : $refund_data['amount']; 66 | $tender_id = empty( $refund_data['tender_id'] ) ? $order->refund->tender_id : $refund_data['tender_id']; 67 | $payment_type = empty( $refund_data['payment_type'] ) ? '' : "-{$refund_data['payment_type']}"; 68 | 69 | $this->square_request = new RefundPaymentRequest( 70 | wc_square()->get_idempotency_key( $order->get_id() . ':' . $refund_obj->get_id() . $payment_type ), 71 | Money_Utility::amount_to_money( $refund_amount, $order->get_currency() ) 72 | ); 73 | 74 | $this->square_request->setPaymentId( $tender_id ); 75 | 76 | $this->square_request->setReason( $order->refund->reason ); 77 | 78 | $this->square_api_args = array( $this->square_request ); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /includes/Gateway/API/Requests/Gift_Card.php: -------------------------------------------------------------------------------- 1 | square_api = $api_client->getGiftCardsApi(); 50 | $this->location_id = $location_id; 51 | } 52 | 53 | /** 54 | * Sets data for the `retrieveGiftCardFromNonce` API method. 55 | * 56 | * @param string $nonce Gift Card payment nonce. 57 | */ 58 | public function set_retrieve_gift_card_data( $nonce = '' ) { 59 | $this->square_request = new \Square\Models\RetrieveGiftCardFromNonceRequest( $nonce ); 60 | $this->square_api_method = 'retrieveGiftCardFromNonce'; 61 | $this->square_api_args = array( $this->square_request ); 62 | } 63 | 64 | 65 | /** 66 | * Sets data for the `retrieveGiftCardFromGAN` API method. 67 | * 68 | * @since 4.2.0 69 | * 70 | * @param string $gan Gift card number. 71 | */ 72 | public function set_retrieve_gift_card_from_gan_data( $gan = '' ) { 73 | $this->square_request = new \Square\Models\RetrieveGiftCardFromGANRequest( $gan ); 74 | $this->square_api_method = 'retrieveGiftCardFromGAN'; 75 | $this->square_api_args = array( $this->square_request ); 76 | } 77 | 78 | /** 79 | * Sets data to create a Gift card. 80 | * 81 | * @since 4.2.0 82 | * 83 | * @param $order_id Line item order ID. 84 | */ 85 | public function set_create_gift_card_data( $order_id ) { 86 | $this->square_api_method = 'createGiftCard'; 87 | $gift_card = new \Square\Models\GiftCard( \Square\Models\GiftCardType::DIGITAL ); 88 | $this->square_request = new \Square\Models\CreateGiftCardRequest( 89 | wc_square()->get_idempotency_key( $order_id, false ), 90 | $this->location_id, 91 | $gift_card 92 | ); 93 | 94 | $this->square_api_args = array( $this->square_request ); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /includes/Gateway/API/Requests/Card.php: -------------------------------------------------------------------------------- 1 | square_api = $api_client->getCardsApi(); 43 | } 44 | 45 | /** 46 | * Sets the data for creating a new customer card. 47 | * 48 | * @since 3.0.0 49 | * 50 | * @param \WC_Order $order order object 51 | */ 52 | public function set_create_card_data( \WC_Order $order ) { 53 | 54 | $this->square_api_method = 'createCard'; 55 | 56 | $card = new \Square\Models\Card(); 57 | $card->setBillingAddress( \WooCommerce\Square\Gateway\API\Requests\Customers::get_address_from_order( $order ) ); 58 | $card->setCardholderName( $order->get_formatted_billing_full_name() ); 59 | $card->setCustomerId( $order->customer_id ); 60 | 61 | $source_id = ! empty( $order->payment->verified_token ) ? $order->payment->verified_token : ( ! empty( $order->payment->token ) ? $order->payment->token : $order->payment->nonce->credit_card ); 62 | $request = new \Square\Models\CreateCardRequest( 63 | wc_square()->get_idempotency_key( '', false ), 64 | $source_id, 65 | $card 66 | ); 67 | 68 | // 3DS / SCA verification token (from JS) 69 | if ( ! empty( $order->payment->verification_token ) ) { 70 | $request->setVerificationToken( $order->payment->verification_token ); 71 | } 72 | 73 | $this->square_request = $request; 74 | 75 | $this->square_api_args = array( 76 | $this->square_request, 77 | ); 78 | } 79 | 80 | /** 81 | * Sets the data for deleting an existing card. 82 | * 83 | * @since 3.0.0 84 | * 85 | * @param string $card_id Square card ID 86 | */ 87 | public function set_delete_card_data( $card_id ) { 88 | 89 | $this->square_api_method = 'disableCard'; 90 | 91 | $this->square_api_args = array( 92 | $card_id, 93 | ); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /includes/Framework/Api/API_JSON_Request.php: -------------------------------------------------------------------------------- 1 | method; 55 | } 56 | 57 | 58 | /** 59 | * Get the request path. 60 | * 61 | * @since 3.0.0 62 | * @see API_Request::get_path() 63 | * @return string 64 | */ 65 | public function get_path() { 66 | return $this->path; 67 | } 68 | 69 | 70 | /** 71 | * Get the request parameters. 72 | * 73 | * @since 3.0.0 74 | * @see API_Request::get_params() 75 | * @return array 76 | */ 77 | public function get_params() { 78 | return $this->params; 79 | } 80 | 81 | 82 | /** 83 | * Get the request data. 84 | * 85 | * @since 3.0.0 86 | * @return array 87 | */ 88 | public function get_data() { 89 | return $this->data; 90 | } 91 | 92 | 93 | /** API Helper Methods ******************************************************/ 94 | 95 | 96 | /** 97 | * Get the string representation of this request. 98 | * 99 | * @since 3.0.0 100 | * @see API_Request::to_string() 101 | * @return string 102 | */ 103 | public function to_string() { 104 | 105 | $data = $this->get_data(); 106 | 107 | return ! empty( $data ) ? wp_json_encode( $data ) : ''; 108 | } 109 | 110 | 111 | /** 112 | * Get the string representation of this request with any and all sensitive elements masked 113 | * or removed. 114 | * 115 | * @since 3.0.0 116 | * @see API_Request::to_string_safe() 117 | * @return string 118 | */ 119 | public function to_string_safe() { 120 | 121 | return $this->to_string(); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /templates/emails/gift-card-sent.php: -------------------------------------------------------------------------------- 1 | 27 | 28 | 59 | 60 |

61 | 68 |

69 | 70 | 71 |
72 | 73 |
74 | get_billing_first_name() ) ); 77 | ?> 78 |
79 | 80 | 81 |
82 |

83 |
84 |

85 |
86 |
87 | 88 | 93 | 94 | 95 | 96 | 21 | 22 | 67 | -------------------------------------------------------------------------------- /includes/Framework/PaymentGateway/PaymentTokens/Square_Credit_Card_Payment_Token.php: -------------------------------------------------------------------------------- 1 | extra_data = array_merge( 15 | $this->extra_data, 16 | array( 17 | 'environment' => '', 18 | 'billing_hash' => '', 19 | 'nickname' => '', 20 | ) 21 | ); 22 | 23 | parent::__construct( $token ); 24 | } 25 | 26 | /** 27 | * Setter for a card's encironment. 28 | * 29 | * @param string $env Environment of the Square account. 30 | * @since 3.8.0 31 | */ 32 | public function set_environment( $env = '' ) { 33 | $this->set_prop( 'environment', $env ); 34 | } 35 | 36 | /** 37 | * Setter for billing hash. 38 | * 39 | * @param string $value The billing hash string. 40 | * @since 3.8.0 41 | */ 42 | public function set_billing_hash( $value = '' ) { 43 | $this->set_prop( 'billing_hash', $value ); 44 | } 45 | 46 | /** 47 | * Setter for a card's nickname. 48 | * 49 | * @param string $value The billing hash string. 50 | * @since 3.8.0 51 | */ 52 | public function set_nickname( $value = '' ) { 53 | $this->set_prop( 'nickname', $value ); 54 | } 55 | 56 | /** 57 | * Getter for a card's environment. 58 | * 59 | * @since 3.8.0 60 | * @return string 61 | */ 62 | public function get_environment( $context = 'view' ) { 63 | return $this->get_prop( 'environment', $context ); 64 | } 65 | 66 | /** 67 | * Getter for billing hash. 68 | * 69 | * @since 3.8.0 70 | * @return string 71 | */ 72 | public function get_billing_hash( $context = 'view' ) { 73 | return $this->get_prop( 'billing_hash', $context ); 74 | } 75 | 76 | /** 77 | * Get expiry date. 78 | * 79 | * @since 3.8.0 80 | * @return string 81 | */ 82 | public function get_exp_date() { 83 | $expiry_month = $this->get_expiry_month(); 84 | $expiry_year = $this->get_expiry_year(); 85 | 86 | $expiry_date = $expiry_month . '/' . substr( $expiry_year, -2 ); 87 | 88 | return $expiry_date; 89 | } 90 | 91 | /** 92 | * Getter for a card's nickname. 93 | * 94 | * @param string $value The billing hash string. 95 | * @since 3.8.0 96 | */ 97 | public function get_nickname( $context = 'view' ) { 98 | $this->get_prop( 'nickname', $context ); 99 | } 100 | 101 | /** 102 | * Retrieves array of Square Payment Tokens. 103 | * 104 | * @param WC_Payment_Token_CC[] $tokens Array of tokens 105 | * @since 3.8.0 106 | * 107 | * @return Square_Credit_Card_Payment_Token[]; 108 | */ 109 | public static function get_square_customer_tokens( $tokens = array() ) { 110 | $square_customer_tokens = array(); 111 | 112 | /** @var \WC_Payment_Token_CC $token */ 113 | foreach ( $tokens as $token_id => $token ) { 114 | if ( \WooCommerce\Square\Plugin::GATEWAY_ID !== $token->get_gateway_id() ) { 115 | continue; 116 | } 117 | 118 | $square_customer_tokens[ $token_id ] = new Square_Credit_Card_Payment_Token( $token ); 119 | } 120 | 121 | return $square_customer_tokens; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /includes/Framework/PaymentGateway/Api/Payment_Gateway_API_Response.php: -------------------------------------------------------------------------------- 1 | gateway = $gateway; 50 | } 51 | 52 | 53 | /** 54 | * Sets the data for merchant validation. 55 | * 56 | * @since 3.0.0 57 | * 58 | * @param string $merchant_id the merchant ID to validate 59 | * @param string $domain_name the verified domain name 60 | * @param string $display_name the merchant display name 61 | */ 62 | public function set_merchant_data( $merchant_id, $domain_name, $display_name ) { 63 | 64 | $data = array( 65 | 'merchantIdentifier' => $merchant_id, 66 | 'domainName' => str_replace( array( 'http://', 'https://' ), '', $domain_name ), 67 | 'displayName' => $display_name, 68 | ); 69 | 70 | /** 71 | * Filters the data for merchant validation. 72 | * 73 | * @since 3.0.0 74 | * 75 | * @param array $data { 76 | * The merchant data. 77 | * 78 | * @var string $merchantIdentifier the merchant ID 79 | * @var string $domainName the verified domain name 80 | * @var string $displayName the merchant display name 81 | * } 82 | * @param Payment_Gateway_Apple_Pay_API_Request the request object 83 | */ 84 | $this->data = apply_filters( 'sv_wc_apple_pay_api_merchant_data', $data, $this ); 85 | } 86 | 87 | 88 | /** 89 | * Get the string representation of this response with any and all sensitive 90 | * elements masked or removed. 91 | * 92 | * @since 3.0.0 93 | * @see API_Response::to_string_safe() 94 | * 95 | * @return string 96 | */ 97 | public function to_string_safe() { 98 | 99 | // mask the merchant ID 100 | $string = str_replace( $this->data['merchantIdentifier'], str_repeat( '*', strlen( $this->data['merchantIdentifier'] ) ), $this->to_string() ); 101 | 102 | return $string; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /includes/Utilities/Array_Utility.php: -------------------------------------------------------------------------------- 1 | 'foo', 'item_2' => 'bar' ) 42 | * 43 | * array_insert_after( $array, 'item_1', array( 'item_1.5' => 'w00t' ) ) 44 | * 45 | * becomes 46 | * 47 | * array( 'item_1' => 'foo', 'item_1.5' => 'w00t', 'item_2' => 'bar' ) 48 | * 49 | * @since 2.2.0 50 | * @param array $array array to insert the given element into 51 | * @param string $insert_key key to insert given element after 52 | * @param array $element element to insert into array 53 | * @return array 54 | */ 55 | public static function array_insert_after( Array $array, $insert_key, Array $element ) { 56 | 57 | $new_array = array(); 58 | 59 | foreach ( $array as $key => $value ) { 60 | 61 | $new_array[ $key ] = $value; 62 | 63 | if ( $insert_key == $key ) { 64 | 65 | foreach ( $element as $k => $v ) { 66 | $new_array[ $k ] = $v; 67 | } 68 | } 69 | } 70 | 71 | return $new_array; 72 | } 73 | 74 | /** 75 | * Lists an array as text. 76 | * 77 | * Takes an array and returns a list like "one, two, three, and four" 78 | * with a (mandatory) oxford comma. 79 | * 80 | * @since 5.2.0 81 | * 82 | * @param array $items items to list 83 | * @param string|null $conjunction coordinating conjunction, like "or" or "and" 84 | * @param string $separator list separator, like a comma 85 | * @return string 86 | */ 87 | public static function list_array_items( array $items, $conjunction = null, $separator = '' ) { 88 | 89 | if ( ! is_string( $conjunction ) ) { 90 | $conjunction = _x( 'and', 'coordinating conjunction for a list of items: a, b, and c', 'woocommerce-square' ); 91 | } 92 | 93 | // append the conjunction to the last item 94 | if ( count( $items ) > 1 ) { 95 | 96 | $last_item = array_pop( $items ); 97 | 98 | array_push( $items, trim( "{$conjunction} {$last_item}" ) ); 99 | 100 | // only use a comma if needed and no separator was passed 101 | if ( count( $items ) < 3 ) { 102 | $separator = ' '; 103 | } elseif ( ! is_string( $separator ) || '' === $separator ) { 104 | $separator = ', '; 105 | } 106 | } 107 | 108 | return implode( $separator, $items ); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /includes/Gateway/API/Responses/Charge.php: -------------------------------------------------------------------------------- 1 | get_tender() ) { 33 | $held = 'AUTHORIZED' === $this->get_tender()->getCardDetails()->getStatus(); 34 | } 35 | 36 | return $held; 37 | } 38 | 39 | 40 | /** Getter methods ************************************************************************************************/ 41 | 42 | 43 | /** 44 | * Gets the authorization code. 45 | * 46 | * @since 2.0.0 47 | * 48 | * @return string 49 | */ 50 | public function get_authorization_code() { 51 | 52 | return $this->get_tender() ? $this->get_tender()->getId() : ''; 53 | } 54 | 55 | 56 | /** 57 | * Gets the transaction ID. 58 | * 59 | * @since 2.0.0 60 | * 61 | * @return string 62 | */ 63 | public function get_transaction_id() { 64 | 65 | return $this->get_transaction() ? $this->get_transaction()->getId() : ''; 66 | } 67 | 68 | 69 | /** 70 | * Gets the location ID. 71 | * 72 | * @since 2.0.0 73 | * 74 | * @return string 75 | */ 76 | public function get_location_id() { 77 | 78 | return $this->get_transaction() ? $this->get_transaction()->getLocationId() : ''; 79 | } 80 | 81 | 82 | /** 83 | * Gets the Square order ID, if any. 84 | * 85 | * @since 2.0.0 86 | * 87 | * @return string 88 | */ 89 | public function get_square_order_id() { 90 | 91 | return $this->get_transaction() ? $this->get_transaction()->getOrderId() : ''; 92 | } 93 | 94 | 95 | /** 96 | * Gets the Square tender (auth) object. 97 | * 98 | * @since 2.0.0 99 | * 100 | * @return \Square\Models\Tender|null 101 | */ 102 | public function get_tender() { 103 | 104 | return $this->get_transaction() ? current( $this->get_transaction()->getTenders() ) : null; 105 | } 106 | 107 | 108 | /** 109 | * Gets the Square transaction object. 110 | * 111 | * @since 2.0.0 112 | * 113 | * @return \Square\Models\Transaction|null 114 | */ 115 | public function get_transaction() { 116 | 117 | return ! $this->has_errors() && $this->get_data()->getTransaction() ? $this->get_data()->getTransaction() : null; 118 | } 119 | 120 | 121 | /** 122 | * Gets the message to display to the user. 123 | * 124 | * @since 2.0.0 125 | * 126 | * @return string 127 | */ 128 | public function get_user_message() { 129 | 130 | $message_id = $this->get_status_code(); 131 | 132 | $helper = new \WooCommerce\Square\Gateway\API\Response_Message_Helper(); 133 | 134 | return $helper->get_user_message( $message_id ); 135 | } 136 | 137 | 138 | /** No-op methods *************************************************************************************************/ 139 | 140 | 141 | public function get_avs_result() { } 142 | 143 | public function get_csc_result() { } 144 | 145 | public function csc_match() { } 146 | 147 | 148 | } 149 | -------------------------------------------------------------------------------- /includes/Admin/Privacy.php: -------------------------------------------------------------------------------- 1 | name = __( 'Square', 'woocommerce-square' ); 54 | 55 | $this->add_eraser( 'woocommerce-square-customer-data', __( 'WooCommerce Square Customer Data', 'woocommerce-square' ), array( $this, 'customer_data_eraser' ) ); 56 | } 57 | 58 | /** 59 | * Gets the message to display. 60 | * 61 | * @since 2.0.0 62 | */ 63 | public function get_privacy_message() { 64 | 65 | return wpautop( 66 | sprintf( 67 | /* translators: Placeholder: %1$s - tag, %2$s - tag */ 68 | __( 'By using this extension, you may be storing personal data or sharing data with an external service. %1$sLearn more about how this works, including what you may want to include in your privacy policy.%2$s', 'woocommerce-square' ), 69 | '', 70 | '' 71 | ) 72 | ); 73 | } 74 | 75 | 76 | /** 77 | * Finds and erases customer data by email address. 78 | * 79 | * @since 2.0.0 80 | * 81 | * @param string $email_address the user email address 82 | * @param int $page page 83 | * @return array an array of personal data in name => value pairs 84 | */ 85 | public function customer_data_eraser( $email_address, $page ) { 86 | 87 | // check if user has an ID to load stored personal data 88 | $user = get_user_by( 'email', $email_address ); 89 | $square_customer_id = get_user_meta( $user->ID, 'wc_square_customer_id', true ); 90 | 91 | $items_removed = false; 92 | $messages = array(); 93 | 94 | if ( ! empty( $square_customer_id ) ) { 95 | 96 | $items_removed = true; 97 | 98 | delete_user_meta( $user->ID, 'wc_square_customer_id' ); 99 | 100 | $messages[] = __( 'Square User Data Erased.', 'woocommerce-square' ); 101 | } 102 | 103 | return array( 104 | 'items_removed' => $items_removed, 105 | 'items_retained' => false, 106 | 'messages' => $messages, 107 | 'done' => true, 108 | ); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /includes/API/Response.php: -------------------------------------------------------------------------------- 1 | raw_response_data = $raw_response_data; 48 | } 49 | 50 | 51 | /** 52 | * Gets the response data. 53 | * 54 | * @since 2.0.0 55 | * 56 | * @return Object 57 | */ 58 | public function get_data() { 59 | 60 | return $this->raw_response_data ?: null; 61 | } 62 | 63 | 64 | /** 65 | * Gets errors returned by the Square API. 66 | * 67 | * @since 2.0.0 68 | * 69 | * @return \stdClass[] 70 | */ 71 | public function get_errors() { 72 | if ( is_array( $this->raw_response_data ) && count( $this->raw_response_data ) > 0 ) { 73 | if ( $this->raw_response_data[0] instanceof \Square\Models\Error ) { 74 | return $this->raw_response_data; 75 | } 76 | } 77 | 78 | return array(); 79 | } 80 | 81 | 82 | /** 83 | * Determines if the API response contains errors. 84 | * 85 | * @since 2.0.0 86 | * 87 | * @return bool 88 | */ 89 | public function has_errors() { 90 | 91 | return ! empty( $this->get_errors() ); 92 | } 93 | 94 | 95 | /** 96 | * Determines if the API response contains a particular error code. 97 | * 98 | * @since 2.1.6 99 | * @param $error \Square\Models\Error 100 | * @return bool 101 | */ 102 | public function has_error_code( $error_code ) { 103 | foreach ( $this->get_errors() as $error ) { 104 | if ( $error_code === $error->getCode() ) { 105 | return true; 106 | } 107 | } 108 | return false; 109 | } 110 | 111 | 112 | /** 113 | * Gets the response data as a string. 114 | * 115 | * @since 2.0.0 116 | * 117 | * @return string 118 | */ 119 | public function to_string() { 120 | $response_data = $this->get_data(); 121 | 122 | if ( is_callable( array( $response_data, '__toString' ) ) ) { 123 | return $this->get_data(); 124 | } else if ( is_callable( array( $response_data, 'jsonSerialize' ) ) ) { 125 | return wp_json_encode( $response_data, JSON_PRETTY_PRINT ); 126 | } 127 | 128 | return ''; 129 | } 130 | 131 | 132 | /** 133 | * Gets the response data a string with all sensitive information masked. 134 | * 135 | * @since 2.0.0 136 | * 137 | * @return string 138 | */ 139 | public function to_string_safe() { 140 | 141 | return $this->to_string(); 142 | } 143 | 144 | 145 | } 146 | -------------------------------------------------------------------------------- /includes/Utilities/Performance_Logger.php: -------------------------------------------------------------------------------- 1 | get_settings_handler() && $plugin->get_settings_handler()->is_debug_enabled() ) { 48 | self::$timers[ $key ] = array( 49 | 'time' => microtime( true ), 50 | 'memory' => memory_get_usage(), 51 | ); 52 | } 53 | } 54 | 55 | /** 56 | * Ends a timer and logs the performance data. 57 | * 58 | * @since 4.9.1 59 | * 60 | * @param string $key Unique identifier for this timer 61 | * @param \WooCommerce\Square\Plugin $plugin Plugin instance for logging 62 | * @param boolean $is_error Whether the operation failed 63 | */ 64 | public static function end( $key, $plugin, $is_error = false ) { 65 | if ( ! isset( self::$timers[ $key ] ) ) { 66 | return; 67 | } 68 | 69 | $duration = microtime( true ) - self::$timers[ $key ]['time']; 70 | $memory_bytes = memory_get_usage() - self::$timers[ $key ]['memory']; 71 | 72 | // Format duration: Show milliseconds if < 1 second, otherwise show seconds 73 | $time_format = $duration < 1 74 | ? sprintf( '%.0fms', $duration * 1000 ) 75 | : sprintf( '%.3fs', $duration ); 76 | 77 | // Format memory: Show MB if > 1MB, otherwise KB 78 | $memory_format = $memory_bytes > 1048576 79 | ? sprintf( '%.2fMB', $memory_bytes / 1048576 ) 80 | : sprintf( '%.2fKB', $memory_bytes / 1024 ); 81 | 82 | $plugin->log( 83 | sprintf( 84 | '[Performance] %s %s in %s with %s of memory usage', 85 | $key, 86 | $is_error ? 'failed' : 'completed', 87 | $time_format, 88 | $memory_format 89 | ) 90 | ); 91 | 92 | unset( self::$timers[ $key ] ); 93 | } 94 | 95 | /** 96 | * Gets the current timer value without logging (useful for testing). 97 | * 98 | * @since 4.9.1 99 | * 100 | * @param string $key Timer identifier 101 | * @return float|null Timer value in seconds or null if timer not found 102 | */ 103 | public static function get_timer( $key ) { 104 | return isset( self::$timers[ $key ] ) ? self::$timers[ $key ] : null; 105 | } 106 | 107 | /** 108 | * Resets all timers (useful for testing). 109 | * 110 | * @since 4.9.1 111 | */ 112 | public static function reset() { 113 | self::$timers = array(); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /includes/Gateway/API/Requests/Customers.php: -------------------------------------------------------------------------------- 1 | square_api_method = 'createCustomer'; 48 | 49 | // set the customer email as the WP user email, if available 50 | try { 51 | 52 | if ( ! $order->get_user_id() ) { 53 | throw new \Exception( 'No user account' ); 54 | } 55 | 56 | $customer = new \WC_Customer( $order->get_user_id() ); 57 | 58 | $email = $customer->get_email(); 59 | 60 | } catch ( \Exception $exception ) { // otherwise, use the order billing email 61 | 62 | $email = $order->get_billing_email(); 63 | } 64 | 65 | $customer_request = new \Square\Models\CreateCustomerRequest(); 66 | $customer_request->setGivenName( $order->get_billing_first_name() ); 67 | $customer_request->setFamilyName( $order->get_billing_last_name() ); 68 | $customer_request->setCompanyName( $order->get_billing_company() ); 69 | $customer_request->setEmailAddress( $email ); 70 | $customer_request->setPhoneNumber( $order->get_billing_phone() ); 71 | 72 | if ( $order->get_user_id() ) { 73 | $customer_request->setReferenceId( (string) $order->get_user_id() ); 74 | } 75 | 76 | $customer_request->setAddress( self::get_address_from_order( $order ) ); 77 | 78 | $this->square_request = $customer_request; 79 | 80 | $this->square_api_args = array( 81 | $this->square_request, 82 | ); 83 | } 84 | 85 | /** 86 | * Gets a billing address model from a WC order. 87 | * 88 | * @since 2.0.0 89 | * 90 | * @param \WC_Order $order order object 91 | * @return \Square\Models\Address 92 | */ 93 | public static function get_address_from_order( \WC_Order $order ) { 94 | 95 | $address = new \Square\Models\Address(); 96 | $address->setFirstName( $order->get_billing_first_name() ); 97 | $address->setLastName( $order->get_billing_last_name() ); 98 | $address->setAddressLine1( $order->get_billing_address_1() ); 99 | $address->setAddressLine2( $order->get_billing_address_2() ); 100 | $address->setLocality( $order->get_billing_city() ); 101 | $address->setAdministrativeDistrictLevel1( $order->get_billing_state() ); 102 | if ( ! empty( $order->payment->postcode ) ) { 103 | $address->setPostalCode( $order->payment->postcode ); 104 | } else { 105 | $address->setPostalCode( $order->get_billing_postcode() ); 106 | } 107 | 108 | if ( $order->get_billing_country() ) { 109 | $address->setCountry( $order->get_billing_country() ); 110 | } 111 | 112 | return $address; 113 | } 114 | 115 | 116 | } 117 | -------------------------------------------------------------------------------- /includes/Gateway/Templates/payment.php: -------------------------------------------------------------------------------- 1 | 27 | 28 |
29 | cart->needs_payment() && ( $is_error || ! $has_balance ) ) : ?> 30 | 45 | 46 |
47 | 54 | 55 | 56 | 57 | 61 | 62 | ' . esc_html( $order_button_text ) . '' ); // @codingStandardsIgnoreLine ?> 63 | 64 | 68 | 69 | 70 |
71 |
72 | has_errors(); 58 | } 59 | 60 | 61 | /** 62 | * Determines if the transaction was held. 63 | * 64 | * @since 2.0.0 65 | * 66 | * @return bool 67 | */ 68 | public function transaction_held() { 69 | 70 | return false; // TODO: make sure there are no held responses 71 | } 72 | 73 | 74 | /** Getter methods ************************************************************************************************/ 75 | 76 | 77 | /** 78 | * Gets the transaction ID. 79 | * 80 | * @since 2.0.0 81 | * 82 | * @return string 83 | */ 84 | public function get_transaction_id() { 85 | 86 | return ''; 87 | } 88 | 89 | 90 | /** 91 | * Gets the response status message. 92 | * 93 | * @since 2.0.0 94 | * 95 | * @return string 96 | */ 97 | public function get_status_message() { 98 | 99 | $message = ''; 100 | 101 | foreach ( $this->get_errors() as $error ) { 102 | 103 | $message = $error->getDetail(); 104 | break; 105 | } 106 | 107 | return $message; 108 | } 109 | 110 | 111 | /** 112 | * Gets the response status code. 113 | * 114 | * @since 2.0.0 115 | * 116 | * @return string 117 | */ 118 | public function get_status_code() { 119 | 120 | $code = ''; 121 | 122 | foreach ( $this->get_errors() as $error ) { 123 | 124 | $code = $error->getCode(); 125 | break; 126 | } 127 | 128 | return $code; 129 | } 130 | 131 | /** 132 | * Gets array of response status codes. 133 | * 134 | * @since 3.5.0 135 | * 136 | * @return array 137 | */ 138 | public function get_status_codes() { 139 | 140 | $codes = array(); 141 | 142 | foreach ( $this->get_errors() as $error ) { 143 | 144 | $codes[] = $error->getCode(); 145 | } 146 | 147 | return $codes; 148 | } 149 | 150 | 151 | /** 152 | * Gets the message to display to the user. 153 | * 154 | * @since 2.0.0 155 | * 156 | * @return string 157 | */ 158 | public function get_user_message() { 159 | 160 | return ''; 161 | } 162 | 163 | 164 | /** 165 | * Gets the payment type. 166 | * 167 | * @since 2.0.0 168 | * 169 | * @return string 170 | */ 171 | public function get_payment_type() { 172 | 173 | return Gateway::PAYMENT_TYPE_CREDIT_CARD; 174 | } 175 | 176 | 177 | } 178 | -------------------------------------------------------------------------------- /includes/Framework/PaymentGateway/Admin/views/html-admin-gateway-status.php: -------------------------------------------------------------------------------- 1 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | get_id() . '_system_status_start', $gateway ); 46 | ?> 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | supports_tokenization() ) : ?> 55 | 56 | 57 | 58 | 59 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 84 | 85 | 86 | get_id() . '_system_status_end', $gateway ); 96 | ?> 97 | 98 | 99 | 100 |
27 | get_method_title() ); ?> 28 | 29 |
:
: 60 | tokenization_enabled() ) : ?> 61 | 62 | 63 | 64 | 65 |
: 74 | debug_log() && $gateway->debug_checkout() ) : ?> 75 | 76 | debug_checkout() ) : ?> 77 | 78 | debug_log() ) : ?> 79 | 80 | 81 | 82 | 83 |
101 | -------------------------------------------------------------------------------- /includes/Framework/Plugin_Compatibility.php: -------------------------------------------------------------------------------- 1 | first_name; 59 | } 60 | 61 | 62 | /** 63 | * Gets the customer first name. 64 | * 65 | * @since 3.0.0 66 | * 67 | * @return string 68 | */ 69 | public function get_last_name() { 70 | 71 | return $this->last_name; 72 | } 73 | 74 | 75 | /** 76 | * Gets the data used to generate a hash for the address. 77 | * 78 | * @see Address::get_hash_data() 79 | * 80 | * @since 3.0.0 81 | * 82 | * @return string[] 83 | */ 84 | protected function get_hash_data() { 85 | 86 | // add the first & last name to data used to generate the hash 87 | $data = array_merge( 88 | array( 89 | $this->get_first_name(), 90 | $this->get_last_name(), 91 | ), 92 | parent::get_hash_data() 93 | ); 94 | 95 | return $data; 96 | } 97 | 98 | 99 | /** Setter Methods ************************************************************************************************/ 100 | 101 | 102 | /** 103 | * Sets the customer first name. 104 | * 105 | * @since 3.0.0 106 | * 107 | * @param string $value first name value 108 | */ 109 | public function set_first_name( $value ) { 110 | 111 | $this->first_name = $value; 112 | } 113 | 114 | 115 | /** 116 | * Sets the customer last name. 117 | * 118 | * @since 3.0.0 119 | * 120 | * @param string $value first name value 121 | */ 122 | public function set_last_name( $value ) { 123 | 124 | $this->last_name = $value; 125 | } 126 | 127 | 128 | /** 129 | * Sets the full address based on a WooCommerce order. 130 | * 131 | * @since 3.0.0 132 | * 133 | * @param \WC_Order $order WooCommerce order object 134 | * @param string $type address type, like billing or shipping 135 | */ 136 | public function set_from_order( \WC_Order $order, $type = 'billing' ) { 137 | 138 | $this->set_first_name( Order_Compatibility::get_prop( $order, "{$type}_first_name" ) ); 139 | $this->set_last_name( Order_Compatibility::get_prop( $order, "{$type}_last_name" ) ); 140 | $this->set_line_1( Order_Compatibility::get_prop( $order, "{$type}_address_1" ) ); 141 | $this->set_line_2( Order_Compatibility::get_prop( $order, "{$type}_address_2" ) ); 142 | $this->set_locality( Order_Compatibility::get_prop( $order, "{$type}_city" ) ); 143 | $this->set_region( Order_Compatibility::get_prop( $order, "{$type}_state" ) ); 144 | $this->set_country( Order_Compatibility::get_prop( $order, "{$type}_country" ) ); 145 | $this->set_postcode( Order_Compatibility::get_prop( $order, "{$type}_postcode" ) ); 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /includes/Admin/Rest/WC_REST_Square_Gift_Cards_Settings_Controller.php: -------------------------------------------------------------------------------- 1 | allowed_params = array( 41 | 'enabled', 42 | 'title', 43 | 'description', 44 | 'is_default_placeholder', 45 | 'placeholder_id', 46 | ); 47 | 48 | add_action( 'rest_api_init', array( $this, 'register_routes' ) ); 49 | } 50 | 51 | /** 52 | * Register routes. 53 | */ 54 | public function register_routes() { 55 | register_rest_route( 56 | $this->namespace, 57 | '/' . $this->rest_base, 58 | array( 59 | 'methods' => WP_REST_Server::READABLE, 60 | 'callback' => array( $this, 'get_settings' ), 61 | 'permission_callback' => array( $this, 'check_permission' ), 62 | ) 63 | ); 64 | register_rest_route( 65 | $this->namespace, 66 | '/' . $this->rest_base, 67 | array( 68 | 'methods' => WP_REST_Server::EDITABLE, 69 | 'callback' => array( $this, 'save_settings' ), 70 | 'permission_callback' => array( $this, 'check_permission' ), 71 | 'args' => array( 72 | 'enabled' => array( 73 | 'description' => __( 'Enable Square payment gateway.', 'woocommerce-square' ), 74 | 'type' => 'string', 75 | 'sanitize_callback' => '', 76 | ), 77 | 'title' => array( 78 | 'description' => __( 'Square payment gateway title.', 'woocommerce-square' ), 79 | 'type' => 'string', 80 | 'sanitize_callback' => '', 81 | ), 82 | 'description' => array( 83 | 'description' => __( 'Square payment gateway description.', 'woocommerce-square' ), 84 | 'type' => 'string', 85 | 'sanitize_callback' => '', 86 | ), 87 | 'is_default_placeholder' => array( 88 | 'description' => __( 'Indicates if a Gift card product should use the default placeholder provided by the plugin.', 'woocommerce-square' ), 89 | 'type' => 'string', 90 | 'sanitize_callback' => '', 91 | ), 92 | 'placeholder_id' => array( 93 | 'description' => __( 'ID of the placeholder media.', 'woocommerce-square' ), 94 | 'type' => 'integer', 95 | 'sanitize_callback' => '', 96 | ), 97 | ), 98 | ) 99 | ); 100 | } 101 | 102 | /** 103 | * Get the data. 104 | * 105 | * @return WP_REST_Response 106 | */ 107 | public function get_settings() { 108 | $square_settings = get_option( Gift_Card::SQUARE_PAYMENT_SETTINGS_OPTION_NAME, array() ); 109 | $filtered_settings = array_intersect_key( $square_settings, array_flip( $this->allowed_params ) ); 110 | 111 | return new WP_REST_Response( $filtered_settings ); 112 | } 113 | 114 | /** 115 | * Update the data. 116 | * 117 | * @param WP_REST_Request $request Full data about the request. 118 | */ 119 | public function save_settings( WP_REST_Request $request ) { 120 | $settings = array(); 121 | 122 | foreach ( $this->allowed_params as $index => $key ) { 123 | $new_value = wc_clean( wp_unslash( $request->get_param( $key ) ) ); 124 | 125 | $settings[ $key ] = $new_value; 126 | } 127 | 128 | update_option( Gift_Card::SQUARE_PAYMENT_SETTINGS_OPTION_NAME, $settings ); 129 | 130 | /** 131 | * Action triggered when the Gift card payment settings are updated. 132 | * 133 | * @since 4.8.1 134 | */ 135 | do_action( 'wc_square_' . Gift_Card::SQUARE_PAYMENT_SETTINGS_OPTION_NAME . '_settings_updated', $settings ); 136 | 137 | wp_send_json_success(); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /includes/Framework/Compatibility/Data_Compatibility.php: -------------------------------------------------------------------------------- 1 | {"get_{$prop}"}( $context ); 49 | } 50 | 51 | return $value; 52 | } 53 | 54 | 55 | /** 56 | * Sets an object's properties. 57 | * 58 | * Note that this does not save any data to the database. 59 | * 60 | * @since 3.0.0 61 | * @param \WC_Data $object the data object, likely \WC_Order or \WC_Product 62 | * @param array $props the new properties as $key => $value 63 | * @param array $compat_props Compatibility properties. 64 | * @return \WC_Data 65 | */ 66 | public static function set_props( $object, $props, $compat_props = array() ) { 67 | $object->set_props( $props ); 68 | 69 | return $object; 70 | } 71 | 72 | 73 | /** 74 | * Gets an object's stored meta value. 75 | * 76 | * @since 3.0.0 77 | * @param \WC_Data $object the data object, likely \WC_Order or \WC_Product 78 | * @param string $key the meta key 79 | * @param bool $single whether to get the meta as a single item. Defaults to `true` 80 | * @param string $context if 'view' then the value will be filtered 81 | * @return mixed 82 | */ 83 | public static function get_meta( $object, $key = '', $single = true, $context = 'edit' ) { 84 | $value = $object->get_meta( $key, $single, $context ); 85 | 86 | return $value; 87 | } 88 | 89 | 90 | /** 91 | * Stores an object meta value. 92 | * 93 | * @since 3.0.0 94 | * @param \WC_Data $object the data object, likely \WC_Order or \WC_Product 95 | * @param string $key the meta key 96 | * @param string $value the meta value 97 | * @param bool $unique Optional. Whether the meta should be unique. 98 | */ 99 | public static function add_meta_data( $object, $key, $value, $unique = false ) { 100 | $object->add_meta_data( $key, $value, $unique ); 101 | $object->save_meta_data(); 102 | } 103 | 104 | 105 | /** 106 | * Updates an object's stored meta value. 107 | * 108 | * @since 3.0.0 109 | * @param \WC_Data $object the data object, likely \WC_Order or \WC_Product 110 | * @param string $key the meta key 111 | * @param string $value the meta value 112 | * @param int|string $meta_id Optional. The specific meta ID to update 113 | */ 114 | public static function update_meta_data( $object, $key, $value, $meta_id = '' ) { 115 | $object->update_meta_data( $key, $value, $meta_id ); 116 | $object->save_meta_data(); 117 | } 118 | 119 | 120 | /** 121 | * Deletes an object's stored meta value. 122 | * 123 | * @since 3.0.0 124 | * @param \WC_Data $object the data object, likely \WC_Order or \WC_Product 125 | * @param string $key the meta key 126 | */ 127 | public static function delete_meta_data( $object, $key ) { 128 | $object->delete_meta_data( $key ); 129 | $object->save_meta_data(); 130 | } 131 | } 132 | 133 | -------------------------------------------------------------------------------- /includes/Sync/Catalog_Item.php: -------------------------------------------------------------------------------- 1 | product = $product; 68 | $this->soft_delete = $is_soft_delete; 69 | } 70 | 71 | 72 | /** 73 | * Gets the object batch. 74 | * 75 | * @since 2.0.0 76 | * 77 | * @param \Square\Models\CatalogObject|null $catalog_object existing catalog object or null to create a new one 78 | * @return \Square\Models\CatalogObjectBatch 79 | * @throws \Exception 80 | */ 81 | public function get_batch( ?\Square\Models\CatalogObject $catalog_object = null ) { 82 | 83 | if ( ! $this->batch ) { 84 | $this->create_batch( $catalog_object ); 85 | } 86 | 87 | return $this->batch; 88 | } 89 | 90 | 91 | /** 92 | * Gets the total number of objects in the batch. 93 | * 94 | * @since 2.0.0 95 | * 96 | * @return int 97 | */ 98 | public function get_batch_object_count() { 99 | 100 | return $this->batch_object_count; 101 | } 102 | 103 | 104 | /** 105 | * Returns whether this catalog object should be soft-deleted. 106 | * 107 | * @since 2.0.0 108 | * 109 | * @return bool 110 | */ 111 | protected function is_soft_delete() { 112 | 113 | return true === $this->soft_delete; 114 | } 115 | 116 | 117 | /** 118 | * Creates a batch containing this item and any variations. 119 | * 120 | * @since 2.0.0 121 | * 122 | * @param \Square\Models\CatalogObject|null $catalog_object existing catalog object or null to create a new one 123 | * @throws \Exception 124 | */ 125 | protected function create_batch( ?\Square\Models\CatalogObject $catalog_object = null ) { 126 | 127 | if ( ! $catalog_object ) { 128 | $catalog_id = Product\Woo_SOR::get_square_item_id( $this->product ); 129 | $catalog_object = new \Square\Models\CatalogObject( 'ITEM', '' ); 130 | } 131 | 132 | // update the object data from the Woo product 133 | $catalog_object = Product\Woo_SOR::update_catalog_item( $catalog_object, $this->product ); 134 | 135 | $batch_data = array( $catalog_object ); 136 | 137 | $this->batch = new \Square\Models\CatalogObjectBatch( $batch_data ); 138 | 139 | $variations = $catalog_object->getItemData()->getVariations() ?: array(); 140 | 141 | $this->batch_object_count = 1 + count( $variations ); 142 | } 143 | 144 | 145 | } 146 | -------------------------------------------------------------------------------- /includes/Utilities/Money_Utility.php: -------------------------------------------------------------------------------- 1 | setAmount( self::amount_to_cents( $amount, $currency ) ); 54 | $amount_money->setCurrency( $currency ); 55 | 56 | return $amount_money; 57 | } 58 | 59 | 60 | /** 61 | * Converts a float amount to cents. 62 | * 63 | * @since 2.0.0 64 | * 65 | * @param float $amount float amount to convert 66 | * @param string $currency currency code for the amount 67 | * @return int 68 | */ 69 | public static function amount_to_cents( $amount, $currency = '' ) { 70 | 71 | if ( ! $currency ) { 72 | $currency = get_woocommerce_currency(); 73 | } 74 | 75 | $cents_factor = 10 ** self::get_currency_decimals( $currency ); 76 | return (int) ( round( $cents_factor * $amount ) ); 77 | } 78 | 79 | 80 | /** 81 | * Converts an amount in cents to a float. 82 | * 83 | * @since 2.0.0 84 | * 85 | * @param int $cents amount in cents 86 | * @param string $currency currency code for the amount 87 | * @return float 88 | */ 89 | public static function cents_to_float( $cents, $currency = '' ) { 90 | 91 | if ( ! $currency ) { 92 | $currency = get_woocommerce_currency(); 93 | } 94 | 95 | $cents_factor = 10 ** self::get_currency_decimals( $currency ); 96 | return (float) ( $cents / $cents_factor ); 97 | } 98 | 99 | 100 | /** 101 | * Gets the standard number of decimals for the given currency. 102 | * 103 | * @since 2.0.2 104 | * 105 | * @param string $currency currency code 106 | * @return int 107 | */ 108 | public static function get_currency_decimals( $currency ) { 109 | 110 | $other_currencies = array( 111 | 'BIF' => 0, 112 | 'CLP' => 0, 113 | 'DJF' => 0, 114 | 'GNF' => 0, 115 | 'HUF' => 0, 116 | 'JPY' => 0, 117 | 'KMF' => 0, 118 | 'KRW' => 0, 119 | 'MGA' => 0, 120 | 'PYG' => 0, 121 | 'RWF' => 0, 122 | 'VND' => 0, 123 | 'VUV' => 0, 124 | 'XAF' => 0, 125 | 'XOF' => 0, 126 | 'XPF' => 0, 127 | ); 128 | 129 | $locale_info = include WC()->plugin_path() . '/i18n/locale-info.php'; 130 | 131 | $currencies = wp_list_pluck( $locale_info, 'num_decimals', 'currency_code' ); 132 | 133 | // ensure the values set in local-info.php always override the above 134 | $currencies = array_merge( $other_currencies, $currencies ); 135 | 136 | /** 137 | * Filters the number of decimals to use for a given currency when converting to or from its smallest denomination. 138 | * 139 | * @since 2.0.2 140 | * 141 | * @param int $decimals number of decimals 142 | * @param string $currency currency code 143 | */ 144 | return apply_filters( 'wc_square_currency_decimals', isset( $currencies[ $currency ] ) ? $currencies[ $currency ] : 2, $currency ); 145 | } 146 | 147 | 148 | } 149 | -------------------------------------------------------------------------------- /includes/Framework/PaymentGateway/Admin/views/html-user-payment-token-editor-token.php: -------------------------------------------------------------------------------- 1 | 21 | 22 | 23 | 24 | 25 | 26 | $field ) : ?> 27 | 28 | get_token(); 34 | break; 35 | 36 | case 'card_type': 37 | $field_value = $token->get_card_type(); 38 | break; 39 | 40 | case 'last_four': 41 | $field_value = $token->get_last4(); 42 | break; 43 | 44 | case 'expiry': 45 | $field_value = $token->get_expiry_month() . '/' . $token->get_expiry_year(); 46 | break; 47 | 48 | default: 49 | break; 50 | } 51 | ?> 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 76 | 77 | 78 | 79 | $value ) { 84 | $attributes[] = esc_attr( $name ) . '=' . esc_attr( $value ); 85 | } 86 | ?> 87 | 88 | 93 | 94 | /> 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | is_default() ); ?>/> 106 | 107 | 108 | 109 | 110 | 111 | $label ) : ?> 112 | 121 | 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /includes/Gateway/API/Responses/Create_Payment.php: -------------------------------------------------------------------------------- 1 | get_payment() ) { 31 | // Check if the card or wallet is AUTHORIZED (WALLET is for Cash App payments). 32 | $card_details = $this->get_payment()->getCardDetails(); 33 | $wallet_details = $this->get_payment()->getWalletDetails(); 34 | if ( ! empty( $card_details ) ) { 35 | $held = self::STATUS_AUTHORIZED === $card_details->getStatus(); 36 | } elseif ( ! empty( $wallet_details ) ) { 37 | $held = self::STATUS_AUTHORIZED === $wallet_details->getStatus(); 38 | } 39 | } 40 | 41 | return $held; 42 | } 43 | 44 | 45 | /** Getter methods ************************************************************************************************/ 46 | 47 | 48 | /** 49 | * Gets the authorization code. 50 | * 51 | * @since 2.2.0 52 | * 53 | * @return string 54 | */ 55 | public function get_authorization_code() { 56 | 57 | return $this->get_payment() ? $this->get_payment()->getId() : ''; 58 | } 59 | 60 | 61 | /** 62 | * Gets the transaction (payment) ID. 63 | * 64 | * @since 2.2.0 65 | * 66 | * @return string 67 | */ 68 | public function get_transaction_id() { 69 | 70 | return $this->get_payment() ? $this->get_payment()->getId() : ''; 71 | } 72 | 73 | 74 | 75 | /** 76 | * Gets the location ID. 77 | * 78 | * @since 2.2.0 79 | * 80 | * @return string 81 | */ 82 | public function get_location_id() { 83 | 84 | return $this->get_payment() ? $this->get_payment()->getLocationId() : ''; 85 | } 86 | 87 | 88 | /** 89 | * Gets the Square order ID, if any. 90 | * 91 | * @since 2.2.0 92 | * 93 | * @return string 94 | */ 95 | public function get_square_order_id() { 96 | 97 | return $this->get_payment() ? $this->get_payment()->getOrderId() : ''; 98 | } 99 | 100 | 101 | /** 102 | * Gets the Square payment object. 103 | * 104 | * @since 2.2.0 105 | * 106 | * @return \Square\Models\Payment|null 107 | */ 108 | public function get_payment() { 109 | 110 | return ! $this->has_errors() && ! is_null( $this->get_data() ) && $this->get_data()->getPayment() ? $this->get_data()->getPayment() : null; 111 | } 112 | 113 | 114 | /** 115 | * Gets the message to display to the user. 116 | * 117 | * @since 2.0.0 118 | * 119 | * @return string 120 | */ 121 | public function get_user_message() { 122 | 123 | $error_codes = $this->get_status_codes(); 124 | 125 | $helper = new \WooCommerce\Square\Gateway\API\Response_Message_Helper(); 126 | 127 | return $helper->get_user_messages( $error_codes ); 128 | } 129 | 130 | /** 131 | * Returns if the card used is a Square Gift Card. 132 | * 133 | * @since 3.9.0 134 | * @return boolean 135 | */ 136 | public function is_gift_card_payment() { 137 | $payment = $this->get_payment(); 138 | $card_details = $payment->getCardDetails(); 139 | 140 | // If the card details are not available, we can't determine if it's a gift card. 141 | if ( ! $card_details ) { 142 | return false; 143 | } 144 | 145 | $card = $card_details->getCard(); 146 | 147 | return 'SQUARE_GIFT_CARD' === $card->getCardBrand(); 148 | } 149 | 150 | /** 151 | * Returns true if the payment status is completed. 152 | * 153 | * @since 4.5.0 154 | * @return boolean 155 | */ 156 | public function is_cash_app_payment_completed() { 157 | return $this->get_payment() && self::STATUS_COMPLETED === $this->get_payment()->getStatus(); 158 | } 159 | 160 | /** 161 | * Returns true if the payment status is approved. 162 | * 163 | * @since 4.6.0 164 | * @return boolean 165 | */ 166 | public function is_cash_app_payment_approved() { 167 | return $this->get_payment() && self::STATUS_APPROVED === $this->get_payment()->getStatus(); 168 | } 169 | 170 | /** No-op methods *************************************************************************************************/ 171 | 172 | public function get_avs_result() { } 173 | 174 | public function get_csc_result() { } 175 | 176 | public function csc_match() { } 177 | 178 | } 179 | -------------------------------------------------------------------------------- /includes/API/Request.php: -------------------------------------------------------------------------------- 1 | square_api; 68 | } 69 | 70 | 71 | /** 72 | * Get the method to call on the Square API instance. 73 | * 74 | * @since 2.0.0 75 | * 76 | * @return string 77 | */ 78 | public function get_square_api_method() { 79 | return $this->square_api_method; 80 | } 81 | 82 | 83 | /** 84 | * Gets the arguments to call the Square API method with. 85 | * 86 | * @since 2.0.0 87 | * 88 | * @return array 89 | */ 90 | public function get_square_api_args() { 91 | 92 | return $this->square_api_args; 93 | } 94 | 95 | 96 | /** 97 | * Returns whether this request is set to get HTTP info. 98 | * 99 | * @since 2.0.0 100 | * 101 | * @return bool 102 | */ 103 | public function get_with_http_info() { 104 | 105 | return $this->with_http_info; 106 | } 107 | 108 | 109 | /** 110 | * Gets the HTTP method. 111 | * 112 | * @since 2.0.0 113 | */ 114 | public function get_method() { 115 | // TODO: Implement get_method() method. 116 | } 117 | 118 | 119 | /** 120 | * Gets the query parameters. 121 | * 122 | * @since 2.0.0 123 | */ 124 | public function get_params() { 125 | // TODO: Implement get_params() method. 126 | } 127 | 128 | 129 | /** 130 | * Gets the path. 131 | * 132 | * @since 2.0.0 133 | */ 134 | public function get_path() { 135 | // TODO: Implement get_path() method. 136 | } 137 | 138 | 139 | /** 140 | * Gets the request data. 141 | * 142 | * @since 2.0.0 143 | */ 144 | public function get_data() { 145 | // TODO: Implement get_data() method. 146 | } 147 | 148 | 149 | /** 150 | * Gets the request data as a string. 151 | * 152 | * @since 2.0.0 153 | * 154 | * @return string 155 | */ 156 | public function to_string() { 157 | 158 | $body = ''; 159 | 160 | if ( is_callable( array( $this->square_request, '__toString' ) ) ) { 161 | 162 | $body = $this->square_request->__toString(); 163 | 164 | } elseif ( is_array( $this->square_api_args ) ) { 165 | 166 | $body = array(); 167 | 168 | foreach ( $this->square_api_args as $key => $arg ) { 169 | 170 | if ( is_callable( array( $arg, '__toString' ) ) ) { 171 | $body[ $key ] = $arg->__toString(); 172 | } elseif ( $arg instanceof \JsonSerializable ) { 173 | $body[ $key ] = wp_json_encode( $arg ); 174 | } 175 | } 176 | 177 | $body = implode( ',', $body ); 178 | } 179 | 180 | return $body; 181 | } 182 | 183 | 184 | /** 185 | * Gets the request data as a string with all sensitive information masked. 186 | * 187 | * @since 2.0.0 188 | * 189 | * @return string 190 | */ 191 | public function to_string_safe() { 192 | 193 | return $this->to_string(); 194 | } 195 | 196 | 197 | } 198 | -------------------------------------------------------------------------------- /includes/Handlers/Email.php: -------------------------------------------------------------------------------- 1 | mailer(); 65 | } 66 | } 67 | 68 | /** 69 | * Initializes Square email classes. 70 | * 71 | * @internal 72 | * 73 | * @since 2.0.0 74 | */ 75 | public function init_emails() { 76 | $this->init_mailer(); 77 | 78 | if ( null === $this->square_sync_completed ) { 79 | require_once WC_SQUARE_PLUGIN_PATH . 'includes/Emails/WC_Square_Sync_Completed.php'; 80 | $this->square_sync_completed = new \WC_Square_Sync_Completed(); 81 | } 82 | 83 | if ( null === $this->square_access_token_email ) { 84 | require_once WC_SQUARE_PLUGIN_PATH . 'includes/Emails/WC_Square_Access_Token_Email.php'; 85 | $this->square_access_token_email = new \WC_Square_Access_Token_Email(); 86 | } 87 | 88 | if ( null === $this->square_gift_card_sent ) { 89 | require_once WC_SQUARE_PLUGIN_PATH . 'includes/Emails/WC_Square_Gift_Card_Sent.php'; 90 | $this->square_gift_card_sent = new \WC_Square_Gift_Card_Sent(); 91 | } 92 | } 93 | 94 | /** 95 | * Adds WooCommerce Square email handlers. 96 | * 97 | * @internal 98 | * 99 | * @since 2.0.0 100 | * 101 | * @param \WC_Email[] $emails associative array of email IDs and objects 102 | * @return \WC_Email[] 103 | */ 104 | public function get_email_classes( $emails = array() ) { 105 | // init emails if uninitialized 106 | $this->init_emails(); 107 | 108 | if ( ! array_key_exists( 'Sync_Completed', $emails ) ) { 109 | $emails['WC_Square_Sync_Completed'] = $this->square_sync_completed; 110 | } 111 | 112 | if ( ! array_key_exists( 'Access_Token_Email', $emails ) ) { 113 | $emails['WC_Square_Access_Token_Email'] = $this->square_access_token_email; 114 | } 115 | 116 | if ( ! array_key_exists( 'WC_Square_Gift_Card_Sent', $emails ) ) { 117 | $emails['WC_Square_Gift_Card_Sent'] = $this->square_gift_card_sent; 118 | } 119 | 120 | return $emails; 121 | } 122 | 123 | /** 124 | * Gets the Square sync completed email instance. 125 | * 126 | * @since 2.0.0 127 | * 128 | * @return WC_Square_Sync_Completed 129 | */ 130 | public function get_sync_completed_email() { 131 | $this->init_emails(); 132 | return $this->square_sync_completed; 133 | } 134 | 135 | /** 136 | * Gets the Square access token email instance. 137 | * 138 | * @since 2.1.0 139 | * 140 | * @return WC_Square_Access_Token_Email 141 | */ 142 | public function get_access_token_email() { 143 | $this->init_emails(); 144 | return $this->square_access_token_email; 145 | } 146 | 147 | /** 148 | * Gets the Square Gift Card email sent instance. 149 | * 150 | * @since 4.2.0 151 | * 152 | * @return WC_Square_Gift_Card_Sent 153 | */ 154 | public function get_gift_card_sent() { 155 | $this->init_emails(); 156 | return $this->square_gift_card_sent; 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /includes/Emails/WC_Square_Access_Token_Email.php: -------------------------------------------------------------------------------- 1 | id = 'wc_square_access_token_email'; 49 | $this->customer_email = false; 50 | $this->title = __( 'Square Access Token Problems', 'woocommerce-square' ); 51 | $this->description = __( 'This email is sent when problems with Access Token are encountered', 'woocommerce-square' ); 52 | $this->subject = _x( '[WooCommerce] There was a problem with your Square Access Token', 'Email subject', 'woocommerce-square' ); 53 | $this->heading = _x( 'There was a problem with your Square Access Token', 'Email heading', 'woocommerce-square' ); 54 | $this->body = _x( 'Heads up! There may be a problem with your connection to Square.', 'Square connection problems email body.', 'woocommerce-square' ); 55 | 56 | $this->enabled_default = 'yes'; 57 | 58 | // call parent constructor 59 | parent::__construct(); 60 | 61 | // set default recipient 62 | $this->recipient = $this->get_option( 'recipient', get_option( 'admin_email' ) ); 63 | } 64 | 65 | /** 66 | * Triggers the email. 67 | * 68 | * @since 2.1.0 69 | */ 70 | public function trigger() { 71 | if ( ! $this->is_enabled() || ! $this->has_recipients() ) { 72 | return; 73 | } 74 | 75 | // send the email at most once a day 76 | $already_sent = get_transient( 'wc_square_access_token_email_sent' ); 77 | if ( false !== $already_sent ) { 78 | return; 79 | } 80 | set_transient( 'wc_square_access_token_email_sent', true, DAY_IN_SECONDS ); 81 | 82 | $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() ); 83 | } 84 | 85 | /** 86 | * Gets the arguments that should be passed to an email template. 87 | * 88 | * @since 2.1.0 89 | * 90 | * @param array $args optional associative array with additional arguments 91 | * @return array 92 | */ 93 | protected function get_template_args( $args = array() ) { 94 | $html = empty( $args['plain_text'] ); 95 | 96 | $email_body = $this->body; 97 | 98 | $square = wc_square(); 99 | $settings_url = $square->get_settings_url(); 100 | $logs_url = esc_url( admin_url( 'admin.php?page=wc-status&tab=logs' ) ); 101 | if ( $html ) { 102 | $email_body .= ' ' . sprintf( 103 | /* translators: Placeholders: %1$s - opening HTML link tag, %2$s - closing HTML link tag */ 104 | esc_html__( 'In order to continue accepting payments, please %1$sdisconnect and re-connect your site%2$s.', 'woocommerce-square' ), 105 | '', 106 | '' 107 | ); 108 | 109 | if ( $square->get_settings_handler()->is_debug_enabled() ) { 110 | $email_body .= '

' . sprintf( 111 | /* translators: Placeholders: %1$s - opening HTML link tag, %2$s - closing HTML link tag */ 112 | esc_html__( '%1$sInspect status logs%2$s', 'woocommerce-square' ), 113 | '', 114 | '' 115 | ); 116 | } 117 | } else { 118 | $email_body .= ' ' . esc_html__( 'In order to continue accepting payments, please disconnect and re-connect your site at ', 'woocommerce-square' ) . esc_url( $settings_url ); 119 | } 120 | 121 | return array_merge( 122 | $args, 123 | array( 124 | 'email' => $this, 125 | 'email_heading' => $this->heading, 126 | 'email_body' => $email_body, 127 | 'additional_content' => $this->get_additional_content(), 128 | ) 129 | ); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /includes/Admin/Rest/WC_REST_Square_Cash_App_Settings_Controller.php: -------------------------------------------------------------------------------- 1 | allowed_params = array( 47 | 'enabled', 48 | 'title', 49 | 'description', 50 | 'transaction_type', 51 | 'button_theme', 52 | 'charge_virtual_orders', 53 | 'enable_paid_capture', 54 | 'button_shape', 55 | ); 56 | 57 | add_action( 'rest_api_init', array( $this, 'register_routes' ) ); 58 | } 59 | 60 | /** 61 | * Register routes. 62 | */ 63 | public function register_routes() { 64 | register_rest_route( 65 | $this->namespace, 66 | '/' . $this->rest_base, 67 | array( 68 | 'methods' => WP_REST_Server::READABLE, 69 | 'callback' => array( $this, 'get_settings' ), 70 | 'permission_callback' => array( $this, 'check_permission' ), 71 | ) 72 | ); 73 | register_rest_route( 74 | $this->namespace, 75 | '/' . $this->rest_base, 76 | array( 77 | 'methods' => WP_REST_Server::EDITABLE, 78 | 'callback' => array( $this, 'save_settings' ), 79 | 'permission_callback' => array( $this, 'check_permission' ), 80 | 'args' => array( 81 | 'enabled' => array( 82 | 'description' => __( 'Enable Square payment gateway.', 'woocommerce-square' ), 83 | 'type' => 'string', 84 | 'sanitize_callback' => '', 85 | ), 86 | 'title' => array( 87 | 'description' => __( 'Square payment gateway title.', 'woocommerce-square' ), 88 | 'type' => 'string', 89 | 'sanitize_callback' => '', 90 | ), 91 | 'description' => array( 92 | 'description' => __( 'Square payment gateway description.', 'woocommerce-square' ), 93 | 'type' => 'string', 94 | 'sanitize_callback' => '', 95 | ), 96 | 'transaction_type' => array( 97 | 'description' => __( 'The transaction type.', 'woocommerce-square' ), 98 | 'type' => 'string', 99 | 'sanitize_callback' => '', 100 | ), 101 | 'charge_virtual_orders' => array( 102 | 'description' => __( 'If the order contains exclusively virtual items, enable this to immediately charge, rather than authorize, the transaction.', 'woocommerce-square' ), 103 | 'type' => 'string', 104 | 'sanitize_callback' => '', 105 | ), 106 | 'enable_paid_capture' => array( 107 | 'description' => __( 'Automatically capture orders when they are changed to Processing or Completed.', 'woocommerce-square' ), 108 | 'type' => 'string', 109 | 'sanitize_callback' => '', 110 | ), 111 | 'button_theme' => array( 112 | 'description' => __( 'Button Theme.', 'woocommerce-square' ), 113 | 'type' => 'string', 114 | 'sanitize_callback' => '', 115 | ), 116 | 'button_shape' => array( 117 | 'description' => __( 'Button Shape.', 'woocommerce-square' ), 118 | 'type' => 'string', 119 | 'sanitize_callback' => '', 120 | ), 121 | ), 122 | ) 123 | ); 124 | } 125 | 126 | /** 127 | * Get the data. 128 | * 129 | * @return WP_REST_Response 130 | */ 131 | public function get_settings() { 132 | $square_settings = get_option( self::SQUARE_CASH_APP_SETTINGS_OPTION_NAME, array() ); 133 | $filtered_settings = array_intersect_key( $square_settings, array_flip( $this->allowed_params ) ); 134 | 135 | return new WP_REST_Response( $filtered_settings ); 136 | } 137 | 138 | /** 139 | * Update the data. 140 | * 141 | * @param WP_REST_Request $request Full data about the request. 142 | */ 143 | public function save_settings( WP_REST_Request $request ) { 144 | $settings = array(); 145 | 146 | foreach ( $this->allowed_params as $index => $key ) { 147 | $new_value = wc_clean( wp_unslash( $request->get_param( $key ) ) ); 148 | 149 | $settings[ $key ] = $new_value; 150 | } 151 | 152 | update_option( self::SQUARE_CASH_APP_SETTINGS_OPTION_NAME, $settings ); 153 | wp_send_json_success(); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /includes/Utilities/String_Utility.php: -------------------------------------------------------------------------------- 1 | prefix}woocommerce_square_customers (square_id, email_address) VALUES "; 42 | 43 | foreach ( $customers as $customer ) { 44 | 45 | // skip any bad data 46 | if ( ! $customer instanceof \Square\Models\Customer ) { 47 | continue; 48 | } 49 | 50 | $placeholders[] = '(%s, %s)'; 51 | 52 | $values[] = wc_clean( $customer->getId() ); 53 | $values[] = wc_clean( $customer->getEmailAddress() ); 54 | } 55 | 56 | $query .= implode( ', ', $placeholders ); 57 | 58 | // update the Square ID value when duplicate email addresses are present 59 | $query .= " ON DUPLICATE KEY UPDATE email_address = VALUES(email_address)"; //phpcs:ignore Squiz.Strings.DoubleQuoteUsage.NotRequired 60 | 61 | $wpdb->query( $wpdb->prepare( $query, $values ) ); //phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared 62 | } 63 | 64 | 65 | /** 66 | * Adds a customer to the index. 67 | * 68 | * @since 2.0.0 69 | * 70 | * @param string $square_id Square customer ID 71 | * @param string $email_address customer email address 72 | * @param int $user_id WordPress user ID 73 | */ 74 | public static function add_customer( $square_id, $email_address, $user_id = 0 ) { 75 | global $wpdb; 76 | 77 | if ( is_email( $email_address ) ) { 78 | 79 | $params = array( 80 | 'square_id' => wc_clean( $square_id ), 81 | 'email_address' => wc_clean( $email_address ), 82 | ); 83 | 84 | if ( $user_id && is_numeric( $user_id ) ) { 85 | $params['user_id'] = (int) $user_id; 86 | } 87 | 88 | $wpdb->insert( 89 | "{$wpdb->prefix}woocommerce_square_customers", 90 | $params 91 | ); 92 | } 93 | } 94 | 95 | 96 | /** 97 | * Gets a Square customer ID from an email address. 98 | * 99 | * @param string $email_address customer email address 100 | * @return string|null 101 | */ 102 | public static function get_square_id( $email_address ) { 103 | global $wpdb; 104 | 105 | $square_id = null; 106 | 107 | if ( is_email( $email_address ) ) { 108 | 109 | $square_id = $wpdb->get_var( 110 | $wpdb->prepare( 111 | "SELECT square_id FROM {$wpdb->prefix}woocommerce_square_customers WHERE email_address = %s", 112 | $email_address 113 | ) 114 | ); 115 | } 116 | 117 | return $square_id; 118 | } 119 | 120 | 121 | public static function get_customers_by_email( $email_address ) { 122 | global $wpdb; 123 | 124 | $square_ids = array(); 125 | 126 | if ( is_email( $email_address ) ) { 127 | 128 | $square_ids = $wpdb->get_col( 129 | $wpdb->prepare( 130 | "SELECT square_id FROM {$wpdb->prefix}woocommerce_square_customers WHERE email_address = %s", 131 | $email_address 132 | ) 133 | ); 134 | } 135 | 136 | return $square_ids; 137 | } 138 | 139 | 140 | /** 141 | * Determines if a customer exists in the index. 142 | * 143 | * @since 2.0.0 144 | * 145 | * @param string $square_id Square customer ID 146 | * @return bool 147 | */ 148 | public static function is_customer_indexed( $square_id ) { 149 | global $wpdb; 150 | 151 | $result = $wpdb->get_var( 152 | $wpdb->prepare( 153 | "SELECT * FROM {$wpdb->prefix}woocommerce_square_customers WHERE square_id = %s", 154 | $square_id 155 | ) 156 | ); 157 | 158 | return (bool) $result; 159 | } 160 | 161 | 162 | /** 163 | * Creates the db table for the customer index. 164 | * 165 | * @since 2.0.0 166 | */ 167 | public static function create_table() { 168 | global $wpdb; 169 | 170 | $wpdb->hide_errors(); 171 | 172 | $collate = ''; 173 | 174 | if ( $wpdb->has_cap( 'collation' ) ) { 175 | $collate = $wpdb->get_charset_collate(); 176 | } 177 | 178 | $schema = $wpdb->prepare( "CREATE TABLE {$wpdb->prefix}woocommerce_square_customers (`square_id` varchar(191) NOT NULL, `email_address` varchar(200) NOT NULL, `user_id` BIGINT UNSIGNED NOT NULL, PRIMARY KEY (`square_id`) ) %1s", $collate ); //phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnquotedComplexPlaceholder 179 | 180 | require_once ABSPATH . 'wp-admin/includes/upgrade.php'; 181 | 182 | dbDelta( $schema ); 183 | } 184 | 185 | 186 | } 187 | -------------------------------------------------------------------------------- /includes/Sync/Job.php: -------------------------------------------------------------------------------- 1 | job = $job; 56 | } 57 | 58 | /** 59 | * Gets an attribute from the underlying job object. 60 | * 61 | * @since 2.0.0 62 | * 63 | * @param string $attr_name the attribute name 64 | * @param mixed $default_value value if attribute is not found 65 | * @return mixed 66 | */ 67 | protected function get_attr( $attr_name, $default_value = null ) { 68 | return isset( $this->job->$attr_name ) ? $this->job->$attr_name : $default_value; 69 | } 70 | 71 | 72 | /** 73 | * Sets an attribute on the underlying job object. 74 | * 75 | * @since 2.0.0 76 | * 77 | * @param string $attr_name the attribute name 78 | * @param mixed $attr_value the attribute value 79 | * @param bool $update whether to update the job object (defaults to true) 80 | */ 81 | protected function set_attr( $attr_name, $attr_value, $update = true ) { 82 | 83 | $this->job->$attr_name = $attr_value; 84 | 85 | if ( true === $update ) { 86 | wc_square()->get_background_job_handler()->update_job( $this->job ); 87 | } 88 | } 89 | 90 | 91 | /** 92 | * Checks if the job is currently locked. 93 | * 94 | * @since 2.0.0 95 | * 96 | * @return bool 97 | */ 98 | protected function is_job_locked() { 99 | 100 | return (bool) $this->get_attr( 'locked' ); 101 | } 102 | 103 | 104 | /** 105 | * Locks the job. 106 | * 107 | * @since 2.0.0 108 | */ 109 | protected function lock_job() { 110 | 111 | $this->set_attr( 'locked', true ); 112 | } 113 | 114 | 115 | /** 116 | * Unlocks the job. 117 | * 118 | * @since 2.0.0 119 | */ 120 | protected function unlock_job() { 121 | 122 | $this->set_attr( 'locked', false ); 123 | } 124 | 125 | 126 | /** 127 | * Executes the job. 128 | * 129 | * Child implementation should override this method with their own job processing logic. 130 | * 131 | * @since 2.0.0 132 | * 133 | * @return \stdClass the job object 134 | */ 135 | public function run() { 136 | wp_set_current_user( $this->get_attr( 'created_by' ) ); // phpcs:ignore Generic.PHP.ForbiddenFunctions.Discouraged -- required for background job processing 137 | 138 | if ( ! defined( 'DOING_SQUARE_SYNC' ) || false === DOING_SQUARE_SYNC ) { 139 | define( 'DOING_SQUARE_SYNC', true ); 140 | } 141 | 142 | return $this->job; 143 | } 144 | 145 | 146 | /** 147 | * Completes the job. 148 | * 149 | * @since 2.0.0 150 | * 151 | * @return \stdClass the job object 152 | */ 153 | protected function complete() { 154 | return $this->job = wc_square()->get_background_job_handler()->complete_job( $this->job ); 155 | } 156 | 157 | 158 | /** 159 | * Fails the job. 160 | * 161 | * @since 2.0.0 162 | * 163 | * @param string $reason failure reason message (optional) 164 | * @return \stdClass the job object 165 | */ 166 | protected function fail( $reason = '' ) { 167 | 168 | if ( ! empty( $reason ) ) { 169 | wc_square()->log( $reason ); 170 | } 171 | 172 | return $this->job = wc_square()->get_background_job_handler()->fail_job( $this->job, $reason ); 173 | } 174 | 175 | 176 | /** 177 | * Checks if this job uses WooCommerce as the SOR. 178 | * 179 | * @since 2.0.0 180 | * 181 | * @return bool 182 | */ 183 | public function is_system_of_record_woocommerce() { 184 | 185 | return 'woocommerce' === $this->get_attr( 'system_of_record' ); 186 | } 187 | 188 | 189 | /** 190 | * Checks if this is job uses square as the SOR. 191 | * 192 | * @since 2.0.0 193 | * 194 | * @return bool 195 | */ 196 | public function is_system_of_record_square() { 197 | 198 | return 'square' === $this->get_attr( 'system_of_record' ); 199 | } 200 | } 201 | -------------------------------------------------------------------------------- /includes/Framework/PaymentGateway/ApplePay/Api/Payment_Gateway_Apple_Pay_Api.php: -------------------------------------------------------------------------------- 1 | gateway = $gateway; 49 | 50 | $this->request_uri = 'https://apple-pay-gateway-cert.apple.com/paymentservices/startSession'; 51 | 52 | $this->set_request_content_type_header( 'application/json' ); 53 | $this->set_request_accept_header( 'application/json' ); 54 | $this->set_response_handler( '\\WooCommerce\\Square\\Framework\\PaymentGateway\\ApplePay\\Api\\Payment_Gateway_Apple_Pay_API_Response' ); 55 | } 56 | 57 | 58 | /** 59 | * Validates the Apple Pay merchant. 60 | * 61 | * @since 3.0.0 62 | * 63 | * @param string $url the validation URL 64 | * @param string $merchant_id the merchant ID to validate 65 | * @param string $domain_name the verified domain name 66 | * @param string $display_name the merchant display name 67 | * @return Payment_Gateway_Apple_Pay_API_Response the response object 68 | * @throws \Exception 69 | */ 70 | public function validate_merchant( $url, $merchant_id, $domain_name, $display_name ) { 71 | 72 | $this->request_uri = $url; 73 | 74 | $request = $this->get_new_request(); 75 | 76 | $request->set_merchant_data( $merchant_id, $domain_name, $display_name ); 77 | 78 | return $this->perform_request( $request ); 79 | } 80 | 81 | 82 | /** 83 | * Performs the request and return the parsed response. 84 | * 85 | * @since 3.0.0 86 | * 87 | * @param SquareFramework\Api\API_Request|object 88 | * @return SquareFramework\Api\API_Response|object 89 | * @throws \Exception 90 | */ 91 | protected function perform_request( $request ) { 92 | 93 | // set PEM file cert for requests 94 | add_action( 'http_api_curl', array( $this, 'set_cert_file' ) ); 95 | 96 | return parent::perform_request( $request ); 97 | } 98 | 99 | 100 | /** 101 | * Sets the PEM file required for authentication. 102 | * 103 | * @internal 104 | * 105 | * @since 3.0.0 106 | * 107 | * @param resource $curl_handle 108 | */ 109 | public function set_cert_file( $curl_handle ) { 110 | 111 | if ( ! $curl_handle ) { 112 | return; 113 | } 114 | 115 | curl_setopt( $curl_handle, CURLOPT_SSLCERT, get_option( 'sv_wc_apple_pay_cert_path' ) ); // phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt 116 | } 117 | 118 | 119 | /** Validation methods ****************************************************/ 120 | 121 | 122 | /** 123 | * Validates the post-parsed response. 124 | * 125 | * @since 3.0.0 126 | * 127 | * @return bool 128 | * 129 | * @throws \Exception 130 | */ 131 | protected function do_post_parse_response_validation() { 132 | 133 | $response = $this->get_response(); 134 | 135 | if ( $response->get_status_code() && 200 !== $response->get_status_code() ) { 136 | throw new \Exception( esc_html( $response->get_status_message() ) ); 137 | } 138 | 139 | return true; 140 | } 141 | 142 | 143 | /** Helper methods ********************************************************/ 144 | 145 | 146 | /** 147 | * Gets a new request object. 148 | * 149 | * @since 3.0.0 150 | * 151 | * @param array $type Optional. The desired request type 152 | * @return Payment_Gateway_Apple_Pay_API_Request the request object 153 | */ 154 | protected function get_new_request( $type = array() ) { 155 | 156 | return new Payment_Gateway_Apple_Pay_API_Request( $this->get_gateway() ); 157 | } 158 | 159 | 160 | /** 161 | * Gets the gateway instance. 162 | * 163 | * @since 3.0.0 164 | * 165 | * @return Payment_Gateway 166 | */ 167 | protected function get_gateway() { 168 | 169 | return $this->gateway; 170 | } 171 | 172 | 173 | /** 174 | * Gets the plugin instance. 175 | * 176 | * @since 3.0.0 177 | * 178 | * @return SquareFramework\PaymentGateway\Payment_Gateway_Plugin 179 | */ 180 | protected function get_plugin() { 181 | 182 | return $this->get_gateway()->get_plugin(); 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /includes/Gateway/API/Requests/Gift_Card_Activities.php: -------------------------------------------------------------------------------- 1 | square_api = $api_client->getGiftCardActivitiesApi(); 50 | $this->location_id = $location_id; 51 | } 52 | 53 | /** 54 | * Sets data required to activate a Gift card. 55 | * 56 | * @since 4.2.0 57 | * 58 | * @param string $gift_card_id The ID of the inactive Gift Card. 59 | * @param string $order_id Square Order ID associated with the Gift Card. 60 | * @param string $line_item_id Line Item ID for the Gift Card. 61 | */ 62 | public function set_activate_gift_card_data( $gift_card_id, $order_id, $line_item_id ) { 63 | $activate_activity_details = new \Square\Models\GiftCardActivityActivate(); 64 | $activate_activity_details->setOrderId( $order_id ); 65 | $activate_activity_details->setLineItemUid( $line_item_id ); 66 | 67 | $gift_card_activity = new \Square\Models\GiftCardActivity( 68 | \Square\Models\GiftCardActivityType::ACTIVATE, 69 | $this->location_id 70 | ); 71 | 72 | $gift_card_activity->setGiftCardId( $gift_card_id ); 73 | $gift_card_activity->setActivateActivityDetails( $activate_activity_details ); 74 | 75 | $this->square_request = new \Square\Models\CreateGiftCardActivityRequest( 76 | wc_square()->get_idempotency_key( $gift_card_id ), 77 | $gift_card_activity 78 | ); 79 | 80 | $this->square_api_method = 'createGiftCardActivity'; 81 | $this->square_api_args = array( $this->square_request ); 82 | } 83 | 84 | /** 85 | * Loads an existing gift card with an amount. 86 | * 87 | * @since 4.2.0 88 | * 89 | * @param string $gan The gift card number. 90 | * @param \WC_Order $order WooCommerce order. 91 | */ 92 | public function set_load_gift_card_data( $gan, $order ) { 93 | $gift_card_line_item_id = wc_square()->get_gateway( $order->get_payment_method() )->get_order_meta( $order, 'gift_card_line_item_id' ); 94 | $square_order_id = wc_square()->get_gateway( $order->get_payment_method() )->get_order_meta( $order, 'square_order_id' ); 95 | 96 | $load_activity_details = new \Square\Models\GiftCardActivityLoad(); 97 | $gift_card_activity = new \Square\Models\GiftCardActivity( 98 | \Square\Models\GiftCardActivityType::LOAD, 99 | wc_square()->get_settings_handler()->get_location_id() 100 | ); 101 | 102 | $load_activity_details->setOrderId( $square_order_id ); 103 | $load_activity_details->setLineItemUid( $gift_card_line_item_id ); 104 | 105 | $gift_card_activity->setGiftCardGan( $gan ); 106 | $gift_card_activity->setLoadActivityDetails( $load_activity_details ); 107 | 108 | $this->square_request = new \Square\Models\CreateGiftCardActivityRequest( 109 | wc_square()->get_idempotency_key( $order->unique_transaction_ref ), 110 | $gift_card_activity 111 | ); 112 | 113 | $this->square_api_method = 'createGiftCardActivity'; 114 | $this->square_api_args = array( $this->square_request ); 115 | } 116 | 117 | /** 118 | * Refunds/adjusts decrement when a Gift Card purchase/reload is refunded. 119 | * 120 | * @since 4.2.0 121 | * 122 | * @param string $gan Gift card number. 123 | * @param \Square\Models\Money $amount_money The amount to be refunded. 124 | * @param \WC_Order $order WooCommerce order. 125 | */ 126 | public function set_gift_card_refund_data( $gan, $amount_money, $order ) { 127 | $adjust_decrement_activity_details = new \Square\Models\GiftCardActivityAdjustDecrement( 128 | $amount_money, 129 | \Square\Models\GiftCardActivityAdjustDecrementReason::PURCHASE_WAS_REFUNDED 130 | ); 131 | 132 | $gift_card_activity = new \Square\Models\GiftCardActivity( 133 | \Square\Models\GiftCardActivityType::ADJUST_DECREMENT, 134 | $this->location_id 135 | ); 136 | 137 | $gift_card_activity->setGiftCardGan( $gan ); 138 | $gift_card_activity->setAdjustDecrementActivityDetails( $adjust_decrement_activity_details ); 139 | 140 | $this->square_request = new \Square\Models\CreateGiftCardActivityRequest( 141 | wc_square()->get_idempotency_key(), 142 | $gift_card_activity 143 | ); 144 | 145 | $this->square_api_method = 'createGiftCardActivity'; 146 | $this->square_api_args = array( $this->square_request ); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /includes/Framework/PaymentGateway/Payment_Gateway_My_Payment_Methods.php: -------------------------------------------------------------------------------- 1 | plugin = $plugin; 65 | 66 | add_filter( 'woocommerce_account_payment_methods_columns', array( $this, 'filter_payment_method_columns' ) ); 67 | add_action( 'woocommerce_account_payment_methods_column_method', array( $this, 'render_payment_method_method_data' ) ); 68 | add_action( 'woocommerce_account_payment_methods_column_details', array( $this, 'render_payment_method_details_data' ) ); 69 | } 70 | 71 | /** Payment Method actions ************************************************/ 72 | 73 | /** 74 | * Adds the details column next to method. 75 | * 76 | * @param array $columns Array of columns for payment methods. 77 | * @return array 78 | */ 79 | public function filter_payment_method_columns( $columns ) { 80 | $filtered_columns = array(); 81 | 82 | foreach ( $columns as $slug => $title ) { 83 | if ( 'method' === $slug ) { 84 | $filtered_columns[ $slug ] = $title; 85 | $filtered_columns['details'] = ' '; 86 | } else { 87 | $filtered_columns[ $slug ] = $title; 88 | } 89 | } 90 | 91 | return $filtered_columns; 92 | } 93 | 94 | /** 95 | * Renders the card brand. 96 | * 97 | * @param array $method Holds data about the payment method. 98 | */ 99 | public function render_payment_method_method_data( $method ) { 100 | echo esc_html( $method['method']['brand'] ); 101 | } 102 | 103 | /** 104 | * Renders card details. 105 | * 106 | * @param array $method Holds data about the payment method. 107 | */ 108 | public function render_payment_method_details_data( $method ) { 109 | $card_brand = $method['method']['brand']; 110 | $card_image_url = wc_square()->get_gateway()->get_payment_method_image_url( $card_brand ); 111 | ?> 112 | 113 | 114 | <?php echo esc_attr( $card_brand ); ?> 121 | 122 | • • • 123 | plugin; 149 | } 150 | 151 | 152 | /** 153 | * Returns true if at least one of the plugin's gateways supports the 154 | * add new payment method feature 155 | * 156 | * @since 3.0.0 157 | * @return bool 158 | */ 159 | protected function supports_add_payment_method() { 160 | 161 | foreach ( $this->get_plugin()->get_gateways() as $gateway ) { 162 | 163 | if ( $gateway->is_direct_gateway() && $gateway->supports_add_payment_method() ) { 164 | return true; 165 | } 166 | } 167 | 168 | return false; 169 | } 170 | 171 | 172 | /** 173 | * Determines if we're viewing the My Account -> Payment Methods page. 174 | * 175 | * @since 3.0.0 176 | * 177 | * @return bool 178 | */ 179 | protected function is_payment_methods_page() { 180 | global $wp; 181 | 182 | return is_user_logged_in() && is_account_page() && isset( $wp->query_vars['payment-methods'] ); 183 | } 184 | } 185 | --------------------------------------------------------------------------------