8 use Business::CreditCard qw(generate_last_digit);
10 if ( stat('/usr/local/etc/freeside/cardfortresstest.txt') ) {
13 plan skip_all => 'CardFortress test encryption key is not installed.';
16 ### can only run on test database (company name "Freeside Test")
17 ### will run upgrade, which uses lots of prints & warns beyond regular test output
19 my $fs = FS::Test->new( user => 'admin' );
20 my $conf = FS::Conf->new;
24 like( $conf->config('company_name'), qr/^Freeside Test/, 'using test database' ) or BAIL_OUT('');
26 # test db no longer contains cardtype overrides
31 $conf->set('business-onlinepayment' => $bopconf);
32 is( join("\n",$conf->config('business-onlinepayment')), $bopconf, "setting first default gateway" ) or BAIL_OUT('');
34 # generate a few void/refund records for upgrading
36 foreach my $cust_pay ( $fs->qsearch('cust_pay',{ payby => 'CARD' }) ) {
38 $err = $cust_pay->void('Testing');
39 $err = "Voiding: $err" if $err;
41 # from realtime_refund_bop, just the important bits
42 while ( $cust_pay->unapplied < $cust_pay->paid ) {
43 my @cust_bill_pay = $cust_pay->cust_bill_pay;
44 last unless @cust_bill_pay;
45 my $cust_bill_pay = pop @cust_bill_pay;
46 $err = $cust_bill_pay->delete;
47 $err = "Refund unapply: $err" if $err;
51 my $cust_refund = new FS::cust_refund ( {
52 'custnum' => $cust_pay->cust_main->custnum,
53 'paynum' => $cust_pay->paynum,
54 'source_paynum' => $cust_pay->paynum,
55 'refund' => $cust_pay->paid,
57 'payby' => $cust_pay->payby,
58 'payinfo' => $cust_pay->payinfo,
59 'reason' => 'Testing',
60 'gatewaynum' => $cust_pay->gatewaynum,
61 'processor' => $cust_pay->payment_gateway ? $cust_pay->payment_gateway->processor : '',
62 'auth' => $cust_pay->auth,
63 'order_number' => $cust_pay->order_number,
65 $err = $cust_refund->insert( reason_type => 'Refund' );
66 $err = "Refunding: $err" if $err;
70 last unless $counter > 0;
72 ok( !$err, "create some refunds and voids" ) or BAIL_OUT($err);
74 # also, just to test behavior in this case, create a record for an aborted
75 # verification payment. this will have no customer number.
77 my $pending_failed = FS::cust_pay_pending->new({
78 'custnum_pending' => 1,
80 '_date' => time - 86400,
83 'statustext' => 'Tokenization upgrade test',
85 $err = $pending_failed->insert;
86 ok( !$err, "create a failed payment attempt" ) or BAIL_OUT($err);
88 # find two stored credit cards.
89 my @cust = map { FS::cust_main->by_key($_) } (10, 12);
90 my @payby = map { ($_->cust_payby)[0] } @cust;
93 ok( $payby[0]->payby eq 'CARD' && !$payby[0]->tokenized,
94 "first customer has a non-tokenized card"
97 $err = $cust[0]->realtime_cust_payby(amount => '2.00');
98 ok( !$err, "create a payment through IPPay" )
100 $payment[0] = $fs->qsearchs('cust_pay', { custnum => $cust[0]->custnum,
102 or BAIL_OUT("can't find payment record");
104 $err = system('freeside-upgrade','admin');
105 ok( !$err, 'initial upgrade' ) or BAIL_OUT('Error string: '.$!);
107 # switch to CardFortress
120 /usr/local/etc/freeside/cardfortresstest.txt';
121 $conf->set('business-onlinepayment' => $bopconf);
122 is( join("\n",$conf->config('business-onlinepayment')), $bopconf, "setting tokenizable default gateway" ) or BAIL_OUT('');
124 # create a payment using a non-tokenized card. this should immediately
125 # trigger tokenization.
126 ok( $payby[1]->payby eq 'CARD' && ! $payby[1]->tokenized,
127 "second customer has a non-tokenized card"
130 $err = $cust[1]->realtime_cust_payby(amount => '3.00');
131 ok( !$err, "tokenize a card when it's first used for payment" )
133 $payment[1] = $fs->qsearchs('cust_pay', { custnum => $cust[1]->custnum,
135 or BAIL_OUT("can't find payment record");
136 ok( $payment[1]->tokenized, "payment is tokenized" );
137 $payby[1] = $payby[1]->replace_old;
138 ok( $payby[1]->tokenized, "card is now tokenized" );
140 # invoke the part of freeside-upgrade that tokenizes
141 FS::cust_main->queueable_upgrade();
142 #$err = system('freeside-upgrade','admin');
143 #ok( !$err, 'tokenizable upgrade' ) or BAIL_OUT('Error string: '.$!);
145 $payby[0] = $payby[0]->replace_old;
146 ok( $payby[0]->tokenized, "old card was tokenized during upgrade" );
147 $payment[0] = $payment[0]->replace_old;
148 ok( $payment[0]->tokenized, "old payment was tokenized during upgrade" );
149 ok( ($payment[0]->cust_pay_pending)[0]->tokenized, "old cust_pay_pending was tokenized during upgrade" );
151 $pending_failed = $pending_failed->replace_old;
152 ok( $pending_failed->tokenized, "cust_pay_pending with no customer was tokenized" );
154 # add a new payment card to one customer
155 $payby[2] = FS::cust_payby->new({
156 custnum => $cust[0]->custnum,
159 $err = $payby[2]->insert;
160 ok( !$err, "new card was saved" );
161 ok($payby[2]->tokenized, "new card is tokenized" );
164 my $payinfo = '4111' . join('', map { int(rand(10)) } 1 .. 11);
165 $payinfo .= generate_last_digit($payinfo);
166 my $paydate = DateTime->now
168 ->truncate(to => 'month')
170 return ( 'payby' => 'CARD',
171 'payinfo' => $payinfo,
172 'paydate' => $paydate,
173 'payname' => 'Tokenize Me',