FR 2884597 - More flexible Credit Card validation in PaymentProcessor

https://sourceforge.net/tracker/index.php?func=detail&aid=2884597&group_id=176962&atid=879335

Changes in brief:
MPayment: change in the processOnline method:
 * Call the payment processor's validate method before calling pp.processCC
   In this way we can validate the card details before trying to process.
PaymentProcessor:
  * Create a standard validation (using existing CC-validation)
    method that's overridable by subclasses.
PaymentOnline:
  * Remove CC-validation from here since it prevents the use of custom CC-validation
    in the custom PaymentProcessor.
VPayment:
  * Don't validate the credit card details here since the payment processor
    is not yet known here. The validation is made later by the payment processor.
    If validation should be done at this point it should depend on the
    payment processor.

Reasons for change:
Not all credit cards and payment gateways have the same validation standard. Especially
test payment gateways can have very different validation standards.
With this change, the same validation remains, but it can be changed by extending
the PaymentProcessor class.
This commit is contained in:
usrdno 2010-01-07 17:38:41 +00:00
parent 760ac455f1
commit af81a9f30e
4 changed files with 64 additions and 45 deletions

View File

@ -493,11 +493,18 @@ public final class MPayment extends X_C_Payment
setErrorMessage("No Payment Processor"); setErrorMessage("No Payment Processor");
else else
{ {
approved = pp.processCC (); // Validate before trying to process
if (approved) String msg = pp.validate();
setErrorMessage(null); if (msg!=null && msg.trim().length()>0) {
else setErrorMessage(Msg.getMsg(getCtx(), msg));
setErrorMessage("From " + getCreditCardName() + ": " + getR_RespMsg()); } else {
// Process if validation succeeds
approved = pp.processCC ();
if (approved)
setErrorMessage(null);
else
setErrorMessage("From " + getCreditCardName() + ": " + getR_RespMsg());
}
} }
} }
catch (Exception e) catch (Exception e)

View File

