/*
jBilling - The Enterprise Open Source Billing System
Copyright (C) 2003-2011 Enterprise jBilling Software Ltd. and Emiliano Conde
This file is part of jbilling.
jbilling is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
jbilling is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with jbilling. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sapienter.jbilling.server.payment.tasks;
import com.sapienter.jbilling.server.payment.IExternalCreditCardStorage;
import com.sapienter.jbilling.server.payment.PaymentDTOEx;
import com.sapienter.jbilling.server.payment.db.PaymentAuthorizationDTO;
import com.sapienter.jbilling.server.payment.db.PaymentResultDAS;
import com.sapienter.jbilling.server.pluggableTask.PaymentTask;
import com.sapienter.jbilling.server.pluggableTask.PaymentTaskWithTimeout;
import com.sapienter.jbilling.server.pluggableTask.admin.PluggableTaskDTO;
import com.sapienter.jbilling.server.pluggableTask.admin.PluggableTaskException;
import com.sapienter.jbilling.server.user.ContactBL;
import com.sapienter.jbilling.server.user.contact.db.ContactDTO;
import com.sapienter.jbilling.server.user.db.CreditCardDTO;
import com.sapienter.jbilling.server.util.Constants;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.util.ParameterParser;
import org.apache.log4j.Logger;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.LinkedList;
import java.util.List;
/**
* A pluggable PaymentTask that uses RBS WorldPay gateway for credit card
* transactions.
*
* The following parameters must be configured for this payment task to work: -
* "URL" WordlPay gateway server url "StoreId" Store ID assigned by RBS WorldPay
* "MerchantID" Merchant ID assigned by RBS WorldPay "TerminalId" Terminal ID
* assigned by RBS WorldPay "SellerId" optional Store SellerId associated with
* the StoreId. The SellerId is mandatory if the security flag is turned on for
* the store. "Password" optional Password associated with the SellerId. The
* Password is mandatory if the security flag is turned on for the store.
*
* timeout_sec - number of seconds for timeout (in inheritance from
* PaymentTaskWithTimeout)
*
* @author othman
*/
public class PaymentWorldPayTask extends PaymentWorldPayBaseTask {
private static final Logger LOG = Logger.getLogger(PaymentWorldPayTask.class);
@Override
String getProcessorName() { return "WorldPay"; }
public boolean process(PaymentDTOEx payment) throws PluggableTaskException {
LOG.debug("Payment processing for " + getProcessorName() + " gateway");
if (payment.getPayoutId() != null) return true;
SvcType transaction = SvcType.SALE;
if (BigDecimal.ZERO.compareTo(payment.getAmount()) > 0 || (payment.getIsRefund() != 0)) {
LOG.debug("Doing a refund using credit card transaction");
transaction = SvcType.REFUND_CREDIT;
}
boolean result;
try {
result = doProcess(payment, transaction, null).shouldCallOtherProcessors();
LOG.debug("Processing result is "
+ payment.getPaymentResult().getId()
+ ", return value of process is " + result);
} catch (Exception e) {
LOG.error("Exception", e);
throw new PluggableTaskException(e);
}
return result;
}
public void failure(Integer userId, Integer retry) {
// not supported
}
public boolean preAuth(PaymentDTOEx payment) throws PluggableTaskException {
LOG.debug("Pre-authorization processing for " + getProcessorName() + " gateway");
return doProcess(payment, SvcType.AUTHORIZE, null).shouldCallOtherProcessors();
}
public boolean confirmPreAuth(PaymentAuthorizationDTO auth, PaymentDTOEx payment)
throws PluggableTaskException {
LOG.debug("Confirming pre-authorization for " + getProcessorName() + " gateway");
if (!getProcessorName() .equals(auth.getProcessor())) {
/* let the processor be called and fail, so the caller can do something
about it: probably re-call this payment task as a new "process()" run */
LOG.warn("The processor of the pre-auth is not " + getProcessorName() + ", is " + auth.getProcessor());
}
CreditCardDTO card = payment.getCreditCard();
if (card == null) {
throw new PluggableTaskException("Credit card is required capturing" + " payment: " + payment.getId());
}
if (!isApplicable(payment)) {
LOG.error("This payment can not be captured" + payment);
return true;
}
return doProcess(payment, SvcType.SETTLE, auth).shouldCallOtherProcessors();
}
@Override // implements abstract method
public NVPList buildRequest(PaymentDTOEx payment, SvcType transaction) throws PluggableTaskException {
NVPList request = new NVPList();
request.add(PARAMETER_MERCHANT_ID, getMerchantId());
request.add(PARAMETER_STORE_ID, getStoreId());
request.add(PARAMETER_TERMINAL_ID, getTerminalId());
request.add(PARAMETER_SELLER_ID, getSellerId());
request.add(PARAMETER_PASSWORD, getPassword());
ContactBL contact = new ContactBL();
contact.set(payment.getUserId());
request.add(WorldPayParams.General.STREET_ADDRESS, contact.getEntity().getAddress1());
request.add(WorldPayParams.General.CITY, contact.getEntity().getCity());
request.add(WorldPayParams.General.STATE, contact.getEntity().getStateProvince());
request.add(WorldPayParams.General.ZIP, contact.getEntity().getPostalCode());
request.add(WorldPayParams.General.FIRST_NAME, contact.getEntity().getFirstName());
request.add(WorldPayParams.General.LAST_NAME, contact.getEntity().getLastName());
request.add(WorldPayParams.General.COUNTRY, contact.getEntity().getCountryCode());
request.add(WorldPayParams.General.AMOUNT, formatDollarAmount(payment.getAmount()));
request.add(WorldPayParams.General.SVC_TYPE, transaction.getCode());
CreditCardDTO card = payment.getCreditCard();
request.add(WorldPayParams.CreditCard.CARD_NUMBER, card.getNumber());
request.add(WorldPayParams.CreditCard.EXPIRATION_DATE, EXPIRATION_DATE_FORMAT.format(card.getCcExpiry()));
if (card.getSecurityCode() != null) {
request.add(WorldPayParams.CreditCard.CVV2, String.valueOf(payment.getCreditCard().getSecurityCode()));
}
return request;
}
}