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