1
|
|
|
<?php |
2
|
|
|
// Exit if accessed directly |
3
|
|
|
if ( ! defined( 'ABSPATH' ) ) exit; |
4
|
|
|
|
5
|
|
|
add_filter( 'wpinv_authorizenet_support_subscription', '__return_true' ); |
6
|
|
|
|
7
|
|
|
function wpinv_authorizenet_cc_form( $invoice_id ) { |
8
|
|
|
$invoice = wpinv_get_invoice( $invoice_id ); |
9
|
|
|
$cc_owner = !empty( $invoice ) ? esc_attr( $invoice->get_user_full_name() ) : ''; |
10
|
|
|
?> |
11
|
|
|
<div id="authorizenet_cc_form" class="form-horizontal wpi-cc-form panel panel-default"> |
12
|
|
|
<div class="panel-heading"><h3 class="panel-title"><?php _e( 'Card Details', 'invoicing' ) ;?></h3></div> |
13
|
|
|
<div class="panel-body"> |
14
|
|
|
<div class="form-group required"> |
15
|
|
|
<label for="auth-input-cc-owner" class="col-sm-3 control-label"><?php _e( 'Card Owner', 'invoicing' ) ;?></label> |
16
|
|
|
<div class="col-sm-5"> |
17
|
|
|
<input type="text" class="form-control" id="auth-input-cc-owner" placeholder="<?php esc_attr_e( 'Card Owner', 'invoicing' ) ;?>" value="<?php echo $cc_owner;?>" name="authorizenet[cc_owner]"> |
18
|
|
|
</div> |
19
|
|
|
</div> |
20
|
|
|
<div class="form-group required"> |
21
|
|
|
<label for="auth-input-cc-number" class="col-sm-3 control-label"><?php _e( 'Card Number', 'invoicing' ) ;?></label> |
22
|
|
|
<div class="col-sm-5"> |
23
|
|
|
<input type="text" class="form-control" id="auth-input-cc-number" placeholder="<?php esc_attr_e( 'Card Number', 'invoicing' ) ;?>" value="" name="authorizenet[cc_number]"> |
24
|
|
|
</div> |
25
|
|
|
</div> |
26
|
|
|
<div class="form-group required"> |
27
|
|
|
<label for="auth-input-cc-expire-date" class="col-sm-3 control-label"><?php _e( 'Card Expiry Date', 'invoicing' ) ;?></label> |
28
|
|
|
<div class="col-sm-2"> |
29
|
|
|
<select class="form-control" id="auth-input-cc-expire-date" name="authorizenet[cc_expire_month]"> |
30
|
|
View Code Duplication |
<?php for ( $i = 1; $i <= 12; $i++ ) { $value = str_pad( $i, 2, '0', STR_PAD_LEFT ); ?> |
31
|
|
|
<option value="<?php echo $value;?>"><?php echo $value;?></option> |
32
|
|
|
<?php } ?> |
33
|
|
|
</select> |
34
|
|
|
</div> |
35
|
|
|
<div class="col-sm-3"> |
36
|
|
|
<select class="form-control" name="authorizenet[cc_expire_year]"> |
37
|
|
|
<?php $year = date( 'Y' ); for ( $i = $year; $i <= ( $year + 10 ); $i++ ) { ?> |
38
|
|
|
<option value="<?php echo $i;?>"><?php echo $i;?></option> |
39
|
|
|
<?php } ?> |
40
|
|
|
</select> |
41
|
|
|
</div> |
42
|
|
|
</div> |
43
|
|
|
<div class="form-group required"> |
44
|
|
|
<label for="auth-input-cc-cvv2" class="col-sm-3 control-label"><?php _e( 'Card Security Code (CVV2)', 'invoicing' ) ;?></label> |
45
|
|
|
<div class="col-sm-5"> |
46
|
|
|
<input type="text" class="form-control" id="auth-input-cc-cvv2" placeholder="<?php esc_attr_e( 'Card Security Code (CVV2)', 'invoicing' ) ;?>" value="" name="authorizenet[cc_cvv2]""> |
47
|
|
|
</div> |
48
|
|
|
</div> |
49
|
|
|
</div> |
50
|
|
|
</div> |
51
|
|
|
<?php |
52
|
|
|
} |
53
|
|
|
add_action( 'wpinv_authorizenet_cc_form', 'wpinv_authorizenet_cc_form', 10, 1 ); |
54
|
|
|
|
55
|
|
|
function wpinv_process_authorizenet_payment( $purchase_data ) { |
56
|
|
|
if( ! wp_verify_nonce( $purchase_data['gateway_nonce'], 'wpi-gateway' ) ) { |
57
|
|
|
wp_die( __( 'Nonce verification has failed', 'invoicing' ), __( 'Error', 'invoicing' ), array( 'response' => 403 ) ); |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
// Collect payment data |
61
|
|
|
$payment_data = array( |
62
|
|
|
'price' => $purchase_data['price'], |
63
|
|
|
'date' => $purchase_data['date'], |
64
|
|
|
'user_email' => $purchase_data['user_email'], |
65
|
|
|
'invoice_key' => $purchase_data['invoice_key'], |
66
|
|
|
'currency' => wpinv_get_currency(), |
67
|
|
|
'items' => $purchase_data['items'], |
68
|
|
|
'user_info' => $purchase_data['user_info'], |
69
|
|
|
'cart_details' => $purchase_data['cart_details'], |
70
|
|
|
'gateway' => 'authorizenet', |
71
|
|
|
'status' => 'wpi-pending' |
72
|
|
|
); |
73
|
|
|
|
74
|
|
|
// Record the pending payment |
75
|
|
|
$invoice = wpinv_get_invoice( $purchase_data['invoice_id'] ); |
76
|
|
|
|
77
|
|
|
if ( !empty( $invoice ) ) { |
78
|
|
|
$authorizenet_card = !empty( $_POST['authorizenet'] ) ? $_POST['authorizenet'] : array(); |
79
|
|
|
$card_defaults = array( |
80
|
|
|
'cc_owner' => $invoice->get_user_full_name(), |
81
|
|
|
'cc_number' => false, |
82
|
|
|
'cc_expire_month' => false, |
83
|
|
|
'cc_expire_year' => false, |
84
|
|
|
'cc_cvv2' => false, |
85
|
|
|
); |
86
|
|
|
$authorizenet_card = wp_parse_args( $authorizenet_card, $card_defaults ); |
87
|
|
|
|
88
|
|
|
if ( empty( $authorizenet_card['cc_owner'] ) ) { |
89
|
|
|
wpinv_set_error( 'empty_card_name', __( 'You must enter the name on your card!', 'invoicing')); |
90
|
|
|
} |
91
|
|
|
if ( empty( $authorizenet_card['cc_number'] ) ) { |
92
|
|
|
wpinv_set_error( 'empty_card', __( 'You must enter a card number!', 'invoicing')); |
93
|
|
|
} |
94
|
|
|
if ( empty( $authorizenet_card['cc_expire_month'] ) ) { |
95
|
|
|
wpinv_set_error( 'empty_month', __( 'You must enter an card expiration month!', 'invoicing')); |
96
|
|
|
} |
97
|
|
|
if ( empty( $authorizenet_card['cc_expire_year'] ) ) { |
98
|
|
|
wpinv_set_error( 'empty_year', __( 'You must enter an card expiration year!', 'invoicing')); |
99
|
|
|
} |
100
|
|
|
if ( empty( $authorizenet_card['cc_cvv2'] ) ) { |
101
|
|
|
wpinv_set_error( 'empty_cvv2', __( 'You must enter a valid CVV2!', 'invoicing' ) ); |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
$errors = wpinv_get_errors(); |
105
|
|
|
|
106
|
|
|
if ( empty( $errors ) ) { |
107
|
|
|
$invoice_id = $invoice->ID; |
108
|
|
|
$quantities_enabled = wpinv_item_quantities_enabled(); |
109
|
|
|
$use_taxes = wpinv_use_taxes(); |
110
|
|
|
|
111
|
|
|
$authorizeAIM = wpinv_authorizenet_AIM(); |
112
|
|
|
$authorizeAIM->first_name = wpinv_utf8_substr( $invoice->get_first_name(), 0, 50 ); |
|
|
|
|
113
|
|
|
$authorizeAIM->last_name = wpinv_utf8_substr( $invoice->get_last_name(), 0, 50 ); |
|
|
|
|
114
|
|
|
$authorizeAIM->company = wpinv_utf8_substr( $invoice->company, 0, 50 ); |
|
|
|
|
115
|
|
|
$authorizeAIM->address = wpinv_utf8_substr( wp_strip_all_tags( $invoice->get_address(), true ), 0, 60 ); |
|
|
|
|
116
|
|
|
$authorizeAIM->city = wpinv_utf8_substr( $invoice->city, 0, 40 ); |
|
|
|
|
117
|
|
|
$authorizeAIM->state = wpinv_utf8_substr( $invoice->state, 0, 40 ); |
|
|
|
|
118
|
|
|
$authorizeAIM->zip = wpinv_utf8_substr( $invoice->zip, 0, 40 ); |
|
|
|
|
119
|
|
|
$authorizeAIM->country = wpinv_utf8_substr( $invoice->country, 0, 60 ); |
|
|
|
|
120
|
|
|
$authorizeAIM->phone = wpinv_utf8_substr( $invoice->phone, 0, 25 ); |
|
|
|
|
121
|
|
|
$authorizeAIM->email = wpinv_utf8_substr( $invoice->get_email(), 0, 255 ); |
|
|
|
|
122
|
|
|
$authorizeAIM->amount = wpinv_sanitize_amount( $invoice->get_total() ); |
|
|
|
|
123
|
|
|
$authorizeAIM->card_num = str_replace( ' ', '', sanitize_text_field( $authorizenet_card['cc_number'] ) ); |
|
|
|
|
124
|
|
|
$authorizeAIM->exp_date = sanitize_text_field( $authorizenet_card['cc_expire_month'] ) . sanitize_text_field( $authorizenet_card['cc_expire_year'] ); |
|
|
|
|
125
|
|
|
$authorizeAIM->card_code = sanitize_text_field( $authorizenet_card['cc_cvv2'] ); |
|
|
|
|
126
|
|
|
$authorizeAIM->invoice_num = $invoice->ID; |
|
|
|
|
127
|
|
|
|
128
|
|
|
$item_desc = array(); |
129
|
|
|
foreach ( $invoice->get_cart_details() as $item ) { |
130
|
|
|
$quantity = $quantities_enabled && !empty( $item['quantity'] ) && $item['quantity'] > 0 ? $item['quantity'] : 1; |
131
|
|
|
$item_name = wpinv_utf8_substr( $item['name'], 0, 31 ); |
132
|
|
|
$item_desc[] = $item_name . ' (' . $quantity . 'x ' . wpinv_price( wpinv_format_amount( $item['item_price'] ) ) . ')'; |
133
|
|
|
|
134
|
|
|
$authorizeAIM->addLineItem( $item['id'], $item_name, '', $quantity, $item['item_price'], ( $use_taxes && !empty( $item['tax'] ) && $item['tax'] > 0 ? 'Y' : 'N' ) ); |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
$item_desc = '#' . $invoice->get_number() . ': ' . implode( ', ', $item_desc ); |
138
|
|
|
|
139
|
|
|
if ( $use_taxes && $invoice->get_tax() > 0 ) { |
140
|
|
|
$authorizeAIM->tax = $invoice->get_tax(); |
|
|
|
|
141
|
|
|
|
142
|
|
|
$item_desc .= ', ' . wp_sprintf( __( 'Tax: %s', 'invoicing' ), $invoice->get_tax( true ) ); |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
if ( $invoice->get_discount() > 0 ) { |
146
|
|
|
$item_desc .= ', ' . wp_sprintf( __( 'Discount: %s', 'invoicing' ), $invoice->get_discount( true ) ); |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
$item_description = wpinv_utf8_substr( $item_desc, 0, 255 ); |
|
|
|
|
150
|
|
|
$item_description = html_entity_decode( $item_desc , ENT_QUOTES, 'UTF-8' ); |
151
|
|
|
|
152
|
|
|
$authorizeAIM->description = wpinv_utf8_substr( $item_description, 0, 255 ); |
|
|
|
|
153
|
|
|
|
154
|
|
|
$is_recurring = $invoice->is_recurring(); // Recurring payment. |
155
|
|
|
|
156
|
|
|
if ( $is_recurring ) { |
157
|
|
|
$authorizeAIM->recurring_billing = true; |
|
|
|
|
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
try { |
161
|
|
|
if ( $is_recurring ) { |
162
|
|
|
$response = $authorizeAIM->authorizeOnly(); |
163
|
|
|
} else { |
164
|
|
|
$response = $authorizeAIM->authorizeAndCapture(); |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
if ( $response->approved || $response->held ) { |
|
|
|
|
168
|
|
|
if ( $response->approved ) { |
|
|
|
|
169
|
|
|
wpinv_update_payment_status( $invoice_id, 'publish' ); |
170
|
|
|
} |
171
|
|
|
wpinv_set_payment_transaction_id( $invoice_id, $response->transaction_id ); |
|
|
|
|
172
|
|
|
|
173
|
|
|
wpinv_insert_payment_note( $invoice_id, wp_sprintf( __( 'Authorize.Net payment response: %s', 'invoicing' ), $response->response_reason_text ), '', '', true ); |
|
|
|
|
174
|
|
|
wpinv_insert_payment_note( $invoice_id, wp_sprintf( __( 'Authorize.Net payment: Transaction ID %s, Transaction Type %s, Authorization Code %s', 'invoicing' ), $response->transaction_id, strtoupper( $response->transaction_type ), $response->authorization_code ), '', '', true ); |
|
|
|
|
175
|
|
|
|
176
|
|
|
do_action( 'wpinv_authorizenet_handle_response', $response, $invoice, $authorizenet_card ); |
177
|
|
|
|
178
|
|
|
wpinv_clear_errors(); |
179
|
|
|
wpinv_empty_cart(); |
180
|
|
|
|
181
|
|
|
wpinv_send_to_success_page( array( 'invoice_key' => $invoice->get_key() ) ); |
182
|
|
|
} else { |
183
|
|
|
if ( !empty( $response->response_reason_text ) ) { |
184
|
|
|
$error = __( $response->response_reason_text, 'invoicing' ); |
185
|
|
|
} else if ( !empty( $response->error_message ) ) { |
186
|
|
|
$error = __( $response->error_message, 'invoicing' ); |
|
|
|
|
187
|
|
|
} else { |
188
|
|
|
$error = wp_sprintf( __( 'Error data: %s', 'invoicing' ), print_r( $response, true ) ); |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
$error = wp_sprintf( __( 'Authorize.Net payment error occurred. %s', 'invoicing' ), $error ); |
192
|
|
|
|
193
|
|
|
wpinv_set_error( 'payment_error', $error ); |
194
|
|
|
wpinv_record_gateway_error( $error, $response ); |
|
|
|
|
195
|
|
|
wpinv_insert_payment_note( $invoice_id, $error, '', '', true ); |
|
|
|
|
196
|
|
|
|
197
|
|
|
wpinv_send_back_to_checkout( '?payment-mode=' . $purchase_data['post_data']['wpi-gateway'] ); |
|
|
|
|
198
|
|
|
} |
199
|
|
|
} catch ( AuthorizeNetException $e ) { |
200
|
|
|
wpinv_set_error( 'request_error', $e->getMessage() ); |
201
|
|
|
wpinv_record_gateway_error( wp_sprintf( __( 'Authorize.Net payment error occurred. %s', 'invoicing' ), $e->getMessage() ) ); |
202
|
|
|
wpinv_send_back_to_checkout( '?payment-mode=' . $purchase_data['post_data']['wpi-gateway'] ); |
|
|
|
|
203
|
|
|
} |
204
|
|
|
} else { |
205
|
|
|
wpinv_send_back_to_checkout( '?payment-mode=' . $purchase_data['post_data']['wpi-gateway'] ); |
|
|
|
|
206
|
|
|
} |
207
|
|
|
} else { |
208
|
|
|
wpinv_record_gateway_error( wp_sprintf( __( 'Authorize.Net payment error occurred. Payment creation failed while processing a Authorize.net payment. Payment data: %s', 'invoicing' ), print_r( $payment_data, true ) ), $invoice ); |
209
|
|
|
wpinv_send_back_to_checkout( '?payment-mode=' . $purchase_data['post_data']['wpi-gateway'] ); |
|
|
|
|
210
|
|
|
} |
211
|
|
|
} |
212
|
|
|
add_action( 'wpinv_gateway_authorizenet', 'wpinv_process_authorizenet_payment' ); |
213
|
|
|
|
214
|
|
|
function wpinv_authorizenet_cancel_subscription( $subscription_id = '' ) { |
215
|
|
|
if ( empty( $subscription_id ) ) { |
216
|
|
|
return false; |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
try { |
220
|
|
|
$authnetXML = wpinv_authorizenet_XML(); |
221
|
|
|
$authnetXML->ARBCancelSubscriptionRequest( array( 'subscriptionId' => $subscription_id ) ); |
|
|
|
|
222
|
|
|
return $authnetXML->isSuccessful(); |
223
|
|
|
} catch( Exception $e ) { |
224
|
|
|
wpinv_error_log( $e->getMessage(), __( 'Authorize.Net cancel subscription', 'invoicing' ) ); |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
return false; |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
function wpinv_recurring_cancel_authorizenet_subscription( $subscription, $valid = false ) { |
231
|
|
|
if ( ! empty( $valid ) && ! empty( $subscription->profile_id ) ) { |
232
|
|
|
return wpinv_authorizenet_cancel_subscription( $subscription->profile_id ); |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
return false; |
236
|
|
|
} |
237
|
|
|
add_action( 'wpinv_recurring_cancel_authorizenet_subscription', 'wpinv_recurring_cancel_authorizenet_subscription', 10, 2 ); |
238
|
|
|
|
239
|
|
|
function wpinv_authorizenet_valid_ipn( $md5_hash, $transaction_id, $amount ) { |
240
|
|
|
$authorizenet_md5_hash = wpinv_get_option( 'authorizenet_md5_hash' ); |
241
|
|
|
if ( empty( $authorizenet_md5_hash ) ) { |
242
|
|
|
return true; |
243
|
|
|
} |
244
|
|
|
|
245
|
|
|
$compare_md5 = strtoupper( md5( $authorizenet_md5_hash . $transaction_id . $amount ) ); |
246
|
|
|
|
247
|
|
|
return hash_equals( $compare_md5, $md5_hash ); |
248
|
|
|
} |
249
|
|
|
|
250
|
|
|
function wpinv_authorizenet_AIM() { |
251
|
|
|
if ( !class_exists( 'AuthorizeNetException' ) ) { |
252
|
|
|
require_once plugin_dir_path( WPINV_PLUGIN_FILE ) . 'includes/gateways/authorizenet/anet_php_sdk/AuthorizeNet.php'; |
253
|
|
|
} |
254
|
|
|
|
255
|
|
|
$authorizeAIM = new AuthorizeNetAIM( wpinv_get_option( 'authorizenet_login_id' ), wpinv_get_option( 'authorizenet_transaction_key' ) ); |
256
|
|
|
|
257
|
|
|
if ( wpinv_is_test_mode( 'authorizenet' ) ) { |
258
|
|
|
$authorizeAIM->setSandbox( true ); |
259
|
|
|
} else { |
260
|
|
|
$authorizeAIM->setSandbox( false ); |
261
|
|
|
} |
262
|
|
|
|
263
|
|
|
$authorizeAIM->customer_ip = wpinv_get_ip(); |
|
|
|
|
264
|
|
|
|
265
|
|
|
return $authorizeAIM; |
266
|
|
|
} |
267
|
|
|
|
268
|
|
|
function wpinv_authorizenet_XML() { |
269
|
|
|
if ( !class_exists( 'AuthnetXML' ) ) { |
270
|
|
|
require_once plugin_dir_path( WPINV_PLUGIN_FILE ) . 'includes/gateways/authorizenet/Authorize.Net-XML/AuthnetXML.class.php'; |
271
|
|
|
} |
272
|
|
|
|
273
|
|
|
$authnetXML = new AuthnetXML( wpinv_get_option( 'authorizenet_login_id' ), wpinv_get_option( 'authorizenet_transaction_key' ), (bool)wpinv_is_test_mode( 'authorizenet' ) ); |
|
|
|
|
274
|
|
|
|
275
|
|
|
return $authnetXML; |
276
|
|
|
} |
277
|
|
|
|
278
|
|
|
function wpinv_authorizenet_handle_response( $response, $invoice, $card_info = array() ) { |
279
|
|
|
if ( empty( $response ) || empty( $invoice ) ) { |
280
|
|
|
return false; |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
if ( $invoice->is_recurring() && !empty( $response->approved ) ) { |
284
|
|
|
$subscription = wpinv_authorizenet_create_new_subscription( $invoice, $response, $card_info ); |
285
|
|
|
$success = false; |
|
|
|
|
286
|
|
|
if ( wpinv_is_test_mode( 'authorizenet' ) ) { |
287
|
|
|
$success = true; |
288
|
|
|
} else { |
289
|
|
|
$success = $subscription->isSuccessful(); |
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
if ( !empty( $subscription ) && $success ) { |
293
|
|
|
do_action( 'wpinv_recurring_post_create_subscription', $subscription, $invoice, 'authorizenet' ); |
294
|
|
|
|
295
|
|
|
wpinv_authorizenet_subscription_record_signup( $subscription, $invoice ); |
296
|
|
|
|
297
|
|
|
do_action( 'wpinv_recurring_post_record_signup', $subscription, $invoice, 'authorizenet' ); |
298
|
|
|
} else { |
299
|
|
|
if ( isset( $subscription->messages->message ) ) { |
300
|
|
|
$error = $subscription->messages->message->code . ': ' . $subscription->messages->message->text; |
301
|
|
|
wpinv_set_error( 'wpinv_authorize_recurring_error', $error, 'invoicing' ); |
|
|
|
|
302
|
|
|
} else { |
303
|
|
|
$error = __( 'Your subscription cannot be created due to an error.', 'invoicing' ); |
304
|
|
|
wpinv_set_error( 'wpinv_authorize_recurring_error', $error ); |
305
|
|
|
} |
306
|
|
|
|
307
|
|
|
wpinv_record_gateway_error( $error, $subscription ); |
308
|
|
|
|
309
|
|
|
wpinv_insert_payment_note( $invoice->ID, wp_sprintf( __( 'Authorize.Net subscription error occurred. %s', 'invoicing' ), $error ), '', '', true ); |
|
|
|
|
310
|
|
|
} |
311
|
|
|
} |
312
|
|
|
} |
313
|
|
|
add_action( 'wpinv_authorizenet_handle_response', 'wpinv_authorizenet_handle_response', 10, 3 ); |
314
|
|
|
|
315
|
|
|
function wpinv_authorizenet_create_new_subscription( $invoice, $response = array(), $card_info = array() ) { |
316
|
|
|
if ( empty( $invoice ) ) { |
317
|
|
|
return false; |
318
|
|
|
} |
319
|
|
|
|
320
|
|
|
$params = wpinv_authorizenet_generate_subscription_params( $invoice, $card_info, $response ); |
321
|
|
|
|
322
|
|
|
try { |
323
|
|
|
$authnetXML = wpinv_authorizenet_XML(); |
324
|
|
|
$authnetXML->ARBCreateSubscriptionRequest( $params ); |
|
|
|
|
325
|
|
|
} catch( Exception $e ) { |
326
|
|
|
$authnetXML = array(); |
327
|
|
|
wpinv_error_log( $e->getMessage(), __( 'Authorize.Net cancel subscription', 'invoicing' ) ); |
328
|
|
|
} |
329
|
|
|
|
330
|
|
|
return $authnetXML; |
331
|
|
|
} |
332
|
|
|
|
333
|
|
|
function wpinv_authorizenet_generate_subscription_params( $invoice, $card_info = array(), $response = array() ) { |
334
|
|
|
if ( empty( $invoice ) ) { |
335
|
|
|
return false; |
336
|
|
|
} |
337
|
|
|
|
338
|
|
|
$subscription_item = $invoice->get_recurring( true ); |
339
|
|
|
if ( empty( $subscription_item->ID ) ) { |
340
|
|
|
return false; |
341
|
|
|
} |
342
|
|
|
|
343
|
|
|
$item = $invoice->get_recurring( true ); |
344
|
|
|
|
345
|
|
|
if ( empty( $item ) ) { |
346
|
|
|
$name = ''; |
|
|
|
|
347
|
|
|
} |
348
|
|
|
|
349
|
|
|
if ( !( $name = $item->get_name() ) ) { |
350
|
|
|
$name = $item->post_name; |
|
|
|
|
351
|
|
|
} |
352
|
|
|
|
353
|
|
|
$card_details = wpinv_authorizenet_generate_card_info( $card_info ); |
354
|
|
|
$subscription_name = $invoice->get_subscription_name(); |
355
|
|
|
$initial_amount = wpinv_round_amount( $invoice->get_total() ); |
356
|
|
|
$recurring_amount = wpinv_round_amount( $invoice->get_recurring_details( 'total' ) ); |
357
|
|
|
$interval = $subscription_item->get_recurring_interval(); |
358
|
|
|
$period = $subscription_item->get_recurring_period(); |
359
|
|
|
$bill_times = (int)$subscription_item->get_recurring_limit(); |
360
|
|
|
$bill_times = $bill_times > 0 ? $bill_times : 9999; |
361
|
|
|
|
362
|
|
|
$time_period = wpinv_authorizenet_get_time_period( $interval, $period ); |
363
|
|
|
$interval = $time_period['interval']; |
364
|
|
|
$period = $time_period['period']; |
365
|
|
|
|
366
|
|
|
$current_tz = date_default_timezone_get(); |
367
|
|
|
date_default_timezone_set( 'America/Denver' ); // Set same timezone as Authorize's server (Mountain Time) to prevent conflicts. |
368
|
|
|
$today = date( 'Y-m-d' ); |
369
|
|
|
date_default_timezone_set( $current_tz ); |
370
|
|
|
|
371
|
|
|
$free_trial = $invoice->is_free_trial(); |
372
|
|
|
if ( $free_trial && $subscription_item->has_free_trial() ) { |
373
|
|
|
$trial_interval = $subscription_item->get_trial_interval(); |
|
|
|
|
374
|
|
|
$trial_period = $subscription_item->get_trial_period( true ); |
|
|
|
|
375
|
|
|
} |
376
|
|
|
|
377
|
|
|
$subscription = array(); |
378
|
|
|
$subscription['name'] = $subscription_name; |
379
|
|
|
|
380
|
|
|
$subscription['paymentSchedule'] = array( |
381
|
|
|
'interval' => array( 'length' => $interval, 'unit' => $period ), |
382
|
|
|
'startDate' => $today, |
383
|
|
|
'totalOccurrences' => $bill_times, |
384
|
|
|
'trialOccurrences' => $free_trial || ( $initial_amount != $recurring_amount ) ? 1 : 0, |
385
|
|
|
); |
386
|
|
|
|
387
|
|
|
$subscription['amount'] = $recurring_amount; |
388
|
|
|
$subscription['trialAmount'] = $initial_amount; |
389
|
|
|
$subscription['payment'] = array( 'creditCard' => $card_details ); |
390
|
|
|
$subscription['order'] = array( 'invoiceNumber' => $invoice->ID, 'description' => '#' . $invoice->get_number() ); |
391
|
|
|
$subscription['customer'] = array( 'id' => $invoice->get_user_id(), 'email' => $invoice->get_email(), 'phoneNumber' => $invoice->phone ); |
392
|
|
|
|
393
|
|
|
$subscription['billTo'] = array( |
394
|
|
|
'firstName' => $invoice->get_first_name(), |
395
|
|
|
'lastName' => $invoice->get_last_name(), |
396
|
|
|
'company' => $invoice->company, |
397
|
|
|
'address' => wp_strip_all_tags( $invoice->get_address(), true ), |
398
|
|
|
'city' => $invoice->city, |
399
|
|
|
'state' => $invoice->state, |
400
|
|
|
'zip' => $invoice->zip, |
401
|
|
|
'country' => $invoice->country, |
402
|
|
|
); |
403
|
|
|
|
404
|
|
|
$params = array( 'subscription' => $subscription ); |
405
|
|
|
|
406
|
|
|
return apply_filters( 'wpinv_authorizenet_generate_subscription_params', $params, $invoice, $card_info, $response ); |
407
|
|
|
} |
408
|
|
|
|
409
|
|
|
function wpinv_authorizenet_generate_card_info( $card_info = array() ) { |
410
|
|
|
$card_defaults = array( |
411
|
|
|
'cc_owner' => null, |
412
|
|
|
'cc_number' => null, |
413
|
|
|
'cc_expire_month' => null, |
414
|
|
|
'cc_expire_year' => null, |
415
|
|
|
'cc_cvv2' => null, |
416
|
|
|
); |
417
|
|
|
$card_info = wp_parse_args( $card_info, $card_defaults ); |
418
|
|
|
|
419
|
|
|
$card_details = array( |
420
|
|
|
'cardNumber' => str_replace( ' ', '', sanitize_text_field( $card_info['cc_number'] ) ), |
421
|
|
|
'expirationDate' => sanitize_text_field( $card_info['cc_expire_month'] ) . sanitize_text_field( $card_info['cc_expire_year'] ), |
422
|
|
|
'cardCode' => sanitize_text_field( $card_info['cc_cvv2'] ), |
423
|
|
|
); |
424
|
|
|
|
425
|
|
|
return $card_details; |
426
|
|
|
} |
427
|
|
|
|
428
|
|
|
function wpinv_authorizenet_subscription_record_signup( $subscription, $invoice ) { |
429
|
|
|
$parent_invoice_id = absint( $invoice->ID ); |
430
|
|
|
|
431
|
|
|
if( empty( $parent_invoice_id ) ) { |
432
|
|
|
return; |
433
|
|
|
} |
434
|
|
|
|
435
|
|
|
$invoice = wpinv_get_invoice( $parent_invoice_id ); |
436
|
|
|
if ( empty( $invoice ) ) { |
437
|
|
|
return; |
438
|
|
|
} |
439
|
|
|
|
440
|
|
|
$subscriptionId = (array)$subscription->subscriptionId; |
441
|
|
|
$subscription_id = !empty( $subscriptionId[0] ) ? $subscriptionId[0] : $parent_invoice_id; |
442
|
|
|
|
443
|
|
|
$subscription = wpinv_get_authorizenet_subscription( $subscription, $parent_invoice_id ); |
444
|
|
|
|
445
|
|
|
if ( false === $subscription ) { |
446
|
|
|
return; |
447
|
|
|
} |
448
|
|
|
|
449
|
|
|
// Set payment to complete |
450
|
|
|
wpinv_update_payment_status( $subscription->parent_payment_id, 'publish' ); |
451
|
|
|
sleep(1); |
452
|
|
|
wpinv_insert_payment_note( $parent_invoice_id, sprintf( __( 'Authorize.Net Subscription ID: %s', 'invoicing' ) , $subscription_id ), '', '', true ); |
|
|
|
|
453
|
|
|
update_post_meta($parent_invoice_id,'_wpinv_subscr_profile_id', $subscription_id); |
454
|
|
|
|
455
|
|
|
$status = 'trialling' == $subscription->status ? 'trialling' : 'active'; |
456
|
|
|
$diff_days = absint( ( ( strtotime( $subscription->expiration ) - strtotime( $subscription->created ) ) / DAY_IN_SECONDS ) ); |
457
|
|
|
$created = date_i18n( 'Y-m-d H:i:s' ); |
458
|
|
|
$expiration = date_i18n( 'Y-m-d 23:59:59', ( strtotime( $created ) + ( $diff_days * DAY_IN_SECONDS ) ) ); |
459
|
|
|
|
460
|
|
|
// Retrieve pending subscription from database and update it's status to active and set proper profile ID |
461
|
|
|
$subscription->update( array( 'profile_id' => $subscription_id, 'status' => $status, 'created' => $created, 'expiration' => $expiration ) ); |
462
|
|
|
} |
463
|
|
|
|
464
|
|
|
function wpinv_authorizenet_validate_checkout( $valid_data, $post ) { |
|
|
|
|
465
|
|
|
if ( !empty( $post['wpi-gateway'] ) && $post['wpi-gateway'] == 'authorizenet' ) { |
466
|
|
|
$error = false; |
467
|
|
|
|
468
|
|
|
if ( empty( $post['authorizenet']['cc_owner'] ) ) { |
469
|
|
|
$error = true; |
470
|
|
|
wpinv_set_error( 'empty_card_name', __( 'You must enter the name on your card!', 'invoicing')); |
471
|
|
|
} |
472
|
|
|
if ( empty( $post['authorizenet']['cc_number'] ) ) { |
473
|
|
|
$error = true; |
474
|
|
|
wpinv_set_error( 'empty_card', __( 'You must enter a card number!', 'invoicing')); |
475
|
|
|
} |
476
|
|
|
if ( empty( $post['authorizenet']['cc_expire_month'] ) ) { |
477
|
|
|
$error = true; |
478
|
|
|
wpinv_set_error( 'empty_month', __( 'You must enter an card expiration month!', 'invoicing')); |
479
|
|
|
} |
480
|
|
|
if ( empty( $post['authorizenet']['cc_expire_year'] ) ) { |
481
|
|
|
$error = true; |
482
|
|
|
wpinv_set_error( 'empty_year', __( 'You must enter an card expiration year!', 'invoicing')); |
483
|
|
|
} |
484
|
|
|
if ( empty( $post['authorizenet']['cc_cvv2'] ) ) { |
485
|
|
|
$error = true; |
486
|
|
|
wpinv_set_error( 'empty_cvv2', __( 'You must enter a valid CVV2!', 'invoicing' ) ); |
487
|
|
|
} |
488
|
|
|
|
489
|
|
|
if ( $error ) { |
490
|
|
|
return; |
491
|
|
|
} |
492
|
|
|
|
493
|
|
|
$invoice = wpinv_get_invoice_cart(); |
494
|
|
|
|
495
|
|
|
if ( !empty( $invoice ) && $subscription_item = $invoice->get_recurring( true ) ) { |
496
|
|
|
$subscription_item = $invoice->get_recurring( true ); |
497
|
|
|
|
498
|
|
|
$interval = $subscription_item->get_recurring_interval(); |
499
|
|
|
$period = $subscription_item->get_recurring_period(); |
500
|
|
|
|
501
|
|
|
if ( $period == 'D' && ( $interval < 7 || $interval > 365 ) ) { |
502
|
|
|
wpinv_set_error( 'authorizenet_subscription_error', __( 'Interval Length must be a value from 7 through 365 for day based subscriptions.', 'invoicing' ) ); |
503
|
|
|
} |
504
|
|
|
} |
505
|
|
|
} |
506
|
|
|
} |
507
|
|
|
add_action( 'wpinv_checkout_error_checks', 'wpinv_authorizenet_validate_checkout', 11, 2 ); |
508
|
|
|
|
509
|
|
|
function wpinv_authorizenet_get_time_period( $subscription_interval, $subscription_period ) { |
510
|
|
|
$subscription_interval = absint( $subscription_interval ); |
511
|
|
|
|
512
|
|
|
switch( $subscription_period ) { |
513
|
|
|
case 'W': |
514
|
|
|
case 'week': |
515
|
|
|
case 'weeks': |
516
|
|
|
$interval = $subscription_interval * 7; |
517
|
|
|
$period = 'days'; |
518
|
|
|
break; |
519
|
|
|
case 'M': |
520
|
|
|
case 'month': |
521
|
|
|
case 'months': |
522
|
|
|
if ( $subscription_interval > 12 ) { |
523
|
|
|
$subscription_interval = 12; |
524
|
|
|
} |
525
|
|
|
|
526
|
|
|
$interval = $subscription_interval; |
527
|
|
|
$period = 'months'; |
528
|
|
|
|
529
|
|
|
if ( !( $subscription_interval === 1 || $subscription_interval === 2 || $subscription_interval === 3 || $subscription_interval === 6 || $subscription_interval === 12 ) ) { |
530
|
|
|
$interval = $subscription_interval * 30; |
531
|
|
|
$period = 'days'; |
532
|
|
|
} |
533
|
|
|
break; |
534
|
|
|
case 'Y': |
535
|
|
|
case 'year': |
536
|
|
|
case 'years': |
537
|
|
|
$interval = 12; |
538
|
|
|
$period = 'months'; |
539
|
|
|
break; |
540
|
|
|
default : |
541
|
|
|
$interval = $subscription_interval; |
542
|
|
|
$period = 'days'; |
543
|
|
|
break; |
544
|
|
|
} |
545
|
|
|
|
546
|
|
|
return compact( 'interval', 'period' ); |
547
|
|
|
} |
548
|
|
|
|
549
|
|
|
function wpinv_authorizenet_process_ipn() { |
550
|
|
|
if ( !( !empty( $_REQUEST['wpi-gateway'] ) && $_REQUEST['wpi-gateway'] == 'authorizenet' ) ) { |
551
|
|
|
return; |
552
|
|
|
} |
553
|
|
|
|
554
|
|
|
$subscription_id = !empty( $_POST['x_subscription_id'] ) ? intval( $_POST['x_subscription_id'] ) : false; |
555
|
|
|
|
556
|
|
|
if ( $subscription_id ) { |
|
|
|
|
557
|
|
|
$response_code = intval( $_POST['x_response_code'] ); |
558
|
|
|
$reason_code = intval( $_POST['x_response_reason_code'] ); |
559
|
|
|
|
560
|
|
|
$subscription = new WPInv_Subscription( $subscription_id, true ); |
561
|
|
|
|
562
|
|
|
if ( !$subscription->id ) { |
563
|
|
|
return; |
564
|
|
|
} |
565
|
|
|
|
566
|
|
|
if ( 1 == $response_code ) { |
567
|
|
|
// Approved |
568
|
|
|
$transaction_id = sanitize_text_field( $_POST['x_trans_id'] ); |
569
|
|
|
$renewal_amount = sanitize_text_field( $_POST['x_amount'] ); |
570
|
|
|
|
571
|
|
|
$args = array( |
572
|
|
|
'amount' => $renewal_amount, |
573
|
|
|
'transaction_id' => $transaction_id, |
574
|
|
|
'gateway' => 'authorizenet' |
575
|
|
|
); |
576
|
|
|
|
577
|
|
|
$subscription->add_payment( $args ); |
578
|
|
|
$subscription->renew(); |
579
|
|
|
|
580
|
|
|
do_action( 'wpinv_recurring_authorizenet_silent_post_payment', $subscription ); |
581
|
|
|
do_action( 'wpinv_authorizenet_renewal_payment', $subscription ); |
582
|
|
|
} else if ( 2 == $response_code ) { |
583
|
|
|
// Declined |
584
|
|
|
$subscription->failing(); |
585
|
|
|
do_action( 'wpinv_authorizenet_renewal_payment_failed', $subscription ); |
586
|
|
|
do_action( 'wpinv_authorizenet_renewal_error', $subscription ); |
587
|
|
|
} else if ( 3 == $response_code || 8 == $reason_code ) { |
588
|
|
|
// An expired card |
589
|
|
|
$subscription->failing(); |
590
|
|
|
do_action( 'wpinv_authorizenet_renewal_payment_failed', $subscription ); |
591
|
|
|
do_action( 'wpinv_authorizenet_renewal_error', $subscription ); |
592
|
|
|
} else { |
593
|
|
|
// Other Error |
594
|
|
|
do_action( 'wpinv_authorizenet_renewal_payment_error', $subscription ); |
595
|
|
|
} |
596
|
|
|
|
597
|
|
|
exit; |
598
|
|
|
} |
599
|
|
|
} |
600
|
|
|
add_action( 'wpinv_verify_authorizenet_ipn', 'wpinv_authorizenet_process_ipn' ); |
601
|
|
|
|
602
|
|
|
/** |
603
|
|
|
* Retrieve the subscription |
604
|
|
|
*/ |
605
|
|
|
function wpinv_get_authorizenet_subscription( $subscription_data = array(), $invoice_id ) { |
606
|
|
|
$parent_invoice_id = absint( $invoice_id ); |
607
|
|
|
|
608
|
|
|
if ( empty( $subscription_data ) ) { |
609
|
|
|
return false; |
610
|
|
|
} |
611
|
|
|
|
612
|
|
|
if ( empty( $parent_invoice_id ) ) { |
613
|
|
|
return false; |
614
|
|
|
} |
615
|
|
|
|
616
|
|
|
$invoice = wpinv_get_invoice( $parent_invoice_id ); |
617
|
|
|
if ( empty( $invoice ) ) { |
618
|
|
|
return false; |
619
|
|
|
} |
620
|
|
|
|
621
|
|
|
$subscriptionId = (array)$subscription_data->subscriptionId; |
622
|
|
|
$subscription_id = !empty( $subscriptionId[0] ) ? $subscriptionId[0] : $parent_invoice_id; |
623
|
|
|
|
624
|
|
|
$subscription = new WPInv_Subscription( $subscription_id, true ); |
625
|
|
|
|
626
|
|
|
if ( ! $subscription || $subscription->id < 1 ) { |
627
|
|
|
$subs_db = new WPInv_Subscriptions_DB; |
628
|
|
|
$subs = $subs_db->get_subscriptions( array( 'parent_payment_id' => $parent_invoice_id, 'number' => 1 ) ); |
629
|
|
|
$subscription = reset( $subs ); |
630
|
|
|
|
631
|
|
|
if ( $subscription && $subscription->id > 0 ) { |
632
|
|
|
// Update the profile ID so it is set for future renewals |
633
|
|
|
$subscription->update( array( 'profile_id' => sanitize_text_field( $subscription_id ) ) ); |
634
|
|
|
} else { |
635
|
|
|
// No subscription found with a matching payment ID, bail |
636
|
|
|
return false; |
637
|
|
|
} |
638
|
|
|
} |
639
|
|
|
|
640
|
|
|
return $subscription; |
641
|
|
|
} |
642
|
|
|
|
643
|
|
|
function wpinv_is_authorizenet_valid_for_use() { |
644
|
|
|
return in_array( wpinv_get_currency(), apply_filters( 'wpinv_authorizenet_supported_currencies', array( 'AUD', 'CAD', 'CHF', 'DKK', 'EUR', 'GBP', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'USD', 'ZAR' ) ) ); |
645
|
|
|
} |
646
|
|
|
function wpinv_check_authorizenet_currency_support( $gateway_list ) { |
647
|
|
|
if ( isset( $gateway_list['authorizenet'] ) && ! wpinv_is_authorizenet_valid_for_use() ) { |
648
|
|
|
unset( $gateway_list['authorizenet'] ); |
649
|
|
|
} |
650
|
|
|
return $gateway_list; |
651
|
|
|
} |
652
|
|
|
add_filter( 'wpinv_enabled_payment_gateways', 'wpinv_check_authorizenet_currency_support', 10, 1 ); |
653
|
|
|
|
654
|
|
View Code Duplication |
function wpinv_authorizenet_link_transaction_id( $transaction_id, $invoice_id, $invoice ) { |
|
|
|
|
655
|
|
|
if ( $transaction_id == $invoice_id ) { |
656
|
|
|
$link = $transaction_id; |
657
|
|
|
} else { |
658
|
|
|
if ( ! empty( $invoice ) && ! empty( $invoice->mode ) ) { |
659
|
|
|
$mode = $invoice->mode; |
660
|
|
|
} else { |
661
|
|
|
$mode = wpinv_is_test_mode( 'authorizenet' ) ? 'test' : 'live'; |
662
|
|
|
} |
663
|
|
|
|
664
|
|
|
$url = $mode == 'test' ? 'https://sandbox.authorize.net/' : 'https://authorize.net/'; |
665
|
|
|
$url .= 'ui/themes/sandbox/Transaction/TransactionReceipt.aspx?transid=' . $transaction_id; |
666
|
|
|
|
667
|
|
|
$link = '<a href="' . esc_url( $url ) . '" target="_blank">' . $transaction_id . '</a>'; |
668
|
|
|
} |
669
|
|
|
|
670
|
|
|
return apply_filters( 'wpinv_authorizenet_link_payment_details_transaction_id', $link, $transaction_id, $invoice ); |
671
|
|
|
} |
672
|
|
|
add_filter( 'wpinv_payment_details_transaction_id-authorizenet', 'wpinv_authorizenet_link_transaction_id', 10, 3 ); |
673
|
|
|
|
674
|
|
View Code Duplication |
function wpinv_authorizenet_transaction_id_link( $transaction_id, $subscription ) { |
|
|
|
|
675
|
|
|
if ( ! empty( $transaction_id ) && ! empty( $subscription ) && ( $invoice_id = $subscription->get_original_payment_id() ) ) { |
676
|
|
|
$invoice = wpinv_get_invoice( $invoice_id ); |
677
|
|
|
|
678
|
|
|
if ( ! empty( $invoice ) ) { |
679
|
|
|
return wpinv_authorizenet_link_transaction_id( $transaction_id, $invoice_id, $invoice ); |
680
|
|
|
} |
681
|
|
|
} |
682
|
|
|
|
683
|
|
|
return $transaction_id; |
684
|
|
|
} |
685
|
|
|
add_filter( 'wpinv_subscription_transaction_link_authorizenet', 'wpinv_authorizenet_transaction_id_link', 10, 2 ); |
686
|
|
|
|
687
|
|
View Code Duplication |
function wpinv_authorizenet_profile_id_link( $profile_id, $subscription ) { |
|
|
|
|
688
|
|
|
$link = $profile_id; |
689
|
|
|
|
690
|
|
|
if ( ! empty( $profile_id ) && ! empty( $subscription ) && ( $invoice_id = $subscription->get_original_payment_id() ) ) { |
691
|
|
|
$invoice = wpinv_get_invoice( $invoice_id ); |
692
|
|
|
|
693
|
|
|
if ( ! empty( $invoice ) && ! empty( $invoice->mode ) ) { |
694
|
|
|
$mode = $invoice->mode; |
695
|
|
|
} else { |
696
|
|
|
$mode = wpinv_is_test_mode( 'authorizenet' ) ? 'test' : 'live'; |
697
|
|
|
} |
698
|
|
|
|
699
|
|
|
$url = $mode == 'test' ? 'https://sandbox.authorize.net/' : 'https://authorize.net/'; |
700
|
|
|
$url .= 'ui/themes/sandbox/ARB/SubscriptionDetail.aspx?SubscrID=' . $profile_id; |
701
|
|
|
|
702
|
|
|
$link = '<a href="' . esc_url( $url ) . '" target="_blank">' . $profile_id . '</a>'; |
703
|
|
|
} |
704
|
|
|
|
705
|
|
|
return apply_filters( 'wpinv_authorizenet_profile_id_link', $link, $profile_id, $subscription ); |
706
|
|
|
} |
707
|
|
|
add_filter( 'wpinv_subscription_profile_link_authorizenet', 'wpinv_authorizenet_profile_id_link', 10, 2 ); |
Since your code implements the magic setter
_set
, this function will be called for any write access on an undefined variable. You can add the@property
annotation to your class or interface to document the existence of this variable.Since the property has write access only, you can use the @property-write annotation instead.
Of course, you may also just have mistyped another name, in which case you should fix the error.
See also the PhpDoc documentation for @property.