Subversion Repositories SmartDukaan

Rev

Rev 4246 | 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;
20112 aman.kumar 4
import in.shop2020.model.v1.order.RechargeOrder;
5
import in.shop2020.model.v1.order.RechargeOrderStatus;
853 rajveer 6
import in.shop2020.payments.Attribute;
741 rajveer 7
import in.shop2020.payments.Payment;
8
import in.shop2020.payments.PaymentException;
894 rajveer 9
import in.shop2020.payments.PaymentService.Client;
719 rajveer 10
import in.shop2020.payments.PaymentStatus;
1905 chandransh 11
import in.shop2020.serving.services.CommonPaymentService;
3126 rajveer 12
import in.shop2020.thrift.clients.PaymentClient;
13
import in.shop2020.thrift.clients.TransactionClient;
14
import in.shop2020.thrift.clients.UserClient;
719 rajveer 15
import in.shop2020.thrift.clients.config.ConfigClient;
16
 
17
import java.io.IOException;
20112 aman.kumar 18
import java.security.MessageDigest;
19
import java.security.NoSuchAlgorithmException;
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;
25
import java.util.TreeMap;
719 rajveer 26
 
27
import javax.servlet.http.HttpServletRequest;
28
 
29
import org.apache.struts2.interceptor.ServletRequestAware;
741 rajveer 30
import org.apache.thrift.TException;
1044 chandransh 31
import org.apache.log4j.Logger;
719 rajveer 32
 
2334 chandransh 33
/**
34
 * This controller processes payment data received on the back channel from
35
 * HDFC. Since this request doesn't have any cookies associated with it, we
36
 * can't extend the BaseController which is intercepted by UserInterceptor. Thus
37
 * to get the parameters from the request, it implements the ServletRequestAware
38
 * interface.
39
 * 
40
 * @author Rajveer, Chandranshu
41
 * @
42
 */
