Subversion Repositories SmartDukaan

Rev

Rev 3616 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
719 rajveer 1
package in.shop2020.serving.controllers;
2
 
741 rajveer 3
import in.shop2020.config.ConfigException;
853 rajveer 4
import in.shop2020.payments.Attribute;
741 rajveer 5
import in.shop2020.payments.Payment;
6
import in.shop2020.payments.PaymentException;
894 rajveer 7
import in.shop2020.payments.PaymentService.Client;
719 rajveer 8
import in.shop2020.payments.PaymentStatus;
1905 chandransh 9
import in.shop2020.serving.services.CommonPaymentService;
3126 rajveer 10
import in.shop2020.thrift.clients.PaymentClient;
11
import in.shop2020.thrift.clients.TransactionClient;
12
import in.shop2020.thrift.clients.UserClient;
719 rajveer 13
import in.shop2020.thrift.clients.config.ConfigClient;
14
 
15
import java.io.IOException;
16
 
17
import javax.servlet.http.HttpServletRequest;
18
 
19
import org.apache.struts2.interceptor.ServletRequestAware;
741 rajveer 20
import org.apache.thrift.TException;
1044 chandransh 21
import org.apache.log4j.Logger;
719 rajveer 22
 
2334 chandransh 23
/**
24
 * This controller processes payment data received on the back channel from
25
 * HDFC. Since this request doesn't have any cookies associated with it, we
26
 * can't extend the BaseController which is intercepted by UserInterceptor. Thus
27
 * to get the parameters from the request, it implements the ServletRequestAware
28
 * interface.
29
 * 
30
 * @author Rajveer, Chandranshu
31
 * @
32
 */
