PluginProbe
PayPlug for WooCommerce (Official) / 1.0.18
PayPlug for WooCommerce (Official) v1.0.18
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
payplug / src / Gateway / PayplugResponse.php

PayplugResponse.php in PayPlug for WooCommerce (Official) 1.0.18, at src/Gateway/PayplugResponse.php

280 lines 7.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Payplug\PayplugWoocommerce\Gateway;
4
5 // Exit if accessed directly
6 if ( ! defined( 'ABSPATH' ) ) {
7 exit;
8 }
9
10 use Payplug\PayplugWoocommerce\PayplugWoocommerceHelper;
11 use Payplug\Resource\IVerifiableAPIResource;
12 use Payplug\Resource\Payment as PaymentResource;
13 use Payplug\Resource\Refund as RefundResource;
14 use WC_Payment_Token_CC;
15
16 /**
17 * Process responses from PayPlug.
18 *
19 * @package Payplug\PayplugWoocommerce\Gateway
20 */
21 class PayplugResponse {
22
23 private $gateway;
24
25 public function __construct( PayplugGateway $gateway ) {
26 $this->gateway = $gateway;
27 }
28
29 /**
30 * Process payment.
31 *
32 * @param $resource
33 * @param $is_payment_with_token
34 *
35 * @return void
36 * @throws \WC_Data_Exception
37 */
38 public function process_payment( $resource, $is_payment_with_token = false ) {
39 $order_id = wc_clean( $resource->metadata['order_id'] );
40 $order = wc_get_order( $order_id );
41 if ( ! $order ) {
42 PayplugGateway::log( sprintf( 'Coudn\'t find order #%s (Transaction %s).', $order_id, wc_clean( $resource->id ) ), 'error' );
43
44 return;
45 }
46
47 PayplugGateway::log( sprintf( 'Order #%s : Begin processing payment IPN %s', $order_id, $resource->id ) );
48
49 // Ignore paid orders
50 if ( $order->is_paid() ) {
51 PayplugGateway::log( sprintf( 'Order #%s : Order is already complete. Ignoring IPN.', $order_id ) );
52
53 return;
54 }
55
56 // Ignore cancelled orders
57 if ( $order->has_status( 'refunded' ) ) {
58 PayplugGateway::log( sprintf( 'Order #%s : Order has been refunded. Ignoring IPN', $order_id ) );
59
60 return;
61 }
62
63 $metadata = PayplugWoocommerceHelper::extract_transaction_metadata( $resource );
64 PayplugWoocommerceHelper::save_transaction_metadata( $order, $metadata );
65
66 if ( $resource->is_paid ) {
67
68 if ( ! $is_payment_with_token ) {
69 $this->maybe_save_card( $resource );
70 }
71
72 $order->add_order_note( sprintf( __( 'PayPlug IPN OK | Transaction %s', 'payplug' ), wc_clean( $resource->id ) ) );
73 $order->payment_complete( wc_clean( $resource->id ) );
74 if ( PayplugWoocommerceHelper::is_pre_30() ) {
75 $order->reduce_order_stock();
76 }
77
78 /**
79 * Fires once a payment response has been processed.
80 *
81 * @param int $order_id Order ID
82 * @param PaymentResource $resource Payment resource
83 */
84 \do_action( 'payplug_gateway_payment_response_processed', $order_id, $resource );
85
86 PayplugGateway::log( sprintf( 'Order #%s : Payment IPN %s processing completed.', $order_id, $resource->id ) );
87
88 return;
89 }
90
91 if ( ! empty( $resource->failure ) ) {
92 $order->update_status(
93 'failed',
94 sprintf( __( 'PayPlug IPN OK | Transaction %s failed : %s', 'payplug' ), $resource->id, wc_clean( $resource->failure->message ) )
95 );
96
97 /** This action is documented in src/Gateway/PayplugResponse */
98 \do_action( 'payplug_gateway_payment_response_processed', $order_id, $resource );
99
100 PayplugGateway::log( sprintf( 'Order #%s : Payment IPN %s processing completed.', $order_id, $resource->id ) );
101
102 return;
103 }
104 }
105
106 /**
107 * Process refund.
108 *
109 * @param $resource
110 *
111 * @throws \Exception
112 */
113 public function process_refund( $resource ) {
114 $transaction_id = wc_clean( $resource->payment_id );
115 $order = $this->get_order_from_transaction_id( $transaction_id );
116 if ( ! $order ) {
117 PayplugGateway::log( sprintf( 'Coudn\'t find order for transaction %s (Refund %s).', wc_clean( $resource->payment_id ), wc_clean( $resource->id ) ), 'error' );
118
119 return;
120 }
121 $order_id = PayplugWoocommerceHelper::is_pre_30() ? $order->id : $order->get_id();
122
123 PayplugGateway::log( sprintf( 'Order #%s : Begin processing refund IPN %s', $order_id, $resource->id ) );
124
125 $refund_exist = $this->refund_exist_for_order( $order_id, $resource->id );
126 if ( $refund_exist ) {
127 PayplugGateway::log( sprintf( 'Order %s : Refund has already been processed. Ignoring IPN.', $order_id ) );
128
129 return;
130 }
131
132 $refund = wc_create_refund( [
133 'amount' => ( (int) $resource->amount ) / 100,
134 'reason' => isset( $resource->metadata['reason'] ) ? $resource->metadata['reason'] : null,
135 'order_id' => (int) $order_id,
136 'refund_id' => 0,
137 'refund_payment' => false,
138 ] );
139 if ( is_wp_error( $refund ) ) {
140 PayplugGateway::log( $refund->get_error_message() );
141 }
142
143 $refund_meta_key = sprintf( '_pr_%s', wc_clean( $resource->id ) );
144 if ( PayplugWoocommerceHelper::is_pre_30() ) {
145 update_post_meta( $order_id, $refund_meta_key, $resource->id );
146 } else {
147 $order->add_meta_data( $refund_meta_key, $resource->id, true );
148 $order->save();
149 }
150
151 $note = sprintf( __( 'Refund %s : Refunded %s', 'payplug' ), wc_clean( $resource->id ), wc_price( ( (int) $resource->amount ) / 100 ) );
152 if ( ! empty( $resource->metadata['reason'] ) ) {
153 $note .= sprintf( ' (%s)', esc_html( $resource->metadata['reason'] ) );
154 }
155 $order->add_order_note( $note );
156
157 /**
158 * Fires once a refund response has been processed.
159 *
160 * @param int $order_id Order ID
161 * @param RefundResource $resource Refund resource
162 */
163 \do_action( 'payplug_gateway_refund_response_processed', $order_id, $resource );
164
165 try {
166 $payment = $this->gateway->api->payment_retrieve( $transaction_id );
167 $metadata = PayplugWoocommerceHelper::extract_transaction_metadata( $payment );
168 PayplugWoocommerceHelper::save_transaction_metadata( $order, $metadata );
169 } catch ( \Exception $e ) {}
170
171 PayplugGateway::log( sprintf( 'Order #%s : Refund IPN %s processing completed.', $order_id, $resource->id ) );
172 }
173
174 /**
175 * Get an order from its transaction id.
176 *
177 * @param int $transaction_id
178 *
179 * @return bool|\WC_Order
180 */
181 protected function get_order_from_transaction_id( $transaction_id ) {
182 global $wpdb;
183
184 $order_id = $wpdb->get_var(
185 $wpdb->prepare(
186 "
187 SELECT post_id
188 FROM $wpdb->postmeta
189 WHERE meta_key = '_transaction_id'
190 AND meta_value = %s
191 ",
192 $transaction_id
193 )
194 );
195
196 return ! is_null( $order_id ) ? wc_get_order( $order_id ) : false;
197 }
198
199 /**
200 * Check if a refund id already exist for the order.
201 *
202 * @param string $refund_id
203 *
204 * @return bool
205 */
206 protected function refund_exist_for_order( $order_id, $refund_id ) {
207 global $wpdb;
208
209 $sql = "
210 SELECT p.ID
211 FROM $wpdb->posts p
212 INNER JOIN $wpdb->postmeta pm
213 ON p.ID = pm.post_id
214 WHERE 1=1
215 AND p.post_type = %s
216 AND p.ID = %d
217 AND pm.meta_key LIKE '_pr_" . esc_sql( $refund_id ) . "'
218 AND pm.meta_value = %s
219 LIMIT 1
220 ";
221
222 $results = $wpdb->get_col(
223 $wpdb->prepare(
224 $sql,
225 'shop_order',
226 (int) $order_id,
227 $refund_id
228 )
229 );
230
231 return ! empty( $results ) ? true : false;
232 }
233
234 /**
235 * Save card from the transaction.
236 *
237 * @param IVerifiableAPIResource $resource
238 *
239 * @return bool
240 */
241 protected function maybe_save_card( $resource ) {
242
243 if ( ! isset( $resource->card ) || empty( $resource->card->id ) ) {
244 return false;
245 }
246
247 if ( ! isset( $resource->metadata['customer_id'] ) ) {
248 return false;
249 }
250
251 $customer = get_user_by( 'id', $resource->metadata['customer_id'] );
252 if ( ! $customer || 0 === (int) $customer->ID ) {
253 return false;
254 }
255
256 $merchant_id = $this->gateway->get_merchant_id();
257 if ( empty( $merchant_id ) ) {
258 return false;
259 }
260
261 PayplugGateway::log( sprintf( 'Saving card from transaction %s for customer %s', wc_clean( $resource->id ), $customer->ID ) );
262
263 $token = new WC_Payment_Token_CC();
264 $token->set_token( wc_clean( $resource->card->id ) );
265 $token->set_gateway_id( 'payplug' );
266 $token->set_last4( wc_clean( $resource->card->last4 ) );
267 $token->set_expiry_year( wc_clean( $resource->card->exp_year ) );
268 $token->set_expiry_month( zeroise( (int) wc_clean( $resource->card->exp_month ), 2 ) );
269 $token->set_card_type( \strtolower( wc_clean( $resource->card->brand ) ) );
270 $token->set_user_id( $customer->ID );
271 $token->add_meta_data( 'mode', $resource->is_live ? 'live' : 'test', true );
272 $token->add_meta_data( 'payplug_account', \wc_clean( $merchant_id ), true );
273 $token->save();
274
275 PayplugGateway::log( sprintf( 'Payment card saved', wc_clean( $resource->id ), $customer->ID ) );
276
277 return true;
278 }
279 }
280