[ljcom] r10193: LJSUP-8014: Credit card payment process ...
Committer: ssafronova
LJSUP-8014: Credit card payment process refactoringU trunk/bin/upgrading/en_LJ.dat U trunk/cgi-bin/LJ/Pay/Payment.pm U trunk/cgi-bin/LJ/Pay/RecBill.pm U trunk/htdocs/admin/accounts/paidsearch.bml U trunk/ssldocs/manage/account/cc.bml U trunk/ssldocs/pay/cc.bml
Modified: trunk/bin/upgrading/en_LJ.dat
===================================================================
--- trunk/bin/upgrading/en_LJ.dat 2011-03-05 07:12:27 UTC (rev 10192)
+++ trunk/bin/upgrading/en_LJ.dat 2011-03-05 08:09:24 UTC (rev 10193)
@@ -138,6 +138,173 @@
after_entry_post_extra_option|staleness=1
after_entry_post_extra_option=Post it to LJ Bazaar
+authcap.reason.code.100=Successful transaction.
+
+authcap.reason.code.101=The request is missing one or more required fields. Resend the request with the complete information.
+
+authcap.reason.code.102=One or more fields in the request contains invalid data. Resend the request with the correct information.
+
+authcap.reason.code.110=Only a partial amount was approved.
+
+authcap.reason.code.150=Error: General system failure at CyberSource.
+
+authcap.reason.code.151<<
+Error: The request was received but there was a server timeout. This error does not include timeouts between the client and the server.
+Possible action: To avoid duplicating the transaction, do not resend the request until you have reviewed the transaction status in the Business Center.
+.
+
+authcap.reason.code.152<<
+Error: The request was received, but a service did not finish running in time.
+Possible action: To avoid duplicating the transaction, do not resend the request until you have reviewed the transaction status in the Business Center.
+.
+
+authcap.reason.code.200<<
+The authorization request was approved by the issuing bank but declined by CyberSource because it did not pass the Address Verification Service (AVS) check.
+Possible action: You can capture the authorization, but consider reviewing the order for the possibility of fraud.
+.
+
+authcap.reason.code.201<<
+The issuing bank has questions about the request. You do not receive an authorization code programmatically, but you might receive one verbally by calling the processor.
+Possible action: Call your processor to possibly receive a verbal authorization. For contact phone numbers, refer to your merchant bank information.
+.
+
+authcap.reason.code.202<<
+Expired card. You might also receive this if the expiration date you provided does not match the date the issuing bank has on file.
+Possible action: Request a different card or other form of payment.
+.
+
+authcap.reason.code.203<<
+General decline of the card. No other information provided by the issuing bank.
+Possible action: Request a different card or other form of payment.
+.
+
+authcap.reason.code.204<<
+Insufficient funds in the account.
+Possible action: Request a different card or other form of payment.
+.
+
+authcap.reason.code.205<<
+Stolen or lost card.
+Possible action: Refer the transaction to your customer support center for manual review.
+.
+
+authcap.reason.code.207<<
+Issuing bank unavailable.
+Possible action: Wait a few minutes and resend the request.
+.
+
+authcap.reason.code.208<<
+Inactive card or card not authorized for card-not-present transactions.
+Possible action: Request a different card or other form of payment.
+.
+
+authcap.reason.code.209<<
+American Express Card Identification Digits (CID) did not match.
+Possible action: Request a different card or other form of payment.
+.
+
+authcap.reason.code.210<<
+The card has reached the credit limit.
+Possible action: Request a different card or other form of payment.
+.
+
+authcap.reason.code.211<<
+Invalid CVN.
+Possible action: Request a different card or other form of payment.
+.
+
+authcap.reason.code.221<<
+The customer matched an entry on the processor’s negative file.
+Possible action: Review the order and contact the payment processor.
+.
+
+authcap.reason.code.230<<
+The authorization request was approved by the issuing bank but declined by CyberSource because it did not pass the CVN check.
+Possible action: You can capture the authorization, but consider reviewing the order for the possibility of fraud.
+.
+
+authcap.reason.code.231<<
+Invalid account number.
+Possible action: Request a different card or other form of payment.
+.
+
+authcap.reason.code.232<<
+The card type is not accepted by the payment processor.
+Possible action: Contact your merchant bank to confirm that your account is set up to receive the card in question.
+.
+
+authcap.reason.code.233<<
+General decline by the processor.
+Possible action: Request a different card or other form of payment.
+.
+
+authcap.reason.code.234<<
+There is a problem with your CyberSource merchant configuration.
+Possible action: Do not resend the request. Contact Customer Support to correct the configuration problem.
+.
+
+authcap.reason.code.235<<
+The requested amount exceeds the originally authorized amount. Occurs, for example, if you try to capture an amount larger than the original authorization amount.
+Possible action: Issue a new authorization and capture request for the new amount.
+.
+
+authcap.reason.code.236<<
+Processor failure.
+Possible action: Wait a few minutes and resend the request.
+.
+
+authcap.reason.code.237<<
+The authorization has already been reversed.
+Possible action: No action required.
+.
+
+authcap.reason.code.238<<
+The authorization has already been captured.
+Possible action: No action required.
+.
+
+authcap.reason.code.239<<
+The requested transaction amount must match the previous transaction amount.
+Possible action: Correct the amount and resend the request.
+.
+
+authcap.reason.code.240<<
+The card type sent is invalid or does not correlate with the credit card number.
+Possible action: Confirm that the card type correlates with the credit card number specified in the request, then resend the request.
+.
+
+authcap.reason.code.241<<
+The request ID is invalid.
+Possible action: Request a new authorization, and if successful, proceed with the capture.
+.
+
+authcap.reason.code.242<<
+You requested a capture, but there is no corresponding, unused authorization record. Occurs if there was not a previously successful authorization request or if the previously successful authorization has already been used by another capture request.
+Possible action: Request a new authorization, and if successful, proceed with the capture.
+.
+
+authcap.reason.code.243<<
+The transaction has already been settled or reversed.
+Possible action: No action required.
+.
+
+authcap.reason.code.246<<
+The capture or credit is not voidable because the capture or credit information has already been submitted to your processor. Or, you requested a void for a type of transaction that cannot be voided.
+Possible action: No action required.
+.
+
+authcap.reason.code.247<<
+You requested a credit for a capture that was previously voided.
+Possible action: No action required.
+.
+
+authcap.reason.code.250<<
+Error: The request was received, but there was a timeout at the payment processor.
+Possible action: To avoid duplicating the transaction, do not resend the request until you have reviewed the transaction status in the Business Center.
+.
+
+authcap.reason.code.unknown=Unknown error, code [[code]]
+
birthday.text=Hey, [[user]], see which of your friends' [[link]] are coming up! LiveJournal keeps a list of their birthdays for you.
bml.badcontent.body=We're sorry, but there was an error in the information you submitted. Please go back and try again.
Modified: trunk/cgi-bin/LJ/Pay/Payment.pm
===================================================================
--- trunk/cgi-bin/LJ/Pay/Payment.pm 2011-03-05 07:12:27 UTC (rev 10192)
+++ trunk/cgi-bin/LJ/Pay/Payment.pm 2011-03-05 08:09:24 UTC (rev 10193)
@@ -1250,13 +1250,14 @@
sub authcap_err_str {
my $self = shift;
my $rv = shift;
+ my $lang = shift;
return 'unknown error' unless ref $rv;
unless (%$rv) {
- return "empty respons from transaction plugin";
+ return "empty response from transaction plugin";
}
- return {
+ my $old_text = {
1 => q{The security information from your card does not match the information you entered. Please go back and try again. Please note that a $1.00 charge may appear on your statement temporarily from the authorization attempt.},
2 => q{Your card was not allowed by our card processor. Please try another card.},
3 => q{The card number you entered is invalid. Please go back and re-enter your card number or try a different card. You may also want to contact your card issuer to see if there is a problem with your account.},
@@ -1274,6 +1275,13 @@
# failed request?
($rv->{req_status} eq 'fail' ? $rv->{req_status_str} : 'Success');
+
+ my $err_code = $rv->{req_status_code};
+ my $err_text = LJ::Lang::get_text($lang, 'authcap.reason.code.' . $err_code, undef, undef);
+ $err_text ||= LJ::Lang::get_text($lang, 'authcap.reason.code.unknown', undef, { code => $err_code });
+
+ my $err_field = $rv->{req_error_field};
+ return ($old_text, $err_text, $err_field);
}
sub authcap_is_success {
Modified: trunk/cgi-bin/LJ/Pay/RecBill.pm
===================================================================
--- trunk/cgi-bin/LJ/Pay/RecBill.pm 2011-03-05 07:12:27 UTC (rev 10192)
+++ trunk/cgi-bin/LJ/Pay/RecBill.pm 2011-03-05 08:09:24 UTC (rev 10193)
@@ -857,6 +857,7 @@
{
my $s = @{$self->{items}||[]} > 1 ? 's' : '';
my $subject = "Payment Failure";
+ my ($old_text, $err_text, $err_field) = LJ::Pay::Payment->authcap_err_str($retval, 'en');
my $msg =
"An automatic payment attempt on your account, $u->{user}, " .
"for \$" . sprintf("%.02f", $pmt->{amount}) . " USD to your " .
@@ -865,7 +866,7 @@
"The card processor reported the following error:\n\n" .
- " " . LJ::Pay::Payment->authcap_err_str($retval) . "\n\n" .
+ " $old_text\n\n" .
"Since your scheduled payment has failed, automatic payments have been" .
"turned off for your account. To reenroll in automatic payments with" .
@@ -2256,9 +2257,9 @@
$$retry_flag = 1 if $trans->should_retry($rv);
# save notes on this payment with the calculated error string
- my $errstr = LJ::Pay::Payment->authcap_err_str($rv);
- $pmt->payvar_set('last_status_str' => $errstr);
- _debug("errstr=$errstr");
+ my ($old_text, $err_text, $err_field) = LJ::Pay::Payment->authcap_err_str($rv, 'en');
+ $pmt->payvar_set('last_status_str' => $old_text);
+ _debug("errstr=$old_text");
return $rv;
}
Modified: trunk/htdocs/admin/accounts/paidsearch.bml
===================================================================
--- trunk/htdocs/admin/accounts/paidsearch.bml 2011-03-05 07:12:27 UTC (rev 10192)
+++ trunk/htdocs/admin/accounts/paidsearch.bml 2011-03-05 08:09:24 UTC (rev 10193)
@@ -76,16 +76,18 @@
);
my $bind = join(",", map { "?" } @acid);
- # include payments tied to account codes either purchased by or used by the user (new payment system)
- $sth = $dbh->prepare("SELECT pi.payid FROM acctpayitem p, payitems pi " .
- "WHERE pi.piid=p.piid AND p.acid IN ($bind) LIMIT 5000");
- $sth->execute(@acid);
- $matched{$_} = 1 while $_ = $sth->fetchrow_array;
-
- # include payments tied to account codes either purchased by or used by the user (new payment system)
- $sth = $dbh->prepare("SELECT payid FROM acctpay WHERE acid IN ($bind) LIMIT 5000");
- $sth->execute(@acid);
- $matched{$_} = 1 while $_ = $sth->fetchrow_array;
+ if ($bind) {
+ # include payments tied to account codes either purchased by or used by the user (new payment system)
+ $sth = $dbh->prepare("SELECT pi.payid FROM acctpayitem p, payitems pi " .
+ "WHERE pi.piid=p.piid AND p.acid IN ($bind) LIMIT 5000");
+ $sth->execute(@acid);
+ $matched{$_} = 1 while $_ = $sth->fetchrow_array;
+
+ # include payments tied to account codes either purchased by or used by the user (new payment system)
+ $sth = $dbh->prepare("SELECT payid FROM acctpay WHERE acid IN ($bind) LIMIT 5000");
+ $sth->execute(@acid);
+ $matched{$_} = 1 while $_ = $sth->fetchrow_array;
+ }
}
}
Modified: trunk/ssldocs/manage/account/cc.bml
===================================================================
--- trunk/ssldocs/manage/account/cc.bml 2011-03-05 07:12:27 UTC (rev 10192)
+++ trunk/ssldocs/manage/account/cc.bml 2011-03-05 08:09:24 UTC (rev 10193)
@@ -77,7 +77,7 @@
my $now = time();
- my ($ret, $err, $err_field, $print_cc_form);
+ my ($ret, $err, $err_field, $print_cc_form, $old_err_text);
# Sysban checks
my $uniq = LJ::Request->notes('uniq');
@@ -139,8 +139,8 @@
return 1;
}
else {
- $$err = BML::ml('.error.autherror', {'errormsg' => LJ::Pay::Payment->authcap_err_str($rv) || $ML{'.error.unknownautherror'}});
-
+ ($old_err_text, $$err, $err_field) = LJ::Pay::Payment->authcap_err_str($rv, BML::get_language());
+ $print_cc_form = 1;
return 0;
}
};
@@ -497,8 +497,9 @@
$pmt->set_mailed('Y');
}
else {
- my $errstr = LJ::Pay::Payment->authcap_err_str($rv);
- $die->( $errstr, 1 );
+ ($old_err_text, $err, $err_field) = LJ::Pay::Payment->authcap_err_str($rv, BML::get_language());
+ $print_cc_form = 1;
+ $die->( $err, 1 );
}
LJ::Pay::release_lock($u);
Modified: trunk/ssldocs/pay/cc.bml
===================================================================
--- trunk/ssldocs/pay/cc.bml 2011-03-05 07:12:27 UTC (rev 10192)
+++ trunk/ssldocs/pay/cc.bml 2011-03-05 08:09:24 UTC (rev 10193)
@@ -116,12 +116,34 @@
$ccform .= LJ::html_hidden("cart", $cart);
$ccform .= LJ::html_hidden("amt_charge", $amt_charge);
+
+ my $cc_form_return = sub {
+ my ($err, $err_field) = @_;
+
+ $ccform .= "<span class='b-bubble b-bubble-warning' id='move_to_$err_field'><i class='i-bubble-arrow-border'></i><i class='i-bubble-arrow'></i>$err</span>";
+ $ccform .= "<script type=\"text/javascript\">jQuery(function(){";
+ $ccform .= "jQuery(\"#move_to_$err_field\").appendTo(jQuery(\"#ccform [name=$err_field]\").closest(\"li\")).show();";
+ $ccform .= "});</script>";
+
+ $ccform .= LJ::Widget::CreditCard::render( LJ::Pay::RecBill->valid_countries, $err, \%POST, undef,
+ {
+ 'cvv2' => 1,
+ 'has_coppa' => $has_coppa,
+ }
+ );
+
+ $ccform .= "</form>";
+
+ $ret .= $ccform;
+ return $ret;
+ };
+
my $email = $remote ? $remote->email_raw : " ";
$email = $POST{email} || $email;
### POST: authorize/capture
- my $err;
+ my ($err, $err_text, $err_field);
if (LJ::did_post()) {
my $dbh = LJ::get_db_writer();
my $no_charge = $ML{'.error.nocharge'};
@@ -509,23 +531,7 @@
# process credit card form fields
my ($formerr, $err_field);
unless (LJ::Widget::CreditCard::validate(\%POST, \$formerr, \$err_field) || $LJ::DEBUG{'no_cc_needed'}) {
-
- $ccform .= "<span class='b-bubble b-bubble-warning' id='move_to_$err_field'><i class='i-bubble-arrow-border'></i><i class='i-bubble-arrow'></i>$formerr</span>";
- $ccform .= "<script type=\"text/javascript\">jQuery(function(){";
- $ccform .= "jQuery(\"#move_to_$err_field\").appendTo(jQuery(\"#ccform [name=$err_field]\").closest(\"li\")).show();";
- $ccform .= "});</script>";
-
- $ccform .= LJ::Widget::CreditCard::render( LJ::Pay::RecBill->valid_countries, $formerr, \%POST, undef,
- {
- 'cvv2' => 1,
- 'has_coppa' => $has_coppa,
- }
- );
-
- $ccform .= "</form>";
-
- $ret .= $ccform;
- return $ret;
+ return $cc_form_return->($formerr, $err_field);
}
# send fraud watch emails if necessary
@@ -597,8 +603,10 @@
if ($coppa_only) {
$capture{charge_amt} = 1.00;
$rv = $cartobj->authorize ( %capture );
- return $error->(LJ::Pay::Payment->authcap_err_str($rv))
- unless LJ::Pay::Payment->authcap_is_success($rv) || $LJ::DEBUG{'no_cc_needed'};
+ unless (LJ::Pay::Payment->authcap_is_success($rv) || $LJ::DEBUG{'no_cc_needed'}) {
+ my ($old_text, $err_text, $err_field) = LJ::Pay::Payment->authcap_err_str($rv, BML::get_language());
+ return $cc_form_return->($err_text, $err_field);
+ }
} elsif ($cartobj->get_amount() > 0) {
$rv = eval { $cartobj->capture ( %capture ) };
return $error->($@) unless $rv;
@@ -608,7 +616,8 @@
$complete_order->();
} else {
my %done; my $emailtxt;
- $err = LJ::Pay::Payment->authcap_err_str($rv);
+ ($err, $err_text, $err_field) = LJ::Pay::Payment->authcap_err_str($rv, BML::get_language());
+ # $err is old message and will be 'en' in any case
my @rcpts = map { [ $_->{'rcptid'}, $_->{'rcptemail'} ] } @{$cartobj->{'items'}};
push @rcpts, [ $remote->{userid}, $remote->email_raw ] if $cartobj->{userid};
@@ -676,9 +685,7 @@
if ($err) {
$unlock->();
- return BML::ml('.error.cantprocesspayment', {'errormsg' => $err}) .
- "<p>$ML{'.error.cantprocesspayment.fundsheld'}</p>" .
- "<p>" . BML::ml('.error.cantprocesspayment.moreinfo', {'aopts' => "href='$LJ::SITEROOT/support/faqbrowse.bml?faqid=190'"}) . "</p>";
+ return $cc_form_return->($err_text, $err_field);
}
# if the order amount is 0, mark this cart as free. this catches
