PluginProbe
PayPlug for WooCommerce (Official) / 1.0.0
PayPlug for WooCommerce (Official) v1.0.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 1.2.6 All 101 releases
payplug / src / Gateway / PayplugResponse.php

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

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