Subversion Repositories SmartDukaan

Rev

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