33
public class HdfcPayResponseController implements ServletRequestAware{
34
 
35
	/**
36
	 * Enum of all statuses that can be returned by the HDFC gateway
37
	 * 
38
	 * @author Chandranshu
39
	 * 
40
	 */
719 rajveer 41
	private enum PaymentReturnStatus{
2334 chandransh 42
		APPROVED("APPROVED"),
43
		NOT_APPROVED("NOT APPROVED"),
719 rajveer 44
		CAPTURED("CAPTURED"),
45
		NOT_CAPTURED ("NOT CAPTURED"),
46
		CANCELLED ("CANCELLED"),
47
		DENIED_BY_RISK("DENIED BY RISK"),
48
		HOST_TIMEOUT("HOST TIMEOUT");
49
		private String value;
50
		PaymentReturnStatus(String value) {
51
			this.value = value;
52
		}
53
		public String value(){
54
			return this.value;
55
		}
56
	}
57
 
58
	HttpServletRequest request;
59
 
1044 chandransh 60
	//private static Logger log = LoggerFactory.getLogger(HdfcPayResponseController.class);
61
	private static Logger log = Logger.getLogger(Class.class);
719 rajveer 62
 
894 rajveer 63
	public static String successUrl;
64
	public static String errorUrl;
65
 
719 rajveer 66
	public static String AMOUNT = "amt";
67
	public static String TRACKID = "trackid";
68
	public static String RESULT = "result";
69
	public static String AUTH = "auth";
70
	public static String TRANID = "tranid";
71
	public static String PAYMENTID = "paymentid";
72
	public static String REF = "ref";
73
	public static String POSTDATE = "postdate";
74
	public static String ERROR = "Error";
75
	public static String ERRORTEXT = "ErrorText";
1905 chandransh 76
	public static String UDF5 = "udf5";	
894 rajveer 77
 
78
	static{
719 rajveer 79
		try {
894 rajveer 80
			successUrl = ConfigClient.getClient().get("payment_success_url");
81
			errorUrl = ConfigClient.getClient().get("payment_error_url");
82
		} catch (ConfigException e) {
83
			log.error("Unable to get success and error usr info from config server.");
719 rajveer 84
		}
85
	}
86
 
1905 chandransh 87
	String redirectUrl;
894 rajveer 88
 
89
	public HdfcPayResponseController() {
90
 
91
	}
2334 chandransh 92
 
93
	/**
94
	 * Sets the redirectUrl instance variable which is used in the view to
95
	 * redirect the customer to the success or failure page.
96
	 * 
97
	 * @return index in all cases.
98
	 * @throws IOException
99
	 * @throws SecurityException
100
	 */
719 rajveer 101
	public String create() throws IOException, SecurityException{
894 rajveer 102
		log.info("Inside hdfc pay response Create");
719 rajveer 103
 
3126 rajveer 104
		PaymentClient paymentServiceClient = null;
105
		TransactionClient transactionServiceClient = null;
106
		UserClient userServiceClient = null;
894 rajveer 107
		try{
3126 rajveer 108
			paymentServiceClient = new PaymentClient();
109
			transactionServiceClient = new TransactionClient();
110
			userServiceClient = new UserClient();
894 rajveer 111
		}catch(Exception e){
112
			//Nothing to worry. lets move forward
2334 chandransh 113
			log.error("Unable to initialize one of the clients", e);
894 rajveer 114
		}
115
 
1905 chandransh 116
		Long txnId = null;
117
 
118
		String paymentId = request.getParameter(PAYMENTID);
119
		String result = request.getParameter(RESULT);
120
		String trackId = request.getParameter(TRACKID);
121
		long merchantPaymentId = Long.parseLong(trackId);
122
		String amount = request.getParameter(AMOUNT);
123
		String errorText = request.getParameter(ERRORTEXT);
124
 
719 rajveer 125
		//FIXME dump them somewhere
853 rajveer 126
		String udf5=request.getParameter(UDF5);
894 rajveer 127
		//FIXME hdfc is sending comma separated amount, which is very disappointing. May be we get more surprises moving forward.
856 rajveer 128
		amount= amount.replace(",", "");
894 rajveer 129
 
2334 chandransh 130
		//Setting redirect URL to the error URL value by default.
131
		this.redirectUrl = errorUrl + "?paymentId=" + merchantPaymentId;
132
 
894 rajveer 133
		Client paymentClient = paymentServiceClient.getClient();
2334 chandransh 134
		Payment payment = null;
741 rajveer 135
		try {
2334 chandransh 136
			payment = paymentClient.getPayment(merchantPaymentId);
1905 chandransh 137
			txnId = payment.getMerchantTxnId();
138
 
139
			if(!validatePaymentParams(paymentId, amount, udf5, payment))
741 rajveer 140
				return "index";
141
		} catch (PaymentException e1) {
2334 chandransh 142
			log.error("Payment exception. It is serious, check merchant payment id + " + merchantPaymentId, e1);
741 rajveer 143
		} catch (TException e1) {
2334 chandransh 144
			log.error("Thrift exception. Check payment id "+ merchantPaymentId, e1);
741 rajveer 145
		}
719 rajveer 146
 
2334 chandransh 147
		if (result != null && result.trim().equals(PaymentReturnStatus.APPROVED.value())) {
148
			log.info("Payment " + merchantPaymentId + " authorized successfully. Updating the database.");
149
			String description = "Payment authorized";
150
			updatePaymentDetails(merchantPaymentId, description, PaymentStatus.AUTHORIZED, request, paymentClient);
3010 chandransh 151
 
4246 rajveer 152
            CommonPaymentService.processSuccessfulTxn(txnId, userServiceClient, transactionServiceClient, false);
3010 chandransh 153
 
154
            this.redirectUrl = successUrl + "?paymentId=" + merchantPaymentId;
1905 chandransh 155
		} else {
156
			updatePaymentDetails(merchantPaymentId, errorText, PaymentStatus.FAILED, request, paymentClient);
157
 
158
			CommonPaymentService.processFailedTxn(txnId, transactionServiceClient);
159
 
160
			this.redirectUrl = errorUrl + "?paymentId=" + merchantPaymentId;
1554 varun.gupt 161
		}
1905 chandransh 162
 
163
		return "index";
164
	}
165
 
166
	private boolean validatePaymentParams(String paymentId,	String amount, String udf5, Payment payment) {
167
		long merchantPaymentId = payment.getPaymentId();
168
		String dbUdf5="";
169
		double dbAmount = payment.getAmount();
170
		for(Attribute attribute: payment.getAttributes()){
171
			if(attribute.getName().trim().equalsIgnoreCase(UDF5)){
172
				dbUdf5 = attribute.getValue();
719 rajveer 173
			}
174
		}
1905 chandransh 175
		// verify 3 things:  udf5, amount and paymentid
176
		//FIXME should we first dump the data and then verify these things. ?? 
2134 chandransh 177
		double returnedAmount = Double.parseDouble(amount);
178
		log.info(paymentId+ ":"+ payment.getGatewayPaymentId() + "\n" + returnedAmount + ":" + dbAmount + "\n" + dbUdf5 + ":" + udf5 );
179
		if(!(paymentId.equalsIgnoreCase(payment.getGatewayPaymentId()) && (Math.abs(dbAmount - returnedAmount) <= 0.50) && udf5.equalsIgnoreCase(dbUdf5))){
1905 chandransh 180
			log.error("Checks and balance failed on returned data");
181
			this.redirectUrl =  errorUrl + "?paymentId="+merchantPaymentId;
182
			return false;
183
		}
184
		return true;
185
	}
186
 
187
	private void updatePaymentDetails(long merchantPaymentId, String message, PaymentStatus status, HttpServletRequest req, Client paymentClient) {
188
		String paymentId = request.getParameter(PAYMENTID);
189
		String result = request.getParameter(RESULT);
190
		String postdate = request.getParameter(POSTDATE);
191
		String tranId = request.getParameter(TRANID);
192
		String auth = request.getParameter(AUTH);
193
		String ref = request.getParameter(REF);
719 rajveer 194
 
1905 chandransh 195
		String sessionId = request.getSession().getId();
196
		String errorNo = request.getParameter(ERROR);
197
		try {
198
			paymentClient.updatePaymentDetails(merchantPaymentId, paymentId, sessionId, result, message, tranId, auth, ref, errorNo, status, postdate, null);
199
		} catch (PaymentException e1) {
2334 chandransh 200
			log.error("Unable to update payment details in our database.", e1);
1905 chandransh 201
		} catch (TException e1) {
2334 chandransh 202
			log.error("Unable to update payment details in our database. Thrift exception.", e1);
1905 chandransh 203
		}
719 rajveer 204
	}
205
 
206
	public String getRedirectUrl(){
207
		return this.redirectUrl;
208
	}
209
 
210
	@Override
211
	public void setServletRequest(HttpServletRequest request) {
212
		this.request = request;
213
		for(Object param: request.getParameterMap().keySet()){
2334 chandransh 214
			log.info("PARAMS: " + param + " = "+ request.getParameter((String)param));
719 rajveer 215
		}
216
	}
1554 varun.gupt 217
}