PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / trunk
WCPOS – Point of Sale (POS) plugin for WooCommerce vtrunk
1.10.15 1.10.13 1.10.14 1.10.12 1.10.11 1.10.10 1.10.9 1.10.8 untagged-3d9b7ccddc54df87c672 1.10.7 1.10.6 1.10.5 1.10.3 1.10.4 1.10.2 1.10.1 1.10.0 1.9.17 1.9.15 1.9.16 1.9.14 1.9.13 1.9.12 1.9.11 1.9.10 All 159 releases
woocommerce-pos / includes / Gateways / Card.php

Card.php in WCPOS – Point of Sale (POS) plugin for WooCommerce trunk, at includes/Gateways/Card.php

251 lines 7.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Provides a Card Payment Gateway.
4 *
5 * @author Paul Kilmurray <paul@kilbot.com>
6 *
7 * @see https://wcpos.com
8 *
9 * @package WCPOS\WooCommercePOS
10 */
11
12 namespace WCPOS\WooCommercePOS\Gateways;
13
14 use WC_Order;
15 use WCPOS\WooCommercePOS\Payments\Abstract_POS_Gateway;
16 use WP_REST_Request;
17
18 /**
19 * Card class.
20 */
21 class Card extends Abstract_POS_Gateway {
22 /**
23 * Constructor for the gateway.
24 */
25 public function __construct() {
26 $this->id = 'pos_card';
27 $this->title = /* translators: POS payment gateway label shown during checkout. */ __( 'Card', 'woocommerce-pos' );
28 $this->description = '';
29 $this->icon = apply_filters( 'woocommerce_pos_card_icon', '' );
30 $this->has_fields = true;
31 $this->enabled = 'no';
32 $this->supports = array( 'products', 'refunds' );
33
34 // Actions.
35 // @phpstan-ignore-next-line -- Action hook type mismatch.
36 add_action(
37 'woocommerce_pos_update_options_payment_gateways_' . $this->id,
38 array(
39 $this,
40 'process_admin_options',
41 )
42 );
43 add_action( 'woocommerce_thankyou_pos_card', array( $this, 'calculate_cashback' ) );
44 $this->register_pos_gateway_contract_hooks();
45 }
46
47 /**
48 * Display the payment fields in the checkout.
49 */
50 public function payment_fields(): void {
51 if ( $this->description ) {
52 echo '<p>' . wp_kses_post( $this->description ) . '</p>';
53 }
54
55 $currency_pos = get_option( 'woocommerce_currency_pos' );
56
57 if ( 'left' == $currency_pos || 'left_space' == $currency_pos ) {
58 $left_addon = '<span class="input-group-addon">' . get_woocommerce_currency_symbol( get_woocommerce_currency() ) . '</span>';
59 $right_addon = '';
60 } else {
61 $left_addon = '';
62 $right_addon = '<span class="input-group-addon">' . get_woocommerce_currency_symbol( get_woocommerce_currency() ) . '</span>';
63 }
64
65 echo '
66 <div class="form-row " id="pos-cashback_field">
67 <label for="pos-cashback" class="">' . /* translators: POS payment gateway label shown during checkout. */ esc_html__( 'Cashback', 'woocommerce-pos' ) . '</label>
68 <div class="input-group">
69 ' . wp_kses_post( $left_addon ) . '
70 <input type="text" class="form-control" name="pos-cashback" id="pos-cashback" placeholder="" maxlength="20" data-value="0" data-numpad="cash" data-label="' . /* translators: POS payment gateway label shown during checkout. */ esc_attr__( 'Cashback', 'woocommerce-pos' ) . '">
71 ' . wp_kses_post( $right_addon ) . '
72 </div>';
73 wp_nonce_field( 'pos_card_payment_nonce', 'pos_card_payment_nonce_field' );
74 echo '
75 </div>
76 ';
77 }
78
79 /**
80 * Process the payment.
81 *
82 * @param int $order_id Order ID.
83 *
84 * @return array
85 */
86 public function process_payment( $order_id ) {
87 // Check nonce.
88 if ( ! isset( $_POST['pos_card_payment_nonce_field'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['pos_card_payment_nonce_field'] ) ), 'pos_card_payment_nonce' ) ) {
89 wp_die( /* translators: Checkout error shown when card nonce validation fails. */ esc_html__( 'Nonce verification failed', 'woocommerce-pos' ) );
90 }
91
92 // get order object.
93 $order = wc_get_order( $order_id );
94
95 $cashback = 0; // Initialize with default value.
96 if ( isset( $_POST['pos-cashback'] ) && ! empty( $_POST['pos-cashback'] ) ) {
97 $cashback = wc_format_decimal( sanitize_text_field( wp_unslash( $_POST['pos-cashback'] ) ) );
98 }
99
100 $result = $this->apply_card_payment( $order, $cashback );
101 if ( is_wp_error( $result ) ) {
102 wc_add_notice( $result->get_error_message(), 'error' );
103
104 return array(
105 'result' => 'failure',
106 'redirect' => '',
107 );
108 }
109
110 // success.
111 return array(
112 'result' => 'success',
113 'redirect' => $this->get_return_url( $order ),
114 );
115 }
116
117 /**
118 * Process a refund.
119 *
120 * Card refunds are handled manually, so just return true.
121 *
122 * @param int $order_id Order ID.
123 * @param float|null $amount Refund amount.
124 * @param string $reason Refund reason.
125 *
126 * @return bool
127 */
128 public function process_refund( $order_id, $amount = null, $reason = '' ) {
129 return true;
130 }
131
132 /**
133 * Calculate and display cashback.
134 *
135 * @param int $order_id Order ID.
136 */
137 public function calculate_cashback( $order_id ): void {
138 $message = '';
139 $order = wc_get_order( $order_id );
140 if ( ! $order ) {
141 return;
142 }
143
144 $cashback = $order->get_meta( '_pos_card_cashback' );
145
146 // construct message.
147 if ( $cashback ) {
148 $message = /* translators: POS payment gateway label shown during checkout. */ __( 'Cashback', 'woocommerce-pos' ) . ': ';
149 $message .= wc_price( $cashback, array( 'currency' => $order->get_currency() ) );
150 }
151
152 echo wp_kses_post( $message );
153 }
154
155 /**
156 * Provider family identifier.
157 *
158 * @param WP_REST_Request|null $request Request object.
159 */
160 public function get_pos_provider( ?WP_REST_Request $request = null ): string {
161 return 'wcpos';
162 }
163
164 /**
165 * Process a POS checkout action for card.
166 *
167 * @param array $state Checkout state.
168 * @param string $action Checkout action.
169 * @param array $payment_data Payment data.
170 * @param WC_Order $order Order object.
171 * @param WP_REST_Request|null $request Request object.
172 *
173 * @return array|\WP_Error
174 */
175 public function process_pos_checkout_action( array $state, string $action, array $payment_data, WC_Order $order, ?WP_REST_Request $request = null ) {
176 if ( 'cancel' === $action ) {
177 $state['status'] = 'cancelled';
178 return $state;
179 }
180
181 if ( 'start' !== $action ) {
182 return $state;
183 }
184
185 $cashback = isset( $payment_data['cashback_amount'] ) && '' !== $payment_data['cashback_amount']
186 ? wc_format_decimal( $payment_data['cashback_amount'] )
187 : 0;
188
189 $result = $this->apply_card_payment( $order, $cashback );
190 if ( is_wp_error( $result ) ) {
191 return $result;
192 }
193
194 $state['status'] = 'completed';
195 $state['provider_data'] = array(
196 'cashback' => $order->get_meta( '_pos_card_cashback' ),
197 );
198
199 return $state;
200 }
201
202 /**
203 * Apply card payment changes to an order.
204 *
205 * @param \WC_Order $order Order object.
206 * @param float|int|string $cashback Cashback amount.
207 *
208 * @return true|\WP_Error
209 */
210 private function apply_card_payment( $order, $cashback ) {
211 $cashback = wc_format_decimal( $cashback );
212
213 if ( (float) $cashback < 0 ) {
214 return new \WP_Error(
215 'wcpos_invalid_cashback_amount',
216 __( 'Cashback amount must be zero or greater.', 'woocommerce-pos' ),
217 array( 'status' => 400 )
218 );
219 }
220
221 $order->set_payment_method( $this->id );
222 $order->set_payment_method_title( $this->title );
223
224 if ( 0 !== $cashback && '0' !== (string) $cashback ) {
225 $order->update_meta_data( '_pos_card_cashback', $cashback );
226
227 $item_id = wc_add_order_item(
228 $order->get_id(),
229 array(
230 'order_item_name' => /* translators: Fee line-item name for cashback charged on card payment. */ __( 'Cashback', 'woocommerce-pos' ),
231 'order_item_type' => 'fee',
232 )
233 );
234
235 if ( $item_id ) {
236 wc_add_order_item_meta( $item_id, '_line_total', $cashback );
237 wc_add_order_item_meta( $item_id, '_line_tax', 0 );
238 wc_add_order_item_meta( $item_id, '_line_subtotal', $cashback );
239 wc_add_order_item_meta( $item_id, '_line_subtotal_tax', 0 );
240 wc_add_order_item_meta( $item_id, '_tax_class', 'zero-rate' );
241 }
242
243 $order->set_total( wc_format_decimal( \floatval( $order->get_total() ) + \floatval( $cashback ) ) );
244 }
245
246 $order->payment_complete();
247
248 return true;
249 }
250 }
251