store a truncated card number on credit card transactions
authorTony Cook <tony@develop-help.com>
Thu, 8 Dec 2011 03:50:02 +0000 (14:50 +1100)
committerTony Cook <tony@develop-help.com>
Thu, 8 Dec 2011 03:50:02 +0000 (14:50 +1100)
We no longer store the card number hash.

We again store the cardHolder, but the payment field name is now ccName.

Changes.txt [new file with mode: 0644]
MANIFEST
schema/bse.sql
site/cgi-bin/modules/BSE/Shop/Util.pm
site/cgi-bin/modules/BSE/TB/Order.pm
site/cgi-bin/modules/BSE/UI/Shop.pm
site/templates/admin/order_detail.tmpl
site/templates/checkoutpay_base.tmpl
site/util/mysql.str

diff --git a/Changes.txt b/Changes.txt
new file mode 100644 (file)
index 0000000..6e1c0b1
--- /dev/null
@@ -0,0 +1,17 @@
+BSE 0.20 (unreleased)
+========
+
+ - store a truncated card number for credit card payments (both online
+   and email).  Reinstate storage of the card holder name in ccName.
+   ccNumberHash is no longer populated.
+
+ - ifNeedDelivery (checkoutnew_base.tmpl) wasn't being reset on order
+   submission.
+
+Template updates:
+
+- checkoutpay_base.tmpl - the name of the cardHolder payment field is
+  now ccName.
+
+- admin/order_detail.tmpl - order ccPAN can be used to display the
+  truncated card number.
index caabab4..3f8ab37 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,4 +1,5 @@
 Artistic
+Changes.txt
 COPYING
 INSTALL.html
 INSTALL.pod
