updated the avs error message for the shop
[commerce_payment_tc.git] / commerce_payment_tc.module
1 <?php
2
3 /*
4
5 Copyright (C) 2016-2019  Ruben Rodriguez <ruben@fsf.org>
6 Copyright (C) 2016-2019  Free Software Foundation
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
21
22 */
23
24
25 /**
26  * @file
27  * Provides an tc payment method for Drupal Commerce for testing and
28  *   development.
29  */
30
31 /**
32  * Implements hook_commerce_payment_method_info().
33  */
34 function commerce_payment_tc_commerce_payment_method_info() {
35   $payment_methods = array();
36
37   $payment_methods['commerce_payment_tc'] = array(
38     'title' => t('Pay with Credit Card'),
39     'description' => t('Trustcommerce credit card payment.'),
40     'active' => TRUE,
41     'offsite' => FALSE,
42   );
43
44   return $payment_methods;
45 }
46
47 /**
48  * Payment method callback: submit form.
49  */
50 function commerce_payment_tc_submit_form($payment_method, $pane_values, $checkout_pane, $order) {
51   module_load_include('inc', 'commerce_payment', 'includes/commerce_payment.credit_card');
52
53   // Default to a known test credit card number. For valid numbers of other card
54   // types see: http://www.rimmkaufman.com/blog/credit-card-test-numbers/09112007/
55   //return commerce_payment_credit_card_form( array('number' => '', 'code' => '','owner' => ''));
56   return commerce_payment_credit_card_form( array('number' => '', 'code' => ''));
57 }
58
59 /**
60  * Payment method callback: submit form validation.
61  */
62 function commerce_payment_tc_submit_form_validate($payment_method, $pane_form, $pane_values, $order, $form_parents = array()) {
63   // Validate the credit card fields.
64   module_load_include('inc', 'commerce_payment', 'includes/commerce_payment.credit_card');
65
66   $settings = array(
67     'form_parents' => array_merge($form_parents, array('credit_card')),
68   );
69
70   // Allow empty cvv field
71   if (empty($pane_values['credit_card']['code']))
72   {
73     unset($pane_values['credit_card']['code']);
74   }
75
76   // Even though a form error triggered by the validate handler would be enough
77   // to stop the submission of the form, it's not enough to stop it from a
78   // Commerce standpoint because of the combined validation / submission going
79   // on per-pane in the checkout form. Thus even with a call to form_set_error()
80   // this validate handler must still return FALSE.
81   if (!commerce_payment_credit_card_validate($pane_values['credit_card'], $settings)) {
82     return FALSE;
83   }
84 }
85
86 /**
87  * Payment method callback: submit form submission.
88  */
89 function commerce_payment_tc_submit_form_submit($payment_method, $pane_form, $pane_values, $order, $charge) {
90
91   $tc = array();
92
93   // NOTE: you need to store the user and password for your TrustCommerce account as Drupal variables
94   // drush variable-set tcuser foo
95   // drush variable-set tcpassword bar
96   $tc['custid']   = variable_get('tcuser');
97   $tc['password'] = variable_get('tcpassword');
98   $tc['checkcvv'] = 'y';// credit verification value
99   $tc['avs']      = 'y'; // address verification service
100   $tc['demo']     = "n"; // ensure that it is in demo mode by default
101   $tc['ticket']   = 'fsfshop-'.$order->order_id; // information transferred to bank;
102
103   $order_wrapper = entity_metadata_wrapper('commerce_order', $order->order_id);
104   $billing_address = $order_wrapper->commerce_customer_billing->commerce_customer_address->value();
105   $tc['name']     = $billing_address['name_line'];
106   $tc['address1'] = $billing_address['thoroughfare'];
107   #$tc['address2'] = $billing_address['premise'];
108   $tc['city']     = $billing_address['locality'];
109   $tc['state']    = $billing_address['administrative_area'];
110   $tc['zip']      = $billing_address['postal_code'];
111   $tc['country']  = $billing_address['country'];
112   #$tc['email']    = $order->mail;
113
114   $tc['cc']   =  $pane_values['credit_card']['number'];
115   $tc['exp']  =  $pane_values['credit_card']['exp_month'] . substr($pane_values['credit_card']['exp_year'],2);
116   $tc['cvv']  =  $pane_values['credit_card']['code'];
117   #$tc['ip']   =  $order->hostname;
118   $tc['media']= 'cc';
119
120   $tc['action']   = 'sale';
121   $tc['amount']   = $charge['amount'];
122
123   $response = _trustcommerce_tclink($tc);
124
125   // Anonymize credit card info for logs
126   $tctmp= $tc;
127   $tctmp['cc'] = "****";
128   $tctmp['exp'] = "****";
129   $tctmp['cvv'] = "****";
130   $tctmp['password'] = "****";
131
132   if ( array_key_exists('declinetype', $response)){
133     $error=sprintf("TrustCommerce: IP=%s ORDER=%s NAME=%s MAIL=%s AMOUNT=%s STATUS=%s AVS=%s TRANSACTION_ID=%s DECLINETYPE=%s",
134         $order->hostname, $order->order_number, $tctmp['name'], $order->mail, $charge['amount'], $response['status'], $response['avs'], $response['transid'], $response['declinetype'] );
135   }
136   else{
137     $error=sprintf("TrustCommerce: ORDER=%s IP=%s NAME=%s MAIL=%s AMOUNT=%s STATUS=%s AVS=%s TRANSACTION_ID=%s",
138          $order->hostname, $order->order_number, $tctmp['name'], $order->mail, $charge['amount'], $response['status'], $response['avs'], $response['transid'] );
139   }
140   error_log($error,0);
141
142   // Just as an example, we might store information in the order object from the
143   // payment parameters, though we would never save a full credit card number,
144   // even in examples!
145   $number = $pane_values['credit_card']['number'];
146   $pane_values['credit_card']['number'] = 0; //substr($number, 0, 4) . str_repeat('-', strlen($number) - 8) . substr($number, -4);
147
148   $order->data['commerce_payment_tc'] = $pane_values;
149   // Every attempted transaction should result in a new transaction entity being
150   // created for the order to log either the success or the failure.
151   commerce_payment_tc_transaction($payment_method, $order, $charge, $response);
152 }
153
154 /**
155  * Creates an tc payment transaction for the specified charge amount.
156  *
157  * @param $payment_method
158  *   The payment method instance object used to charge this payment.
159  * @param $order
160  *   The order object the payment applies to.
161  * @param $charge
162  *   An array indicating the amount and currency code to charge.
163  */
164 function commerce_payment_tc_transaction($payment_method, $order, $charge, $response) {
165   $card_details = $order->data['commerce_payment_tc']['credit_card'];
166
167   $txid=$response['transid'];
168   $status=$response['status'];
169
170   $transaction = commerce_payment_transaction_new('commerce_payment_tc', $order->order_id);
171   $transaction->remote_id = $txid;
172   $transaction->instance_id = $payment_method['instance_id'];
173   $transaction->amount = $charge['amount'];
174   $transaction->currency_code = $charge['currency_code'];
175   $transaction->status = $status;
176   //$transaction->message = 'Number: @number<br/>Expiration: @month/@year';
177   $transaction->message = print_r($response, true);
178   $transaction->message_variables = array(
179     '@number' => $card_details['number'],
180     '@month' => $card_details['exp_month'],
181     '@year' => $card_details['exp_year'],
182   );
183
184   if ($status == 'approved'){
185     $transaction->status = COMMERCE_PAYMENT_STATUS_SUCCESS;
186     drupal_set_message(t('Order approved'), 'status');
187     commerce_payment_transaction_save($transaction);
188   }
189   else {
190     $transaction->status = COMMERCE_PAYMENT_STATUS_FAILURE;
191     commerce_payment_transaction_save($transaction);
192     //https://vault.trustcommerce.com/downloads/TCDevGuide.html#Decline%20Type|outline
193     if ($response['declinetype']=='avs') drupal_set_message(t('The credit card charge failed, please verify that the "Full name" and other fields of your "Billing Address" match the info set at your bank for that credit card'), 'error');
194     elseif ($response['declinetype']=='decline') drupal_set_message(t('The credit card was declined, please contact your bank.'), 'error');
195     elseif ($response['declinetype']=='cvv') drupal_set_message(t('Your transaction was declined. Please check the correctness of your credit card information, including CC number, expiration date and CVV code.'), 'error');
196     elseif ($response['declinetype']=='call') drupal_set_message(t('The credit card must be authorized manually over the phone, please contact your bank.'), 'error');
197     elseif ($response['declinetype']=='expiredcard ') drupal_set_message(t('The credit card is expired.'), 'error');
198     elseif ($response['declinetype']=='carderror') drupal_set_message(t('Card number is invalid, which could be a typo, or sometimes a card reported stolen, please contact your bank.'), 'error');
199     elseif ($response['declinetype']=='fraud') drupal_set_message(t('The credit card fraud score is too high, please contact your bank.'), 'error');
200     elseif ($response['declinetype']=='blacklist') drupal_set_message(t('The credit card is blacklisted, please contact your bank.'), 'error');
201     elseif ($response['declinetype']=='velocity') drupal_set_message(t('The credit card was used too recently, please try again later.'), 'error');
202     elseif ($response['declinetype']=='dailylimit') drupal_set_message(t('The credit card has reached its daily limit, please contact your bank.'), 'error');
203     elseif ($response['declinetype']=='weeklylimit') drupal_set_message(t('The credit card has reached its weekly limit, please contact your bank.'), 'error');
204     elseif ($response['declinetype']=='monthlylimit') drupal_set_message(t('The credit card has reached its monthly limit, please contact your bank.'), 'error');
205     else drupal_set_message(t('The payment failed, please contact with us at donate@fsf.org'), 'error');
206     drupal_goto(commerce_checkout_order_uri($order));
207     commerce_payment_redirect_pane_previous_page($order);
208   }
209   return $transaction;
210 }
211
212 function _trustcommerce_tclink($tc) {
213   // verify that the module is loaded
214   // You need to download this from TrustCommerce separately
215   if (!extension_loaded("tclink")) {
216     if (!dl("tclink.so")) {
217       drupal_set_message("tclink.so is not loaded- aborting");
218       exit(1);
219     }
220   }
221   $answer = tclink_send($tc); //send it to the payment gateway
222   return $answer;
223 }