1
|
|
|
<?php |
|
|
|
|
2
|
|
|
|
3
|
|
|
use Omnipay\Omnipay; |
4
|
|
|
use Omnipay\Common\Exception\InvalidResponseException; |
5
|
|
|
use Omnipay\Common\Exception\OmnipayException; |
6
|
|
|
|
7
|
|
|
if ( !defined('ABSPATH') ) exit; |
|
|
|
|
8
|
|
|
|
9
|
|
|
/** |
10
|
|
|
* WC_Gateway_FirstAtlanticCommerce class |
11
|
|
|
* |
12
|
|
|
* @extends WC_Payment_Gateway |
13
|
|
|
*/ |
14
|
|
|
class WC_Gateway_FirstAtlanticCommerce extends WC_Payment_Gateway |
|
|
|
|
15
|
|
|
{ |
16
|
|
|
/** |
|
|
|
|
17
|
|
|
* Constructor |
|
|
|
|
18
|
|
|
*/ |
|
|
|
|
19
|
|
|
public function __construct() |
|
|
|
|
20
|
|
|
{ |
|
|
|
|
21
|
|
|
$this->id = 'fac'; |
|
|
|
|
22
|
|
|
$this->method_title = __('First Atlantic Commerce', 'wc-gateway-fac'); |
|
|
|
|
23
|
|
|
$this->method_description = __('First Atlantic Commerce works by adding credit card fields on the checkout and then sending the details to First Atlantic Commerce for verification.', 'wc-gateway-fac'); |
|
|
|
|
24
|
|
|
$this->has_fields = true; |
|
|
|
|
25
|
|
|
$this->supports = [ |
|
|
|
|
26
|
|
|
//'subscriptions', |
|
|
|
|
27
|
|
|
'products', |
|
|
|
|
28
|
|
|
'refunds', |
|
|
|
|
29
|
|
|
//'subscription_cancellation', |
|
|
|
|
30
|
|
|
//'subscription_reactivation', |
|
|
|
|
31
|
|
|
//'subscription_suspension', |
|
|
|
|
32
|
|
|
//'subscription_amount_changes', |
|
|
|
|
33
|
|
|
//'subscription_payment_method_change', |
|
|
|
|
34
|
|
|
//'subscription_date_changes', |
|
|
|
|
35
|
|
|
//'pre-orders', |
|
|
|
|
36
|
|
|
'default_credit_card_form' |
|
|
|
|
37
|
|
|
]; |
|
|
|
|
38
|
|
|
|
39
|
|
|
// Load the form fields |
|
|
|
|
40
|
|
|
$this->init_form_fields(); |
|
|
|
|
41
|
|
|
|
42
|
|
|
// Load the settings |
|
|
|
|
43
|
|
|
$this->init_settings(); |
|
|
|
|
44
|
|
|
|
45
|
|
|
// User defined settings |
|
|
|
|
46
|
|
|
$this->title = $this->get_option('title'); |
|
|
|
|
47
|
|
|
$this->description = $this->get_option('description'); |
|
|
|
|
48
|
|
|
$this->enabled = $this->get_option('enabled'); |
|
|
|
|
49
|
|
|
$this->testmode = 'yes' === $this->get_option('testmode', 'no'); |
|
|
|
|
50
|
|
|
$this->capture = $this->get_option('capture', "yes") === "yes" ? true : false; |
|
|
|
|
51
|
|
|
//$this->saved_cards = $this->get_option( 'saved_cards' ) === "yes" ? true : false; |
|
|
|
|
52
|
|
|
$this->merchant_id = $this->testmode ? $this->get_option('test_merchant_id') : $this->get_option('merchant_id'); |
|
|
|
|
53
|
|
|
$this->merchant_password = $this->testmode ? $this->get_option('test_merchant_password') : $this->get_option('merchant_password'); |
|
|
|
|
54
|
|
|
|
55
|
|
|
// Hooks |
|
|
|
|
56
|
|
|
add_action('admin_notices', [$this, 'admin_notices']); |
|
|
|
|
57
|
|
|
add_action('woocommerce_update_options_payment_gateways_' . $this->id, [$this, 'process_admin_options']); |
|
|
|
|
58
|
|
|
} |
|
|
|
|
59
|
|
|
|
60
|
|
|
/** |
|
|
|
|
61
|
|
|
* Notify of issues in wp-admin |
|
|
|
|
62
|
|
|
*/ |
|
|
|
|
63
|
|
|
public function admin_notices() |
|
|
|
|
64
|
|
|
{ |
|
|
|
|
65
|
|
|
if ($this->enabled == 'no') |
|
|
|
|
66
|
|
|
{ |
|
|
|
|
67
|
|
|
return; |
|
|
|
|
68
|
|
|
} |
|
|
|
|
69
|
|
|
|
70
|
|
|
// Check required fields |
|
|
|
|
71
|
|
|
if (!$this->merchant_id) |
|
|
|
|
72
|
|
|
{ |
|
|
|
|
73
|
|
|
echo '<div class="error"><p>' . sprintf( __( 'First Atlantic Commerce error: Please enter your merchant id <a href="%s">here</a>', 'woocommerce-gateway-fac' ), admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=wc_gateway_fac' ) ) . '</p></div>'; |
|
|
|
|
74
|
|
|
return; |
|
|
|
|
75
|
|
|
} |
|
|
|
|
76
|
|
|
elseif (!$this->merchant_password) |
|
|
|
|
77
|
|
|
{ |
|
|
|
|
78
|
|
|
echo '<div class="error"><p>' . sprintf( __( 'First Atlantic Commerce error: Please enter your merchant password <a href="%s">here</a>', 'woocommerce-gateway-fac' ), admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=wc_gateway_fac' ) ) . '</p></div>'; |
|
|
|
|
79
|
|
|
return; |
|
|
|
|
80
|
|
|
} |
|
|
|
|
81
|
|
|
|
82
|
|
|
// Check if enabled and force SSL is disabled |
|
|
|
|
83
|
|
|
if ( get_option('woocommerce_force_ssl_checkout') == 'no' ) { |
|
|
|
|
84
|
|
|
echo '<div class="error"><p>' . sprintf( __( 'First Atlantic 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 - First Atlantic Commerce will only work in test mode.', 'woocommerce-gateway-fac' ), admin_url( 'admin.php?page=wc-settings&tab=checkout' ) ) . '</p></div>'; |
|
|
|
|
85
|
|
|
return; |
|
|
|
|
86
|
|
|
} |
|
|
|
|
87
|
|
|
} |
|
|
|
|
88
|
|
|
|
89
|
|
|
/** |
|
|
|
|
90
|
|
|
* Logging method |
|
|
|
|
91
|
|
|
* |
|
|
|
|
92
|
|
|
* @param string $message |
|
|
|
|
93
|
|
|
* |
|
|
|
|
94
|
|
|
* @return void |
|
|
|
|
95
|
|
|
*/ |
|
|
|
|
96
|
|
|
public function log($message) |
|
|
|
|
97
|
|
|
{ |
|
|
|
|
98
|
|
|
if ( empty($this->log) ) |
|
|
|
|
99
|
|
|
{ |
|
|
|
|
100
|
|
|
$this->log = new WC_Logger(); |
|
|
|
|
101
|
|
|
} |
|
|
|
|
102
|
|
|
|
103
|
|
|
$this->log->add($this->id, $message); |
|
|
|
|
104
|
|
|
} |
|
|
|
|
105
|
|
|
|
106
|
|
|
/** |
|
|
|
|
107
|
|
|
* Check if the gateway is available for use |
|
|
|
|
108
|
|
|
* |
|
|
|
|
109
|
|
|
* @return bool |
|
|
|
|
110
|
|
|
*/ |
|
|
|
|
111
|
|
|
public function is_available() |
|
|
|
|
112
|
|
|
{ |
|
|
|
|
113
|
|
|
$is_available = parent::is_available(); |
|
|
|
|
114
|
|
|
|
115
|
|
|
// Only allow unencrypted connections when testing |
|
|
|
|
116
|
|
|
if (!is_ssl() && !$this->testmode) |
|
|
|
|
117
|
|
|
{ |
|
|
|
|
118
|
|
|
$is_available = false; |
|
|
|
|
119
|
|
|
} |
|
|
|
|
120
|
|
|
|
121
|
|
|
// Required fields check |
|
|
|
|
122
|
|
|
if (!$this->merchant_id || !$this->merchant_password) |
|
|
|
|
123
|
|
|
{ |
|
|
|
|
124
|
|
|
$is_available = false; |
|
|
|
|
125
|
|
|
} |
|
|
|
|
126
|
|
|
|
127
|
|
|
return $is_available; |
|
|
|
|
128
|
|
|
} |
|
|
|
|
129
|
|
|
|
130
|
|
|
/** |
|
|
|
|
131
|
|
|
* Initialise Gateway Settings Form Fields |
|
|
|
|
132
|
|
|
*/ |
|
|
|
|
133
|
|
|
public function init_form_fields() |
|
|
|
|
134
|
|
|
{ |
|
|
|
|
135
|
|
|
$this->form_fields = apply_filters('wc_fac_settings', [ |
|
|
|
|
136
|
|
|
'enabled' => [ |
|
|
|
|
137
|
|
|
'title' => __('Enable/Disable', 'woocommerce-gateway-fac'), |
|
|
|
|
138
|
|
|
'label' => __('Enable FAC', 'woocommerce-gateway-fac'), |
|
|
|
|
139
|
|
|
'type' => 'checkbox', |
|
|
|
|
140
|
|
|
'description' => '', |
|
|
|
|
141
|
|
|
'default' => 'no' |
|
|
|
|
142
|
|
|
], |
|
|
|
|
143
|
|
|
'title' => [ |
|
|
|
|
144
|
|
|
'title' => __('Title', 'woocommerce-gateway-fac'), |
|
|
|
|
145
|
|
|
'type' => 'text', |
|
|
|
|
146
|
|
|
'description' => __('This controls the title which the user sees during checkout.', 'woocommerce-gateway-fac'), |
|
|
|
|
147
|
|
|
'default' => __('Credit card', 'woocommerce-gateway-fac') |
|
|
|
|
148
|
|
|
], |
|
|
|
|
149
|
|
|
'description' => [ |
|
|
|
|
150
|
|
|
'title' => __('Description', 'woocommerce-gateway-fac'), |
|
|
|
|
151
|
|
|
'type' => 'textarea', |
|
|
|
|
152
|
|
|
'description' => __('This controls the description which the user sees during checkout.', 'woocommerce-gateway-fac'), |
|
|
|
|
153
|
|
|
'default' => __('Pay with your credit card.', 'woocommerce-gateway-fac') |
|
|
|
|
154
|
|
|
], |
|
|
|
|
155
|
|
|
'testmode' => [ |
|
|
|
|
156
|
|
|
'title' => __('Test mode', 'woocommerce-gateway-fac'), |
|
|
|
|
157
|
|
|
'label' => __('Enable Test Mode', 'woocommerce-gateway-fac'), |
|
|
|
|
158
|
|
|
'type' => 'checkbox', |
|
|
|
|
159
|
|
|
'description' => __('Place the payment gateway in test mode using test API credentials.', 'woocommerce-gateway-fac'), |
|
|
|
|
160
|
|
|
'default' => 'yes' |
|
|
|
|
161
|
|
|
], |
|
|
|
|
162
|
|
|
'merchant_id' => [ |
|
|
|
|
163
|
|
|
'title' => __('Live Merchant ID', 'woocommerce-gateway-fac'), |
|
|
|
|
164
|
|
|
'type' => 'text', |
|
|
|
|
165
|
|
|
'description' => __('Get your API credentials from your merchant account.', 'woocommerce-gateway-fac'), |
|
|
|
|
166
|
|
|
'default' => '' |
|
|
|
|
167
|
|
|
], |
|
|
|
|
168
|
|
|
'merchant_password' => [ |
|
|
|
|
169
|
|
|
'title' => __('Live Merchant Password', 'woocommerce-gateway-fac'), |
|
|
|
|
170
|
|
|
'type' => 'text', |
|
|
|
|
171
|
|
|
'description' => __('Get your API credentials from your merchant account.', 'woocommerce-gateway-fac'), |
|
|
|
|
172
|
|
|
'default' => '' |
|
|
|
|
173
|
|
|
], |
|
|
|
|
174
|
|
|
'test_merchant_id' => [ |
|
|
|
|
175
|
|
|
'title' => __('Test Merchant ID', 'woocommerce-gateway-fac'), |
|
|
|
|
176
|
|
|
'type' => 'text', |
|
|
|
|
177
|
|
|
'description' => __('Get your API credentials from your merchant account.', 'woocommerce-gateway-fac'), |
|
|
|
|
178
|
|
|
'default' => '' |
|
|
|
|
179
|
|
|
], |
|
|
|
|
180
|
|
|
'test_merchant_password' => [ |
|
|
|
|
181
|
|
|
'title' => __('Test Merchant Password', 'woocommerce-gateway-fac'), |
|
|
|
|
182
|
|
|
'type' => 'text', |
|
|
|
|
183
|
|
|
'description' => __('Get your API credentials from your merchant account.', 'woocommerce-gateway-fac'), |
|
|
|
|
184
|
|
|
'default' => '' |
|
|
|
|
185
|
|
|
], |
|
|
|
|
186
|
|
|
'capture' => [ |
|
|
|
|
187
|
|
|
'title' => __('Capture', 'woocommerce-gateway-fac'), |
|
|
|
|
188
|
|
|
'label' => __('Capture charge immediately', 'woocommerce-gateway-fac'), |
|
|
|
|
189
|
|
|
'type' => 'checkbox', |
|
|
|
|
190
|
|
|
'description' => __('Whether or not to immediately capture the charge. When unchecked, the charge issues an authorization and will need to be captured later. Uncaptured charges expire in 7 days.', 'woocommerce-gateway-fac'), |
|
|
|
|
191
|
|
|
'default' => 'yes' |
|
|
|
|
192
|
|
|
]/*, |
|
|
|
|
193
|
|
|
'saved_cards' => [ |
194
|
|
|
'title' => __('Saved cards', 'woocommerce-gateway-fac'), |
195
|
|
|
'label' => __('Enable saved cards', 'woocommerce-gateway-fac'), |
196
|
|
|
'type' => 'checkbox', |
197
|
|
|
'description' => __('If enabled, users will be able to pay with a saved card during checkout. Card details are saved on FAC servers, not on your store.', 'woocommerce-gateway-fac'), |
198
|
|
|
'default' => 'no' |
199
|
|
|
]*/ |
200
|
|
|
]); |
|
|
|
|
201
|
|
|
} |
|
|
|
|
202
|
|
|
|
203
|
|
|
/** |
|
|
|
|
204
|
|
|
* Setup the gateway object |
|
|
|
|
205
|
|
|
*/ |
|
|
|
|
206
|
|
|
public function setup_gateway() |
|
|
|
|
207
|
|
|
{ |
|
|
|
|
208
|
|
|
$gateway = Omnipay::create('FirstAtlanticCommerce'); |
|
|
|
|
209
|
|
|
|
210
|
|
|
$gateway->setMerchantId($this->merchant_id); |
|
|
|
|
211
|
|
|
$gateway->setMerchantPassword($this->merchant_password); |
|
|
|
|
212
|
|
|
|
213
|
|
|
if ($this->testmode) |
|
|
|
|
214
|
|
|
{ |
|
|
|
|
215
|
|
|
$gateway->setTestMode(true); |
|
|
|
|
216
|
|
|
} |
|
|
|
|
217
|
|
|
|
218
|
|
|
return $gateway; |
|
|
|
|
219
|
|
|
} |
|
|
|
|
220
|
|
|
|
221
|
|
|
/** |
|
|
|
|
222
|
|
|
* Output payment fields |
|
|
|
|
223
|
|
|
* |
|
|
|
|
224
|
|
|
* @return void |
|
|
|
|
225
|
|
|
*/ |
|
|
|
|
226
|
|
|
public function payment_fields() |
|
|
|
|
227
|
|
|
{ |
|
|
|
|
228
|
|
|
// Default credit card form |
|
|
|
|
229
|
|
|
$this->credit_card_form(); |
|
|
|
|
230
|
|
|
} |
|
|
|
|
231
|
|
|
|
232
|
|
|
/** |
|
|
|
|
233
|
|
|
* Validate form fields |
|
|
|
|
234
|
|
|
* |
|
|
|
|
235
|
|
|
* @return bool |
|
|
|
|
236
|
|
|
*/ |
|
|
|
|
237
|
|
|
public function validate_fields() |
|
|
|
|
238
|
|
|
{ |
|
|
|
|
239
|
|
|
$validated = true; |
|
|
|
|
240
|
|
|
|
241
|
|
View Code Duplication |
if ( empty($_POST['fac-card-number']) ) |
|
|
|
|
242
|
|
|
{ |
|
|
|
|
243
|
|
|
wc_add_notice( $this->get_validation_error( __('Card Number', 'woocommerce-gateway-fac'), $_POST['fac-card-number'] ), 'error' ); |
|
|
|
|
244
|
|
|
$validated = false; |
|
|
|
|
245
|
|
|
} |
|
|
|
|
246
|
|
View Code Duplication |
if ( empty($_POST['fac-card-expiry']) ) |
|
|
|
|
247
|
|
|
{ |
|
|
|
|
248
|
|
|
wc_add_notice( $this->get_validation_error( __('Card Expiry', 'woocommerce-gateway-fac'), $_POST['fac-card-number'] ), 'error' ); |
|
|
|
|
249
|
|
|
$validated = false; |
|
|
|
|
250
|
|
|
} |
|
|
|
|
251
|
|
View Code Duplication |
if ( empty($_POST['fac-card-cvc']) ) |
|
|
|
|
252
|
|
|
{ |
|
|
|
|
253
|
|
|
wc_add_notice( $this->get_validation_error( __('Card Code', 'woocommerce-gateway-fac'), $_POST['fac-card-number'] ), 'error' ); |
|
|
|
|
254
|
|
|
$validated = false; |
|
|
|
|
255
|
|
|
} |
|
|
|
|
256
|
|
|
|
257
|
|
|
return $validated; |
|
|
|
|
258
|
|
|
} |
|
|
|
|
259
|
|
|
|
260
|
|
|
/** |
|
|
|
|
261
|
|
|
* Get error message for form fields |
|
|
|
|
262
|
|
|
* |
|
|
|
|
263
|
|
|
* @param string $field |
|
|
|
|
264
|
|
|
* @param string $type |
|
|
|
|
265
|
|
|
* @return string |
|
|
|
|
266
|
|
|
*/ |
|
|
|
|
267
|
|
|
protected function get_validation_error($field, $type = 'undefined') |
|
|
|
|
268
|
|
|
{ |
|
|
|
|
269
|
|
|
if ( $type === 'invalid' ) |
|
|
|
|
270
|
|
|
{ |
|
|
|
|
271
|
|
|
return sprintf( __( 'Please enter a valid %s.', 'woocommerce-gateway-fac' ), "<strong>$field</strong>" ); |
|
|
|
|
272
|
|
|
} |
|
|
|
|
273
|
|
|
else |
|
|
|
|
274
|
|
|
{ |
|
|
|
|
275
|
|
|
return sprintf( __( '%s is a required field.', 'woocommerce-gateway-fac' ), "<strong>$field</strong>" ); |
|
|
|
|
276
|
|
|
} |
|
|
|
|
277
|
|
|
} |
|
|
|
|
278
|
|
|
|
279
|
|
|
/** |
|
|
|
|
280
|
|
|
* Can the order be processed? |
|
|
|
|
281
|
|
|
* |
|
|
|
|
282
|
|
|
* @param WC_Order $order |
|
|
|
|
283
|
|
|
* |
|
|
|
|
284
|
|
|
* @return bool |
|
|
|
|
285
|
|
|
*/ |
|
|
|
|
286
|
|
|
public function can_process_order($order) |
|
|
|
|
287
|
|
|
{ |
|
|
|
|
288
|
|
|
return $order && $order->payment_method == 'fac'; |
|
|
|
|
289
|
|
|
} |
|
|
|
|
290
|
|
|
|
291
|
|
|
/** |
|
|
|
|
292
|
|
|
* Process the payment and return the result |
|
|
|
|
293
|
|
|
* |
|
|
|
|
294
|
|
|
* @param int $order_id |
|
|
|
|
295
|
|
|
* |
|
|
|
|
296
|
|
|
* @return array |
|
|
|
|
297
|
|
|
*/ |
|
|
|
|
298
|
|
|
public function process_payment($order_id) |
|
|
|
|
299
|
|
|
{ |
|
|
|
|
300
|
|
|
$order = new WC_Order($order_id); |
|
|
|
|
301
|
|
|
|
302
|
|
|
if ( !$this->can_process_order($order) ) return; |
|
|
|
|
303
|
|
|
|
304
|
|
|
$transaction = $order->get_transaction_id(); |
|
|
|
|
305
|
|
|
$captured = get_post_meta($order_id, '_fac_captured', true); |
|
|
|
|
306
|
|
|
|
307
|
|
|
// Skip already captured transactions |
|
|
|
|
308
|
|
|
if ($captured) return; |
|
|
|
|
309
|
|
|
|
310
|
|
|
try |
|
|
|
|
311
|
|
|
{ |
|
|
|
|
312
|
|
|
$gateway = $this->setup_gateway(); |
|
|
|
|
313
|
|
|
|
314
|
|
|
$data = [ |
|
|
|
|
315
|
|
|
'transactionId' => $order->get_order_number(), |
|
|
|
|
316
|
|
|
'amount' => $this->get_order_total(), |
|
|
|
|
317
|
|
|
'currency' => $order->order_currency |
|
|
|
|
318
|
|
|
]; |
|
|
|
|
319
|
|
|
|
320
|
|
|
// Already authorized transactions should be captured |
|
|
|
|
321
|
|
|
if ( $transaction && !$captured ) |
|
|
|
|
322
|
|
|
{ |
|
|
|
|
323
|
|
|
$response = $gateway->capture($data)->send(); |
|
|
|
|
324
|
|
|
} |
|
|
|
|
325
|
|
|
else |
|
|
|
|
326
|
|
|
{ |
|
|
|
|
327
|
|
|
$card_number = str_replace( [' ', '-'], '', wc_clean($_POST['fac-card-number']) ); |
|
|
|
|
328
|
|
|
$card_cvv = wc_clean($_POST['fac-card-cvc']); |
|
|
|
|
329
|
|
|
$card_expiry = preg_split('/\s?\/\s?/', wc_clean($_POST['fac-card-expiry']), 2); |
|
|
|
|
330
|
|
|
|
331
|
|
|
$data['card'] = [ |
|
|
|
|
332
|
|
|
'firstName' => $order->billing_first_name, |
|
|
|
|
333
|
|
|
'lastName' => $order->billing_last_name, |
|
|
|
|
334
|
|
|
'number' => $card_number, |
|
|
|
|
335
|
|
|
'expiryMonth' => $card_expiry[0], |
|
|
|
|
336
|
|
|
'expiryYear' => $card_expiry[1], |
|
|
|
|
337
|
|
|
'cvv' => $card_cvv, |
|
|
|
|
338
|
|
|
'billingAddress1' => $order->billing_address_1, |
|
|
|
|
339
|
|
|
'billingAddress2' => $order->billing_address_2, |
|
|
|
|
340
|
|
|
'billingCity' => $order->billing_city, |
|
|
|
|
341
|
|
|
'billingPostcode' => $order->billing_postcode, |
|
|
|
|
342
|
|
|
'billingState' => $order->billing_state, |
|
|
|
|
343
|
|
|
'billingCountry' => $order->billing_country, |
|
|
|
|
344
|
|
|
'email' => $order->billing_email |
|
|
|
|
345
|
|
|
]; |
|
|
|
|
346
|
|
|
|
347
|
|
|
// Capture in one pass if enabled, otherwise authorize |
|
|
|
|
348
|
|
|
if ($this->capture) |
|
|
|
|
349
|
|
|
{ |
|
|
|
|
350
|
|
|
$response = $gateway->purchase($data)->send(); |
|
|
|
|
351
|
|
|
} |
|
|
|
|
352
|
|
|
else |
|
|
|
|
353
|
|
|
{ |
|
|
|
|
354
|
|
|
$response = $gateway->authorize($data)->send(); |
|
|
|
|
355
|
|
|
} |
|
|
|
|
356
|
|
|
} |
|
|
|
|
357
|
|
|
|
358
|
|
|
if ( $response->isSuccessful() ) |
|
|
|
|
359
|
|
|
{ |
|
|
|
|
360
|
|
|
$reference = $response->getTransactionReference(); |
|
|
|
|
361
|
|
|
|
362
|
|
|
// Captured transaction |
|
|
|
|
363
|
|
|
if ( ($transaction && !$captured) || (!$transaction && $this->capture) ) |
|
|
|
|
364
|
|
|
{ |
|
|
|
|
365
|
|
|
// Store captured |
|
|
|
|
366
|
|
|
update_post_meta($order_id, '_fac_captured', true); |
|
|
|
|
367
|
|
|
|
368
|
|
|
// Complete payment |
|
|
|
|
369
|
|
|
$order->payment_complete($reference); |
|
|
|
|
370
|
|
|
|
371
|
|
|
// Add note to order |
|
|
|
|
372
|
|
|
$order->add_order_note( sprintf( __('FAC transaction complete (ID: %s)', 'woocommerce-gateway-fac'), $reference ) ); |
|
|
|
|
373
|
|
|
} |
|
|
|
|
374
|
|
|
// Authorized transaction |
|
|
|
|
375
|
|
|
else |
|
|
|
|
376
|
|
|
{ |
|
|
|
|
377
|
|
|
// Store captured |
|
|
|
|
378
|
|
|
update_post_meta($order_id, '_transaction_id', $reference, true); |
|
|
|
|
379
|
|
|
update_post_meta($order_id, '_fac_captured', false); |
|
|
|
|
380
|
|
|
|
381
|
|
|
// Mark order as on-hold and add note |
|
|
|
|
382
|
|
|
$order->update_status( 'on-hold', sprintf( __('FAC charge authorized (ID: %s). Process the order to take payment, or cancel to remove the pre-authorization.', 'woocommerce-gateway-fac'), $reference ) ); |
|
|
|
|
383
|
|
|
|
384
|
|
|
// Reduce stock level |
|
|
|
|
385
|
|
|
$order->reduce_order_stock(); |
|
|
|
|
386
|
|
|
} |
|
|
|
|
387
|
|
|
|
388
|
|
|
// Clear cart |
|
|
|
|
389
|
|
|
WC()->cart->empty_cart(); |
|
|
|
|
390
|
|
|
|
391
|
|
|
// Return thank you page redirect |
|
|
|
|
392
|
|
|
return [ |
|
|
|
|
393
|
|
|
'result' => 'success', |
|
|
|
|
394
|
|
|
'redirect' => $this->get_return_url($order) |
|
|
|
|
395
|
|
|
]; |
|
|
|
|
396
|
|
|
} |
|
|
|
|
397
|
|
|
else |
|
|
|
|
398
|
|
|
{ |
|
|
|
|
399
|
|
|
throw new InvalidResponseException( $response->getMessage(), $response->getCode() ); |
|
|
|
|
400
|
|
|
} |
|
|
|
|
401
|
|
|
} |
|
|
|
|
402
|
|
|
catch (OmnipayException $e) |
|
|
|
|
403
|
|
|
{ |
|
|
|
|
404
|
|
|
$message = 'Transaction Failed: '. $e->getCode() .' – '. $e->getMessage(); |
|
|
|
|
405
|
|
|
|
406
|
|
|
$this->log($message); |
|
|
|
|
407
|
|
|
$order->add_order_note( __($message, 'woocommerce-gateway-fac') ); |
|
|
|
|
408
|
|
|
|
409
|
|
|
// Friendly declined message |
|
|
|
|
410
|
|
|
if ( in_array( $e->getCode(), [2, 3, 4, 35, 38, 39] ) ) |
|
|
|
|
411
|
|
|
{ |
|
|
|
|
412
|
|
|
$message = __('Unfortunately your order cannot be processed as the originating bank/merchant has declined your transaction.', 'woocommerce') .' '. __('Please attempt your purchase again.', 'woocommerce'); |
|
|
|
|
413
|
|
|
} |
|
|
|
|
414
|
|
|
|
415
|
|
|
// Friendly error message |
|
|
|
|
416
|
|
|
else |
|
|
|
|
417
|
|
|
{ |
|
|
|
|
418
|
|
|
$message = __('Unfortunately your order cannot be processed as an error has occured.', 'woocommerce') .' '. __('Please attempt your purchase again.', 'woocommerce'); |
|
|
|
|
419
|
|
|
} |
|
|
|
|
420
|
|
|
|
421
|
|
|
if ( !is_admin() || ( defined('DOING_AJAX') && DOING_AJAX ) ) |
|
|
|
|
422
|
|
|
{ |
|
|
|
|
423
|
|
|
wc_add_notice($message, 'error'); |
|
|
|
|
424
|
|
|
} |
|
|
|
|
425
|
|
|
|
426
|
|
|
return; |
|
|
|
|
427
|
|
|
} |
|
|
|
|
428
|
|
|
} |
|
|
|
|
429
|
|
|
|
430
|
|
|
/** |
|
|
|
|
431
|
|
|
* Can the order be refunded? |
|
|
|
|
432
|
|
|
* |
|
|
|
|
433
|
|
|
* @param WC_Order $order |
|
|
|
|
434
|
|
|
* |
|
|
|
|
435
|
|
|
* @return bool |
|
|
|
|
436
|
|
|
*/ |
|
|
|
|
437
|
|
|
public function can_refund_order($order) |
|
|
|
|
438
|
|
|
{ |
|
|
|
|
439
|
|
|
return $order && $order->payment_method == 'fac' && $order->get_transaction_id(); |
|
|
|
|
440
|
|
|
} |
|
|
|
|
441
|
|
|
|
442
|
|
|
/** |
|
|
|
|
443
|
|
|
* Refund a charge |
|
|
|
|
444
|
|
|
* |
|
|
|
|
445
|
|
|
* @param int $order_id |
|
|
|
|
446
|
|
|
* @param float $amount |
|
|
|
|
447
|
|
|
* |
|
|
|
|
448
|
|
|
* @return bool |
|
|
|
|
449
|
|
|
*/ |
|
|
|
|
450
|
|
|
public function process_refund($order_id, $amount = null, $reason = '') |
|
|
|
|
451
|
|
|
{ |
|
|
|
|
452
|
|
|
$order = wc_get_order($order_id); |
|
|
|
|
453
|
|
|
|
454
|
|
|
if ( !$this->can_refund_order($order) ) |
|
|
|
|
455
|
|
|
{ |
|
|
|
|
456
|
|
|
$this->log('Refund Failed: No transaction ID for FAC'); |
|
|
|
|
457
|
|
|
return false; |
|
|
|
|
458
|
|
|
} |
|
|
|
|
459
|
|
|
|
460
|
|
|
$transaction = $order->get_transaction_id(); |
|
|
|
|
461
|
|
|
$captured = get_post_meta($order_id, '_fac_captured', true); |
|
|
|
|
462
|
|
|
|
463
|
|
|
if ( is_null($amount) ) |
|
|
|
|
464
|
|
|
{ |
|
|
|
|
465
|
|
|
$amount = $order->get_total(); |
|
|
|
|
466
|
|
|
} |
|
|
|
|
467
|
|
|
|
468
|
|
|
try |
|
|
|
|
469
|
|
|
{ |
|
|
|
|
470
|
|
|
$gateway = $this->setup_gateway(); |
|
|
|
|
471
|
|
|
|
472
|
|
|
$data = [ |
|
|
|
|
473
|
|
|
'transactionId' => $order->get_order_number(), |
|
|
|
|
474
|
|
|
'amount' => $amount |
|
|
|
|
475
|
|
|
]; |
|
|
|
|
476
|
|
|
|
477
|
|
|
if ($captured) |
|
|
|
|
478
|
|
|
{ |
|
|
|
|
479
|
|
|
$response = $gateway->refund($data)->send(); |
|
|
|
|
480
|
|
|
} |
|
|
|
|
481
|
|
|
else |
|
|
|
|
482
|
|
|
{ |
|
|
|
|
483
|
|
|
$response = $gateway->void($data)->send(); |
|
|
|
|
484
|
|
|
} |
|
|
|
|
485
|
|
|
|
486
|
|
|
if ( $response->isSuccessful() ) |
|
|
|
|
487
|
|
|
{ |
|
|
|
|
488
|
|
|
$order->add_order_note( sprintf( __('Refunded %s', 'woocommerce-gateway-fac'), $data['amount'] ) ); |
|
|
|
|
489
|
|
|
return true; |
|
|
|
|
490
|
|
|
} |
|
|
|
|
491
|
|
|
else |
|
|
|
|
492
|
|
|
{ |
|
|
|
|
493
|
|
|
throw new InvalidResponseException( $response->getMessage(), $response->getCode() ); |
|
|
|
|
494
|
|
|
} |
|
|
|
|
495
|
|
|
} |
|
|
|
|
496
|
|
|
catch (OmnipayException $e) |
|
|
|
|
497
|
|
|
{ |
|
|
|
|
498
|
|
|
$message = 'Refund Failed: '. $e->getCode() .' – '. $e->getMessage(); |
|
|
|
|
499
|
|
|
|
500
|
|
|
$this->log($message); |
|
|
|
|
501
|
|
|
$order->add_order_note( __($message, 'woocommerce-gateway-fac') ); |
|
|
|
|
502
|
|
|
|
503
|
|
|
return new WP_Error( 'fac-refund', __($e->getCode() .' – '.$e->getMessage(), 'woocommerce-gateway-fac') ); |
|
|
|
|
504
|
|
|
} |
|
|
|
|
505
|
|
|
} |
|
|
|
|
506
|
|
|
} |
507
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.