index 2532b5f..37c03bf 100644 (file)
@@ -339,6 +339,9 @@ create table orders (
 
   stage varchar(20) not null default '',
 
+  -- truncated credit card number
+  ccPAN varchar(4) not null default '',
+
   primary key (id),
   index order_cchash(ccNumberHash),
   index order_userId(userId, orderDate)
index b656f11..73dbcbe 100644 (file)
@@ -7,7 +7,7 @@ use vars qw(@ISA @EXPORT_OK);
                 payment_types order_item_opts
  PAYMENT_CC PAYMENT_CHEQUE PAYMENT_CALLME PAYMENT_MANUAL PAYMENT_PAYPAL/;
 
-our $VERSION = "1.005";
+our $VERSION = "1.006";
 
 our %EXPORT_TAGS =
   (
@@ -242,7 +242,6 @@ my %nostore =
   (
    cardNumber => 1,
    cardExpiry => 1,
-   cardHolder => 1,
   );
 
 sub load_order_fields {
@@ -254,7 +253,7 @@ sub load_order_fields {
   my $cust_class = custom_class($cfg);
 
   my @required = $cust_class->required_fields($q, $session->{custom});
-  push(@required, qw(cardHolder cardExpiry)) if $wantcard;
+  push(@required, qw(ccName cardExpiry)) if $wantcard;
   for my $field (@required) {
     defined($q->param($field)) && length($q->param($field))
       or do { $$error = "Field $field is required"; return 0 };
@@ -449,7 +448,7 @@ sub payment_types {
       id => PAYMENT_CC, 
       name => 'CC', 
       desc => 'Credit Card',
-      require => [ qw/cardNumber cardExpiry cardHolder/ ],
+      require => [ qw/cardNumber cardExpiry ccName/ ],
      },
      {
       id => PAYMENT_CHEQUE, 
index 51c6706..4ad931c 100644 (file)
@@ -6,7 +6,7 @@ use vars qw/@ISA/;
 @ISA = qw/Squirrel::Row/;
 use Carp 'confess';
 
-our $VERSION = "1.012";
+our $VERSION = "1.013";
 
 sub columns {
   return qw/id
@@ -28,7 +28,7 @@ sub columns {
            ccStatus2 ccTranId complete delivOrganization billOrganization
            delivStreet2 billStreet2 purchase_order shipping_method
            shipping_name shipping_trace
-          paypal_token paypal_tran_id freight_tracking stage/;
+          paypal_token paypal_tran_id freight_tracking stage ccPAN/;
 }
 
 sub table {
@@ -95,6 +95,7 @@ sub defaults {
      paypal_tran_id => "",
      freight_tracking => "",
      stage => "incomplete",
+     ccPAN => "",
     );
 }
 
@@ -298,7 +299,7 @@ sub valid_payment_fields {
       description => "Credit Card Expiry Date",
       rules => 'creditcardexpirysingle',
      },
-     cardHolder => { description => "Credit Card Holder" },
+     ccName => { description => "Credit Card Holder" },
      ccType => { description => "Credit Card Type" },
      cardVerify => 
      { 
@@ -650,4 +651,14 @@ sub new_stage {
   }
 }
 
+sub set_ccPANTruncate {
+  my ($self, $pan) = @_;
+
+  if (length $pan > 4) {
+    $pan = substr($pan, -4);
+  }
+
+  $self->set_ccPAN($pan);
+}
+
 1;
index 323def2..774ad0a 100644 (file)
@@ -17,7 +17,7 @@ use BSE::Shipping;
 use BSE::Countries qw(bse_country_code);
 use BSE::Util::Secure qw(make_secret);
 
-our $VERSION = "1.023";
+our $VERSION = "1.024";
 
 use constant MSG_SHOP_CART_FULL => 'Your shopping cart is full, please remove an item and try adding an item again';
 
@@ -867,7 +867,7 @@ my %nostore =
    cardExpiry => 1,
    delivery_in => 1,
    cardVerify => 1,
-   cardHolder => 1,
+   ccName => 1,
   );
 
 my %bill_ccmap =
@@ -1086,7 +1086,7 @@ sub req_payment {
   if ($paymentType == PAYMENT_CC) {
     my $ccNumber = $cgi->param('cardNumber');
     my $ccExpiry = $cgi->param('cardExpiry');
-    my $ccName   = $cgi->param('cardHolder');
+    my $ccName   = $cgi->param('ccName');
     
     if ($ccprocessor) {
       my $cc_class = credit_card_class($cfg);
@@ -1138,14 +1138,16 @@ sub req_payment {
       $order->{ccStatus2}          = 0;
       $order->{ccStatusText}  = '';
       $order->{ccTranId}           = $result->{transactionid};
+      $order->set_ccPANTruncate($ccNumber);
       defined $order->{ccTranId} or $order->{ccTranId} = '';
       $order->{paidFor}            = 1;
     }
     else {
       $ccNumber =~ tr/0-9//cd;
-      $order->{ccNumberHash} = md5_hex($ccNumber);
       $order->{ccExpiryHash} = md5_hex($ccExpiry);
+      $order->set_ccPANTruncate($ccNumber);
     }
+    $order->set_ccName($ccName);
   }
   elsif ($paymentType == PAYMENT_PAYPAL) {
     require BSE::PayPal;
@@ -1190,7 +1192,7 @@ sub _finish_order {
   $self->_send_order($req, $order);
 
   # empty the cart ready for the next order
-  delete @{$req->session}{qw/order_info order_info_confirmed cart order_work/};
+  delete @{$req->session}{qw/order_info order_info_confirmed order_need_delivery cart order_work/};
 }
 
 sub req_orderdone {
index 64ba314..878fb80 100644 (file)
@@ -172,6 +172,12 @@ Shipping via <:order shipping_method:>
 <:ifOrder ccTranId:>
 <tr><th>Transaction Id:</th><td><:order ccTranId:></td></tr>
 <:or:><:eif:>
+<:ifOrder ccName:>
+<tr><th>Card Holder:</th><td><:order ccName:></td>
+<:or:><:eif:>
+<:ifOrder ccPAN:>
+<tr><th>Card Number (partial):</th><td>...<:order ccPAN:></td>
+<:or:><:eif:>
 </table>
 <:or Order:>
 <p>This transaction <b>FAILED</b>.</p>
@@ -184,6 +190,16 @@ Shipping via <:order shipping_method:>
 </table>
 <:eif Order:>
 <:case Eq [order paymentType] "0":><p>Payment made by credit card.  Credit card details can be found in the encrypted email you received when the customer made the order.</p>
+<:if Or [order ccPAN] [order ccName]:>
+<table>
+<:ifOrder ccName:>
+<tr><th>Card Holder</th><td><:order ccName:></td>
+<:or:><:eif:>
+<:ifOrder ccPAN:>
+<tr><th>Card Number (partial)</th><td>...<:order ccPAN:></td>
+<:or:><:eif:>
+</table>
+<:or Or:><:eif Or:>
 <:case Eq [order paymentType] "1":><p>Payment will be made by cheque.</p>
 <:case Eq [order paymentType] "2":><p>Contact the customer to arrange for payment.</p>
 <:case Eq [order paymentType] "3":><p>Paid manually (staff marked this order paid) - you can <a href="<:adminurl shopadmin a_order_unpaid 1 id [order id]:>">unmark it</a></p>
index c540513..7305309 100644 (file)
       <td> <font face="Verdana, Arial, Helvetica, sans-serif" size="2"> Name on 
         Card: </font></td>
       <td> <font face="Verdana, Arial, Helvetica, sans-serif" size="2"> 
-        <input type="Text" name="cardHolder" size=30 value="<:old cardHolder:>"><:error_img cardHolder:>
+        <input type="Text" name="ccName" size=30 value="<:old ccName:>"><:error_img ccName:>
         (As per card) *</font></td>
     </tr>
     <tr> 
index 9e88ddd..6217a74 100644 (file)
@@ -566,6 +566,7 @@ Column paypal_token;varchar(255);YES;NULL;
 Column paypal_tran_id;varchar(255);YES;NULL;
 Column freight_tracking;varchar(255);NO;;
 Column stage;varchar(20);NO;;
+Column ccPAN;varchar(4);NO;;
 Index PRIMARY;1;[id]
 Index order_cchash;0;[ccNumberHash]
 Index order_userId;0;[userId;orderDate]