UI spring cleaning: process card/chek payments
[freeside.git] / httemplate / misc / payment.cgi
1 <& /elements/header.html, mt("Process [_1] payment",$type{$payby})  &>
2 <& /elements/small_custview.html, $cust_main, '', '', popurl(2) . "view/cust_main.cgi" &>
3 <BR>
4
5 <FORM NAME="OneTrueForm" ACTION="process/payment.cgi" METHOD="POST" onSubmit="document.OneTrueForm.process.disabled=true">
6 <INPUT TYPE="hidden" NAME="custnum"   VALUE="<% $custnum %>">
7 <INPUT TYPE="hidden" NAME="payby"     VALUE="<% $payby %>">
8 <INPUT TYPE="hidden" NAME="payunique" VALUE="<% $payunique %>">
9 <INPUT TYPE="hidden" NAME="balance"   VALUE="<% $balance %>">
10
11 <& /elements/init_overlib.html &>
12
13 <TABLE class="fsinnerbox">
14
15   <& /elements/tr-amount_fee.html,
16        'amount'             => $amount,
17        'process-pkgpart'    => 
18           scalar($conf->config('manual_process-pkgpart', $cust_main->agentnum)),
19        'process-display'    => scalar($conf->config('manual_process-display')),
20        'process-skip_first' => $conf->exists('manual_process-skip_first'),
21        'num_payments'       => scalar($cust_main->cust_pay), 
22        'surcharge_percentage' =>
23          ( $payby eq 'CARD'
24              ? scalar($conf->config('credit-card-surcharge-percentage'))
25              : 0
26          ),
27   &>
28
29 % if ( $conf->exists('part_pkg-term_discounts') ) {
30     <& /elements/tr-select-discount_term.html,
31          'custnum'   => $custnum,
32          'amount_id' => 'amount',
33     &>
34 % }
35
36 % if ( $payby eq 'CARD' ) {
37 %
38 %   my( $payinfo, $paycvv, $month, $year ) = ( '', '', '', '' );
39 %   my $payname = $cust_main->first. ' '. $cust_main->getfield('last');
40 %   if ( $cust_main->payby =~ /^(CARD|DCRD)$/ ) {
41 %     $payinfo = $cust_main->paymask;
42 %     $paycvv = $cust_main->paycvv;
43 %     ( $month, $year ) = $cust_main->paydate_monthyear;
44 %     $payname = $cust_main->payname if $cust_main->payname;
45 %   }
46
47     <TR>
48       <TH ALIGN="right"><% mt('Card number') |h %></TH>
49       <TD COLSPAN=7>
50         <TABLE>
51           <TR>
52             <TD>
53               <INPUT TYPE="text" NAME="payinfo" SIZE=20 MAXLENGTH=19 VALUE="<%$payinfo%>"> </TD>
54             <TH><% mt('Exp.') |h %></TH>
55             <TD>
56               <SELECT NAME="month">
57 % for ( ( map "0$_", 1 .. 9 ), 10 .. 12 ) { 
58
59                   <OPTION<% $_ == $month ? ' SELECTED' : '' %>><% $_ %>
60 % } 
61
62               </SELECT>
63             </TD>
64             <TD> / </TD>
65             <TD>
66               <SELECT NAME="year">
67 % my @a = localtime; for ( $a[5]+1900 .. $a[5]+1915 ) { 
68
69                   <OPTION<% $_ == $year ? ' SELECTED' : '' %>><% $_ %>
70 % } 
71
72               </SELECT>
73             </TD>
74           </TR>
75         </TABLE>
76       </TD>
77     </TR>
78     <TR>
79       <TH ALIGN="right"><% mt('CVV2') |h %></TH>
80       <TD><INPUT TYPE="text" NAME="paycvv" VALUE="<% $paycvv %>" SIZE=4 MAXLENGTH=4>
81           (<A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('../docs/cvv2.html', 480, 352, 'cvv2_popup' ), CAPTION, 'CVV2 Help', STICKY, AUTOSTATUSCAP, CLOSECLICK, DRAGGABLE ); return false;"><% mt('help') |h %></A>)
82       </TD>
83     </TR>
84     <TR>
85       <TH ALIGN="right"><% mt('Exact name on card') |h %></TH>
86       <TD><INPUT TYPE="text" SIZE=32 MAXLENGTH=80 NAME="payname" VALUE="<%$payname%>"></TD>
87     </TR>
88
89     <& /elements/location.html,
90                   'object'         => $cust_main->bill_location,
91                   'no_asterisks'   => 1,
92                   'address1_label' => emt('Card billing address'),
93     &>
94
95 % } elsif ( $payby eq 'CHEK' ) {
96 %
97 %   my( $account, $aba, $branch, $payname, $ss, $paytype, $paystate,
98 %       $stateid, $stateid_state )
99 %     = ( '', '', '', '', '', '', '', '', '' );
100 %   if ( $cust_main->payby =~ /^(CHEK|DCHK)$/ ) {
101 %     $cust_main->paymask =~ /^([\dx]+)\@([\d\.x]*)$/i
102 %       or die "unparsable payinfo ". $cust_main->payinfo;
103 %     ($account, $aba) = ($1, $2);
104 %     ($branch,$aba) = split('\.',$aba)
105 %       if $conf->config('echeck-country') eq 'CA';
106 %     $payname = $cust_main->payname;
107 %     $ss = $cust_main->ss;
108 %     $paytype = $cust_main->getfield('paytype');
109 %     $paystate = $cust_main->getfield('paystate');
110 %     $stateid = $cust_main->getfield('stateid');
111 %     $stateid_state = $cust_main->getfield('stateid_state');
112 %   }
113 %
114 %  #false laziness w/{edit,view}/cust_main/billing.html
115 %  my $routing_label = $conf->config('echeck-country') eq 'US'
116 %                        ? 'ABA/Routing number'
117 %                        : 'Routing number';
118 %  my $routing_size      = $conf->config('echeck-country') eq 'CA' ? 4 : 10;
119 %  my $routing_maxlength = $conf->config('echeck-country') eq 'CA' ? 3 : 9;
120
121     <INPUT TYPE="hidden" NAME="month" VALUE="12">
122     <INPUT TYPE="hidden" NAME="year" VALUE="2037">
123     <TR>
124       <TD ALIGN="right"><% mt('Account number') |h %></TD>
125       <TD><INPUT TYPE="text" SIZE=10 NAME="payinfo1" VALUE="<%$account%>"></TD>
126       <TD ALIGN="right"><% mt('Type') |h %></TD>
127       <TD><SELECT NAME="paytype"><% join('', map { qq!<OPTION VALUE="$_" !.($paytype eq $_ ? 'SELECTED' : '').">$_</OPTION>" } FS::cust_payby->paytypes) %></SELECT></TD>
128     </TR>
129     <TR>
130       <TD ALIGN="right"><% mt($routing_label) |h %></TD>
131       <TD>
132         <INPUT TYPE="text" SIZE="<% $routing_size %>" MAXLENGTH="<% $routing_maxlength %>" NAME="payinfo2" VALUE="<%$aba%>">
133         (<A HREF="javascript:void(0);" onClick="overlib( OLiframeContent('../docs/ach.html', 380, 240, 'ach_popup' ), CAPTION, 'ACH Help', STICKY, AUTOSTATUSCAP, CLOSECLICK, DRAGGABLE ); return false;"><% mt('help') |h %></A>)
134       </TD>
135     </TR>
136 %   if ( $conf->config('echeck-country') eq 'CA' ) {
137       <TR>
138         <TD ALIGN="right"><% mt('Branch number') |h %></TD>
139         <TD>
140           <INPUT TYPE="text" NAME="payinfo3" VALUE="<%$branch%>" SIZE=6 MAXLENGTH=5>
141         </TD>
142       </TR>
143 %   }
144     <TR>
145       <TD ALIGN="right"><% mt('Bank name') |h %></TD>
146       <TD><INPUT TYPE="text" NAME="payname" VALUE="<%$payname%>"></TD>
147     </TR>
148
149 %   if ( $conf->exists('show_bankstate') ) {
150       <TR>
151         <TD ALIGN="right"><% mt('Bank state') |h %></TD>
152         <TD><& /elements/select-state.html,
153                          'disable_empty' => 0,
154                          'empty_label'   => emt('(choose)'),
155                          'state'         => $paystate,
156                          'country'       => $cust_main->country,
157                          'prefix'        => 'pay',
158             &>
159         </TD>
160       </TR>
161 %   } else {
162       <INPUT TYPE="hidden" NAME="paystate" VALUE="<% $paystate %>">
163 %   }
164
165 %   if ( $conf->exists('show_ss') ) {
166       <TR>
167         <TD ALIGN="right">
168           <% mt('Account holder') |h %><BR>
169           <% mt('Social security or tax ID #') |h %> 
170         </TD>
171         <TD><INPUT TYPE="text" NAME="ss" VALUE="<% $ss %>"></TD>
172       </TR>
173 %   } else {
174       <INPUT TYPE="hidden" NAME="ss" VALUE="<% $ss %>"></TD>
175 %   }
176
177 %   if ( $conf->exists('show_stateid') ) {
178       <TR>
179         <TD ALIGN="right">
180           <% mt('Account holder') |h %><BR>
181           <% mt("Driver's license or state ID #") |h %> 
182         </TD>
183         <TD><INPUT TYPE="text" NAME="stateid" VALUE="<% $stateid %>"></TD>
184         <TD ALIGN="right"><% mt('State') |h %></TD>
185         <TD><& /elements/select-state.html,
186                          'disable_empty' => 0,
187                          'empty_label'   => emt('(choose)'),
188                          'state'         => $stateid_state,
189                          'country'       => $cust_main->country,
190                          'prefix'        => 'stateid_',
191             &>
192         </TD>
193       </TR>
194 %   } else {
195       <INPUT TYPE="hidden" NAME="stateid" VALUE="<% $stateid %>">
196       <INPUT TYPE="hidden" NAME="stateid_state" VALUE="<% $stateid_state %>">
197 %   }
198
199 % } #end CARD/CHEK-specific section
200
201
202 <TR>
203   <TD COLSPAN=2>
204     <INPUT TYPE="checkbox" CHECKED NAME="save" VALUE="1">
205     <% mt('Remember this information') |h %>
206   </TD>
207 </TR>
208
209 % if ( $conf->exists("batch-enable")
210 %      || grep $payby eq $_, $conf->config('batch-enable_payby')
211 %    ) {
212 %
213 %     if ( grep $payby eq $_, $conf->config('realtime-disable_payby') ) {
214
215           <INPUT TYPE="hidden" NAME="batch" VALUE="1">
216
217 %     } else {
218
219           <TR>
220             <TD COLSPAN=2>
221               <INPUT TYPE="checkbox" NAME="batch" VALUE="1">
222               <% mt('Add to current batch') |h %> 
223             </TD>
224           </TR>
225
226 %     }
227 % }
228
229 <TR>
230   <TD COLSPAN=2>
231     <INPUT TYPE="checkbox"<% ( ( $payby eq 'CARD' && $cust_main->payby ne 'DCRD' ) || ( $payby eq 'CHEK' && $cust_main->payby eq 'CHEK' ) ) ? ' CHECKED' : '' %> NAME="auto" VALUE="1" onClick="if (this.checked) { document.OneTrueForm.save.checked=true; }">
232     <% mt("Charge future payments to this [_1] automatically",$type{$payby}) |h %> 
233   </TD>
234 </TR>
235
236 </TABLE>
237
238 <BR>
239 <INPUT TYPE="submit" NAME="process" VALUE="<% mt('Process payment') |h %>">
240 </FORM>
241
242 <& /elements/footer.html &>
243 <%init>
244
245 die "access denied"
246   unless $FS::CurrentUser::CurrentUser->access_right('Process payment');
247
248 my %type = ( 'CARD' => 'credit card',
249              'CHEK' => 'electronic check (ACH)',
250            );
251
252 $cgi->param('payby') =~ /^(CARD|CHEK)$/
253   or die "unknown payby ". $cgi->param('payby');
254 my $payby = $1;
255
256 $cgi->param('custnum') =~ /^(\d+)$/
257   or die "illegal custnum ". $cgi->param('custnum');
258 my $custnum = $1;
259
260 my $cust_main = qsearchs( 'cust_main', { 'custnum'=>$custnum } );
261 die "unknown custnum $custnum" unless $cust_main;
262
263 my $location = $cust_main->bill_location;
264 # no proper error handling on this anyway, but when we have it,
265 # remember to repopulate fields in $location
266
267 my $balance = $cust_main->balance;
268
269 my $payinfo = '';
270
271 my $conf = new FS::Conf;
272
273 #false laziness w/selfservice make_payment.html shortcut for one-country
274 my %states = map { $_->state => 1 }
275                qsearch('cust_main_county', {
276                  'country' => $conf->config('countrydefault') || 'US'
277                } );
278 my @states = sort { $a cmp $b } keys %states;
279
280 my $amount = '';
281 if ( $balance > 0 ) {
282   # when configured to do so, amount will only auto-fill with balance
283   # if balance represents a single invoice
284   $amount = $balance
285     unless $conf->exists('manual_process-single_invoice_amount')
286       && ($cust_main->open_cust_bill != 1);
287 }
288
289 my $payunique = "webui-payment-". time. "-$$-". rand() * 2**32;
290
291 </%init>