@ -31,6 +31,8 @@ import java.util.logging.Level;
import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.HttpsURLConnection;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.compiere.util.Env;
import org.compiere.util.Msg;
/** /**
* Payment Processor Abstract Class * Payment Processor Abstract Class
@ -123,11 +125,58 @@ public abstract class PaymentProcessor
public abstract boolean processCC () throws IllegalArgumentException; public abstract boolean processCC () throws IllegalArgumentException;
/** /**
* Payment is procesed successfully * Payment is processed successfully
* @return true if OK * @return true if OK
*/ */
public abstract boolean isProcessedOK(); public abstract boolean isProcessedOK();
/**************************************************************************/
// Validation methods. Override if you have specific needs.
/**
* Validate payment before process.
* @return "" or Error AD_Message.
* @throws IllegalArgumentException
*/
public String validate() throws IllegalArgumentException {
String msg = null;
if (MPayment.TENDERTYPE_CreditCard.equals(p_mp.getTenderType())) {
msg = validateCreditCard();
} else if (MPayment.TENDERTYPE_Check.equals(p_mp.getTenderType())) {
msg = validateCheckNo();
} else if (MPayment.TENDERTYPE_Account.equals(p_mp.getTenderType())) {
msg = validateAccountNo();
}
return(msg);
}
/**
* Standard account validation.
* @return
*/
public String validateAccountNo() {
return MPaymentValidate.validateAccountNo(p_mp.getAccountNo());
}
public String validateCheckNo() {
return MPaymentValidate.validateCheckNo(p_mp.getCheckNo());
}
public String validateCreditCard() throws IllegalArgumentException {
String msg = MPaymentValidate.validateCreditCardNumber(p_mp.getCreditCardNumber(), p_mp.getCreditCardType());
if (msg != null && msg.length() > 0)
throw new IllegalArgumentException(Msg.getMsg(Env.getCtx(), msg));
msg = MPaymentValidate.validateCreditCardExp(p_mp.getCreditCardExpMM(), p_mp.getCreditCardExpYY());
if (msg != null && msg.length() > 0)
throw new IllegalArgumentException(Msg.getMsg(Env.getCtx(), msg));
if (p_mp.getCreditCardVV() != null && p_mp.getCreditCardVV().length() > 0)
{
msg = MPaymentValidate.validateCreditCardVV(p_mp.getCreditCardVV(), p_mp.getCreditCardType());
if (msg != null && msg.length() > 0)
throw new IllegalArgumentException(Msg.getMsg(Env.getCtx(), msg));
}
return(msg);
}
/************************************************************************** /**************************************************************************
* Set Timeout * Set Timeout
@ -287,7 +336,6 @@ public abstract class PaymentProcessor
// open secure connection // open secure connection
URL url = new URL(urlString); URL url = new URL(urlString);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
// URLConnection connection = url.openConnection();
connection.setDoOutput(true); connection.setDoOutput(true);
connection.setUseCaches(false); connection.setUseCaches(false);
connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");

View File

@ -20,8 +20,6 @@ package org.compiere.process;
import java.util.logging.Level; import java.util.logging.Level;
import org.compiere.model.MPayment; import org.compiere.model.MPayment;
import org.compiere.model.MPaymentValidate;
import org.compiere.util.Msg;
/** /**
@ -58,19 +56,6 @@ public class PaymentOnline extends SvrProcess
log.info("Record_ID=" + getRecord_ID()); log.info("Record_ID=" + getRecord_ID());
// get Payment // get Payment
MPayment pp = new MPayment (getCtx(), getRecord_ID(), get_TrxName()); MPayment pp = new MPayment (getCtx(), getRecord_ID(), get_TrxName());
// Validate Number
String msg = MPaymentValidate.validateCreditCardNumber(pp.getCreditCardNumber(), pp.getCreditCardType());
if (msg != null && msg.length() > 0)
throw new IllegalArgumentException(Msg.getMsg(getCtx(), msg));
msg = MPaymentValidate.validateCreditCardExp(pp.getCreditCardExpMM(), pp.getCreditCardExpYY());
if (msg != null && msg.length() > 0)
throw new IllegalArgumentException(Msg.getMsg(getCtx(), msg));
if (pp.getCreditCardVV() != null && pp.getCreditCardVV().length() > 0)
{
msg = MPaymentValidate.validateCreditCardVV(pp.getCreditCardVV(), pp.getCreditCardType());
if (msg != null && msg.length() > 0)
throw new IllegalArgumentException(Msg.getMsg(getCtx(), msg));
}
// Process it // Process it
boolean ok = pp.processOnline(); boolean ok = pp.processOnline();

View File

@ -1325,29 +1325,8 @@ public class VPayment extends CDialog
vp = (ValueNamePair)kTypeCombo.getSelectedItem(); vp = (ValueNamePair)kTypeCombo.getSelectedItem();
if (vp != null) if (vp != null)
CCType = vp.getValue(); CCType = vp.getValue();
// // Validation of the credit card number is moved to the payment processor.
String error = MPaymentValidate.validateCreditCardNumber(kNumberField.getText(), CCType); // Different payment processors can have different validation rules.
if (error.length() != 0)
{
kNumberField.setBackground(AdempierePLAF.getFieldBackground_Error());
if (error.indexOf('?') == -1)
{
ADialog.error(m_WindowNo, this, error);
dataOK = false;
}
else // warning
{
if (!ADialog.ask(m_WindowNo, this, error))
dataOK = false;
}
}
error = MPaymentValidate.validateCreditCardExp(kExpField.getText());
if(error.length() != 0)
{
kExpField.setBackground(AdempierePLAF.getFieldBackground_Error());
ADialog.error(m_WindowNo, this, error);
dataOK = false;
}
} }
// T (Transfer) BPartner_Bank // T (Transfer) BPartner_Bank