1 <?php
2 3 4 5 6 7 8 9 10
11
12 13 14 15 16 17 18 19
20 add_action( 'edd_paypal_cc_form', '__return_false' );
21
22 23 24 25 26 27 28 29
30 function edd_process_paypal_purchase( $purchase_data ) {
31 global $edd_options;
32
33
34 if ( ! isset( $purchase_data['post_data']['edd-gateway'] ) )
35 return;
36
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
54
55
56 $payment_data = array(
57 'price' => $purchase_data['price'],
58 'date' => $purchase_data['date'],
59 'user_email' => $purchase_data['user_email'],
60 'purchase_key' => $purchase_data['purchase_key'],
61 'currency' => $edd_options['currency'],
62 'downloads' => $purchase_data['downloads'],
63 'user_info' => $purchase_data['user_info'],
64 'cart_details' => $purchase_data['cart_details'],
65 'status' => 'pending'
66 );
67
68
69 $payment = edd_insert_payment( $payment_data );
70
71
72 if ( ! $payment ) {
73
74 edd_record_gateway_error( __( 'Payment Error', 'edd' ), sprintf( __( 'Payment creation failed before sending buyer to PayPal. Payment data: %s', 'edd' ), json_encode( $payment_data ) ), $payment );
75
76 edd_send_back_to_checkout( '?payment-mode=' . $purchase_data['post_data']['edd-gateway'] );
77 } else {
78
79 $listener_url = trailingslashit( home_url() ).'?edd-listener=IPN';
80
81
82 $return_url = add_query_arg( 'payment-confirmation', 'paypal', get_permalink( $edd_options['success_page'] ) );
83
84
85 $summary = edd_get_purchase_summary( $purchase_data, false );
86
87
88 $paypal_redirect = trailingslashit( edd_get_paypal_redirect() ) . '?';
89
90
91 $paypal_args = array(
92 'cmd' => '_xclick',
93 'amount' => round( $purchase_data['price'] - $purchase_data['tax'], 2 ),
94 'business' => $edd_options['paypal_email'],
95 'item_name' => stripslashes_deep( html_entity_decode( wp_strip_all_tags( $summary ), ENT_COMPAT, 'UTF-8' ) ),
96 'email' => $purchase_data['user_email'],
97 'no_shipping' => '1',
98 'shipping' => '0',
99 'no_note' => '1',
100 'currency_code' => $edd_options['currency'],
101 'item_number' => $purchase_data['purchase_key'],
102 'charset' => get_bloginfo( 'charset' ),
103 'custom' => $payment,
104 'rm' => '2',
105 'return' => $return_url,
106 'cancel_return' => edd_get_failed_transaction_uri(),
107 'notify_url' => $listener_url,
108 'page_style' => edd_get_paypal_page_style()
109 );
110
111 if ( edd_use_taxes() )
112 $paypal_args['tax'] = $purchase_data['tax'];
113
114 $paypal_args = apply_filters('edd_paypal_redirect_args', $paypal_args, $purchase_data );
115
116
117 $paypal_redirect .= http_build_query( $paypal_args );
118
119
120 edd_empty_cart();
121
122
123 wp_redirect( $paypal_redirect );
124 exit;
125 }
126
127 }
128 add_action( 'edd_gateway_paypal', 'edd_process_paypal_purchase' );
129
130 131 132 133 134 135 136
137 function edd_listen_for_paypal_ipn() {
138 global $edd_options;
139
140
141 if ( isset( $_GET['edd-listener'] ) && $_GET['edd-listener'] == 'IPN' ) {
142 do_action( 'edd_verify_paypal_ipn' );
143 }
144 }
145 add_action( 'init', 'edd_listen_for_paypal_ipn' );
146
147 148 149 150 151 152 153
154 function edd_process_paypal_ipn() {
155 global $edd_options;
156
157
158 if ( isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] != 'POST' ) {
159 return;
160 }
161
162
163 $post_data = false;
164
165
166 if ( ini_get( 'allow_url_fopen' ) ) {
167 $post_data = file_get_contents( 'php://input' );
168 } else {
169
170 ini_set( 'post_max_size', '12M' );
171 }
172
173 $encoded_data = 'cmd=_notify-validate';
174
175
176 $arg_separator = edd_get_php_arg_separator_output();
177
178
179 if ( $post_data || strlen( $post_data ) > 0 ) {
180
181 $encoded_data .= $arg_separator.$post_data;
182 } else {
183
184 if ( empty( $_POST ) ) {
185
186 return;
187 } else {
188
189 foreach ( $_POST as $key => $value ) {
190
191 $encoded_data .= $arg_separator."$key=" . urlencode( $value );
192 }
193 }
194 }
195
196
197 parse_str( $encoded_data, $encoded_data_array );
198
199
200 $paypal_redirect = edd_get_paypal_redirect(true);
201
202 $remote_post_vars = array(
203 'method' => 'POST',
204 'timeout' => 45,
205 'redirection' => 5,
206 'httpversion' => '1.0',
207 'blocking' => true,
208 'headers' => array(
209 'host' => 'www.paypal.com',
210 'connection' => 'close',
211 'content-type' => 'application/x-www-form-urlencoded',
212 'post' => '/cgi-bin/webscr HTTP/1.1',
213
214 ),
215 'sslverify' => false,
216 'body' => $encoded_data_array
217 );
218
219
220 $api_response = wp_remote_post( edd_get_paypal_redirect(), $remote_post_vars );
221
222 if ( is_wp_error( $api_response ) ) {
223 edd_record_gateway_error( __( 'IPN Error', 'edd' ), sprintf( __( 'Invalid IPN verification response. IPN data: ', 'edd' ), json_encode( $api_response ) ) );
224 return;
225 }
226
227 if ( $api_response['body'] !== 'VERIFIED' && !isset( $edd_options['disable_paypal_verification'] ) ) {
228 edd_record_gateway_error( __( 'IPN Error', 'edd' ), sprintf( __( 'Invalid IPN verification response. IPN data: ', 'edd' ), json_encode( $api_response ) ) );
229 return;
230 }
231
232
233 if ( ! is_array( $encoded_data_array ) && !empty( $encoded_data_array ) )
234 return;
235
236 if ( has_action( 'edd_paypal_' . $encoded_data_array['txn_type'] ) ) {
237
238 do_action( 'edd_paypal_' . $encoded_data_array['txn_type'], $encoded_data_array );
239 } else {
240
241 do_action( 'edd_paypal_web_accept', $encoded_data_array );
242 }
243 }
244 add_action( 'edd_verify_paypal_ipn', 'edd_process_paypal_ipn' );
245
246 247 248 249 250 251 252 253
254 function edd_process_paypal_web_accept( $data ) {
255 global $edd_options;
256
257 if ( $data['txn_type'] != 'web_accept' )
258 return;
259
260
261 $payment_id = $data['custom'];
262 $purchase_key = $data['item_number'];
263 $paypal_amount = $data['mc_gross'];
264 $payment_status = strtolower( $data['payment_status'] );
265 $currency_code = strtolower( $data['mc_currency'] );
266
267
268 $payment_amount = edd_format_amount( edd_get_payment_amount( $payment_id ) );
269
270 if( get_post_status( $payment_id ) == 'complete' )
271 return;
272
273 if ( edd_get_payment_gateway( $payment_id ) != 'paypal' )
274 return;
275
276
277 if ( $currency_code != strtolower( $edd_options['currency'] ) ) {
278
279
280 edd_record_gateway_error( __( 'IPN Error', 'edd' ), sprintf( __( 'Invalid currency in IPN response. IPN data: ', 'edd' ), json_encode( $data ) ), $payment_id );
281 edd_update_payment_status( $payment_id, 'failed' );
282 return;
283 }
284
285 if ( $payment_status == 'refunded' ) {
286
287 edd_process_paypal_refund( $data );
288 } else {
289 if ( number_format( (float)$paypal_amount, 2) != $payment_amount ) {
290
291 edd_record_gateway_error( __( 'IPN Error', 'edd' ), sprintf( __( 'Invalid payment amount in IPN response. IPN data: ', 'edd' ), json_encode( $data ) ), $payment_id );
292
293 }
294 if ( $purchase_key != edd_get_payment_key( $payment_id ) ) {
295
296 edd_record_gateway_error( __( 'IPN Error', 'edd' ), sprintf( __( 'Invalid purchase key in IPN response. IPN data: ', 'edd' ), json_encode( $data ) ), $payment_id );
297 edd_update_payment_status( $payment_id, 'failed' );
298 return;
299 }
300
301 if ( $payment_status == 'completed' || edd_is_test_mode() ) {
302 edd_insert_payment_note( $payment_id, sprintf( __( 'PayPal Transaction ID: %s', 'edd' ) , $data['txn_id'] ) );
303 edd_update_payment_status( $payment_id, 'publish' );
304 }
305 }
306 }
307 add_action( 'edd_paypal_web_accept', 'edd_process_paypal_web_accept' );
308
309 310 311 312 313 314 315 316
317 function edd_process_paypal_refund( $data ) {
318 global $edd_options;
319
320
321 $payment_id = intval( $data['custom'] );
322
323 edd_insert_payment_note( $payment_id, sprintf( __( 'PayPal Payment #%s Refunded', 'edd' ) , $data['parent_txn_id'] ) );
324 edd_insert_payment_note( $payment_id, sprintf( __( 'PayPal Refund Transaction ID: %s', 'edd' ) , $data['txn_id'] ) );
325 edd_update_payment_status( $payment_id, 'refunded' );
326 }
327
328 329 330 331 332 333 334 335
336 function edd_get_paypal_redirect( $ssl_check = false ) {
337 global $edd_options;
338
339 if ( is_ssl() || ! $ssl_check ) {
340 $protocal = 'https://';
341 } else {
342 $protocal = 'http://';
343 }
344
345
346 if ( edd_is_test_mode() ) {
347
348 $paypal_uri = $protocal . 'www.sandbox.paypal.com/cgi-bin/webscr';
349 } else {
350
351 $paypal_uri = $protocal . 'www.paypal.com/cgi-bin/webscr';
352 }
353
354 return $paypal_uri;
355 }
356
357 358 359 360 361 362 363
364 function edd_get_paypal_page_style() {
365 global $edd_options;
366
367 $page_style = 'PayPal';
368
369 if ( isset( $edd_options['paypal_page_style'] ) )
370 $page_style = trim( $edd_options['paypal_page_style'] );
371
372 return apply_filters( 'edd_paypal_page_style', $page_style );
373 }