1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
if ( ! defined( 'ABSPATH' ) ) { |
4
|
|
|
exit; // Exit if accessed directly |
5
|
|
|
} |
6
|
|
|
|
7
|
|
|
/** |
8
|
|
|
* Simplify Commerce Gateway. |
9
|
|
|
* |
10
|
|
|
* @class WC_Gateway_Simplify_Commerce |
11
|
|
|
* @extends WC_Payment_Gateway_CC |
12
|
|
|
* @since 2.2.0 |
13
|
|
|
* @version 1.0.0 |
14
|
|
|
* @package WooCommerce/Classes/Payment |
15
|
|
|
* @author WooThemes |
16
|
|
|
*/ |
17
|
|
|
class WC_Gateway_Simplify_Commerce extends WC_Payment_Gateway_CC { |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* Constructor. |
21
|
|
|
*/ |
22
|
|
|
public function __construct() { |
23
|
|
|
$this->id = 'simplify_commerce'; |
24
|
|
|
$this->method_title = __( 'Simplify Commerce', 'woocommerce' ); |
25
|
|
|
$this->method_description = __( 'Take payments via Simplify Commerce - uses simplify.js to create card tokens and the Simplify Commerce SDK. Requires SSL when sandbox is disabled.', 'woocommerce' ); |
26
|
|
|
$this->new_method_label = __( 'Use a new card', 'woocommerce' ); |
27
|
|
|
$this->has_fields = true; |
28
|
|
|
$this->supports = array( |
29
|
|
|
'subscriptions', |
30
|
|
|
'products', |
31
|
|
|
'subscription_cancellation', |
32
|
|
|
'subscription_reactivation', |
33
|
|
|
'subscription_suspension', |
34
|
|
|
'subscription_amount_changes', |
35
|
|
|
'subscription_payment_method_change', // Subscriptions 1.n compatibility |
36
|
|
|
'subscription_payment_method_change_customer', |
37
|
|
|
'subscription_payment_method_change_admin', |
38
|
|
|
'subscription_date_changes', |
39
|
|
|
'multiple_subscriptions', |
40
|
|
|
'default_credit_card_form', |
41
|
|
|
'tokenization', |
42
|
|
|
'refunds', |
43
|
|
|
'pre-orders' |
44
|
|
|
); |
45
|
|
|
$this->view_transaction_url = 'https://www.simplify.com/commerce/app#/payment/%s'; |
46
|
|
|
|
47
|
|
|
// Load the form fields |
48
|
|
|
$this->init_form_fields(); |
49
|
|
|
|
50
|
|
|
// Load the settings. |
51
|
|
|
$this->init_settings(); |
52
|
|
|
|
53
|
|
|
// Get setting values |
54
|
|
|
$this->title = $this->get_option( 'title' ); |
55
|
|
|
$this->description = $this->get_option( 'description' ); |
56
|
|
|
$this->enabled = $this->get_option( 'enabled' ); |
57
|
|
|
$this->mode = $this->get_option( 'mode', 'standard' ); |
58
|
|
|
$this->modal_color = $this->get_option( 'modal_color', '#a46497' ); |
59
|
|
|
$this->sandbox = $this->get_option( 'sandbox' ); |
60
|
|
|
$this->public_key = $this->sandbox == 'no' ? $this->get_option( 'public_key' ) : $this->get_option( 'sandbox_public_key' ); |
61
|
|
|
$this->private_key = $this->sandbox == 'no' ? $this->get_option( 'private_key' ) : $this->get_option( 'sandbox_private_key' ); |
62
|
|
|
|
63
|
|
|
$this->init_simplify_sdk(); |
64
|
|
|
|
65
|
|
|
// Hooks |
66
|
|
|
add_action( 'wp_enqueue_scripts', array( $this, 'payment_scripts' ) ); |
67
|
|
|
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) ); |
68
|
|
|
add_action( 'woocommerce_receipt_' . $this->id, array( $this, 'receipt_page' ) ); |
69
|
|
|
add_action( 'woocommerce_api_wc_gateway_simplify_commerce', array( $this, 'return_handler' ) ); |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* Init Simplify SDK. |
74
|
|
|
*/ |
75
|
|
|
protected function init_simplify_sdk() { |
76
|
|
|
// Include lib |
77
|
|
|
require_once( 'includes/Simplify.php' ); |
78
|
|
|
|
79
|
|
|
Simplify::$publicKey = $this->public_key; |
80
|
|
|
Simplify::$privateKey = $this->private_key; |
81
|
|
|
Simplify::$userAgent = 'WooCommerce/' . WC()->version; |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* Admin Panel Options. |
86
|
|
|
* - Options for bits like 'title' and availability on a country-by-country basis. |
87
|
|
|
*/ |
88
|
|
|
public function admin_options() { |
89
|
|
|
?> |
90
|
|
|
<h3><?php _e( 'Simplify Commerce by MasterCard', 'woocommerce' ); ?></h3> |
91
|
|
|
|
92
|
|
|
<?php if ( empty( $this->public_key ) ) : ?> |
93
|
|
|
<div class="simplify-commerce-banner updated"> |
94
|
|
|
<img src="<?php echo WC()->plugin_url() . '/includes/gateways/simplify-commerce/assets/images/logo.png'; ?>" /> |
95
|
|
|
<p class="main"><strong><?php _e( 'Getting started', 'woocommerce' ); ?></strong></p> |
96
|
|
|
<p><?php _e( 'Simplify Commerce is your merchant account and payment gateway all rolled into one. Choose Simplify Commerce as your WooCommerce payment gateway to get access to your money quickly with a powerful, secure payment engine backed by MasterCard.', 'woocommerce' ); ?></p> |
97
|
|
|
|
98
|
|
|
<p><a href="https://www.simplify.com/commerce/partners/woocommerce#/signup" target="_blank" class="button button-primary"><?php _e( 'Sign up for Simplify Commerce', 'woocommerce' ); ?></a> <a href="https://www.simplify.com/commerce/partners/woocommerce#/" target="_blank" class="button"><?php _e( 'Learn more', 'woocommerce' ); ?></a></p> |
99
|
|
|
|
100
|
|
|
</div> |
101
|
|
|
<?php else : ?> |
102
|
|
|
<p><?php _e( 'Simplify Commerce is your merchant account and payment gateway all rolled into one. Choose Simplify Commerce as your WooCommerce payment gateway to get access to your money quickly with a powerful, secure payment engine backed by MasterCard.', 'woocommerce' ); ?></p> |
103
|
|
|
<?php endif; ?> |
104
|
|
|
|
105
|
|
|
<?php $this->checks(); ?> |
106
|
|
|
|
107
|
|
|
<table class="form-table"> |
108
|
|
|
<?php $this->generate_settings_html(); ?> |
109
|
|
|
<script type="text/javascript"> |
110
|
|
|
jQuery( '#woocommerce_simplify_commerce_sandbox' ).on( 'change', function() { |
111
|
|
|
var sandbox = jQuery( '#woocommerce_simplify_commerce_sandbox_public_key, #woocommerce_simplify_commerce_sandbox_private_key' ).closest( 'tr' ), |
112
|
|
|
production = jQuery( '#woocommerce_simplify_commerce_public_key, #woocommerce_simplify_commerce_private_key' ).closest( 'tr' ); |
113
|
|
|
|
114
|
|
|
if ( jQuery( this ).is( ':checked' ) ) { |
115
|
|
|
sandbox.show(); |
116
|
|
|
production.hide(); |
117
|
|
|
} else { |
118
|
|
|
sandbox.hide(); |
119
|
|
|
production.show(); |
120
|
|
|
} |
121
|
|
|
}).change(); |
122
|
|
|
|
123
|
|
|
jQuery( '#woocommerce_simplify_commerce_mode' ).on( 'change', function() { |
124
|
|
|
var color = jQuery( '#woocommerce_simplify_commerce_modal_color' ).closest( 'tr' ); |
125
|
|
|
|
126
|
|
|
if ( 'standard' === jQuery( this ).val() ) { |
127
|
|
|
color.hide(); |
128
|
|
|
} else { |
129
|
|
|
color.show(); |
130
|
|
|
} |
131
|
|
|
}).change(); |
132
|
|
|
</script> |
133
|
|
|
</table> |
134
|
|
|
<?php |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* Check if SSL is enabled and notify the user. |
139
|
|
|
*/ |
140
|
|
|
public function checks() { |
141
|
|
|
if ( 'no' == $this->enabled ) { |
142
|
|
|
return; |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
// PHP Version |
146
|
|
|
if ( version_compare( phpversion(), '5.3', '<' ) ) { |
147
|
|
|
echo '<div class="error"><p>' . sprintf( __( 'Simplify Commerce Error: Simplify commerce requires PHP 5.3 and above. You are using version %s.', 'woocommerce' ), phpversion() ) . '</p></div>'; |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
// Check required fields |
151
|
|
|
elseif ( ! $this->public_key || ! $this->private_key ) { |
152
|
|
|
echo '<div class="error"><p>' . __( 'Simplify Commerce Error: Please enter your public and private keys', 'woocommerce' ) . '</p></div>'; |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
// Show message when using standard mode and no SSL on the checkout page |
156
|
|
|
elseif ( 'standard' == $this->mode && ! wc_checkout_is_https() ) { |
157
|
|
|
echo '<div class="error"><p>' . sprintf( __( 'Simplify Commerce is enabled, but the <a href="%s">force SSL option</a> is disabled; your checkout may not be secure! Please enable SSL and ensure your server has a valid SSL certificate - Simplify Commerce will only work in sandbox mode.', 'woocommerce'), admin_url( 'admin.php?page=wc-settings&tab=checkout' ) ) . '</p></div>'; |
158
|
|
|
} |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
/** |
162
|
|
|
* Check if this gateway is enabled. |
163
|
|
|
* |
164
|
|
|
* @return bool |
165
|
|
|
*/ |
166
|
|
|
public function is_available() { |
167
|
|
|
if ( 'yes' !== $this->enabled ) { |
168
|
|
|
return false; |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
if ( 'standard' === $this->mode && 'yes' !== $this->sandbox && ! wc_checkout_is_https() ) { |
172
|
|
|
return false; |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
if ( ! $this->public_key || ! $this->private_key ) { |
176
|
|
|
return false; |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
return true; |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
/** |
183
|
|
|
* Initialise Gateway Settings Form Fields. |
184
|
|
|
*/ |
185
|
|
|
public function init_form_fields() { |
186
|
|
|
$this->form_fields = array( |
187
|
|
|
'enabled' => array( |
188
|
|
|
'title' => __( 'Enable/Disable', 'woocommerce' ), |
189
|
|
|
'label' => __( 'Enable Simplify Commerce', 'woocommerce' ), |
190
|
|
|
'type' => 'checkbox', |
191
|
|
|
'description' => '', |
192
|
|
|
'default' => 'no' |
193
|
|
|
), |
194
|
|
|
'title' => array( |
195
|
|
|
'title' => __( 'Title', 'woocommerce' ), |
196
|
|
|
'type' => 'text', |
197
|
|
|
'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ), |
198
|
|
|
'default' => __( 'Credit card', 'woocommerce' ), |
199
|
|
|
'desc_tip' => true |
200
|
|
|
), |
201
|
|
|
'description' => array( |
202
|
|
|
'title' => __( 'Description', 'woocommerce' ), |
203
|
|
|
'type' => 'text', |
204
|
|
|
'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce' ), |
205
|
|
|
'default' => 'Pay with your credit card via Simplify Commerce by MasterCard.', |
206
|
|
|
'desc_tip' => true |
207
|
|
|
), |
208
|
|
|
'mode' => array( |
209
|
|
|
'title' => __( 'Payment Mode', 'woocommerce' ), |
210
|
|
|
'label' => __( 'Enable Hosted Payments', 'woocommerce' ), |
211
|
|
|
'type' => 'select', |
212
|
|
|
'description' => sprintf( __( 'Standard will display the credit card fields on your store (SSL required). %1$s Hosted Payments will display a Simplify Commerce modal dialog on your store (if SSL) or will redirect the customer to Simplify Commerce hosted page (if not SSL). %1$s Note: Hosted Payments need a new API Key pair with the hosted payments flag selected. %2$sFor more details check the Simplify Commerce docs%3$s.', 'woocommerce' ), '<br />', '<a href="https://simplify.desk.com/customer/portal/articles/1792405-how-do-i-enable-hosted-payments" target="_blank">', '</a>' ), |
213
|
|
|
'default' => 'standard', |
214
|
|
|
'options' => array( |
215
|
|
|
'standard' => __( 'Standard', 'woocommerce' ), |
216
|
|
|
'hosted' => __( 'Hosted Payments', 'woocommerce' ) |
217
|
|
|
) |
218
|
|
|
), |
219
|
|
|
'modal_color' => array( |
220
|
|
|
'title' => __( 'Modal Color', 'woocommerce' ), |
221
|
|
|
'type' => 'color', |
222
|
|
|
'description' => __( 'Set the color of the buttons and titles on the modal dialog.', 'woocommerce' ), |
223
|
|
|
'default' => '#a46497', |
224
|
|
|
'desc_tip' => true |
225
|
|
|
), |
226
|
|
|
'sandbox' => array( |
227
|
|
|
'title' => __( 'Sandbox', 'woocommerce' ), |
228
|
|
|
'label' => __( 'Enable Sandbox Mode', 'woocommerce' ), |
229
|
|
|
'type' => 'checkbox', |
230
|
|
|
'description' => __( 'Place the payment gateway in sandbox mode using sandbox API keys (real payments will not be taken).', 'woocommerce' ), |
231
|
|
|
'default' => 'yes' |
232
|
|
|
), |
233
|
|
|
'sandbox_public_key' => array( |
234
|
|
|
'title' => __( 'Sandbox Public Key', 'woocommerce' ), |
235
|
|
|
'type' => 'text', |
236
|
|
|
'description' => __( 'Get your API keys from your Simplify account: Settings > API Keys.', 'woocommerce' ), |
237
|
|
|
'default' => '', |
238
|
|
|
'desc_tip' => true |
239
|
|
|
), |
240
|
|
|
'sandbox_private_key' => array( |
241
|
|
|
'title' => __( 'Sandbox Private Key', 'woocommerce' ), |
242
|
|
|
'type' => 'text', |
243
|
|
|
'description' => __( 'Get your API keys from your Simplify account: Settings > API Keys.', 'woocommerce' ), |
244
|
|
|
'default' => '', |
245
|
|
|
'desc_tip' => true |
246
|
|
|
), |
247
|
|
|
'public_key' => array( |
248
|
|
|
'title' => __( 'Public Key', 'woocommerce' ), |
249
|
|
|
'type' => 'text', |
250
|
|
|
'description' => __( 'Get your API keys from your Simplify account: Settings > API Keys.', 'woocommerce' ), |
251
|
|
|
'default' => '', |
252
|
|
|
'desc_tip' => true |
253
|
|
|
), |
254
|
|
|
'private_key' => array( |
255
|
|
|
'title' => __( 'Private Key', 'woocommerce' ), |
256
|
|
|
'type' => 'text', |
257
|
|
|
'description' => __( 'Get your API keys from your Simplify account: Settings > API Keys.', 'woocommerce' ), |
258
|
|
|
'default' => '', |
259
|
|
|
'desc_tip' => true |
260
|
|
|
), |
261
|
|
|
); |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
/** |
265
|
|
|
* Payment form on checkout page. |
266
|
|
|
*/ |
267
|
|
|
public function payment_fields() { |
268
|
|
|
$description = $this->get_description(); |
269
|
|
|
|
270
|
|
|
if ( 'yes' == $this->sandbox ) { |
271
|
|
|
$description .= ' ' . sprintf( __( 'TEST MODE ENABLED. Use a test card: %s', 'woocommerce' ), '<a href="https://www.simplify.com/commerce/docs/tutorial/index#testing">https://www.simplify.com/commerce/docs/tutorial/index#testing</a>' ); |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
if ( $description ) { |
275
|
|
|
echo wpautop( wptexturize( trim( $description ) ) ); |
276
|
|
|
} |
277
|
|
|
|
278
|
|
|
if ( 'standard' == $this->mode ) { |
279
|
|
|
parent::payment_fields(); |
280
|
|
|
} |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
/** |
284
|
|
|
* Outputs scripts used for simplify payment. |
285
|
|
|
*/ |
286
|
|
|
public function payment_scripts() { |
287
|
|
|
$load_scripts = false; |
288
|
|
|
|
289
|
|
|
if ( is_checkout() ) { |
290
|
|
|
$load_scripts = true; |
291
|
|
|
} |
292
|
|
|
if ( $this->is_available() ) { |
293
|
|
|
$load_scripts = true; |
294
|
|
|
} |
295
|
|
|
|
296
|
|
|
if ( false === $load_scripts ) { |
297
|
|
|
return; |
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
wp_enqueue_script( 'simplify-commerce', 'https://www.simplify.com/commerce/v1/simplify.js', array( 'jquery' ), WC_VERSION, true ); |
301
|
|
|
wp_enqueue_script( 'wc-simplify-commerce', WC()->plugin_url() . '/includes/gateways/simplify-commerce/assets/js/simplify-commerce.js', array( 'simplify-commerce', 'wc-credit-card-form' ), WC_VERSION, true ); |
302
|
|
|
wp_localize_script( 'wc-simplify-commerce', 'Simplify_commerce_params', array( |
303
|
|
|
'key' => $this->public_key, |
304
|
|
|
'card.number' => __( 'Card Number', 'woocommerce' ), |
305
|
|
|
'card.expMonth' => __( 'Expiry Month', 'woocommerce' ), |
306
|
|
|
'card.expYear' => __( 'Expiry Year', 'woocommerce' ), |
307
|
|
|
'is_invalid' => __( 'is invalid', 'woocommerce' ), |
308
|
|
|
'mode' => $this->mode, |
309
|
|
|
'is_ssl' => is_ssl() |
310
|
|
|
) ); |
311
|
|
|
} |
312
|
|
|
|
313
|
|
|
public function add_payment_method() { |
314
|
|
|
if ( empty ( $_POST['simplify_token'] ) ) { |
315
|
|
|
wc_add_notice( __( 'There was a problem adding this card.', 'woocommerce' ), 'error' ); |
316
|
|
|
return; |
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
$cart_token = wc_clean( $_POST['simplify_token'] ); |
320
|
|
|
$customer_token = $this->get_users_token(); |
321
|
|
|
$current_user = wp_get_current_user(); |
322
|
|
|
$customer_info = array( |
323
|
|
|
'email' => $current_user->user_email, |
324
|
|
|
'name' => $current_user->display_name, |
325
|
|
|
); |
326
|
|
|
|
327
|
|
|
$token = $this->save_token( $customer_token, $cart_token, $customer_info ); |
328
|
|
|
if ( is_null( $token ) ) { |
329
|
|
|
wc_add_notice( __( 'There was a problem adding this card.', 'woocommerce' ), 'error' ); |
330
|
|
|
return; |
331
|
|
|
} |
332
|
|
|
|
333
|
|
|
return array( |
334
|
|
|
'result' => 'success', |
335
|
|
|
'redirect' => wc_get_endpoint_url( 'payment-methods' ), |
336
|
|
|
); |
337
|
|
|
} |
338
|
|
|
|
339
|
|
|
/** |
340
|
|
|
* Actualy saves a customer token to the database. |
341
|
|
|
* |
342
|
|
|
* @param WC_Payment_Token $customer_token Payment Token |
343
|
|
|
* @param string $cart_token CC Token |
344
|
|
|
* @param array $customer_info 'email', 'name' |
345
|
|
|
*/ |
346
|
|
|
public function save_token( $customer_token, $cart_token, $customer_info ) { |
347
|
|
|
if ( ! is_null( $customer_token ) ) { |
348
|
|
|
$customer = Simplify_Customer::findCustomer( $customer_token->get_token() ); |
349
|
|
|
$updates = array( 'token' => $cart_token ); |
350
|
|
|
$customer->setAll( $updates ); |
351
|
|
|
$customer->updateCustomer(); |
352
|
|
|
$customer = Simplify_Customer::findCustomer( $customer_token->get_token() ); // get updated customer with new set card |
353
|
|
|
$token = $customer_token; |
354
|
|
|
} else { |
355
|
|
|
$customer = Simplify_Customer::createCustomer( array( |
356
|
|
|
'token' => $cart_token, |
357
|
|
|
'email' => $customer_info['email'], |
358
|
|
|
'name' => $customer_info['name'], |
359
|
|
|
) ); |
360
|
|
|
$token = new WC_Payment_Token_CC(); |
361
|
|
|
$token->set_token( $customer->id ); |
362
|
|
|
} |
363
|
|
|
|
364
|
|
|
// If we were able to create an save our card, save the data on our side too |
365
|
|
|
if ( is_object( $customer ) && '' != $customer->id ) { |
366
|
|
|
$customer_properties = $customer->getProperties(); |
367
|
|
|
$card = $customer_properties['card']; |
368
|
|
|
$token->set_gateway_id( $this->id ); |
369
|
|
|
$token->set_card_type( strtolower( $card->type ) ); |
370
|
|
|
$token->set_last4( $card->last4 ); |
371
|
|
|
$expiry_month = ( 1 === strlen( $card->expMonth ) ? '0' . $card->expMonth : $card->expMonth ); |
372
|
|
|
$token->set_expiry_month( $expiry_month ); |
373
|
|
|
$token->set_expiry_year( '20' . $card->expYear ); |
374
|
|
|
if ( is_user_logged_in() ) { |
375
|
|
|
$token->set_user_id( get_current_user_id() ); |
376
|
|
|
} |
377
|
|
|
$token->save(); |
378
|
|
|
return $token; |
379
|
|
|
} |
380
|
|
|
|
381
|
|
|
return null; |
382
|
|
|
} |
383
|
|
|
|
384
|
|
|
/** |
385
|
|
|
* Process customer: updating or creating a new customer/saved CC |
386
|
|
|
* |
387
|
|
|
* @param WC_Order $order Order object |
388
|
|
|
* @param WC_Payment_Token $customer_token Payment Token |
389
|
|
|
* @param string $cart_token CC Token |
390
|
|
|
*/ |
391
|
|
|
protected function process_customer( $order, $customer_token = null, $cart_token = '' ) { |
392
|
|
|
// Are we saving a new payment method? |
393
|
|
|
if ( is_user_logged_in() && isset( $_POST['wc-simplify_commerce-new-payment-method'] ) && true === (bool) $_POST['wc-simplify_commerce-new-payment-method'] ) { |
394
|
|
|
$customer_info = array( |
395
|
|
|
'email' => $order->billing_email, |
396
|
|
|
'name' => trim( $order->get_formatted_billing_full_name() ), |
397
|
|
|
); |
398
|
|
|
$token = $this->save_token( $customer_token, $cart_token, $customer_info ); |
399
|
|
|
if ( ! is_null( $token ) ) { |
400
|
|
|
$order->add_payment_token( $token ); |
401
|
|
|
} |
402
|
|
|
} |
403
|
|
|
} |
404
|
|
|
|
405
|
|
|
/** |
406
|
|
|
* Process standard payments. |
407
|
|
|
* |
408
|
|
|
* @param WC_Order $order |
409
|
|
|
* @param string $cart_token |
410
|
|
|
* @uses Simplify_ApiException |
411
|
|
|
* @uses Simplify_BadRequestException |
412
|
|
|
* @return array |
413
|
|
|
*/ |
414
|
|
|
protected function process_standard_payments( $order, $cart_token = '', $customer_token = '' ) { |
415
|
|
|
try { |
416
|
|
|
|
417
|
|
|
if ( empty( $cart_token ) && empty( $customer_token ) ) { |
418
|
|
|
$error_msg = __( 'Please make sure your card details have been entered correctly and that your browser supports JavaScript.', 'woocommerce' ); |
419
|
|
|
|
420
|
|
|
if ( 'yes' == $this->sandbox ) { |
421
|
|
|
$error_msg .= ' ' . __( 'Developers: Please make sure that you\'re including jQuery and there are no JavaScript errors on the page.', 'woocommerce' ); |
422
|
|
|
} |
423
|
|
|
|
424
|
|
|
throw new Simplify_ApiException( $error_msg ); |
425
|
|
|
} |
426
|
|
|
|
427
|
|
|
// We need to figure out if we want to charge the card token (new unsaved token, no customer, etc) |
428
|
|
|
// or the customer token (just saved method, previously saved method) |
429
|
|
|
$pass_tokens = array(); |
430
|
|
|
|
431
|
|
|
if ( ! empty ( $cart_token ) ) { |
432
|
|
|
$pass_tokens['token'] = $cart_token; |
433
|
|
|
} |
434
|
|
|
|
435
|
|
|
if ( ! empty ( $customer_token ) ) { |
436
|
|
|
$pass_tokens['customer'] = $customer_token; |
437
|
|
|
// Use the customer token only, since we already saved the (one time use) card token to the customer |
438
|
|
|
if ( isset( $_POST['wc-simplify_commerce-new-payment-method'] ) && true === (bool) $_POST['wc-simplify_commerce-new-payment-method'] ) { |
439
|
|
|
unset( $pass_tokens['token'] ); |
440
|
|
|
} |
441
|
|
|
} |
442
|
|
|
|
443
|
|
|
// Did we create an account and save a payment method? We might need to use the customer token instead of the card token |
444
|
|
|
if ( isset( $_POST['createaccount'] ) && true === (bool) $_POST['createaccount'] && empty ( $customer_token ) ) { |
445
|
|
|
$user_token = $this->get_users_token(); |
446
|
|
|
if ( ! is_null( $user_token ) ) { |
447
|
|
|
$pass_tokens['customer'] = $user_token->get_token(); |
448
|
|
|
unset( $pass_tokens['token'] ); |
449
|
|
|
} |
450
|
|
|
} |
451
|
|
|
|
452
|
|
|
$payment_response = $this->do_payment( $order, $order->get_total(), $pass_tokens ); |
453
|
|
|
|
454
|
|
|
if ( is_wp_error( $payment_response ) ) { |
455
|
|
|
throw new Exception( $payment_response->get_error_message() ); |
456
|
|
|
} else { |
457
|
|
|
// Remove cart |
458
|
|
|
WC()->cart->empty_cart(); |
459
|
|
|
|
460
|
|
|
// Return thank you page redirect |
461
|
|
|
return array( |
462
|
|
|
'result' => 'success', |
463
|
|
|
'redirect' => $this->get_return_url( $order ) |
464
|
|
|
); |
465
|
|
|
} |
466
|
|
|
|
467
|
|
|
} catch ( Simplify_ApiException $e ) { |
468
|
|
|
if ( $e instanceof Simplify_BadRequestException && $e->hasFieldErrors() && $e->getFieldErrors() ) { |
469
|
|
|
foreach ( $e->getFieldErrors() as $error ) { |
470
|
|
|
wc_add_notice( $error->getFieldName() . ': "' . $error->getMessage() . '" (' . $error->getErrorCode() . ')', 'error' ); |
471
|
|
|
} |
472
|
|
|
} else { |
473
|
|
|
wc_add_notice( $e->getMessage(), 'error' ); |
474
|
|
|
} |
475
|
|
|
|
476
|
|
|
return array( |
477
|
|
|
'result' => 'fail', |
478
|
|
|
'redirect' => '' |
479
|
|
|
); |
480
|
|
|
} |
481
|
|
|
} |
482
|
|
|
|
483
|
|
|
/** |
484
|
|
|
* do payment function. |
485
|
|
|
* |
486
|
|
|
* @param WC_order $order |
487
|
|
|
* @param int $amount (default: 0) |
488
|
|
|
* @uses Simplify_BadRequestException |
489
|
|
|
* @return bool|WP_Error |
490
|
|
|
*/ |
491
|
|
|
public function do_payment( $order, $amount = 0, $token = array() ) { |
492
|
|
|
if ( $amount * 100 < 50 ) { |
493
|
|
|
return new WP_Error( 'simplify_error', __( 'Sorry, the minimum allowed order total is 0.50 to use this payment method.', 'woocommerce' ) ); |
494
|
|
|
} |
495
|
|
|
|
496
|
|
|
try { |
497
|
|
|
// Charge the customer |
498
|
|
|
$data = array( |
499
|
|
|
'amount' => $amount * 100, // In cents. |
500
|
|
|
'description' => sprintf( __( '%s - Order #%s', 'woocommerce' ), esc_html( get_bloginfo( 'name', 'display' ) ), $order->get_order_number() ), |
501
|
|
|
'currency' => strtoupper( get_woocommerce_currency() ), |
502
|
|
|
'reference' => $order->id |
503
|
|
|
); |
504
|
|
|
|
505
|
|
|
$data = array_merge( $data, $token ); |
506
|
|
|
$payment = Simplify_Payment::createPayment( $data ); |
507
|
|
|
|
508
|
|
|
} catch ( Exception $e ) { |
509
|
|
|
|
510
|
|
|
$error_message = $e->getMessage(); |
511
|
|
|
|
512
|
|
|
if ( $e instanceof Simplify_BadRequestException && $e->hasFieldErrors() && $e->getFieldErrors() ) { |
513
|
|
|
$error_message = ''; |
514
|
|
|
foreach ( $e->getFieldErrors() as $error ) { |
515
|
|
|
$error_message .= ' ' . $error->getFieldName() . ': "' . $error->getMessage() . '" (' . $error->getErrorCode() . ')'; |
516
|
|
|
} |
517
|
|
|
} |
518
|
|
|
|
519
|
|
|
$order->add_order_note( sprintf( __( 'Simplify payment error: %s', 'woocommerce' ), $error_message ) ); |
520
|
|
|
|
521
|
|
|
return new WP_Error( 'simplify_payment_declined', $e->getMessage(), array( 'status' => $e->getCode() ) ); |
522
|
|
|
} |
523
|
|
|
|
524
|
|
|
if ( 'APPROVED' == $payment->paymentStatus ) { |
525
|
|
|
// Payment complete |
526
|
|
|
$order->payment_complete( $payment->id ); |
527
|
|
|
|
528
|
|
|
// Add order note |
529
|
|
|
$order->add_order_note( sprintf( __( 'Simplify payment approved (ID: %s, Auth Code: %s)', 'woocommerce' ), $payment->id, $payment->authCode ) ); |
530
|
|
|
|
531
|
|
|
return true; |
532
|
|
|
} else { |
533
|
|
|
$order->add_order_note( __( 'Simplify payment declined', 'woocommerce' ) ); |
534
|
|
|
|
535
|
|
|
return new WP_Error( 'simplify_payment_declined', __( 'Payment was declined - please try another card.', 'woocommerce' ) ); |
536
|
|
|
} |
537
|
|
|
} |
538
|
|
|
|
539
|
|
|
/** |
540
|
|
|
* Process standard payments. |
541
|
|
|
* |
542
|
|
|
* @param WC_Order $order |
543
|
|
|
* @return array |
544
|
|
|
*/ |
545
|
|
|
protected function process_hosted_payments( $order ) { |
546
|
|
|
return array( |
547
|
|
|
'result' => 'success', |
548
|
|
|
'redirect' => $order->get_checkout_payment_url( true ) |
549
|
|
|
); |
550
|
|
|
} |
551
|
|
|
|
552
|
|
|
protected function get_users_token() { |
553
|
|
|
$customer_token = null; |
554
|
|
|
if ( is_user_logged_in() ) { |
555
|
|
|
$tokens = WC_Payment_Tokens::get_customer_tokens( get_current_user_id() ) ; |
556
|
|
|
foreach ( $tokens as $token ) { |
557
|
|
|
if ( $token->get_gateway_id() === $this->id ) { |
558
|
|
|
$customer_token = $token; |
559
|
|
|
break; |
560
|
|
|
} |
561
|
|
|
} |
562
|
|
|
} |
563
|
|
|
return $customer_token; |
564
|
|
|
} |
565
|
|
|
|
566
|
|
|
/** |
567
|
|
|
* Process the payment. |
568
|
|
|
* |
569
|
|
|
* @param int $order_id |
570
|
|
|
*/ |
571
|
|
|
public function process_payment( $order_id ) { |
572
|
|
|
$order = wc_get_order( $order_id ); |
573
|
|
|
|
574
|
|
|
// Payment/CC form is hosted on Simplify |
575
|
|
|
if ( 'hosted' === $this->mode ) { |
576
|
|
|
return $this->process_hosted_payments( $order ); |
577
|
|
|
} |
578
|
|
|
|
579
|
|
|
// New CC info was entered |
580
|
|
|
if ( isset( $_POST['simplify_token'] ) ) { |
581
|
|
|
$cart_token = wc_clean( $_POST['simplify_token'] ); |
582
|
|
|
$customer_token = $this->get_users_token(); |
583
|
|
|
$customer_token_value = ( ! is_null( $customer_token ) ? $customer_token->get_token() : '' ); |
584
|
|
|
$this->process_customer( $order, $customer_token, $cart_token ); |
585
|
|
|
return $this->process_standard_payments( $order, $cart_token, $customer_token_value ); |
586
|
|
|
} |
587
|
|
|
|
588
|
|
|
// Possibly Create (or update) customer/save payment token, use an existing token, and then process the payment |
589
|
|
|
if ( isset( $_POST['wc-simplify_commerce-payment-token'] ) && 'new' !== $_POST['wc-simplify_commerce-payment-token'] ) { |
590
|
|
|
$token_id = wc_clean( $_POST['wc-simplify_commerce-payment-token'] ); |
591
|
|
|
$token = WC_Payment_Tokens::get( $token_id ); |
592
|
|
|
if ( $token->get_user_id() !== get_current_user_id() ) { |
593
|
|
|
wc_add_notice( __( 'Please make sure your card details have been entered correctly and that your browser supports JavaScript.', 'woocommerce' ), 'error' ); |
594
|
|
|
return; |
595
|
|
|
} |
596
|
|
|
$this->process_customer( $order, $token ); |
597
|
|
|
return $this->process_standard_payments( $order, '', $token->get_token() ); |
598
|
|
|
} |
599
|
|
|
} |
600
|
|
|
|
601
|
|
|
/** |
602
|
|
|
* Hosted payment args. |
603
|
|
|
* |
604
|
|
|
* @param WC_Order $order |
605
|
|
|
* |
606
|
|
|
* @return array |
607
|
|
|
*/ |
608
|
|
|
protected function get_hosted_payments_args( $order ) { |
609
|
|
|
$args = apply_filters( 'woocommerce_simplify_commerce_hosted_args', array( |
610
|
|
|
'sc-key' => $this->public_key, |
611
|
|
|
'amount' => $order->order_total * 100, |
612
|
|
|
'reference' => $order->id, |
613
|
|
|
'name' => esc_html( get_bloginfo( 'name', 'display' ) ), |
614
|
|
|
'description' => sprintf( __( 'Order #%s', 'woocommerce' ), $order->get_order_number() ), |
615
|
|
|
'receipt' => 'false', |
616
|
|
|
'color' => $this->modal_color, |
617
|
|
|
'redirect-url' => WC()->api_request_url( 'WC_Gateway_Simplify_Commerce' ), |
618
|
|
|
'address' => $order->billing_address_1 . ' ' . $order->billing_address_2, |
619
|
|
|
'address-city' => $order->billing_city, |
620
|
|
|
'address-state' => $order->billing_state, |
621
|
|
|
'address-zip' => $order->billing_postcode, |
622
|
|
|
'address-country' => $order->billing_country, |
623
|
|
|
'operation' => 'create.token', |
624
|
|
|
), $order->id ); |
625
|
|
|
|
626
|
|
|
return $args; |
627
|
|
|
} |
628
|
|
|
|
629
|
|
|
/** |
630
|
|
|
* Receipt page. |
631
|
|
|
* |
632
|
|
|
* @param int $order_id |
633
|
|
|
*/ |
634
|
|
|
public function receipt_page( $order_id ) { |
635
|
|
|
$order = wc_get_order( $order_id ); |
636
|
|
|
|
637
|
|
|
echo '<p>' . __( 'Thank you for your order, please click the button below to pay with credit card using Simplify Commerce by MasterCard.', 'woocommerce' ) . '</p>'; |
638
|
|
|
|
639
|
|
|
$args = $this->get_hosted_payments_args( $order ); |
640
|
|
|
$button_args = array(); |
641
|
|
|
foreach ( $args as $key => $value ) { |
642
|
|
|
$button_args[] = 'data-' . esc_attr( $key ) . '="' . esc_attr( $value ) . '"'; |
643
|
|
|
} |
644
|
|
|
|
645
|
|
|
echo '<script type="text/javascript" src="https://www.simplify.com/commerce/simplify.pay.js"></script> |
646
|
|
|
<button class="button alt" id="simplify-payment-button" ' . implode( ' ', $button_args ) . '>' . __( 'Pay Now', 'woocommerce' ) . '</button> <a class="button cancel" href="' . esc_url( $order->get_cancel_order_url() ) . '">' . __( 'Cancel order & restore cart', 'woocommerce' ) . '</a> |
647
|
|
|
'; |
648
|
|
|
} |
649
|
|
|
|
650
|
|
|
/** |
651
|
|
|
* Return handler for Hosted Payments. |
652
|
|
|
*/ |
653
|
|
|
public function return_handler() { |
654
|
|
|
@ob_clean(); |
655
|
|
|
header( 'HTTP/1.1 200 OK' ); |
656
|
|
|
|
657
|
|
|
if ( isset( $_REQUEST['reference'] ) && isset( $_REQUEST['paymentId'] ) && isset( $_REQUEST['signature'] ) ) { |
658
|
|
|
$signature = strtoupper( md5( $_REQUEST['amount'] . $_REQUEST['reference'] . $_REQUEST['paymentId'] . $_REQUEST['paymentDate'] . $_REQUEST['paymentStatus'] . $this->private_key ) ); |
659
|
|
|
$order_id = absint( $_REQUEST['reference'] ); |
660
|
|
|
$order = wc_get_order( $order_id ); |
661
|
|
|
|
662
|
|
|
if ( $signature === $_REQUEST['signature'] ) { |
663
|
|
|
$order_complete = $this->process_order_status( $order, $_REQUEST['paymentId'], $_REQUEST['paymentStatus'], $_REQUEST['paymentDate'] ); |
664
|
|
|
|
665
|
|
|
if ( ! $order_complete ) { |
666
|
|
|
$order->update_status( 'failed', __( 'Payment was declined by Simplify Commerce.', 'woocommerce' ) ); |
667
|
|
|
} |
668
|
|
|
|
669
|
|
|
wp_redirect( $this->get_return_url( $order ) ); |
670
|
|
|
exit(); |
671
|
|
|
} |
672
|
|
|
} |
673
|
|
|
|
674
|
|
|
wp_redirect( wc_get_page_permalink( 'cart' ) ); |
675
|
|
|
exit(); |
676
|
|
|
} |
677
|
|
|
|
678
|
|
|
/** |
679
|
|
|
* Process the order status. |
680
|
|
|
* |
681
|
|
|
* @param WC_Order $order |
682
|
|
|
* @param string $payment_id |
683
|
|
|
* @param string $status |
684
|
|
|
* @param string $auth_code |
685
|
|
|
* |
686
|
|
|
* @return bool |
687
|
|
|
*/ |
688
|
|
|
public function process_order_status( $order, $payment_id, $status, $auth_code ) { |
689
|
|
|
if ( 'APPROVED' == $status ) { |
690
|
|
|
// Payment complete |
691
|
|
|
$order->payment_complete( $payment_id ); |
692
|
|
|
|
693
|
|
|
// Add order note |
694
|
|
|
$order->add_order_note( sprintf( __( 'Simplify payment approved (ID: %s, Auth Code: %s)', 'woocommerce' ), $payment_id, $auth_code ) ); |
695
|
|
|
|
696
|
|
|
// Remove cart |
697
|
|
|
WC()->cart->empty_cart(); |
698
|
|
|
|
699
|
|
|
return true; |
700
|
|
|
} |
701
|
|
|
|
702
|
|
|
return false; |
703
|
|
|
} |
704
|
|
|
|
705
|
|
|
/** |
706
|
|
|
* Process refunds. |
707
|
|
|
* WooCommerce 2.2 or later. |
708
|
|
|
* |
709
|
|
|
* @param int $order_id |
710
|
|
|
* @param float $amount |
711
|
|
|
* @param string $reason |
712
|
|
|
* @uses Simplify_ApiException |
713
|
|
|
* @uses Simplify_BadRequestException |
714
|
|
|
* @return bool|WP_Error |
715
|
|
|
*/ |
716
|
|
|
public function process_refund( $order_id, $amount = null, $reason = '' ) { |
717
|
|
|
try { |
718
|
|
|
$payment_id = get_post_meta( $order_id, '_transaction_id', true ); |
719
|
|
|
|
720
|
|
|
$refund = Simplify_Refund::createRefund( array( |
721
|
|
|
'amount' => $amount * 100, // In cents. |
722
|
|
|
'payment' => $payment_id, |
723
|
|
|
'reason' => $reason, |
724
|
|
|
'reference' => $order_id |
725
|
|
|
) ); |
726
|
|
|
|
727
|
|
|
if ( 'APPROVED' == $refund->paymentStatus ) { |
728
|
|
|
return true; |
729
|
|
|
} else { |
730
|
|
|
throw new Simplify_ApiException( __( 'Refund was declined.', 'woocommerce' ) ); |
731
|
|
|
} |
732
|
|
|
|
733
|
|
|
} catch ( Simplify_ApiException $e ) { |
734
|
|
|
if ( $e instanceof Simplify_BadRequestException && $e->hasFieldErrors() && $e->getFieldErrors() ) { |
735
|
|
|
foreach ( $e->getFieldErrors() as $error ) { |
736
|
|
|
return new WP_Error( 'simplify_refund_error', $error->getFieldName() . ': "' . $error->getMessage() . '" (' . $error->getErrorCode() . ')' ); |
737
|
|
|
} |
738
|
|
|
} else { |
739
|
|
|
return new WP_Error( 'simplify_refund_error', $e->getMessage() ); |
740
|
|
|
} |
741
|
|
|
} |
742
|
|
|
|
743
|
|
|
return false; |
744
|
|
|
} |
745
|
|
|
|
746
|
|
|
/** |
747
|
|
|
* Get gateway icon. |
748
|
|
|
* |
749
|
|
|
* @access public |
750
|
|
|
* @return string |
751
|
|
|
*/ |
752
|
|
|
public function get_icon() { |
753
|
|
|
$icon = '<img src="' . WC_HTTPS::force_https_url( WC()->plugin_url() . '/assets/images/icons/credit-cards/visa.svg' ) . '" alt="Visa" width="32" />'; |
754
|
|
|
$icon .= '<img src="' . WC_HTTPS::force_https_url( WC()->plugin_url() . '/assets/images/icons/credit-cards/mastercard.svg' ) . '" alt="MasterCard" width="32" />'; |
755
|
|
|
$icon .= '<img src="' . WC_HTTPS::force_https_url( WC()->plugin_url() . '/assets/images/icons/credit-cards/discover.svg' ) . '" alt="Discover" width="32" />'; |
756
|
|
|
$icon .= '<img src="' . WC_HTTPS::force_https_url( WC()->plugin_url() . '/assets/images/icons/credit-cards/amex.svg' ) . '" alt="Amex" width="32" />'; |
757
|
|
|
$icon .= '<img src="' . WC_HTTPS::force_https_url( WC()->plugin_url() . '/assets/images/icons/credit-cards/jcb.svg' ) . '" alt="JCB" width="32" />'; |
758
|
|
|
|
759
|
|
|
return apply_filters( 'woocommerce_gateway_icon', $icon, $this->id ); |
760
|
|
|
} |
761
|
|
|
} |
762
|
|
|
|