+ my $card_type = '';
+ $card_type = cardtype($payinfo) if $payby eq 'CARD';
+
+ {
+ 'cust_main' => $cust_main, #XXX or just custnum??
+ 'amount' => $amount,
+ 'payby' => $payby,
+ 'payinfo' => $payinfo,
+ 'paymask' => $cust_main->mask_payinfo( $payby, $payinfo ),
+ 'card_type' => $card_type,
+ 'paydate' => $p->{'year'}. '-'. $p->{'month'}. '-01',
+ 'paydate_pretty' => $p->{'month'}. ' / '. $p->{'year'},
+ 'payname' => $payname,
+ 'paybatch' => $paybatch, #this doesn't actually do anything
+ 'paycvv' => $paycvv,
+ 'payname' => $payname,
+ 'discount_term' => $discount_term,
+ 'pkgnum' => $session->{'pkgnum'},
+ map { $_ => $p->{$_} } ( @{ $payby2fields{$payby} },
+ qw( save auto ),
+ )
+ };
+
+}
+
+sub store_payment {
+ my $p = shift;
+
+ my $validate = validate_payment($p);
+ return $validate if $validate->{'error'};
+
+ my $conf = new FS::Conf;
+ my $timeout = $conf->config('selfservice-session_timeout') || '1 hour'; #?
+ _cache->set( 'payment_'.$p->{'session_id'}, $validate, $timeout );
+
+ +{ map { $_=>$validate->{$_} }
+ qw( card_type paymask payname paydate_pretty amount )
+ };
+
+}
+
+sub process_stored_payment {
+ my $p = shift;
+
+ my $session_id = $p->{'session_id'};
+
+ my $payment_info = _cache->get( "payment_$session_id" )
+ or return { 'error' => "Can't resume session" }; #better error message
+
+ do_process_payment($payment_info);
+
+}
+
+sub process_payment {
+ my $p = shift;
+
+ my $payment_info = validate_payment($p);
+ return $payment_info if $payment_info->{'error'};
+
+ do_process_payment($payment_info);
+
+}
+
+sub do_process_payment {
+ my $validate = shift;
+
+ my $cust_main = $validate->{'cust_main'};
+
+ my $amount = delete $validate->{'amount'};
+ my $paynum = '';
+
+ my $payby = delete $validate->{'payby'};
+