43
public class HdfcPayResponseController implements ServletRequestAware{
44
 
20112 aman.kumar 45
	private static String rechargeResultUri;
46
 
2334 chandransh 47
	/**
20112 aman.kumar 48
	 * The secret key used to decode RC4 encoded data.
49
	 */
50
	private static String accountKey;
51
 
52
	private static String salt;
53
 
54
	private String eurl;
55
	private String surl;
56
 
57
	/**
2334 chandransh 58
	 * Enum of all statuses that can be returned by the HDFC gateway
59
	 * 
60
	 * @author Chandranshu
61
	 * 
62
	 */
719 rajveer 63
	private enum PaymentReturnStatus{
2334 chandransh 64
		APPROVED("APPROVED"),
65
		NOT_APPROVED("NOT APPROVED"),
719 rajveer 66
		CAPTURED("CAPTURED"),
67
		NOT_CAPTURED ("NOT CAPTURED"),
68
		CANCELLED ("CANCELLED"),
69
		DENIED_BY_RISK("DENIED BY RISK"),
70
		HOST_TIMEOUT("HOST TIMEOUT");
71
		private String value;
72
		PaymentReturnStatus(String value) {
73
			this.value = value;
74
		}
75
		public String value(){
76
			return this.value;
77
		}
78
	}
79
 
80
	HttpServletRequest request;
81
 
1044 chandransh 82
	//private static Logger log = LoggerFactory.getLogger(HdfcPayResponseController.class);
83
	private static Logger log = Logger.getLogger(Class.class);
719 rajveer 84
 
894 rajveer 85
	public static String successUrl;
86
	public static String errorUrl;
87
 
20112 aman.kumar 88
	public static String AMOUNT = "Amount";
89
	public static String PAYMENTID = "PaymentID";
719 rajveer 90
	public static String ERROR = "Error";
20112 aman.kumar 91
	public static String MERCHANTREFNO="MerchantRefNo";
92
	public static String RESPONSECODE="ResponseCode";
93
	public static String SECUREHASH="SecureHash";
94
	public static String RESPONSEMESSAGE  = "ResponseMessage";
95
	public static String ISFLAGGED = "IsFlagged";
96
	public static String TRANSACTIONID ="TransactionID";
97
	public static String PAYMENTMETHOD = "PaymentMethod";
98
	public static String REQUESTID= "RequestID";
99
	public static String DATECREATED = "DateCreated";
100
	public static String SUCCESS= "0";//responsecode for successfull transaction by hdfc gateway
894 rajveer 101
 
102
	static{
719 rajveer 103
		try {
20112 aman.kumar 104
			ConfigClient cc = ConfigClient.getClient();
105
			successUrl = cc.get("payment_success_url");
106
			errorUrl = cc.get("payment_error_url");
107
			rechargeResultUri = cc.get("recharge_result_uri");
894 rajveer 108
		} catch (ConfigException e) {
109
			log.error("Unable to get success and error usr info from config server.");
719 rajveer 110
		}
111
	}
1905 chandransh 112
	String redirectUrl;
894 rajveer 113
 
114
	public HdfcPayResponseController() {
115
 
116
	}
20112 aman.kumar 117
 
118
	private Map<String, String> paymentParams = new TreeMap<String, String>();
2334 chandransh 119
 
120
	/**
121
	 * Sets the redirectUrl instance variable which is used in the view to
122
	 * redirect the customer to the success or failure page.
123
	 * 
124
	 * @return index in all cases.
125
	 * @throws IOException
126
	 * @throws SecurityException
127
	 */
719 rajveer 128
	public String create() throws IOException, SecurityException{
894 rajveer 129
		log.info("Inside hdfc pay response Create");
20112 aman.kumar 130
		eurl = errorUrl;
131
		surl = successUrl;
132
		updatePaymentParams(request.getParameterMap());
133
 
3126 rajveer 134
		PaymentClient paymentServiceClient = null;
135
		TransactionClient transactionServiceClient = null;
136
		UserClient userServiceClient = null;
20112 aman.kumar 137
		try {
138
			userServiceClient = new UserClient();
3126 rajveer 139
			paymentServiceClient = new PaymentClient();
140
			transactionServiceClient = new TransactionClient();
20112 aman.kumar 141
		} catch (Exception e) {
2334 chandransh 142
			log.error("Unable to initialize one of the clients", e);
894 rajveer 143
		}
144
 
20112 aman.kumar 145
		long merchantPaymentId = Long.parseLong(paymentParams.get(MERCHANTREFNO));
146
		String gatewayPaymentId = paymentParams.get(PAYMENTID);
147
		double amount = Double.parseDouble(paymentParams.get(AMOUNT));
148
		String gatewayTxnStatus = paymentParams.get(RESPONSECODE);
149
		String hash = paymentParams.get(SECUREHASH);
150
		String transactionId = paymentParams.get(TRANSACTIONID);
151
		String requestId = paymentParams.get(REQUESTID);
152
		String error = paymentParams.get(ERROR);
153
		List<Attribute> attributes = new ArrayList<Attribute>();
1905 chandransh 154
 
20112 aman.kumar 155
 
2334 chandransh 156
		Payment payment = null;
20112 aman.kumar 157
		Long txnId = null;
741 rajveer 158
		try {
20112 aman.kumar 159
			payment = paymentServiceClient.getClient().getPayment(merchantPaymentId);
1905 chandransh 160
			txnId = payment.getMerchantTxnId();
741 rajveer 161
		} catch (PaymentException e1) {
2334 chandransh 162
			log.error("Payment exception. It is serious, check merchant payment id + " + merchantPaymentId, e1);
741 rajveer 163
		} catch (TException e1) {
2334 chandransh 164
			log.error("Thrift exception. Check payment id "+ merchantPaymentId, e1);
741 rajveer 165
		}
719 rajveer 166
 
20112 aman.kumar 167
		if(payment.getStatus() != PaymentStatus.INIT){
168
			// We have already processed a response for this payment. Processing
169
			// it again may fail his orders. So, let's ask him to check his
170
			// account.
171
			return "ebs-pay-response-maybe";
172
		}
3010 chandransh 173
 
20112 aman.kumar 174
		if(payment.isIsDigital()){
175
			eurl = rechargeResultUri;
176
			surl = rechargeResultUri;
177
		}
178
 
179
		if(!validatePaymentParams(amount, payment, hash)){
180
			this.redirectUrl = eurl + "?paymentId=" + merchantPaymentId;
181
			return "index";
182
		}
3010 chandransh 183
 
20112 aman.kumar 184
		if(gatewayTxnStatus.equalsIgnoreCase(SUCCESS)){
185
			try {
186
				attributes.add(new Attribute(DATECREATED, paymentParams.get(DATECREATED)));
187
				paymentServiceClient.getClient().updatePaymentDetails(merchantPaymentId, gatewayPaymentId,
188
						"", gatewayTxnStatus, "Transaction captured at PG", 
189
						transactionId, "", requestId, "", PaymentStatus.SUCCESS,
190
								new SimpleDateFormat().format(new Date()), attributes);
191
			} catch (PaymentException e) {
192
				this.redirectUrl = eurl + "?paymentId=" + merchantPaymentId;
193
				return "index";
194
			} catch (TException e) {
195
				this.redirectUrl = eurl + "?paymentId=" + merchantPaymentId;
196
				return "index";
197
			}
198
            if(payment.isIsDigital()){
199
            	RechargeOrder rechargeOrder = null;
200
                try {
201
                    rechargeOrder = transactionServiceClient.getClient().getRechargeOrdersForTransaction(txnId);
202
                } catch (Exception e1) {
203
                    log.error("Problem with txn client while getting recharge object", e1);
204
    				this.redirectUrl = eurl + "?paymentId=" + merchantPaymentId;
205
    				return "index";
206
                }
207
 
208
		        try {
209
		            PaymentClient pcl = new PaymentClient();
210
		            boolean isCaptured = pcl.getClient().capturePayment(txnId, true);
211
 
212
		            //Retry in case we are not able to capture first time
213
		            if(!isCaptured){
214
		            	Thread.sleep(2000);
215
		            	isCaptured = pcl.getClient().capturePayment(txnId, true);
216
		            }
217
		            if(!isCaptured){
218
		            	Thread.sleep(2000);
219
		            	isCaptured = pcl.getClient().capturePayment(txnId, true);
220
		            }
221
 
222
		            if(isCaptured) {
223
		                transactionServiceClient.getClient().updateRechargeOrderStatus(rechargeOrder.getId(), RechargeOrderStatus.PAYMENT_SUCCESSFUL);
224
		            } else {
225
                        transactionServiceClient.getClient().updateRechargeOrderStatus(rechargeOrder.getId(), RechargeOrderStatus.PAYMENT_FAILED);
226
		            }
227
		        } catch (Exception e) {
228
		            log.error("Problem with txn client while trying to recharge", e);
229
		        }
230
            } else {
231
		        CommonPaymentService.processSuccessfulTxn(txnId, userServiceClient, transactionServiceClient, false);
232
            }
233
            this.redirectUrl = surl + "?paymentId=" + merchantPaymentId;
234
 
235
		} else{
236
			try {
237
				attributes.add(new Attribute(ERROR, error));
238
				paymentServiceClient.getClient().updatePaymentDetails(merchantPaymentId, gatewayPaymentId,
239
						"", gatewayTxnStatus, "Payment Failed at PG ", "", "", "", "", PaymentStatus.FAILED, new SimpleDateFormat().format(new Date()), attributes);
240
			} catch (PaymentException e) {
241
			    log.error("Unable to mark the payment as failed", e);
242
			} catch (TException e) {
243
			    log.error("Unable to mark the payment as failed", e);
244
			}
1905 chandransh 245
 
20112 aman.kumar 246
			if(!payment.isIsDigital()) {
247
				CommonPaymentService.processFailedTxn(txnId, transactionServiceClient);
248
			}
1905 chandransh 249
 
20112 aman.kumar 250
			this.redirectUrl = eurl + "?paymentId=" + merchantPaymentId;
1554 varun.gupt 251
		}
20112 aman.kumar 252
 
253
		log.info("User will be redirected to: " + surl + "?paymentId=" + merchantPaymentId);
254
		return "index";
255
 
1905 chandransh 256
 
257
	}
20112 aman.kumar 258
 
259
 
260
	private boolean validatePaymentParams(double returnedAmount, Payment payment, String hash){
261
		boolean hashCheckResult= hash.equals(getSecureHash());
262
		hashCheckResult = true;//remove this and implement hash check
263
		if(!(payment != null && Math.abs(payment.getAmount() - returnedAmount) <= 0.50
264
				&& hashCheckResult)){
265
			// We did not request this payment or the authorised amount is different.
266
			log.error("Checks and balance failed on returned data");
267
			return false;
268
		}
269
		return true;
270
	}
1905 chandransh 271
 
20112 aman.kumar 272
 
273
	public String getSecureHash(){
274
		/*try{
275
 
276
			//to do implement hash check
277
		}catch(Exception nsae){
278
			log.error("No such algorithm exception");
279
			return null;
280
		}*/
281
		return "";
282
	}
283
 
284
	private void updatePaymentParams(Map map){
285
		for(Object key : map.keySet()){
286
		    String keyStr = (String)key;
287
		    String[] vals = (String[])map.get(keyStr);
288
		    String value = vals[0];
289
		    System.out.println("Key " + (String)key + "     :    " + value);
290
		    paymentParams.put(keyStr, value);
291
		}
292
	}
293
/*	private boolean validatePaymentParams(String paymentId,	String amount, String udf5, Payment payment) {
1905 chandransh 294
		long merchantPaymentId = payment.getPaymentId();
295
		String dbUdf5="";
296
		double dbAmount = payment.getAmount();
297
		for(Attribute attribute: payment.getAttributes()){
298
			if(attribute.getName().trim().equalsIgnoreCase(UDF5)){
299
				dbUdf5 = attribute.getValue();
719 rajveer 300
			}
301
		}
1905 chandransh 302
		// verify 3 things:  udf5, amount and paymentid
303
		//FIXME should we first dump the data and then verify these things. ?? 
2134 chandransh 304
		double returnedAmount = Double.parseDouble(amount);
305
		log.info(paymentId+ ":"+ payment.getGatewayPaymentId() + "\n" + returnedAmount + ":" + dbAmount + "\n" + dbUdf5 + ":" + udf5 );
306
		if(!(paymentId.equalsIgnoreCase(payment.getGatewayPaymentId()) && (Math.abs(dbAmount - returnedAmount) <= 0.50) && udf5.equalsIgnoreCase(dbUdf5))){
1905 chandransh 307
			log.error("Checks and balance failed on returned data");
308
			this.redirectUrl =  errorUrl + "?paymentId="+merchantPaymentId;
309
			return false;
310
		}
311
		return true;
20112 aman.kumar 312
	}*/
1905 chandransh 313
 
20112 aman.kumar 314
/*	private void updatePaymentDetails(long merchantPaymentId, String message, PaymentStatus status, HttpServletRequest req, Client paymentClient) {
1905 chandransh 315
		String paymentId = request.getParameter(PAYMENTID);
719 rajveer 316
 
1905 chandransh 317
		String sessionId = request.getSession().getId();
318
		String errorNo = request.getParameter(ERROR);
319
		try {
320
			paymentClient.updatePaymentDetails(merchantPaymentId, paymentId, sessionId, result, message, tranId, auth, ref, errorNo, status, postdate, null);
321
		} catch (PaymentException e1) {
2334 chandransh 322
			log.error("Unable to update payment details in our database.", e1);
1905 chandransh 323
		} catch (TException e1) {
2334 chandransh 324
			log.error("Unable to update payment details in our database. Thrift exception.", e1);
1905 chandransh 325
		}
20112 aman.kumar 326
	}*/
719 rajveer 327
 
328
	public String getRedirectUrl(){
329
		return this.redirectUrl;
330
	}
331
 
332
	@Override
333
	public void setServletRequest(HttpServletRequest request) {
334
		this.request = request;
335
		for(Object param: request.getParameterMap().keySet()){
2334 chandransh 336
			log.info("PARAMS: " + param + " = "+ request.getParameter((String)param));
719 rajveer 337
		}
338
	}
1554 varun.gupt 339
}