1
|
|
|
<?php |
2
|
|
|
/* |
3
|
|
|
$Id$ |
4
|
|
|
|
5
|
|
|
osCommerce, Open Source E-Commerce Solutions |
6
|
|
|
http://www.oscommerce.com |
7
|
|
|
|
8
|
|
|
Copyright (c) 2016 osCommerce |
9
|
|
|
|
10
|
|
|
Released under the GNU General Public License |
11
|
|
|
*/ |
12
|
|
|
|
13
|
|
|
if ( !class_exists('OSCOM_Braintree') ) { |
14
|
|
|
include(DIR_FS_CATALOG . 'includes/apps/braintree/OSCOM_Braintree.php'); |
15
|
|
|
} |
16
|
|
|
|
17
|
|
|
class braintree_cc { |
18
|
|
|
var $code, $title, $description, $enabled, $_app, $payment_types; |
19
|
|
|
|
20
|
|
|
function braintree_cc() { |
21
|
|
|
global $PHP_SELF, $order, $appBraintreeCcRightTurn, $payment; |
22
|
|
|
|
23
|
|
|
$this->_app = new OSCOM_Braintree(); |
24
|
|
|
$this->_app->loadLanguageFile('modules/CC/CC.php'); |
25
|
|
|
|
26
|
|
|
$this->signature = 'braintree|braintree_cc|' . $this->_app->getVersion() . '|2.3'; |
|
|
|
|
27
|
|
|
$this->api_version = '3'; |
|
|
|
|
28
|
|
|
|
29
|
|
|
$this->code = 'braintree_cc'; |
30
|
|
|
$this->title = $this->_app->getDef('module_cc_title'); |
31
|
|
|
$this->public_title = $this->_app->getDef('module_cc_public_title'); |
|
|
|
|
32
|
|
|
$this->description = '<div align="center">' . $this->_app->drawButton($this->_app->getDef('module_cc_legacy_admin_app_button'), tep_href_link('braintree.php', 'action=configure&module=CC'), 'primary', null, true) . '</div>'; |
33
|
|
|
$this->sort_order = defined('OSCOM_APP_PAYPAL_BRAINTREE_CC_SORT_ORDER') ? OSCOM_APP_PAYPAL_BRAINTREE_CC_SORT_ORDER : 0; |
|
|
|
|
34
|
|
|
$this->enabled = defined('OSCOM_APP_PAYPAL_BRAINTREE_CC_STATUS') && in_array(OSCOM_APP_PAYPAL_BRAINTREE_CC_STATUS, array('1', '0')) ? true : false; |
35
|
|
|
$this->order_status = defined('OSCOM_APP_PAYPAL_BRAINTREE_CC_ORDER_STATUS_ID') && ((int)OSCOM_APP_PAYPAL_BRAINTREE_CC_ORDER_STATUS_ID > 0) ? (int)OSCOM_APP_PAYPAL_BRAINTREE_CC_ORDER_STATUS_ID : 0; |
|
|
|
|
36
|
|
|
|
37
|
|
View Code Duplication |
if ( defined('OSCOM_APP_PAYPAL_BRAINTREE_CC_STATUS') ) { |
|
|
|
|
38
|
|
|
if ( OSCOM_APP_PAYPAL_BRAINTREE_CC_STATUS == '0' ) { |
39
|
|
|
$this->title .= ' [Sandbox]'; |
40
|
|
|
$this->public_title .= ' (' . $this->code . '; Sandbox)'; |
41
|
|
|
} |
42
|
|
|
} |
43
|
|
|
|
44
|
|
|
$braintree_error = null; |
45
|
|
|
|
46
|
|
|
if ( version_compare(PHP_VERSION, '5.4.0', '<') ) { |
47
|
|
|
$braintree_error = true; |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
if ( !isset($braintree_error) ) { |
51
|
|
|
$requiredExtensions = array('xmlwriter', 'openssl', 'dom', 'hash', 'curl'); |
52
|
|
|
|
53
|
|
|
$exts = array(); |
54
|
|
|
|
55
|
|
|
foreach ( $requiredExtensions as $ext ) { |
56
|
|
|
if ( !extension_loaded($ext) ) { |
57
|
|
|
$exts[] = $ext; |
58
|
|
|
} |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
if ( !empty($exts) ) { |
62
|
|
|
$braintree_error = true; |
63
|
|
|
} |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
if ( !isset($braintree_error) ) { |
67
|
|
|
$this->api_version .= ' [SDK v' . Braintree_Version::get() . ']'; |
68
|
|
|
} else { |
69
|
|
|
$this->enabled = false; |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
if ( defined('OSCOM_APP_PAYPAL_BRAINTREE_CC_PAYMENT_TYPES') && tep_not_null(OSCOM_APP_PAYPAL_BRAINTREE_CC_PAYMENT_TYPES) ) { |
73
|
|
|
$this->payment_types = explode(';', OSCOM_APP_PAYPAL_BRAINTREE_CC_PAYMENT_TYPES); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
if ( $this->enabled === true ) { |
77
|
|
|
if ( isset($order) && is_object($order) ) { |
78
|
|
|
$this->update_status(); |
79
|
|
|
} |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
// When changing the shipping address due to no shipping rates being available, head straight to the checkout confirmation page |
83
|
|
|
if ((basename($PHP_SELF) == 'checkout_payment.php') && isset($appBraintreeCcRightTurn)) { |
84
|
|
|
tep_session_unregister('appBraintreeCcRightTurn'); |
85
|
|
|
|
86
|
|
|
if (isset($payment) && ($payment == 'braintree_cc')) { |
87
|
|
|
tep_redirect(tep_href_link('checkout_confirmation.php', '', 'SSL')); |
88
|
|
|
} |
89
|
|
|
} |
90
|
|
|
} |
91
|
|
|
|
92
|
|
View Code Duplication |
function update_status() { |
|
|
|
|
93
|
|
|
global $order; |
94
|
|
|
|
95
|
|
|
if ( ($this->enabled == true) && ((int)OSCOM_APP_PAYPAL_DP_ZONE > 0) ) { |
|
|
|
|
96
|
|
|
$check_flag = false; |
97
|
|
|
$check_query = tep_db_query("select zone_id from " . TABLE_ZONES_TO_GEO_ZONES . " where geo_zone_id = '" . OSCOM_APP_PAYPAL_DP_ZONE . "' and zone_country_id = '" . $order->delivery['country']['id'] . "' order by zone_id"); |
98
|
|
|
while ($check = tep_db_fetch_array($check_query)) { |
99
|
|
|
if ($check['zone_id'] < 1) { |
100
|
|
|
$check_flag = true; |
101
|
|
|
break; |
102
|
|
|
} elseif ($check['zone_id'] == $order->delivery['zone_id']) { |
103
|
|
|
$check_flag = true; |
104
|
|
|
break; |
105
|
|
|
} |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
if ($check_flag == false) { |
|
|
|
|
109
|
|
|
$this->enabled = false; |
110
|
|
|
} |
111
|
|
|
} |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
function checkout_initialization_method() { |
115
|
|
|
global $cart, $appBraintreeCcFormHash; |
116
|
|
|
|
117
|
|
|
$content = ''; |
118
|
|
|
|
119
|
|
|
if ($this->isPaymentTypeAccepted('paypal')) { |
120
|
|
|
$this->_app->setupCredentials(); |
121
|
|
|
|
122
|
|
|
$transaction_currency = $this->getTransactionCurrency(); |
123
|
|
|
|
124
|
|
|
$clientToken = Braintree_ClientToken::generate(array( |
125
|
|
|
'merchantAccountId' => $this->getMerchantAccountId($transaction_currency) |
126
|
|
|
)); |
127
|
|
|
|
128
|
|
|
$amount = $this->_app->formatCurrencyRaw($cart->show_total(), $transaction_currency); |
129
|
|
|
|
130
|
|
|
$formUrl = tep_href_link('ext/modules/payment/braintree_cc/rpc.php', 'action=paypal', 'SSL'); |
131
|
|
|
$formHash = $appBraintreeCcFormHash = $this->_app->createRandomValue(16); |
132
|
|
|
tep_session_register('appBraintreeCcFormHash'); |
133
|
|
|
|
134
|
|
|
$intent = (OSCOM_APP_PAYPAL_BRAINTREE_CC_TRANSACTION_METHOD == '1') ? 'sale' : 'authorize'; |
135
|
|
|
|
136
|
|
|
$enableShippingAddress = in_array($cart->get_content_type(), array('physical', 'mixed')) ? 'true' : 'false'; |
137
|
|
|
|
138
|
|
View Code Duplication |
switch (OSCOM_APP_PAYPAL_BRAINTREE_CC_PAYPAL_BUTTON_COLOR) { |
|
|
|
|
139
|
|
|
case '2': |
140
|
|
|
$button_color = 'blue'; |
141
|
|
|
break; |
142
|
|
|
|
143
|
|
|
case '3': |
144
|
|
|
$button_color = 'silver'; |
145
|
|
|
break; |
146
|
|
|
|
147
|
|
|
case '1': |
148
|
|
|
default: |
149
|
|
|
$button_color = 'gold'; |
150
|
|
|
} |
151
|
|
|
|
152
|
|
View Code Duplication |
switch (OSCOM_APP_PAYPAL_BRAINTREE_CC_PAYPAL_BUTTON_SIZE) { |
|
|
|
|
153
|
|
|
case '2': |
154
|
|
|
$button_size = 'small'; |
155
|
|
|
break; |
156
|
|
|
|
157
|
|
|
case '3': |
158
|
|
|
$button_size = 'medium'; |
159
|
|
|
break; |
160
|
|
|
|
161
|
|
|
case '1': |
162
|
|
|
default: |
163
|
|
|
$button_size = 'tiny'; |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
switch (OSCOM_APP_PAYPAL_BRAINTREE_CC_PAYPAL_BUTTON_SHAPE) { |
167
|
|
|
case '2': |
168
|
|
|
$button_shape = 'rect'; |
169
|
|
|
break; |
170
|
|
|
|
171
|
|
|
case '1': |
172
|
|
|
default: |
173
|
|
|
$button_shape = 'pill'; |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
$content = <<<EOD |
177
|
|
|
<script> |
178
|
|
|
if ( typeof jQuery == 'undefined' ) { |
179
|
|
|
document.write('<scr' + 'ipt src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></scr' + 'ipt>'); |
180
|
|
|
} |
181
|
|
|
</script> |
182
|
|
|
<script src="https://www.paypalobjects.com/api/button.js?" |
183
|
|
|
data-merchant="braintree" |
184
|
|
|
data-id="bt-paypal-button" |
185
|
|
|
data-button="checkout" |
186
|
|
|
data-color="{$button_color}" |
187
|
|
|
data-size="{$button_size}" |
188
|
|
|
data-shape="{$button_shape}" |
189
|
|
|
data-button_type="submit" |
190
|
|
|
data-button_disabled="false" |
191
|
|
|
></script> |
192
|
|
|
<script> |
193
|
|
|
$(function() { |
194
|
|
|
braintree.client.create({ |
195
|
|
|
authorization: '{$clientToken}' |
196
|
|
|
}, function (clientErr, clientInstance) { |
197
|
|
|
if (clientErr) { |
198
|
|
|
$('#bt-paypal-button').hide(); |
199
|
|
|
|
200
|
|
|
return; |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
braintree.paypal.create({ |
204
|
|
|
client: clientInstance |
205
|
|
|
}, function (paypalErr, paypalInstance) { |
206
|
|
|
if (paypalErr) { |
207
|
|
|
$('#bt-paypal-button').hide(); |
208
|
|
|
|
209
|
|
|
return; |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
$('#bt-paypal-button').prop('disabled', false); |
213
|
|
|
|
214
|
|
|
$('#bt-paypal-button').on('click', function (event) { |
215
|
|
|
event.preventDefault(); |
216
|
|
|
|
217
|
|
|
paypalInstance.tokenize({ |
218
|
|
|
flow: 'checkout', |
219
|
|
|
amount: {$amount}, |
220
|
|
|
currency: '{$transaction_currency}', |
221
|
|
|
enableShippingAddress: {$enableShippingAddress}, |
222
|
|
|
enableBillingAddress: true, |
223
|
|
|
intent: '{$intent}' |
224
|
|
|
}, function (tokenizeErr, payload) { |
225
|
|
|
if (tokenizeErr) { |
226
|
|
|
return; |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
$('#bt-paypal-button').prop('disabled', true); |
230
|
|
|
|
231
|
|
|
$('<form>').attr({ |
232
|
|
|
name: 'bt_checkout_paypal', |
233
|
|
|
action: '{$formUrl}', |
234
|
|
|
method: 'post' |
235
|
|
|
}).insertAfter('form[name="cart_quantity"]'); |
236
|
|
|
|
237
|
|
|
$('<input>').attr({ |
238
|
|
|
type: 'hidden', |
239
|
|
|
name: 'bt_paypal_form_hash', |
240
|
|
|
value: '{$formHash}' |
241
|
|
|
}).appendTo('form[name="bt_checkout_paypal"]'); |
242
|
|
|
|
243
|
|
|
$('<input>').attr({ |
244
|
|
|
type: 'hidden', |
245
|
|
|
name: 'bt_paypal_nonce', |
246
|
|
|
value: payload.nonce |
247
|
|
|
}).appendTo('form[name="bt_checkout_paypal"]'); |
248
|
|
|
|
249
|
|
|
$('form[name="bt_checkout_paypal"]').submit(); |
250
|
|
|
}); |
251
|
|
|
}); |
252
|
|
|
}); |
253
|
|
|
}); |
254
|
|
|
}); |
255
|
|
|
</script> |
256
|
|
|
EOD; |
257
|
|
|
|
258
|
|
|
$ext_scripts = '<script src="https://js.braintreegateway.com/web/3.2.0/js/client.min.js"></script><script src="https://js.braintreegateway.com/web/3.2.0/js/paypal.min.js"></script>'; |
259
|
|
|
|
260
|
|
|
if ($this->templateClassExists()) { |
261
|
|
|
$GLOBALS['oscTemplate']->addBlock($ext_scripts, 'footer_scripts'); |
262
|
|
|
} else { |
263
|
|
|
$content .= $ext_scripts; |
264
|
|
|
} |
265
|
|
|
} |
266
|
|
|
|
267
|
|
|
return $content; |
268
|
|
|
} |
269
|
|
|
|
270
|
|
|
function javascript_validation() { |
271
|
|
|
return false; |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
function selection() { |
275
|
|
|
if (tep_session_is_registered('appBraintreeCcNonce')) { |
276
|
|
|
tep_session_unregister('appBraintreeCcNonce'); |
277
|
|
|
} |
278
|
|
|
|
279
|
|
|
return array('id' => $this->code, |
280
|
|
|
'module' => $this->public_title); |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
function pre_confirmation_check() { |
284
|
|
|
global $order, $request_type; |
285
|
|
|
|
286
|
|
|
if (!tep_session_is_registered('appBraintreeCcNonce') && (OSCOM_APP_PAYPAL_BRAINTREE_CC_ENTRY_FORM == '3')) { |
287
|
|
|
if (($request_type == 'NONSSL') && ((OSCOM_APP_PAYPAL_BRAINTREE_CC_THREE_D_SECURE === '1') || (OSCOM_APP_PAYPAL_BRAINTREE_CC_THREE_D_SECURE === '2'))) { |
288
|
|
View Code Duplication |
if (ENABLE_SSL == true) { |
|
|
|
|
289
|
|
|
// prevent redirect loop for incorrectly configured servers |
290
|
|
|
if (!tep_session_is_registered('bt_3ds_ssl_check')) { |
291
|
|
|
$bt_3ds_ssl_check = true; |
|
|
|
|
292
|
|
|
tep_session_register('bt_3ds_ssl_check'); |
293
|
|
|
|
294
|
|
|
tep_redirect(tep_href_link(FILENAME_CHECKOUT_CONFIRMATION, '', 'SSL')); |
295
|
|
|
} |
296
|
|
|
} |
297
|
|
|
} |
298
|
|
|
|
299
|
|
|
if (tep_session_is_registered('bt_3ds_ssl_check')) { |
300
|
|
|
tep_session_unregister('bt_3ds_ssl_check'); |
301
|
|
|
} |
302
|
|
|
|
303
|
|
|
if ($this->templateClassExists()) { |
304
|
|
|
$GLOBALS['oscTemplate']->addBlock($this->getSubmitCardDetailsJavascript(), 'footer_scripts'); |
305
|
|
|
} |
306
|
|
|
} |
307
|
|
|
|
308
|
|
|
if ($this->isPaymentTypeAccepted('paypal') && tep_session_is_registered('appBraintreeCcNonce')) { |
309
|
|
|
$order->info['payment_method'] = '<img src="https://www.paypalobjects.com/webstatic/mktg/Logo/pp-logo-100px.png" border="0" alt="PayPal Logo" style="padding: 3px;" />'; |
310
|
|
|
} |
311
|
|
|
} |
312
|
|
|
|
313
|
|
|
function confirmation() { |
314
|
|
|
global $customer_id, $order, $currencies, $currency; |
315
|
|
|
|
316
|
|
|
if (tep_session_is_registered('appBraintreeCcNonce')) { |
317
|
|
|
return false; |
318
|
|
|
} |
319
|
|
|
|
320
|
|
|
if (OSCOM_APP_PAYPAL_BRAINTREE_CC_ENTRY_FORM == '3') { |
321
|
|
|
$content = '<div id="btCardStatus" class="ui-state-error ui-corner-all" style="display: none; padding: 10px; margin-bottom: 10px;"></div>'; |
322
|
|
|
|
323
|
|
|
if (!$this->templateClassExists()) { |
324
|
|
|
$content .= $this->getSubmitCardDetailsJavascript(); |
325
|
|
|
} |
326
|
|
|
|
327
|
|
|
if (!$this->isValidCurrency($currency)) { |
328
|
|
|
$content .= '<div class="ui-state-highlight ui-corner-all" style="padding: 10px; margin-bottom: 10px;">' . |
329
|
|
|
$this->_app->getDef('module_cc_notice_currency_charge', array( |
330
|
|
|
'currency_total' => $currencies->format($order->info['total'], true, DEFAULT_CURRENCY), |
331
|
|
|
'currency' => DEFAULT_CURRENCY, |
332
|
|
|
'current_currency' => $currency |
333
|
|
|
)) . |
334
|
|
|
'</div>'; |
335
|
|
|
} |
336
|
|
|
|
337
|
|
|
$default_token = null; |
338
|
|
|
|
339
|
|
|
if ((OSCOM_APP_PAYPAL_BRAINTREE_CC_CC_TOKENS == '1') || (OSCOM_APP_PAYPAL_BRAINTREE_CC_CC_TOKENS == '2')) { |
340
|
|
|
$tokens_query = tep_db_query('select id, card_type, number_filtered, expiry_date from customers_braintree_tokens where customers_id = "' . (int)$customer_id . '" order by date_added'); |
341
|
|
|
if (tep_db_num_rows($tokens_query)) { |
342
|
|
|
$t = array(); |
343
|
|
|
|
344
|
|
|
while ($tokens = tep_db_fetch_array($tokens_query)) { |
345
|
|
|
$default_token = (int)$tokens['id']; |
346
|
|
|
|
347
|
|
|
$t[] = array( |
348
|
|
|
'id' => (int)$tokens['id'], |
349
|
|
|
'text' => $this->_app->getDef('module_cc_stored_card_selection_title', array( |
350
|
|
|
'card_type' => $tokens['card_type'], |
351
|
|
|
'card_number' => $tokens['number_filtered'], |
352
|
|
|
'card_expiry_date_month' => substr($tokens['expiry_date'], 0, 2), |
353
|
|
|
'card_expiry_date_year' => substr($tokens['expiry_date'], 2) |
354
|
|
|
)) |
355
|
|
|
); |
356
|
|
|
} |
357
|
|
|
|
358
|
|
|
$t[] = array( |
359
|
|
|
'id' => '0', |
360
|
|
|
'text' => $this->_app->getDef('module_cc_new_card') |
361
|
|
|
); |
362
|
|
|
|
363
|
|
|
$content .= '<div style="margin-bottom: 10px;"> |
364
|
|
|
<label class="hosted-fields--label" for="braintree_cards">' . $this->_app->getDef('module_cc_payment_cards_title') . '</label>' . |
365
|
|
|
tep_draw_pull_down_menu('braintree_cards', $t, $default_token, 'id="braintree_cards" class="hosted-field"') . ' |
366
|
|
|
</div>'; |
367
|
|
|
|
368
|
|
View Code Duplication |
if (OSCOM_APP_PAYPAL_BRAINTREE_CC_VERIFY_CVV == '1') { |
|
|
|
|
369
|
|
|
$content .= '<div id="braintree_stored_card_cvv"> |
370
|
|
|
<label class="hosted-fields--label" for="card-token-cvv">' . $this->_app->getDef('module_cc_card_cvv') . ' <span class="ui-icon ui-icon-info" style="float: right;" title="' . addslashes($this->_app->getDef('module_cc_card_cvv_info')) . '" id="btCvvTokenInfoIcon"></span></label> |
371
|
|
|
<div id="card-token-cvv" class="hosted-field"></div> |
372
|
|
|
</div>'; |
373
|
|
|
} |
374
|
|
|
|
375
|
|
|
$content .= '</div>'; |
376
|
|
|
} |
377
|
|
|
} |
378
|
|
|
|
379
|
|
|
$content .= '<div id="braintree_new_card"> |
380
|
|
|
<label class="hosted-fields--label" for="card-number">' . $this->_app->getDef('module_cc_card_number') . '</label> |
381
|
|
|
<div id="card-number" class="hosted-field"></div> |
382
|
|
|
|
383
|
|
|
<label class="hosted-fields--label" for="card-exp">' . $this->_app->getDef('module_cc_card_expiration_date') . '</label> |
384
|
|
|
<div id="card-exp" class="hosted-field"></div>'; |
385
|
|
|
|
386
|
|
View Code Duplication |
if ((OSCOM_APP_PAYPAL_BRAINTREE_CC_VERIFY_CVV == '1') || (OSCOM_APP_PAYPAL_BRAINTREE_CC_VERIFY_CVV == '2')) { |
|
|
|
|
387
|
|
|
$content .= '<label class="hosted-fields--label" for="card-cvv">' . $this->_app->getDef('module_cc_card_cvv') . ' <span class="ui-icon ui-icon-info" style="float: right;" title="' . addslashes($this->_app->getDef('module_cc_card_cvv_info')) . '" id="btCvvInfoIcon"></span></label> |
388
|
|
|
<div id="card-cvv" class="hosted-field"></div>'; |
389
|
|
|
} |
390
|
|
|
|
391
|
|
|
if (OSCOM_APP_PAYPAL_BRAINTREE_CC_CC_TOKENS == '1') { |
392
|
|
|
$content .= '<div> |
393
|
|
|
<label>' . tep_draw_checkbox_field('cc_save', 'true', true) . ' ' . $this->_app->getDef('module_cc_save_new_card') . '</label> |
394
|
|
|
</div>'; |
395
|
|
|
} |
396
|
|
|
|
397
|
|
|
$content .= '</div>'; |
398
|
|
|
|
399
|
|
|
$content .= <<<EOD |
400
|
|
|
<input type="hidden" name="payment_method_nonce"> |
401
|
|
|
|
402
|
|
|
<script> |
403
|
|
|
if ($('#braintree_cards').length > 0) { |
404
|
|
|
$('#braintree_new_card').hide(); |
405
|
|
|
} |
406
|
|
|
</script> |
407
|
|
|
EOD; |
408
|
|
|
|
409
|
|
|
if ((OSCOM_APP_PAYPAL_BRAINTREE_CC_VERIFY_CVV == '1') || (OSCOM_APP_PAYPAL_BRAINTREE_CC_VERIFY_CVV == '2')) { |
410
|
|
|
$content .= <<<EOD |
411
|
|
|
<script> |
412
|
|
|
$(function() { |
413
|
|
|
$('#btCvvTokenInfoIcon, #btCvvInfoIcon').tooltip(); |
414
|
|
|
}); |
415
|
|
|
</script> |
416
|
|
|
EOD; |
417
|
|
|
} |
418
|
|
|
} else { |
419
|
|
|
$this->_app->setupCredentials(); |
420
|
|
|
|
421
|
|
|
$transaction_currency = $this->getTransactionCurrency(); |
422
|
|
|
|
423
|
|
|
$clientToken = Braintree_ClientToken::generate(array( |
424
|
|
|
'merchantAccountId' => $this->getMerchantAccountId($transaction_currency) |
425
|
|
|
)); |
426
|
|
|
|
427
|
|
|
$amount = $this->_app->formatCurrencyRaw($order->info['total'], $transaction_currency); |
428
|
|
|
|
429
|
|
|
$content = <<<EOD |
430
|
|
|
<script> |
431
|
|
|
if ( typeof jQuery == 'undefined' ) { |
432
|
|
|
document.write('<scr' + 'ipt src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></scr' + 'ipt>'); |
433
|
|
|
} |
434
|
|
|
</script> |
435
|
|
|
|
436
|
|
|
<script> |
437
|
|
|
$(function() { |
438
|
|
|
braintree.setup('{$clientToken}', 'dropin', { |
439
|
|
|
container: 'checkout_bt', |
440
|
|
|
paypal: { |
441
|
|
|
singleUse: true, |
442
|
|
|
amount: {$amount}, |
443
|
|
|
currency: '{$transaction_currency}' |
444
|
|
|
} |
445
|
|
|
}); |
446
|
|
|
}); |
447
|
|
|
</script> |
448
|
|
|
|
449
|
|
|
<div id="checkout_bt"></div> |
450
|
|
|
EOD; |
451
|
|
|
|
452
|
|
|
$ext_script = '<script src="https://js.braintreegateway.com/v2/braintree.js"></script>'; |
453
|
|
|
|
454
|
|
|
if ($this->templateClassExists()) { |
455
|
|
|
$GLOBALS['oscTemplate']->addBlock($ext_script, 'footer_scripts'); |
456
|
|
|
} else { |
457
|
|
|
$content .= $ext_script; |
458
|
|
|
} |
459
|
|
|
} |
460
|
|
|
|
461
|
|
|
if (isset($content)) { |
462
|
|
|
$confirmation = array( |
463
|
|
|
'title' => $content |
464
|
|
|
); |
465
|
|
|
|
466
|
|
|
return $confirmation; |
467
|
|
|
} |
468
|
|
|
|
469
|
|
|
return false; |
470
|
|
|
} |
471
|
|
|
|
472
|
|
|
function process_button() { |
473
|
|
|
return false; |
474
|
|
|
} |
475
|
|
|
|
476
|
|
|
function before_process() { |
477
|
|
|
global $HTTP_POST_VARS, $customer_id, $order, $braintree_result, $braintree_token, $messageStack, $appBraintreeCcNonce; |
478
|
|
|
|
479
|
|
|
$braintree_token = null; |
480
|
|
|
$braintree_error = null; |
|
|
|
|
481
|
|
|
|
482
|
|
|
if (!tep_session_is_registered('appBraintreeCcNonce') && ((OSCOM_APP_PAYPAL_BRAINTREE_CC_CC_TOKENS == '1') || (OSCOM_APP_PAYPAL_BRAINTREE_CC_CC_TOKENS == '2'))) { |
483
|
|
|
if (isset($HTTP_POST_VARS['braintree_cards']) && is_numeric($HTTP_POST_VARS['braintree_cards']) && ($HTTP_POST_VARS['braintree_cards'] > 0)) { |
484
|
|
|
$token_query = tep_db_query('select braintree_token from customers_braintree_tokens where id = "' . (int)$HTTP_POST_VARS['braintree_cards'] . '" and customers_id = "' . (int)$customer_id . '"'); |
485
|
|
|
if (tep_db_num_rows($token_query)) { |
486
|
|
|
$token = tep_db_fetch_array($token_query); |
487
|
|
|
|
488
|
|
|
$braintree_token = $token['braintree_token']; |
489
|
|
|
} |
490
|
|
|
} |
491
|
|
|
} |
492
|
|
|
|
493
|
|
|
$braintree_result = null; |
494
|
|
|
|
495
|
|
|
$this->_app->setupCredentials(); |
496
|
|
|
|
497
|
|
|
$transaction_currency = $this->getTransactionCurrency(); |
498
|
|
|
|
499
|
|
|
if (tep_session_is_registered('appBraintreeCcNonce')) { |
500
|
|
|
$data = array( |
501
|
|
|
'amount' => $this->_app->formatCurrencyRaw($order->info['total'], $transaction_currency), |
502
|
|
|
'paymentMethodNonce' => $appBraintreeCcNonce, |
503
|
|
|
'merchantAccountId' => $this->getMerchantAccountId($transaction_currency) |
504
|
|
|
); |
505
|
|
|
} else { |
506
|
|
|
$data = array( |
507
|
|
|
'paymentMethodNonce' => $HTTP_POST_VARS['payment_method_nonce'], |
508
|
|
|
'amount' => $this->_app->formatCurrencyRaw($order->info['total'], $transaction_currency), |
509
|
|
|
'merchantAccountId' => $this->getMerchantAccountId($transaction_currency), |
510
|
|
|
'customer' => array( |
511
|
|
|
'firstName' => $order->customer['firstname'], |
512
|
|
|
'lastName' => $order->customer['lastname'], |
513
|
|
|
'company' => $order->customer['company'], |
514
|
|
|
'phone' => $order->customer['telephone'], |
515
|
|
|
'email' => $order->customer['email_address'] |
516
|
|
|
), |
517
|
|
|
'billing' => array( |
518
|
|
|
'firstName' => $order->billing['firstname'], |
519
|
|
|
'lastName' => $order->billing['lastname'], |
520
|
|
|
'company' => $order->billing['company'], |
521
|
|
|
'streetAddress' => $order->billing['street_address'], |
522
|
|
|
'extendedAddress' => $order->billing['suburb'], |
523
|
|
|
'locality' => $order->billing['city'], |
524
|
|
|
'region' => tep_get_zone_code($order->billing['country']['id'], $order->billing['zone_id'], $order->billing['state']), |
525
|
|
|
'postalCode' => $order->billing['postcode'], |
526
|
|
|
'countryCodeAlpha2' => $order->billing['country']['iso_code_2'] |
527
|
|
|
), |
528
|
|
|
'options' => array() |
529
|
|
|
); |
530
|
|
|
|
531
|
|
|
if (OSCOM_APP_PAYPAL_BRAINTREE_CC_TRANSACTION_METHOD == '1') { |
532
|
|
|
$data['options']['submitForSettlement'] = true; |
533
|
|
|
} |
534
|
|
|
|
535
|
|
|
if (!isset($braintree_token)) { |
536
|
|
|
if (((OSCOM_APP_PAYPAL_BRAINTREE_CC_CC_TOKENS == '1') && isset($HTTP_POST_VARS['cc_save']) && ($HTTP_POST_VARS['cc_save'] == 'true')) || (OSCOM_APP_PAYPAL_BRAINTREE_CC_CC_TOKENS === '2')) { |
537
|
|
|
$data['options']['storeInVaultOnSuccess'] = true; |
538
|
|
|
} |
539
|
|
|
} |
540
|
|
|
} |
541
|
|
|
|
542
|
|
|
if ($order->content_type != 'virtual') { |
543
|
|
|
$data['shipping'] = array( |
544
|
|
|
'firstName' => $order->delivery['firstname'], |
545
|
|
|
'lastName' => $order->delivery['lastname'], |
546
|
|
|
'company' => $order->delivery['company'], |
547
|
|
|
'streetAddress' => $order->delivery['street_address'], |
548
|
|
|
'extendedAddress' => $order->delivery['suburb'], |
549
|
|
|
'locality' => $order->delivery['city'], |
550
|
|
|
'region' => tep_get_zone_code($order->delivery['country']['id'], $order->delivery['zone_id'], $order->delivery['state']), |
551
|
|
|
'postalCode' => $order->delivery['postcode'], |
552
|
|
|
'countryCodeAlpha2' => $order->delivery['country']['iso_code_2'] |
553
|
|
|
); |
554
|
|
|
} |
555
|
|
|
|
556
|
|
|
$data['channel'] = $this->_app->getIdentifier(); |
557
|
|
|
|
558
|
|
|
$error = false; |
559
|
|
|
|
560
|
|
|
try { |
561
|
|
|
$braintree_result = Braintree_Transaction::sale($data); |
562
|
|
|
} catch (Exception $e) { |
563
|
|
|
$error = true; |
564
|
|
|
} |
565
|
|
|
|
566
|
|
|
if (($error === false) && ($braintree_result->success === true)) { |
567
|
|
|
return true; |
568
|
|
|
} |
569
|
|
|
|
570
|
|
|
$message = $this->_app->getDef('module_cc_error_general'); |
571
|
|
|
|
572
|
|
|
if (isset($braintree_result->transaction)) { |
573
|
|
|
if (isset($braintree_result->transaction->gatewayRejectionReason)) { |
574
|
|
|
switch ($braintree_result->transaction->gatewayRejectionReason) { |
575
|
|
|
case 'cvv': |
576
|
|
|
$message = $this->_app->getDef('module_cc_error_cvv'); |
577
|
|
|
break; |
578
|
|
|
|
579
|
|
|
case 'avs': |
580
|
|
|
$message = $this->_app->getDef('module_cc_error_avs'); |
581
|
|
|
break; |
582
|
|
|
|
583
|
|
|
case 'avs_and_cvv': |
584
|
|
|
$message = $this->_app->getDef('module_cc_error_avs_and_cvv'); |
585
|
|
|
break; |
586
|
|
|
} |
587
|
|
|
} |
588
|
|
|
} |
589
|
|
|
|
590
|
|
|
$messageStack->add_session('checkout_confirmation', $message); |
591
|
|
|
|
592
|
|
|
tep_redirect(tep_href_link('checkout_confirmation.php', null, 'SSL')); |
593
|
|
|
} |
594
|
|
|
|
595
|
|
|
function after_process() { |
596
|
|
|
global $HTTP_POST_VARS, $customer_id, $insert_id, $braintree_result, $braintree_token; |
597
|
|
|
|
598
|
|
|
$status_comment = array( |
599
|
|
|
'Transaction ID: ' . tep_db_prepare_input($braintree_result->transaction->id) |
600
|
|
|
); |
601
|
|
|
|
602
|
|
|
if (($braintree_result->transaction->paymentInstrumentType == 'credit_card') && ((OSCOM_APP_PAYPAL_BRAINTREE_CC_THREE_D_SECURE === '1') || ((OSCOM_APP_PAYPAL_BRAINTREE_CC_THREE_D_SECURE === '2') && !isset($braintree_token)))) { |
603
|
|
|
if (isset($braintree_result->transaction->threeDSecureInfo) && is_object($braintree_result->transaction->threeDSecureInfo)) { |
604
|
|
|
$status_comment[] = '3D Secure: ' . tep_db_prepare_input($braintree_result->transaction->threeDSecureInfo->status . ' (Liability Shifted: ' . ($braintree_result->transaction->threeDSecureInfo->liabilityShifted === true ? 'true' : 'false') . ')'); |
605
|
|
|
} else { |
606
|
|
|
$status_comment[] = '3D Secure: ** MISSING **'; |
607
|
|
|
} |
608
|
|
|
} |
609
|
|
|
|
610
|
|
|
$status_comment[] = 'Payment Status: ' . tep_db_prepare_input($braintree_result->transaction->status); |
611
|
|
|
$status_comment[] = 'Payment Type: ' . tep_db_prepare_input($braintree_result->transaction->paymentInstrumentType); |
612
|
|
|
|
613
|
|
|
if (Braintree_Configuration::environment() !== 'production') { |
614
|
|
|
$status_comment[] = 'Server: ' . tep_db_prepare_input(Braintree_Configuration::environment()); |
615
|
|
|
} |
616
|
|
|
|
617
|
|
|
if (!tep_session_is_registered('appBraintreeCcNonce') && (((OSCOM_APP_PAYPAL_BRAINTREE_CC_CC_TOKENS == '1') && isset($HTTP_POST_VARS['cc_save']) && ($HTTP_POST_VARS['cc_save'] == 'true')) || (OSCOM_APP_PAYPAL_BRAINTREE_CC_CC_TOKENS === '2')) && !isset($braintree_token) && isset($braintree_result->transaction->creditCard['token'])) { |
618
|
|
|
$token = $braintree_result->transaction->creditCard['token']; |
619
|
|
|
$type = $braintree_result->transaction->creditCard['cardType']; |
620
|
|
|
$number = $braintree_result->transaction->creditCard['last4']; |
621
|
|
|
$expiry = $braintree_result->transaction->creditCard['expirationMonth'] . $braintree_result->transaction->creditCard['expirationYear']; |
622
|
|
|
|
623
|
|
|
$check_query = tep_db_query('select id from customers_braintree_tokens where customers_id = "' . (int)$customer_id . '" and braintree_token = "' . tep_db_input(tep_db_prepare_input($token)) . '"'); |
624
|
|
|
if (!tep_db_num_rows($check_query)) { |
625
|
|
|
$sql_data_array = array( |
626
|
|
|
'customers_id' => (int)$customer_id, |
627
|
|
|
'braintree_token' => $token, |
628
|
|
|
'card_type' => $type, |
629
|
|
|
'number_filtered' => $number, |
630
|
|
|
'expiry_date' => $expiry, |
631
|
|
|
'date_added' => 'now()' |
632
|
|
|
); |
633
|
|
|
|
634
|
|
|
tep_db_perform('customers_braintree_tokens', $sql_data_array); |
635
|
|
|
} |
636
|
|
|
|
637
|
|
|
$status_comment[] = 'Token Created: Yes'; |
638
|
|
|
} elseif (isset($braintree_token)) { |
639
|
|
|
$status_comment[] = 'Token Used: Yes'; |
640
|
|
|
} |
641
|
|
|
|
642
|
|
|
$sql_data_array = array( |
643
|
|
|
'orders_id' => $insert_id, |
644
|
|
|
'orders_status_id' => OSCOM_APP_PAYPAL_BRAINTREE_TRANSACTIONS_ORDER_STATUS_ID, |
645
|
|
|
'date_added' => 'now()', |
646
|
|
|
'customer_notified' => '0', |
647
|
|
|
'comments' => implode("\n", $status_comment) |
648
|
|
|
); |
649
|
|
|
|
650
|
|
|
tep_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array); |
651
|
|
|
|
652
|
|
|
if (tep_session_is_registered('appBraintreeCcNonce')) { |
653
|
|
|
tep_session_unregister('appBraintreeCcNonce'); |
654
|
|
|
} |
655
|
|
|
|
656
|
|
|
if (tep_session_is_registered('appBraintreeCcFormHash')) { |
657
|
|
|
tep_session_unregister('appBraintreeCcFormHash'); |
658
|
|
|
} |
659
|
|
|
} |
660
|
|
|
|
661
|
|
|
function get_error() { |
662
|
|
|
global $HTTP_GET_VARS; |
663
|
|
|
|
664
|
|
|
$error_message = $this->_app->getDef('module_cc_error_general'); |
665
|
|
|
|
666
|
|
|
switch ($HTTP_GET_VARS['error']) { |
667
|
|
|
case 'not_available': |
668
|
|
|
$error_message = $this->_app->getDef('module_cc_error_unavailable'); |
669
|
|
|
break; |
670
|
|
|
} |
671
|
|
|
|
672
|
|
|
$error = array('title' => $this->_app->getDef('module_cc_error_title'), |
673
|
|
|
'error' => $error_message); |
674
|
|
|
|
675
|
|
|
return $error; |
676
|
|
|
} |
677
|
|
|
|
678
|
|
|
function check() { |
679
|
|
|
$check_query = tep_db_query("select configuration_value from " . TABLE_CONFIGURATION . " where configuration_key = 'OSCOM_APP_PAYPAL_BRAINTREE_CC_STATUS'"); |
680
|
|
|
if ( tep_db_num_rows($check_query) ) { |
681
|
|
|
$check = tep_db_fetch_array($check_query); |
682
|
|
|
|
683
|
|
|
return tep_not_null($check['configuration_value']); |
684
|
|
|
} |
685
|
|
|
|
686
|
|
|
return false; |
687
|
|
|
} |
688
|
|
|
|
689
|
|
|
function install() { |
690
|
|
|
tep_redirect(tep_href_link('braintree.php', 'action=configure')); |
691
|
|
|
} |
692
|
|
|
|
693
|
|
|
function remove() { |
694
|
|
|
tep_redirect(tep_href_link('braintree.php', 'action=configure')); |
695
|
|
|
} |
696
|
|
|
|
697
|
|
|
function keys() { |
698
|
|
|
return array('OSCOM_APP_PAYPAL_BRAINTREE_CC_SORT_ORDER'); |
699
|
|
|
} |
700
|
|
|
|
701
|
|
|
function getTransactionCurrency() { |
702
|
|
|
global $currency; |
703
|
|
|
|
704
|
|
|
return $this->isValidCurrency($currency) ? $currency : DEFAULT_CURRENCY; |
705
|
|
|
} |
706
|
|
|
|
707
|
|
|
function getMerchantAccountId($currency) { |
708
|
|
|
$currencies_ma = (OSCOM_APP_PAYPAL_BRAINTREE_CC_STATUS === '1') ? OSCOM_APP_PAYPAL_BRAINTREE_CURRENCIES_MA : OSCOM_APP_PAYPAL_BRAINTREE_SANDBOX_CURRENCIES_MA; |
709
|
|
|
|
710
|
|
|
foreach (explode(';', $currencies_ma) as $ma) { |
711
|
|
|
list($a, $c) = explode(':', $ma); |
712
|
|
|
|
713
|
|
|
if ($c == $currency) { |
714
|
|
|
return $a; |
715
|
|
|
} |
716
|
|
|
} |
717
|
|
|
|
718
|
|
|
return ''; |
719
|
|
|
} |
720
|
|
|
|
721
|
|
|
function isValidCurrency($currency) { |
722
|
|
|
global $currencies; |
723
|
|
|
|
724
|
|
|
$currencies_ma = (OSCOM_APP_PAYPAL_BRAINTREE_CC_STATUS === '1') ? OSCOM_APP_PAYPAL_BRAINTREE_CURRENCIES_MA : OSCOM_APP_PAYPAL_BRAINTREE_SANDBOX_CURRENCIES_MA; |
725
|
|
|
|
726
|
|
|
foreach (explode(';', $currencies_ma) as $combo) { |
727
|
|
|
list($id, $c) = explode(':', $combo); |
|
|
|
|
728
|
|
|
|
729
|
|
|
if ($c == $currency) { |
730
|
|
|
return $currencies->is_set($c); |
731
|
|
|
} |
732
|
|
|
} |
733
|
|
|
|
734
|
|
|
return false; |
735
|
|
|
} |
736
|
|
|
|
737
|
|
|
function templateClassExists() { |
738
|
|
|
return class_exists('oscTemplate') && isset($GLOBALS['oscTemplate']) && is_object($GLOBALS['oscTemplate']) && (get_class($GLOBALS['oscTemplate']) == 'oscTemplate'); |
739
|
|
|
} |
740
|
|
|
|
741
|
|
|
function deleteCard($token, $token_id) { |
742
|
|
|
global $customer_id; |
743
|
|
|
|
744
|
|
|
$result = false; |
745
|
|
|
|
746
|
|
|
try { |
747
|
|
|
$this->_app->setupCredentials(); |
748
|
|
|
|
749
|
|
|
Braintree_CreditCard::delete($token); |
750
|
|
|
|
751
|
|
|
tep_db_query('delete from customers_braintree_tokens where id = "' . (int)$token_id . '" and customers_id = "' . (int)$customer_id . '" and braintree_token = "' . tep_db_input($token) . '"'); |
752
|
|
|
|
753
|
|
|
$result = true; |
754
|
|
|
} catch (Exception $e) { |
|
|
|
|
755
|
|
|
} |
756
|
|
|
|
757
|
|
|
return $result === true; |
758
|
|
|
} |
759
|
|
|
|
760
|
|
|
function getSubmitCardDetailsJavascript() { |
761
|
|
|
global $order, $request_type; |
762
|
|
|
|
763
|
|
|
$this->_app->setupCredentials(); |
764
|
|
|
|
765
|
|
|
$transaction_currency = $this->getTransactionCurrency(); |
766
|
|
|
|
767
|
|
|
$clientToken = Braintree_ClientToken::generate(array( |
768
|
|
|
'merchantAccountId' => $this->getMerchantAccountId($transaction_currency) |
769
|
|
|
)); |
770
|
|
|
|
771
|
|
|
$order_total = $this->_app->formatCurrencyRaw($order->info['total'], $transaction_currency); |
772
|
|
|
|
773
|
|
|
$getCardTokenRpcUrl = tep_href_link('ext/modules/payment/braintree_cc/rpc.php', 'action=getCardToken', 'SSL'); |
774
|
|
|
|
775
|
|
|
if ((OSCOM_APP_PAYPAL_BRAINTREE_CC_THREE_D_SECURE === '1') && ($request_type == 'SSL')) { |
776
|
|
|
$has3ds = 'all'; |
777
|
|
|
} elseif ((OSCOM_APP_PAYPAL_BRAINTREE_CC_THREE_D_SECURE === '2') && ($request_type == 'SSL')) { |
778
|
|
|
$has3ds = 'new'; |
779
|
|
|
} else { |
780
|
|
|
$has3ds = 'none'; |
781
|
|
|
} |
782
|
|
|
|
783
|
|
|
$url_not_available = addslashes(str_replace('&', '&', tep_href_link('checkout_payment.php', 'payment_error=braintree_cc&error=not_available', 'SSL'))); |
784
|
|
|
|
785
|
|
|
$error_unavailable = addslashes($this->_app->getDef('module_cc_error_unavailable')); |
786
|
|
|
$error_all_fields_required = addslashes($this->_app->getDef('module_cc_error_all_fields_required')); |
787
|
|
|
$error_fields_required = addslashes($this->_app->getDef('module_cc_error_fields_required')); |
788
|
|
|
$error_tmp_processing_problem = addslashes($this->_app->getDef('module_cc_error_tmp_processing_problem')); |
789
|
|
|
|
790
|
|
|
$js = <<<EOD |
791
|
|
|
<style> |
792
|
|
|
.hosted-field { |
793
|
|
|
height: 40px; |
794
|
|
|
box-sizing: border-box; |
795
|
|
|
width: 100%; |
796
|
|
|
padding: 6px; |
797
|
|
|
display: inline-block; |
798
|
|
|
box-shadow: none; |
799
|
|
|
font-weight: 600; |
800
|
|
|
border-radius: 6px; |
801
|
|
|
border: 1px solid #dddddd; |
802
|
|
|
background: #fcfcfc; |
803
|
|
|
margin-bottom: 12px; |
804
|
|
|
background: linear-gradient(to right, white 50%, #fcfcfc 50%); |
805
|
|
|
background-size: 200% 100%; |
806
|
|
|
background-position: right bottom; |
807
|
|
|
transition: all 300ms ease-in-out; |
808
|
|
|
} |
809
|
|
|
|
810
|
|
|
.hosted-fields--label { |
811
|
|
|
display: block; |
812
|
|
|
margin-bottom: 6px; |
813
|
|
|
} |
814
|
|
|
</style> |
815
|
|
|
|
816
|
|
|
<script> |
817
|
|
|
if ( typeof jQuery == 'undefined' ) { |
818
|
|
|
document.write('<scr' + 'ipt src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></scr' + 'ipt>'); |
819
|
|
|
} |
820
|
|
|
</script> |
821
|
|
|
|
822
|
|
|
<script> |
823
|
|
|
$('form[name="checkout_confirmation"]').attr('id', 'braintree-payment-form'); |
824
|
|
|
$('#braintree-payment-form button[type="submit"]').attr('id', 'braintree-payment-form-submit-button').button('disable'); |
825
|
|
|
|
826
|
|
|
$(function() { |
827
|
|
|
if (typeof $('#braintree-payment-form-submit-button').data('orig-button-text') === 'undefined') { |
828
|
|
|
$('#braintree-payment-form-submit-button').data('orig-button-text', $('#braintree-payment-form-submit-button').html()); |
829
|
|
|
} |
830
|
|
|
|
831
|
|
|
var has3ds = '{$has3ds}'; |
832
|
|
|
var do3ds = false; |
833
|
|
|
|
834
|
|
|
function doTokenize(hostedFieldsInstance, clientInstance, nonce) { |
835
|
|
|
if ((hostedFieldsInstance === undefined) && (nonce !== undefined)) { |
836
|
|
|
if (do3ds === true) { |
837
|
|
|
create3DS(clientInstance, nonce); |
838
|
|
|
} else { |
839
|
|
|
$('#braintree-payment-form input[name="payment_method_nonce"]').val(nonce); |
840
|
|
|
|
841
|
|
|
$('#braintree-payment-form').submit(); |
842
|
|
|
} |
843
|
|
|
|
844
|
|
|
return; |
845
|
|
|
} |
846
|
|
|
|
847
|
|
|
hostedFieldsInstance.tokenize(function (tokenizeErr, payload) { |
848
|
|
|
if (tokenizeErr) { |
849
|
|
|
switch (tokenizeErr.code) { |
850
|
|
|
case 'HOSTED_FIELDS_FIELDS_EMPTY': |
851
|
|
|
$('#btCardStatus').html('{$error_all_fields_required}'); |
852
|
|
|
|
853
|
|
|
if ($('#btCardStatus').is(':hidden')) { |
854
|
|
|
$('#btCardStatus').show(); |
855
|
|
|
} |
856
|
|
|
|
857
|
|
|
if (($('#braintree_cards').length > 0) && ($('#braintree_cards').val() !== '0')) { |
858
|
|
|
$('#braintree-payment-form label[for=card-token-cvv]').addClass('ui-state-error-text'); |
859
|
|
|
} else { |
860
|
|
|
$('#braintree-payment-form label[for=card-number]').addClass('ui-state-error-text'); |
861
|
|
|
$('#braintree-payment-form label[for=card-exp]').addClass('ui-state-error-text'); |
862
|
|
|
|
863
|
|
|
if ($('#card-cvv').length === 1) { |
864
|
|
|
$('#braintree-payment-form label[for=card-cvv]').addClass('ui-state-error-text'); |
865
|
|
|
} |
866
|
|
|
} |
867
|
|
|
|
868
|
|
|
break; |
869
|
|
|
|
870
|
|
|
case 'HOSTED_FIELDS_FIELDS_INVALID': |
871
|
|
|
$('#btCardStatus').html('{$error_fields_required}'); |
872
|
|
|
|
873
|
|
|
if ($('#btCardStatus').is(':hidden')) { |
874
|
|
|
$('#btCardStatus').show(); |
875
|
|
|
} |
876
|
|
|
|
877
|
|
|
if (($('#braintree_cards').length > 0) && ($('#braintree_cards').val() !== '0')) { |
878
|
|
|
if ($.inArray('cvv', tokenizeErr.details.invalidFieldKeys) !== -1) { |
879
|
|
|
$('#braintree-payment-form label[for=card-token-cvv]').addClass('ui-state-error-text'); |
880
|
|
|
} |
881
|
|
|
} else { |
882
|
|
|
if ($.inArray('number', tokenizeErr.details.invalidFieldKeys) !== -1) { |
883
|
|
|
$('#braintree-payment-form label[for=card-number]').addClass('ui-state-error-text'); |
884
|
|
|
} |
885
|
|
|
|
886
|
|
|
if ($.inArray('expirationDate', tokenizeErr.details.invalidFieldKeys) !== -1) { |
887
|
|
|
$('#braintree-payment-form label[for=card-exp]').addClass('ui-state-error-text'); |
888
|
|
|
} |
889
|
|
|
|
890
|
|
|
if ($.inArray('cvv', tokenizeErr.details.invalidFieldKeys) !== -1) { |
891
|
|
|
if ($('#card-cvv').length === 1) { |
892
|
|
|
$('#braintree-payment-form label[for=card-cvv]').addClass('ui-state-error-text'); |
893
|
|
|
} |
894
|
|
|
} |
895
|
|
|
} |
896
|
|
|
|
897
|
|
|
break; |
898
|
|
|
|
899
|
|
|
default: |
900
|
|
|
$('#btCardStatus').html('{$error_tmp_processing_problem}'); |
901
|
|
|
|
902
|
|
|
if ($('#btCardStatus').is(':hidden')) { |
903
|
|
|
$('#btCardStatus').show(); |
904
|
|
|
} |
905
|
|
|
} |
906
|
|
|
|
907
|
|
|
$('#braintree-payment-form-submit-button').html($('#braintree-payment-form-submit-button').data('orig-button-text')).button('enable'); |
908
|
|
|
|
909
|
|
|
return; |
910
|
|
|
} |
911
|
|
|
|
912
|
|
|
if (nonce === undefined) { |
913
|
|
|
nonce = payload.nonce; |
914
|
|
|
} |
915
|
|
|
|
916
|
|
|
if (do3ds === true) { |
917
|
|
|
create3DS(clientInstance, nonce); |
918
|
|
|
} else { |
919
|
|
|
$('#braintree-payment-form input[name="payment_method_nonce"]').val(nonce); |
920
|
|
|
|
921
|
|
|
$('#braintree-payment-form').submit(); |
922
|
|
|
} |
923
|
|
|
}); |
924
|
|
|
} |
925
|
|
|
|
926
|
|
|
function create3DS(clientInstance, nonce) { |
927
|
|
|
try { |
928
|
|
|
braintree.threeDSecure.create({ |
929
|
|
|
client: clientInstance |
930
|
|
|
}, function (threeDSecureErr, threeDSecureInstance) { |
931
|
|
|
if (threeDSecureErr) { |
932
|
|
|
$('#btCardStatus').html('{$error_tmp_processing_problem}'); |
933
|
|
|
|
934
|
|
|
if ($('#btCardStatus').is(':hidden')) { |
935
|
|
|
$('#btCardStatus').show(); |
936
|
|
|
} |
937
|
|
|
|
938
|
|
|
$('#braintree-payment-form-submit-button').html($('#braintree-payment-form-submit-button').data('orig-button-text')).button('enable'); |
939
|
|
|
|
940
|
|
|
return; |
941
|
|
|
} |
942
|
|
|
|
943
|
|
|
threeDSecureInstance.verifyCard({ |
944
|
|
|
amount: {$order_total}, |
945
|
|
|
nonce: nonce, |
946
|
|
|
addFrame: function (err, iframe) { |
947
|
|
|
$.colorbox({ |
948
|
|
|
transition: 'none', |
949
|
|
|
closeButton: false, |
950
|
|
|
overlayClose: false, |
951
|
|
|
escKey: false, |
952
|
|
|
arrowKey: false, |
953
|
|
|
html: $('<div>').html(iframe).html() |
954
|
|
|
}); |
955
|
|
|
}, |
956
|
|
|
removeFrame: function () { |
957
|
|
|
$.colorbox.close(); |
958
|
|
|
} |
959
|
|
|
}, function (error, response) { |
960
|
|
|
if (error) { |
961
|
|
|
$('#btCardStatus').html('{$error_tmp_processing_problem}'); |
962
|
|
|
|
963
|
|
|
if ($('#btCardStatus').is(':hidden')) { |
964
|
|
|
$('#btCardStatus').show(); |
965
|
|
|
} |
966
|
|
|
|
967
|
|
|
$('#braintree-payment-form-submit-button').html($('#braintree-payment-form-submit-button').data('orig-button-text')).button('enable'); |
968
|
|
|
|
969
|
|
|
return; |
970
|
|
|
} |
971
|
|
|
|
972
|
|
|
$('#braintree-payment-form input[name="payment_method_nonce"]').val(response.nonce); |
973
|
|
|
|
974
|
|
|
$('#braintree-payment-form').submit(); |
975
|
|
|
}); |
976
|
|
|
}); |
977
|
|
|
} catch (err) { |
978
|
|
|
$('#btCardStatus').html('{$error_tmp_processing_problem}'); |
979
|
|
|
|
980
|
|
|
if ($('#btCardStatus').is(':hidden')) { |
981
|
|
|
$('#btCardStatus').show(); |
982
|
|
|
} |
983
|
|
|
|
984
|
|
|
$('#braintree-payment-form-submit-button').html($('#braintree-payment-form-submit-button').data('orig-button-text')).button('enable'); |
985
|
|
|
} |
986
|
|
|
} |
987
|
|
|
|
988
|
|
|
var btClientInstance; |
989
|
|
|
var btHostedFieldsInstance; |
990
|
|
|
|
991
|
|
|
if ($('#braintree_cards').length > 0) { |
992
|
|
|
$('#braintree_cards').change(function() { |
993
|
|
|
$('#braintree-payment-form-submit-button').button('disable'); |
994
|
|
|
|
995
|
|
|
var selected = $(this).val(); |
996
|
|
|
|
997
|
|
|
if (selected == '0') { |
998
|
|
|
braintreeShowNewCardFields(); |
999
|
|
|
} else { |
1000
|
|
|
braintreeShowStoredCardFields(selected); |
1001
|
|
|
} |
1002
|
|
|
}); |
1003
|
|
|
} |
1004
|
|
|
|
1005
|
|
|
braintree.client.create({ |
1006
|
|
|
authorization: '{$clientToken}' |
1007
|
|
|
}, function (clientErr, clientInstance) { |
1008
|
|
|
if (clientErr) { |
1009
|
|
|
$('#btCardStatus').html('{$error_unavailable}'); |
1010
|
|
|
|
1011
|
|
|
if ($('#btCardStatus').is(':hidden')) { |
1012
|
|
|
$('#btCardStatus').show(); |
1013
|
|
|
} |
1014
|
|
|
|
1015
|
|
|
$('#braintree-payment-form-submit-button').hide(); |
1016
|
|
|
|
1017
|
|
|
window.location = '{$url_not_available}'; |
1018
|
|
|
|
1019
|
|
|
return; |
1020
|
|
|
} |
1021
|
|
|
|
1022
|
|
|
btClientInstance = clientInstance; |
1023
|
|
|
|
1024
|
|
|
if (($('#braintree_cards').length > 0) && ($('#braintree_cards').val() !== '0')) { |
1025
|
|
|
braintreeShowStoredCardFields($('#braintree_cards').val()); |
1026
|
|
|
} else { |
1027
|
|
|
braintreeShowNewCardFields(); |
1028
|
|
|
} |
1029
|
|
|
}); |
1030
|
|
|
|
1031
|
|
|
$('#braintree-payment-form').on('submit', function (event) { |
1032
|
|
|
if ($('#braintree-payment-form input[name="payment_method_nonce"]').val().length > 0) { |
1033
|
|
|
return; |
1034
|
|
|
} |
1035
|
|
|
|
1036
|
|
|
event.preventDefault(); |
1037
|
|
|
|
1038
|
|
|
var doTokenizeCall = true; |
1039
|
|
|
|
1040
|
|
|
if ($('#braintree_cards').length > 0) { |
1041
|
|
|
if (($('#card-token-cvv').length === 1) && $('#braintree-payment-form label[for=card-token-cvv]').hasClass('ui-state-error-text')) { |
1042
|
|
|
$('#braintree-payment-form label[for=card-token-cvv]').removeClass('ui-state-error-text'); |
1043
|
|
|
} |
1044
|
|
|
} |
1045
|
|
|
|
1046
|
|
|
if ($('#braintree-payment-form label[for=card-number]').hasClass('ui-state-error-text')) { |
1047
|
|
|
$('#braintree-payment-form label[for=card-number]').removeClass('ui-state-error-text'); |
1048
|
|
|
} |
1049
|
|
|
|
1050
|
|
|
if ($('#braintree-payment-form label[for=card-exp]').hasClass('ui-state-error-text')) { |
1051
|
|
|
$('#braintree-payment-form label[for=card-exp]').removeClass('ui-state-error-text'); |
1052
|
|
|
} |
1053
|
|
|
|
1054
|
|
|
if (($('#card-cvv').length === 1) && $('#braintree-payment-form label[for=card-cvv]').hasClass('ui-state-error-text')) { |
1055
|
|
|
$('#braintree-payment-form label[for=card-cvv]').removeClass('ui-state-error-text'); |
1056
|
|
|
} |
1057
|
|
|
|
1058
|
|
|
do3ds = false; |
1059
|
|
|
|
1060
|
|
|
if (($('#braintree_cards').length > 0) && ($('#braintree_cards').val() !== '0')) { |
1061
|
|
|
if (has3ds === 'all') { |
1062
|
|
|
do3ds = true; |
1063
|
|
|
} |
1064
|
|
|
} else { |
1065
|
|
|
if ((has3ds === 'all') || (has3ds === 'new')) { |
1066
|
|
|
do3ds = true; |
1067
|
|
|
} |
1068
|
|
|
} |
1069
|
|
|
|
1070
|
|
|
if ($('#braintree_cards').length > 0) { |
1071
|
|
|
var cardsel = $('#braintree_cards').val(); |
1072
|
|
|
|
1073
|
|
|
if (cardsel !== '0') { |
1074
|
|
|
doTokenizeCall = false; |
1075
|
|
|
|
1076
|
|
|
$.post('{$getCardTokenRpcUrl}', {card_id: cardsel}, function(response) { |
1077
|
|
|
if ((typeof response == 'object') && ('result' in response) && (response.result === 1)) { |
1078
|
|
|
doTokenize(btHostedFieldsInstance, btClientInstance, response.token); |
1079
|
|
|
} |
1080
|
|
|
}, 'json'); |
1081
|
|
|
} |
1082
|
|
|
} |
1083
|
|
|
|
1084
|
|
|
if (doTokenizeCall === true) { |
1085
|
|
|
doTokenize(btHostedFieldsInstance, btClientInstance); |
1086
|
|
|
} |
1087
|
|
|
}); |
1088
|
|
|
|
1089
|
|
|
function braintreeShowNewCardFields() { |
1090
|
|
|
if ($('#braintree_stored_card_cvv').length === 1) { |
1091
|
|
|
if ($('#braintree_stored_card_cvv').is(':visible')) { |
1092
|
|
|
$('#braintree_stored_card_cvv').hide(); |
1093
|
|
|
} |
1094
|
|
|
} |
1095
|
|
|
|
1096
|
|
|
if ($('#braintree-payment-form label[for=card-number]').hasClass('ui-state-error-text')) { |
1097
|
|
|
$('#braintree-payment-form label[for=card-number]').removeClass('ui-state-error-text'); |
1098
|
|
|
} |
1099
|
|
|
|
1100
|
|
|
if ($('#braintree-payment-form label[for=card-exp]').hasClass('ui-state-error-text')) { |
1101
|
|
|
$('#braintree-payment-form label[for=card-exp]').removeClass('ui-state-error-text'); |
1102
|
|
|
} |
1103
|
|
|
|
1104
|
|
|
if (($('#card-cvv').length === 1) && $('#braintree-payment-form label[for=card-cvv]').hasClass('ui-state-error-text')) { |
1105
|
|
|
$('#braintree-payment-form label[for=card-cvv]').removeClass('ui-state-error-text'); |
1106
|
|
|
} |
1107
|
|
|
|
1108
|
|
|
if ($('#braintree_new_card').not(':visible')) { |
1109
|
|
|
$('#braintree_new_card').show(); |
1110
|
|
|
} |
1111
|
|
|
|
1112
|
|
|
if (btHostedFieldsInstance !== undefined) { |
1113
|
|
|
btHostedFieldsInstance.teardown(function (teardownErr) { |
1114
|
|
|
if (teardownErr) { |
1115
|
|
|
return; |
1116
|
|
|
} |
1117
|
|
|
|
1118
|
|
|
braintreeCreateInstance(); |
1119
|
|
|
}); |
1120
|
|
|
|
1121
|
|
|
return; |
1122
|
|
|
} |
1123
|
|
|
|
1124
|
|
|
braintreeCreateInstance(); |
1125
|
|
|
} |
1126
|
|
|
|
1127
|
|
|
function braintreeShowStoredCardFields(id) { |
1128
|
|
|
if ($('#braintree_stored_card_cvv').length === 1) { |
1129
|
|
|
if ($('#braintree-payment-form label[for=card-token-cvv]').hasClass('ui-state-error-text')) { |
1130
|
|
|
$('#braintree-payment-form label[for=card-token-cvv]').removeClass('ui-state-error-text'); |
1131
|
|
|
} |
1132
|
|
|
|
1133
|
|
|
if ($('#braintree_stored_card_cvv').not(':visible')) { |
1134
|
|
|
$('#braintree_stored_card_cvv').show(); |
1135
|
|
|
} |
1136
|
|
|
} |
1137
|
|
|
|
1138
|
|
|
if ($('#braintree_new_card').is(':visible')) { |
1139
|
|
|
$('#braintree_new_card').hide(); |
1140
|
|
|
|
1141
|
|
|
if (btHostedFieldsInstance !== undefined) { |
1142
|
|
|
btHostedFieldsInstance.teardown(function (teardownErr) { |
1143
|
|
|
if (teardownErr) { |
1144
|
|
|
return; |
1145
|
|
|
} |
1146
|
|
|
|
1147
|
|
|
braintreeCreateStoredCardInstance(); |
1148
|
|
|
}); |
1149
|
|
|
|
1150
|
|
|
return; |
1151
|
|
|
} |
1152
|
|
|
|
1153
|
|
|
braintreeCreateStoredCardInstance(); |
1154
|
|
|
|
1155
|
|
|
return; |
1156
|
|
|
} |
1157
|
|
|
|
1158
|
|
|
if (btHostedFieldsInstance === undefined) { |
1159
|
|
|
braintreeCreateStoredCardInstance(); |
1160
|
|
|
} else { |
1161
|
|
|
$('#braintree-payment-form-submit-button').button('enable'); |
1162
|
|
|
} |
1163
|
|
|
} |
1164
|
|
|
|
1165
|
|
|
function braintreeCreateInstance() { |
1166
|
|
|
var fields = { |
1167
|
|
|
number: { |
1168
|
|
|
selector: '#card-number' |
1169
|
|
|
}, |
1170
|
|
|
expirationDate: { |
1171
|
|
|
selector: '#card-exp', |
1172
|
|
|
placeholder: 'MM / YYYY' |
1173
|
|
|
} |
1174
|
|
|
}; |
1175
|
|
|
|
1176
|
|
|
if ($('#card-cvv').length === 1) { |
1177
|
|
|
fields.cvv = { |
1178
|
|
|
selector: '#card-cvv' |
1179
|
|
|
}; |
1180
|
|
|
} |
1181
|
|
|
|
1182
|
|
|
braintree.hostedFields.create({ |
1183
|
|
|
client: btClientInstance, |
1184
|
|
|
styles: { |
1185
|
|
|
':focus': { |
1186
|
|
|
'color': 'black' |
1187
|
|
|
}, |
1188
|
|
|
'.valid': { |
1189
|
|
|
'color': '#8bdda8' |
1190
|
|
|
} |
1191
|
|
|
}, |
1192
|
|
|
fields: fields |
1193
|
|
|
}, function (hostedFieldsErr, hostedFieldsInstance) { |
1194
|
|
|
if (hostedFieldsErr) { |
1195
|
|
|
$('#btCardStatus').html('{$error_unavailable}'); |
1196
|
|
|
|
1197
|
|
|
if ($('#btCardStatus').is(':hidden')) { |
1198
|
|
|
$('#btCardStatus').show(); |
1199
|
|
|
} |
1200
|
|
|
|
1201
|
|
|
$('#braintree-payment-form-submit-button').hide(); |
1202
|
|
|
|
1203
|
|
|
window.location = '{$url_not_available}'; |
1204
|
|
|
|
1205
|
|
|
return; |
1206
|
|
|
} |
1207
|
|
|
|
1208
|
|
|
btHostedFieldsInstance = hostedFieldsInstance; |
1209
|
|
|
|
1210
|
|
|
$('#braintree-payment-form-submit-button').button('enable'); |
1211
|
|
|
}); |
1212
|
|
|
} |
1213
|
|
|
|
1214
|
|
|
function braintreeCreateStoredCardInstance() { |
1215
|
|
|
if ($('#card-token-cvv').length === 1) { |
1216
|
|
|
braintree.hostedFields.create({ |
1217
|
|
|
client: btClientInstance, |
1218
|
|
|
styles: { |
1219
|
|
|
':focus': { |
1220
|
|
|
'color': 'black' |
1221
|
|
|
}, |
1222
|
|
|
'.valid': { |
1223
|
|
|
'color': '#8bdda8' |
1224
|
|
|
} |
1225
|
|
|
}, |
1226
|
|
|
fields: { |
1227
|
|
|
cvv: { |
1228
|
|
|
selector: '#card-token-cvv' |
1229
|
|
|
} |
1230
|
|
|
} |
1231
|
|
|
}, function (hostedFieldsErr, hostedFieldsInstance) { |
1232
|
|
|
if (hostedFieldsErr) { |
1233
|
|
|
$('#btCardStatus').html('{$error_unavailable}'); |
1234
|
|
|
|
1235
|
|
|
if ($('#btCardStatus').is(':hidden')) { |
1236
|
|
|
$('#btCardStatus').show(); |
1237
|
|
|
} |
1238
|
|
|
|
1239
|
|
|
$('#braintree-payment-form-submit-button').hide(); |
1240
|
|
|
|
1241
|
|
|
window.location = '{$url_not_available}'; |
1242
|
|
|
|
1243
|
|
|
return; |
1244
|
|
|
} |
1245
|
|
|
|
1246
|
|
|
btHostedFieldsInstance = hostedFieldsInstance; |
1247
|
|
|
|
1248
|
|
|
$('#braintree-payment-form-submit-button').button('enable'); |
1249
|
|
|
}); |
1250
|
|
|
} else { |
1251
|
|
|
btHostedFieldsInstance = undefined; |
1252
|
|
|
|
1253
|
|
|
$('#braintree-payment-form-submit-button').button('enable'); |
1254
|
|
|
} |
1255
|
|
|
} |
1256
|
|
|
}); |
1257
|
|
|
</script> |
1258
|
|
|
EOD; |
1259
|
|
|
|
1260
|
|
|
$js_scripts = '<script src="https://js.braintreegateway.com/web/3.2.0/js/client.min.js"></script>' . |
1261
|
|
|
'<script src="https://js.braintreegateway.com/web/3.2.0/js/hosted-fields.min.js"></script>'; |
1262
|
|
|
|
1263
|
|
|
if ((OSCOM_APP_PAYPAL_BRAINTREE_CC_THREE_D_SECURE === '1') || (OSCOM_APP_PAYPAL_BRAINTREE_CC_THREE_D_SECURE === '2')) { |
1264
|
|
|
$js_scripts .= '<script src="https://js.braintreegateway.com/web/3.2.0/js/three-d-secure.min.js"></script>'; |
1265
|
|
|
} |
1266
|
|
|
|
1267
|
|
|
if ($this->templateClassExists()) { |
1268
|
|
|
$GLOBALS['oscTemplate']->addBlock($js_scripts, 'footer_scripts'); |
1269
|
|
|
} else { |
1270
|
|
|
$js .= $js_scripts; |
1271
|
|
|
} |
1272
|
|
|
|
1273
|
|
|
return $js; |
1274
|
|
|
} |
1275
|
|
|
|
1276
|
|
|
function isPaymentTypeAccepted($type) { |
1277
|
|
|
return in_array($type, $this->payment_types); |
1278
|
|
|
} |
1279
|
|
|
} |
1280
|
|
|
?> |
|
|
|
|
1281
|
|
|
|
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: