PluginProbe
PayPlug for WooCommerce (Official) / 3.1.0
PayPlug for WooCommerce (Official) v3.1.0
3.1.0 3.0.0 2.18.0 1.0.17 1.0.18 1.0.19 1.0.20 1.0.21 1.0.22 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.1.0 1.10.0 1.10.1 1.2.1 1.2.10 1.2.11 1.2.2 1.2.3 1.2.4 1.2.5 All 102 releases
← All changes | src/Gateway/PayplugResponse.php +436 -373 1.10.1 → 3.1.0 View file →
@@ -2,408 +2,471 @@
2 2
3 3 namespace Payplug\PayplugWoocommerce\Gateway;
4 4
5 5 // Exit if accessed directly
6 -if ( ! defined( 'ABSPATH' ) ) {
7 - exit;
6 +if (!defined('ABSPATH')) {
7 + exit;
8 8 }
9 9
10 +use Automattic\WooCommerce\Utilities\OrderUtil;
10 11 use Payplug\PayplugWoocommerce\PayplugWoocommerceHelper;
11 12 use Payplug\Resource\IVerifiableAPIResource;
12 13 use Payplug\Resource\Payment as PaymentResource;
13 14 use Payplug\Resource\Refund as RefundResource;
15 +use WC_Payment_Token_CC;
14 16 use WC_Payment_Tokens;
15 -use WC_Payment_Token_CC;
16 17
17 18 /**
18 19 * Process responses from PayPlug.
19 - *
20 - * @package Payplug\PayplugWoocommerce\Gateway
21 20 */
22 -class PayplugResponse {
21 +class PayplugResponse
22 +{
23 + private $gateway;
23 24
24 - private $gateway;
25 + public function __construct(PayplugGateway $gateway)
26 + {
27 + $this->gateway = $gateway;
28 + }
25 29
26 - public function __construct( PayplugGateway $gateway ) {
27 - $this->gateway = $gateway;
28 - }
30 + /**
31 + * Process payment.
32 + *
33 + * @param $resource
34 + * @param $is_payment_with_token
35 + *
36 + * @throws \WC_Data_Exception
37 + *
38 + * @return void
39 + */
40 + public function process_payment($resource, $is_payment_with_token = false, $source = ''): void
41 + {
42 + $order_id = wc_clean($resource->metadata['order_id']);
29 43
30 - /**
31 - * Process payment.
32 - *
33 - * @param $resource
34 - * @param $is_payment_with_token
35 - *
36 - * @return void
37 - * @throws \WC_Data_Exception
38 - */
39 - public function process_payment($resource, $is_payment_with_token = false, $source = null)
40 - {
41 - $order_id = wc_clean($resource->metadata['order_id']);
42 - $order = wc_get_order($order_id);
43 - $gateway_id = $order->get_payment_method();
44 - $metadata = PayplugWoocommerceHelper::extract_transaction_metadata($resource);
44 + $order = wc_get_order($order_id);
45 + $gateway_id = $order->get_payment_method();
46 + $metadata = PayplugWoocommerceHelper::extract_transaction_metadata($resource);
45 47
48 + // Ignore undefined orders
49 + if (!$order) {
50 + PayplugGateway::log(sprintf('Coudn\'t find order #%s (Transaction %s).', $order_id, wc_clean($resource->id)), 'error');
46 51
47 - // Ignore undefined orders
48 - if (!$order) {
49 - PayplugGateway::log(sprintf('Coudn\'t find order #%s (Transaction %s).', $order_id, wc_clean($resource->id)), 'error');
50 - return;
51 - }
52 + return;
53 + }
52 54
53 - /**
54 - *
55 - * Checking if it is coming from the order confirmation page or the IPN
56 - *
57 - */
55 + /**
56 + * Checking if it is coming from the order confirmation page or the IPN
57 + */
58 + if (($gateway_id == $this->gateway->id) || (!empty($source) && ($source === 'ipn'))) {
59 + // Ignore cancelled orders
60 + if ($order->has_status('refunded')) {
61 + PayplugGateway::log(sprintf('Order #%s : ' . $this->gateway_name($gateway_id) . ' order has been refunded. Ignoring IPN', $order_id));
58 62
59 - if (($gateway_id == $this->gateway->id) || (!empty($source) && ($source === "ipn"))) {
63 + return;
64 + }
65 + $paid_date = $order->get_date_paid();
66 + if (isset($paid_date) && !$order->is_paid()) {
67 + $finished_status = wc_get_is_paid_statuses();
68 + $order->set_status($finished_status[0]);
69 + }
60 70
61 - // Ignore cancelled orders
62 - if ($order->has_status('refunded')) {
63 - PayplugGateway::log(sprintf('Order #%s : '. $this->gateway_name($gateway_id) .' order has been refunded. Ignoring IPN', $order_id));
64 - return;
65 - }
71 + // Ignore paid orders
72 + if ($order->is_paid()) {
73 + PayplugGateway::log(sprintf('Order #%s : ' . $this->gateway_name($gateway_id) . ' order is already complete. Ignoring IPN. "' . !empty($source) ? '[IPN]' : '' . '"', $order_id));
66 74
67 - // Ignore paid orders
68 - if ($order->is_paid()) {
69 - PayplugGateway::log(sprintf('Order #%s : '. $this->gateway_name($gateway_id) .' order is already complete. Ignoring IPN.', $order_id));
70 - return;
71 - }
75 + return;
76 + }
72 77
73 - // Handle failed payments
74 - if (!empty($resource->failure)) {
75 - PayplugWoocommerceHelper::set_flag_ipn_order($order, $metadata, true);
76 - $order->update_status(
77 - 'failed',
78 - sprintf(__('PayPlug IPN OK | Transaction %s failed : %s', 'payplug'), $resource->id, wc_clean($resource->failure->message))
79 - );
80 - /** This action is documented in src/Gateway/PayplugResponse */
81 - \do_action('payplug_gateway_payment_response_processed', $order_id, $resource);
82 - PayplugWoocommerceHelper::set_flag_ipn_order($order, $metadata, false);
83 - PayplugGateway::log(sprintf('Order #%s : '. $this->gateway_name($gateway_id) .' payment IPN %s processing completed but failed.', $order_id, $resource->id));
84 - return;
85 - }
78 + // Handle failed payments
79 + if (!empty($resource->failure)) {
80 + if ($order->get_status() != 'failed') {
81 + $order->update_status('failed', sprintf(__('PayPlug %s OK | Transaction %s failed : %s', 'payplug'), strtoupper($source), $resource->id, wc_clean($resource->failure->message)));
82 + }
86 83
87 - // Save Logs of the payment for the different payment gateways:
88 - // For Oney 4 gateways & Bancontact gateway: "$resource->payment_method" exists and is an array
89 - // but not for Payplug credit card gateway (in this case we check the payment_method from the order itself not the $resource)
90 - if (isset($resource->payment_method) && is_array($resource->payment_method)) {
91 - $gateway_id = $resource->payment_method['type'];
84 + /** This action is documented in src/Gateway/PayplugResponse */
85 + \do_action('payplug_gateway_payment_response_processed', $order_id, $resource);
86 + PayplugWoocommerceHelper::set_flag_ipn_order($order, $metadata, false);
87 + PayplugGateway::log(sprintf('Order #%s : ' . $this->gateway_name($gateway_id) . ' payment IPN %s processing completed but failed.', $order_id, $resource->id));
88 + wc_increase_stock_levels($order);
92 89
93 - switch ($gateway_id) {
94 - case substr( $gateway_id, 0, 5 ) === "oney_" :
95 - $this->oney_ipn($resource);
96 - break;
97 - case "bancontact" :
98 - $this->bancontact_ipn($resource);
99 - break;
100 - case "apple_pay" :
101 - $this->apple_pay_ipn($resource);
102 - break;
103 - case "american_express" :
104 - $this->amex_ipn($resource);
105 - break;
106 - }
90 + return;
91 + } elseif (($resource->failure == null) && !empty($resource->payment_method['is_pending'])
92 + && ($resource->payment_method['is_pending'] == true)) {
93 + $this->handle_pending_oney($order, $resource, $source);
94 + }
107 95
108 - } elseif ($gateway_id == "payplug") {
109 - $this->payplug_ipn($resource);
110 - }
96 + // Save Logs of the payment for the different payment gateways:
97 + // For Oney 4 gateways & Bancontact gateway: "$resource->payment_method" exists and is an array
98 + // but not for Payplug credit card gateway (in this case we check the payment_method from the order itself not the $resource)
99 + if (isset($resource->payment_method) && is_array($resource->payment_method)) {
100 + $gateway_id = $resource->payment_method['type'];
111 101
112 - // Handle successful payments
113 - if ($resource->is_paid) {
114 - PayplugWoocommerceHelper::set_flag_ipn_order($order, $metadata, true);
115 - if (!$is_payment_with_token) {
116 - $this->maybe_save_card($resource);
117 - }
118 - $this->maybe_save_address_hash($resource);
119 - $order->add_order_note(sprintf(__('PayPlug IPN OK | Transaction %s', 'payplug'), wc_clean($resource->id)));
120 - $order->payment_complete(wc_clean($resource->id));
121 - if (PayplugWoocommerceHelper::is_pre_30()) {
122 - $order->reduce_order_stock();
123 - }
124 - /**
125 - * Fires once a payment response has been processed.
126 - *
127 - * @param int $order_id Order ID
128 - * @param PaymentResource $resource Payment resource
129 - */
130 - \do_action('payplug_gateway_payment_response_processed', $order_id, $resource);
131 - PayplugWoocommerceHelper::set_flag_ipn_order($order, $metadata, false);
132 - PayplugGateway::log(sprintf('Order #%s : '. $this->gateway_name($gateway_id) .' payment IPN %s processing completed successfully.', $order_id, $resource->id));
133 - }
134 - }
135 - }
102 + switch ($gateway_id) {
103 + case 'oney_' === substr($gateway_id, 0, 5):
104 + $this->oney_ipn($resource);
105 + break;
106 + case 'bancontact':
107 + $this->bancontact_ipn($resource, $source);
108 + break;
109 + case 'apple_pay':
110 + $this->apple_pay_ipn($resource, $source);
111 + break;
112 + case 'american_express':
113 + $this->amex_ipn($resource, $source);
114 + break;
115 + }
116 + } elseif ('payplug' == $gateway_id) {
117 + if (!$is_payment_with_token) {
118 + $this->payplug_ipn($resource, $source);
119 + }
120 + }
136 121
137 - /**
138 - * Payplug IPN
139 - *
140 - * @param $resource
141 - */
142 - public function payplug_ipn($resource) {
143 - $order_id = wc_clean( $resource->metadata['order_id'] );
144 - PayplugGateway::log( sprintf( 'Order #%s : Begin processing Payplug payment IPN %s', $order_id, $resource->id ) );
145 - }
122 + // Handle successful payments
123 + if ($resource->is_paid) {
124 + if (!$is_payment_with_token) {
125 + $this->maybe_save_card($resource);
126 + }
127 + $this->maybe_save_address_hash($resource);
128 + $order->add_order_note(sprintf(__('PayPlug %s OK | Transaction %s', 'payplug'), strtoupper($source), wc_clean($resource->id)));
129 + $order->payment_complete(wc_clean($resource->id));
130 + if (PayplugWoocommerceHelper::is_pre_30()) {
131 + $order->reduce_order_stock();
132 + }
133 + /**
134 + * Fires once a payment response has been processed.
135 + *
136 + * @param int $order_id Order ID
137 + * @param PaymentResource $resource Payment resource
138 + */
139 + \do_action('payplug_gateway_payment_response_processed', $order_id, $resource);
140 + PayplugWoocommerceHelper::set_flag_ipn_order($order, $metadata, false);
141 + PayplugGateway::log(sprintf('Order #%s : ' . $this->gateway_name($gateway_id) . ' payment %s %s processing completed successfully.', strtoupper($source), $order_id, $resource->id));
142 + }
143 + }
144 + }
146 145
147 - /**
148 - * Bancontact IPN
149 - *
150 - * @param $resource
151 - */
152 - public function bancontact_ipn($resource) {
153 - $order_id = wc_clean( $resource->metadata['order_id'] );
154 - PayplugGateway::log( sprintf( 'Order #%s : Begin processing Bancontact payment IPN %s', $order_id, $resource->id ) );
155 - }
146 + /**
147 + * Handle pending oney payments orders
148 + *
149 + * @param $order
150 + * @param $resource
151 + *
152 + * @return void
153 + */
154 + public function handle_pending_oney($order, $resource, $source): void
155 + {
156 + $order->add_order_note(sprintf(__('PayPlug %s OK | Transaction %s | Payment PENDING to be checked by an Oney agent', 'payplug'), strtoupper($source), wc_clean($resource->id)));
157 + wc_reduce_stock_levels($order);
158 + }
156 159
157 - /**
158 - * Apple Pay IPN
159 - *
160 - * @param $resource
161 - */
162 - public function apple_pay_ipn($resource) {
163 - $order_id = wc_clean( $resource->metadata['order_id'] );
164 - PayplugGateway::log( sprintf( 'Order #%s : Begin processing Apple Pay payment IPN %s', $order_id, $resource->id ) );
165 - }
160 + /**
161 + * Payplug IPN
162 + *
163 + * @param $resource
164 + */
165 + public function payplug_ipn($resource, $source): void
166 + {
167 + $order_id = wc_clean($resource->metadata['order_id']);
168 + PayplugGateway::log(sprintf('Order #%s : Begin processing Payplug payment %s %s', $order_id, strtoupper($source), $resource->id));
169 + }
166 170
167 - /**
168 - * American Express IPN
169 - *
170 - * @param $resource
171 - */
172 - public function amex_ipn($resource) {
173 - $order_id = wc_clean( $resource->metadata['order_id'] );
174 - PayplugGateway::log( sprintf( 'Order #%s : Begin processing Amex payment IPN %s', $order_id, $resource->id ) );
175 - }
171 + /**
172 + * Bancontact IPN
173 + *
174 + * @param $resource
175 + */
176 + public function bancontact_ipn($resource, $source): void
177 + {
178 + $order_id = wc_clean($resource->metadata['order_id']);
179 + PayplugGateway::log(sprintf('Order #%s : Begin processing Bancontact payment %s %s', $order_id, strtoupper($source), $resource->id));
180 + }
176 181
177 - /**
178 - * Oney IPN
179 - *
180 - * @param $resource
181 - */
182 - public function oney_ipn( $resource ) {
183 - $gateway_id = $resource->payment_method['type'];
184 - $order_id = wc_clean( $resource->metadata['order_id'] );
185 - $order = wc_get_order( $order_id );
186 - $order_metadata = $order->get_meta( '_payplug_metadata', true );
182 + /**
183 + * Apple Pay IPN
184 + *
185 + * @param $resource
186 + */
187 + public function apple_pay_ipn($resource, $source): void
188 + {
189 + $order_id = wc_clean($resource->metadata['order_id']);
190 + PayplugGateway::log(sprintf('Order #%s : Begin processing Apple Pay payment %s %s', $order_id, strtoupper($source), $resource->id));
191 + }
187 192
188 - if ( is_array( $order_metadata ) && array_key_exists( 'transaction_in_progress', $order_metadata ) ) {
189 - PayplugGateway::log( sprintf( 'Order #%s : Order '. $this->gateway_name($gateway_id) .' IPN already in progress. Ignoring IPN', $order_id ) );
190 - return;
191 - }
193 + /**
194 + * American Express IPN
195 + *
196 + * @param $resource
197 + */
198 + public function amex_ipn($resource, $source): void
199 + {
200 + $order_id = wc_clean($resource->metadata['order_id']);
201 + PayplugGateway::log(sprintf('Order #%s : Begin processing Amex payment %s %s', $order_id, strtoupper($source), $resource->id));
202 + }
192 203
193 - if ( ( $resource->is_paid == true ) && ( $resource->failure == null ) ) {
194 - PayplugGateway::log( sprintf( 'Order #%s : '. $this->gateway_name($gateway_id) .' payment SUCCESS', $order_id ) );
195 - }
204 + /**
205 + * Oney IPN
206 + *
207 + * @param $resource
208 + */
209 + public function oney_ipn($resource): void
210 + {
211 + $gateway_id = $resource->payment_method['type'];
212 + $order_id = wc_clean($resource->metadata['order_id']);
196 213
197 - if ( ( $resource->is_paid == false ) && ( $resource->failure != null ) ) {
198 - PayplugGateway::log( sprintf( 'Order #%s : '. $this->gateway_name($gateway_id) .' payment FAILED', $order_id ) );
199 - }
214 + if (($resource->is_paid == true) && ($resource->failure == null)) {
215 + PayplugGateway::log(sprintf('Order #%s : ' . $this->gateway_name($gateway_id) . ' payment SUCCESS', $order_id));
216 + }
200 217
201 - if ( ( $resource->is_paid == false ) && ( $resource->failure == null ) && ( $resource->payment_method['is_pending'] == true ) ) {
202 - PayplugGateway::log( sprintf( 'Order #%s : '. $this->gateway_name($gateway_id) .' payment PENDING and checked by an Oney agent', $order_id ) );
203 - }
204 - }
218 + if (($resource->is_paid == false) && ($resource->failure != null)) {
219 + PayplugGateway::log(sprintf('Order #%s : ' . $this->gateway_name($gateway_id) . ' payment FAILED', $order_id));
220 + }
205 221
206 - /**
207 - * Get the gateway name from the gateway_id
208 - *
209 - * @param $gateway_id
210 - */
211 - private function gateway_name($gateway_id){
212 - return ucwords(str_replace("_", " ", $gateway_id));
213 - }
222 + if (($resource->is_paid == false) && ($resource->failure == null) && ($resource->payment_method['is_pending'] == true)) {
223 + PayplugGateway::log(sprintf('Order #%s : ' . $this->gateway_name($gateway_id) . ' payment PENDING and checked by an Oney agent', $order_id));
224 + }
225 + }
214 226
215 - /**
216 - * Process refund.
217 - *
218 - * @param $resource
219 - * @param bool $ignore_woocommerce_refund Flag to determine if IPN notification for refunds created by WooCommerce
220 - * should be ignored or not. Default to true.
221 - *
222 - * @throws \Exception
223 - */
224 - public function process_refund( $resource, $ignore_woocommerce_refund = true ) {
225 - $refund_id = wc_clean( $resource->id );
226 - $transaction_id = wc_clean( $resource->payment_id );
227 - $order = $this->get_order_from_transaction_id( $transaction_id );
228 - if ( ! $order ) {
229 - PayplugGateway::log( sprintf( 'Coudn\'t find order for transaction %s (Refund %s).', wc_clean( $resource->payment_id ), wc_clean( $resource->id ) ), 'error' );
227 + /**
228 + * Get the gateway name from the gateway_id
229 + *
230 + * @param $gateway_id
231 + */
232 + private function gateway_name($gateway_id)
233 + {
234 + return ucwords(str_replace('_', ' ', $gateway_id));
235 + }
230 236
231 - return;
232 - }
233 - $order_id = PayplugWoocommerceHelper::is_pre_30() ? $order->id : $order->get_id();
237 + /**
238 + * Process refund.
239 + *
240 + * @param $resource
241 + * @param bool $ignore_woocommerce_refund Flag to determine if IPN notification for refunds created by WooCommerce
242 + * should be ignored or not. Default to true.
243 + *
244 + * @throws \Exception
245 + */
246 + public function process_refund($resource, $ignore_woocommerce_refund = true): void
247 + {
248 + $refund_id = wc_clean($resource->id);
249 + $transaction_id = wc_clean($resource->payment_id);
250 + $order = $this->get_order_from_transaction_id($transaction_id);
251 + if (!$order) {
252 + PayplugGateway::log(sprintf('Coudn\'t find order for transaction %s (Refund %s).', wc_clean($resource->payment_id), wc_clean($resource->id)), 'error');
234 253
235 - PayplugGateway::log( sprintf( 'Order #%s : Begin processing refund IPN %s', $order_id, $resource->id ) );
254 + return;
255 + }
256 + $order_id = PayplugWoocommerceHelper::is_pre_30() ? $order->id : $order->get_id();
236 257
237 - $refund_exist = $this->refund_exist_for_order( $order_id, $refund_id );
238 - if ( $refund_exist ) {
239 - PayplugGateway::log( sprintf( 'Order #%s : Refund has already been processed. Ignoring IPN.', $order_id ) );
258 + PayplugGateway::log(sprintf('Order #%s : Begin processing refund IPN %s', $order_id, $resource->id));
240 259
241 - return;
242 - }
260 + $refund_exist = $this->refund_exist_for_order($order_id, $refund_id);
261 + if ($refund_exist) {
262 + PayplugGateway::log(sprintf('Order #%s : Refund has already been processed. Ignoring IPN.', $order_id));
243 263
244 - // Since refund notification doesn't contain the full resource, we need to retrieve
245 - // the refund resource to access its metadata.
246 - try {
247 - $refund = $this->gateway->api->refund_retrieve( $transaction_id, $refund_id );
248 - } catch ( \Exception $e ) {
249 - PayplugGateway::log( sprintf( 'Order #%s : Fail to retrieve refund data with error %s', $order_id, $e->getMessage() ) );
264 + return;
265 + }
250 266
251 - return;
252 - }
267 + // Since refund notification doesn't contain the full resource, we need to retrieve
268 + // the refund resource to access its metadata.
269 + try {
270 + $refund = $this->gateway->payplug_api->refund_retrieve($transaction_id, $refund_id);
271 + } catch (\Exception $e) {
272 + PayplugGateway::log(sprintf('Order #%s : Fail to retrieve refund data with error %s', $order_id, $e->getMessage()));
253 273
254 - if (
255 - $ignore_woocommerce_refund
256 - && isset( $refund->metadata['refund_from'] )
257 - && 'woocommerce' === $refund->metadata['refund_from']
258 - ) {
259 - PayplugGateway::log( sprintf( 'Order #%s : Refund created by WooCommerce. Ignoring IPN.', $order_id ) );
274 + return;
275 + }
260 276
261 - return;
262 - }
277 + if (
278 + $ignore_woocommerce_refund
279 + && isset($refund->metadata['refund_from'])
280 + && 'woocommerce' === $refund->metadata['refund_from']
281 + ) {
282 + PayplugGateway::log(sprintf('Order #%s : Refund created by WooCommerce. Ignoring IPN.', $order_id));
263 283
264 - $refund = wc_create_refund( [
265 - 'amount' => ( (int) $resource->amount ) / 100,
266 - 'reason' => isset( $resource->metadata['reason'] ) ? $resource->metadata['reason'] : null,
267 - 'order_id' => (int) $order_id,
268 - 'refund_id' => 0,
269 - 'refund_payment' => false,
270 - ] );
271 - if ( is_wp_error( $refund ) ) {
272 - PayplugGateway::log( $refund->get_error_message() );
273 - }
284 + return;
285 + }
274 286
275 - $refund_meta_key = sprintf( '_pr_%s', wc_clean( $resource->id ) );
276 - if ( PayplugWoocommerceHelper::is_pre_30() ) {
277 - update_post_meta( $order_id, $refund_meta_key, $resource->id );
278 - } else {
279 - $order->add_meta_data( $refund_meta_key, $resource->id, true );
280 - $order->save();
281 - }
287 + $refund = wc_create_refund([
288 + 'amount' => ((int) $resource->amount) / 100,
289 + 'reason' => isset($resource->metadata['reason']) ? $resource->metadata['reason'] : null,
290 + 'order_id' => (int) $order_id,
291 + 'refund_id' => 0,
292 + 'refund_payment' => false,
293 + ]);
294 + if (is_wp_error($refund)) {
295 + PayplugGateway::log($refund->get_error_message());
296 + }
282 297
283 - $note = sprintf( __( 'Refund %s : Refunded %s', 'payplug' ), wc_clean( $resource->id ), wc_price( ( (int) $resource->amount ) / 100 ) );
284 - if ( ! empty( $resource->metadata['reason'] ) ) {
285 - $note .= sprintf( ' (%s)', esc_html( $resource->metadata['reason'] ) );
286 - }
287 - $order->add_order_note( $note );
298 + $refund_meta_key = sprintf('_pr_%s', wc_clean($resource->id));
299 + if (PayplugWoocommerceHelper::is_pre_30()) {
300 + update_post_meta($order_id, $refund_meta_key, $resource->id);
301 + } else {
302 + $order->add_meta_data($refund_meta_key, $resource->id, true);
303 + $order->save();
304 + }
288 305
289 - /**
290 - * Fires once a refund response has been processed.
291 - *
292 - * @param int $order_id Order ID
293 - * @param RefundResource $resource Refund resource
294 - */
295 - \do_action( 'payplug_gateway_refund_response_processed', $order_id, $resource );
306 + $note = sprintf(__('Refund %s : Refunded %s', 'payplug'), wc_clean($resource->id), wc_price(((int) $resource->amount) / 100));
307 + if (!empty($resource->metadata['reason'])) {
308 + $note .= sprintf(' (%s)', esc_html($resource->metadata['reason']));
309 + }
310 + $order->add_order_note($note);
296 311
297 - try {
298 - $payment = $this->gateway->api->payment_retrieve( $transaction_id );
299 - $metadata = PayplugWoocommerceHelper::extract_transaction_metadata( $payment );
300 - PayplugWoocommerceHelper::save_transaction_metadata( $order, $metadata );
301 - } catch ( \Exception $e ) {}
312 + /**
313 + * Fires once a refund response has been processed.
314 + *
315 + * @param int $order_id Order ID
316 + * @param RefundResource $resource Refund resource
317 + */
318 + \do_action('payplug_gateway_refund_response_processed', $order_id, $resource);
302 319
303 - PayplugGateway::log( sprintf( 'Order #%s : Refund IPN %s processing completed.', $order_id, $resource->id ) );
304 - }
320 + try {
321 + $payment = $this->gateway->payplug_api->payment_retrieve($transaction_id);
322 + $metadata = PayplugWoocommerceHelper::extract_transaction_metadata($payment);
323 + PayplugWoocommerceHelper::save_transaction_metadata($order, $metadata);
324 + } catch (\Exception $e) {
325 + }
305 326
306 - /**
307 - * Get an order from its transaction id.
308 - *
309 - * @param int $transaction_id
310 - *
311 - * @return bool|\WC_Order
312 - */
313 - protected function get_order_from_transaction_id( $transaction_id ) {
314 - global $wpdb;
327 + PayplugGateway::log(sprintf('Order #%s : Refund IPN %s processing completed.', $order_id, $resource->id));
328 + }
315 329
316 - $order_id = $wpdb->get_var(
317 - $wpdb->prepare(
318 - "
319 - SELECT post_id
320 - FROM $wpdb->postmeta
321 - WHERE meta_key = '_transaction_id'
322 - AND meta_value = %s
323 - ",
324 - $transaction_id
325 - )
326 - );
330 + /**
331 + * Get an order from its transaction id.
332 + *
333 + * @param int $transaction_id
334 + *
335 + * @return bool|\WC_Order
336 + */
337 + protected function get_order_from_transaction_id($transaction_id)
338 + {
339 + global $wpdb;
327 340
328 - return ! is_null( $order_id ) ? wc_get_order( $order_id ) : false;
329 - }
341 + if (OrderUtil::custom_orders_table_usage_is_enabled()) {
342 + $orders = wc_get_orders(
343 + [
344 + 'field_query' => [
345 + [
346 + 'field' => 'transaction_id',
347 + 'value' => $transaction_id,
348 + ],
349 + ],
350 + ]
351 + );
352 + $order = $orders[0];
353 + $order_id = $order->get_id();
354 + //$sql = "SELECT o.id FROM $wpdb->wc_orders o WHERE o.transaction_id = %s";
355 + } else {
356 + $order_id = $wpdb->get_var(
357 + $wpdb->prepare(
358 + "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_transaction_id' AND meta_value = %s",
359 + $transaction_id
360 + )
361 + );
362 + }
330 363
331 - /**
332 - * Check if a refund id already exist for the order.
333 - *
334 - * @param string $refund_id
335 - *
336 - * @return bool
337 - */
338 - protected function refund_exist_for_order( $order_id, $refund_id ) {
339 - global $wpdb;
364 + return !is_null($order_id) ? wc_get_order($order_id) : false;
365 + }
340 366
341 - $sql = "
367 + /**
368 + * Check if a refund id already exist for the order.
369 + *
370 + * @param string $refund_id
371 + *
372 + * @return bool
373 + */
374 + protected function refund_exist_for_order($order_id, $refund_id)
375 + {
376 + global $wpdb;
377 +
378 + if (OrderUtil::custom_orders_table_usage_is_enabled()) {
379 + $results = wc_get_orders(
380 + [
381 + 'meta_query' => [
382 + [
383 + 'field_query' => [
384 + 'relation' => 'AND',
385 + [
386 + 'field' => 'meta_key',
387 + 'value' => '_pr_' . esc_sql($refund_id),
388 + ],
389 + [
390 + 'field' => 'meta_value',
391 + 'value' => $refund_id,
392 + ],
393 + [
394 + 'field' => 'order_id',
395 + 'value' => (int) $order_id,
396 + ],
397 + ],
398 + ],
399 + ],
400 + ]
401 + );
402 + } else {
403 + $sql = "
342 404 SELECT p.ID
343 - FROM $wpdb->posts p
344 - INNER JOIN $wpdb->postmeta pm
345 - ON p.ID = pm.post_id
346 - WHERE 1=1
347 - AND p.post_type = %s
348 - AND p.ID = %d
349 - AND pm.meta_key LIKE '_pr_" . esc_sql( $refund_id ) . "'
350 - AND pm.meta_value = %s
405 + FROM $wpdb->posts p
406 + INNER JOIN $wpdb->postmeta pm
407 + ON p.ID = pm.post_id
408 + WHERE 1=1
409 + AND p.post_type = %s
410 + AND p.ID = %d
411 + AND pm.meta_key LIKE '_pr_" . esc_sql($refund_id) . "'
412 + AND pm.meta_value = %s
351 413 LIMIT 1
352 - ";
414 + ";
353 415
354 - $results = $wpdb->get_col(
355 - $wpdb->prepare(
356 - $sql,
357 - 'shop_order',
358 - (int) $order_id,
359 - $refund_id
360 - )
361 - );
416 + $results = $wpdb->get_col(
417 + $wpdb->prepare(
418 + $sql,
419 + 'shop_order',
420 + (int) $order_id,
421 + $refund_id
422 + )
423 + );
424 + }
362 425
363 - return ! empty( $results ) ? true : false;
364 - }
426 + return !empty($results) ? true : false;
427 + }
365 428
366 - /**
367 - * Save card from the transaction.
368 - *
369 - * @param IVerifiableAPIResource $resource
370 - *
371 - * @return bool
372 - */
373 - protected function maybe_save_card( $resource ) {
429 + /**
430 + * Save card from the transaction.
431 + *
432 + * @param IVerifiableAPIResource $resource
433 + *
434 + * @return bool
435 + */
436 + protected function maybe_save_card($resource)
437 + {
438 + if (!isset($resource->card) || empty($resource->card->id)) {
439 + return false;
440 + }
374 441
375 - if ( ! isset( $resource->card ) || empty( $resource->card->id ) ) {
376 - return false;
377 - }
442 + if (!isset($resource->metadata['customer_id'])) {
443 + return false;
444 + }
378 445
379 - if ( ! isset( $resource->metadata['customer_id'] ) ) {
380 - return false;
381 - }
446 + $customer = get_user_by('id', $resource->metadata['customer_id']);
447 + if (!$customer || 0 === (int) $customer->ID) {
448 + return false;
449 + }
382 450
383 - $customer = get_user_by( 'id', $resource->metadata['customer_id'] );
384 - if ( ! $customer || 0 === (int) $customer->ID ) {
385 - return false;
386 - }
451 + $merchant_id = $this->gateway->get_merchant_id();
452 + if (empty($merchant_id)) {
453 + return false;
454 + }
387 455
388 - $merchant_id = $this->gateway->get_merchant_id();
389 - if ( empty( $merchant_id ) ) {
390 - return false;
391 - }
456 + PayplugGateway::log(sprintf('Saving card from transaction %s for customer %s', wc_clean($resource->id), $customer->ID));
392 457
393 - PayplugGateway::log( sprintf( 'Saving card from transaction %s for customer %s', wc_clean( $resource->id ), $customer->ID ) );
394 -
395 458 $token = new WC_Payment_Token_CC();
396 - $existing_tokens = WC_Payment_Tokens::get_customer_tokens( $customer->ID , $this->gateway->id );
397 - $set_token = wc_clean( $resource->card->id );
398 - $set_last4 = wc_clean( $resource->card->last4 );
399 - $set_expiry_year = wc_clean( $resource->card->exp_year ) ;
400 - $set_expiry_month = zeroise( (int) wc_clean( $resource->card->exp_month ), 2 ) ;
401 - $set_card_type = \strtolower( wc_clean( $resource->card->brand ) ) ;
402 - if(!empty($existing_tokens)) {
403 - foreach($existing_tokens as $token_id => $existing_token) {
459 + $existing_tokens = WC_Payment_Tokens::get_customer_tokens($customer->ID, $this->gateway->id);
460 + $set_token = wc_clean($resource->card->id);
461 + $set_last4 = wc_clean($resource->card->last4);
462 + $set_expiry_year = wc_clean($resource->card->exp_year);
463 + $set_expiry_month = zeroise((int) wc_clean($resource->card->exp_month), 2);
464 + $set_card_type = \strtolower(wc_clean($resource->card->brand));
465 + if (!empty($existing_tokens)) {
466 + foreach ($existing_tokens as $token_id => $existing_token) {
404 467 $current_data = $existing_token->get_data();
405 - if( $current_data['token'] === $set_token &&
468 + if ($current_data['token'] === $set_token &&
406 469 $current_data['last4'] === $set_last4 &&
407 470 $current_data['expiry_year'] === $set_expiry_year &&
408 471 $current_data['expiry_month'] === $set_expiry_month &&
409 472 $current_data['card_type'] === $set_card_type) {
@@ -411,52 +474,52 @@
411 474 }
412 475 }
413 476 }
414 477
415 - $token->set_token( $set_token );
416 - $token->set_gateway_id( 'payplug' );
417 - $token->set_last4( $set_last4 );
418 - $token->set_expiry_year( $set_expiry_year );
419 - $token->set_expiry_month( $set_expiry_month );
420 - $token->set_card_type( $set_card_type );
421 - $token->set_user_id( $customer->ID );
422 - $token->add_meta_data( 'mode', $resource->is_live ? 'live' : 'test', true );
423 - $token->add_meta_data( 'payplug_account', \wc_clean( $merchant_id ), true );
424 - $token->save();
478 + $token->set_token($set_token);
479 + $token->set_gateway_id('payplug');
480 + $token->set_last4($set_last4);
481 + $token->set_expiry_year($set_expiry_year);
482 + $token->set_expiry_month($set_expiry_month);
483 + $token->set_card_type($set_card_type);
484 + $token->set_user_id($customer->ID);
485 + $token->add_meta_data('mode', $resource->is_live ? 'live' : 'test', true);
486 + $token->add_meta_data('payplug_account', \wc_clean($merchant_id), true);
487 + $token->save();
425 488
426 - PayplugGateway::log( sprintf( 'Payment card saved', wc_clean( $resource->id ), $customer->ID ) );
489 + PayplugGateway::log(sprintf('Payment card saved', wc_clean($resource->id), $customer->ID));
427 490
428 - return true;
429 - }
491 + return true;
492 + }
430 493
431 - /**
432 - * Save shipping address.
433 - *
434 - * @param IVerifiableAPIResource $resource
435 - *
436 - * @return bool
437 - */
438 - protected function maybe_save_address_hash( $resource ) {
494 + /**
495 + * Save shipping address.
496 + *
497 + * @param IVerifiableAPIResource $resource
498 + *
499 + * @return bool
500 + */
501 + protected function maybe_save_address_hash($resource)
502 + {
503 + if (!isset($resource->metadata['customer_id'])) {
504 + return false;
505 + }
439 506
440 - if ( ! isset( $resource->metadata['customer_id'] ) ) {
441 - return false;
442 - }
507 + $customer = get_user_by('id', $resource->metadata['customer_id']);
508 + if (!$customer || 0 === (int) $customer->ID) {
509 + return false;
510 + }
443 511
444 - $customer = get_user_by( 'id', $resource->metadata['customer_id'] );
445 - if ( ! $customer || 0 === (int) $customer->ID ) {
446 - return false;
447 - }
512 + $shipping = [];
513 + foreach (PayplugAddressData::$address_fields as $field) {
514 + $shipping[$field] = $resource->shipping->{$field};
515 + }
448 516
449 - $shipping = [];
450 - foreach ( PayplugAddressData::$address_fields as $field ) {
451 - $shipping[ $field ] = $resource->shipping->{$field};
452 - }
517 + $shipping_hash = PayplugAddressData::hash_address($shipping);
518 + $hash_list = PayplugAddressData::get_customer_addresses_hash($customer->ID);
519 + $hash_list[] = $shipping_hash;
520 + $hash_list = array_unique($hash_list);
521 + PayplugAddressData::update_customer_addresses_hash($customer->ID, $hash_list);
453 522
454 - $shipping_hash = PayplugAddressData::hash_address( $shipping );
455 - $hash_list = PayplugAddressData::get_customer_addresses_hash( $customer->ID );
456 - $hash_list[] = $shipping_hash;
457 - $hash_list = array_unique( $hash_list );
458 - PayplugAddressData::update_customer_addresses_hash( $customer->ID, $hash_list );
459 -
460 - return true;
461 - }
523 + return true;
524 + }
462 525 }