Subversion Repositories SmartDukaan

Rev

Rev 6058 | Go to most recent revision | Details | Last modification | View Log | RSS feed

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