Subversion Repositories SmartDukaan

Rev

Rev 6058 | Details | Compare with Previous | 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;
6058 anupam.sin 4
import in.shop2020.model.v1.order.RechargeOrder;
6050 anupam.sin 5
import in.shop2020.model.v1.order.RechargeOrderStatus;
6
import in.shop2020.model.v1.order.TransactionServiceException;
7
import in.shop2020.payments.Attribute;
8
import in.shop2020.payments.Payment;
9
import in.shop2020.payments.PaymentException;
10
import in.shop2020.payments.PaymentService.Client;
11
import in.shop2020.payments.PaymentStatus;
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
 
6058 anupam.sin 21
import org.apache.log4j.Logger;
6050 anupam.sin 22
import org.apache.struts2.interceptor.ServletRequestAware;
23
import org.apache.thrift.TException;
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();
6058 anupam.sin 136
            RechargeOrder rechargeOrder = transactionServiceClient.getClient().getRechargeOrdersForTransaction(txnId);
6050 anupam.sin 137
            if(!validatePaymentParams(paymentId, amount, udf5, payment))
138
                return "index";
139
 
6138 rajveer 140
            if (result != null && result.trim().equals(PaymentReturnStatus.CAPTURED.value())) {
141
                log.info("Payment " + merchantPaymentId + " captured successfully. Updating the database.");
142
                String description = "Payment captured";
143
                updatePaymentDetails(merchantPaymentId, description, PaymentStatus.SUCCESS, request, paymentClient);
6058 anupam.sin 144
                transactionServiceClient.getClient().updateRechargeOrderStatus(rechargeOrder.getId(), RechargeOrderStatus.PAYMENT_SUCCESSFUL);
6050 anupam.sin 145
                this.redirectUrl = successUrl + "?paymentId=" + merchantPaymentId;
146
            } else {
147
                updatePaymentDetails(merchantPaymentId, errorText, PaymentStatus.FAILED, request, paymentClient);
6058 anupam.sin 148
                transactionServiceClient.getClient().updateRechargeOrderStatus(rechargeOrder.getId(), RechargeOrderStatus.PAYMENT_FAILED);
6050 anupam.sin 149
 
150
                this.redirectUrl = errorUrl + "?paymentId=" + merchantPaymentId;
151
            }
152
        } catch (PaymentException e1) {
153
            log.error("Payment exception. It is serious, check merchant payment id + " + merchantPaymentId, e1);
154
        } catch (TException e1) {
155
            log.error("Thrift exception. Check payment id "+ merchantPaymentId, e1);
156
        } catch (TransactionServiceException e) {
157
            // TODO Auto-generated catch block
158
            e.printStackTrace();
159
        }
160
 
161
        return "index";
162
    }
163
 
164
    private boolean validatePaymentParams(String paymentId, String amount, String udf5, Payment payment) {
165
        long merchantPaymentId = payment.getPaymentId();
166
        String dbUdf5="";
167
        double dbAmount = payment.getAmount();
168
        for(Attribute attribute: payment.getAttributes()){
169
            if(attribute.getName().trim().equalsIgnoreCase(UDF5)){
170
                dbUdf5 = attribute.getValue();
171
            }
172
        }
173
        // verify 3 things:  udf5, amount and paymentid
174
        //FIXME should we first dump the data and then verify these things. ?? 
175
        double returnedAmount = Double.parseDouble(amount);
176
        log.info(paymentId+ ":"+ payment.getGatewayPaymentId() + "\n" + returnedAmount + ":" + dbAmount + "\n" + dbUdf5 + ":" + udf5 );
177
        if(!(paymentId.equalsIgnoreCase(payment.getGatewayPaymentId()) && (Math.abs(dbAmount - returnedAmount) <= 0.50) && udf5.equalsIgnoreCase(dbUdf5))){
178
            log.error("Checks and balance failed on returned data");
179
            this.redirectUrl =  errorUrl + "?paymentId="+merchantPaymentId;
180
            return false;
181
        }
182
        return true;
183
    }
184
 
185
    private void updatePaymentDetails(long merchantPaymentId, String message, PaymentStatus status, HttpServletRequest req, Client paymentClient) {
186
        String paymentId = request.getParameter(PAYMENTID);
187
        String result = request.getParameter(RESULT);
188
        String postdate = request.getParameter(POSTDATE);
189
        String tranId = request.getParameter(TRANID);
190
        String auth = request.getParameter(AUTH);
191
        String ref = request.getParameter(REF);
192
 
193
        String sessionId = request.getSession().getId();
194
        String errorNo = request.getParameter(ERROR);
195
        try {
196
            paymentClient.updatePaymentDetails(merchantPaymentId, paymentId, sessionId, result, message, tranId, auth, ref, errorNo, status, postdate, null);
197
        } catch (PaymentException e1) {
198
            log.error("Unable to update payment details in our database.", e1);
199
        } catch (TException e1) {
200
            log.error("Unable to update payment details in our database. Thrift exception.", e1);
201
        }
202
    }
203
 
204
    public String getRedirectUrl(){
205
        return this.redirectUrl;
206
    }
207
 
208
    @Override
209
    public void setServletRequest(HttpServletRequest request) {
210
        this.request = request;
211
        for(Object param: request.getParameterMap().keySet()){
212
            log.info("PARAMS: " + param + " = "+ request.getParameter((String)param));
213
        }
214
    }
215
}