Subversion Repositories SmartDukaan

Rev

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

Rev Author Line No. Line
2391 chandransh 1
package in.shop2020.payment.service.handler;
2
 
3
import in.shop2020.config.ConfigException;
3010 chandransh 4
import in.shop2020.payment.domain.Payment;
2391 chandransh 5
import in.shop2020.thrift.clients.config.ConfigClient;
6
 
7
import java.io.BufferedReader;
8
import java.io.DataOutputStream;
9
import java.io.IOException;
10
import java.io.InputStreamReader;
11
import java.io.StringReader;
5364 mandeep.dh 12
import java.net.ConnectException;
2391 chandransh 13
import java.net.MalformedURLException;
14
import java.net.URL;
15
import java.net.URLConnection;
16
import java.net.URLEncoder;
17
import java.util.HashMap;
18
import java.util.Map;
19
import java.util.Map.Entry;
20
 
21
import javax.xml.xpath.XPath;
22
import javax.xml.xpath.XPathConstants;
23
import javax.xml.xpath.XPathExpressionException;
24
import javax.xml.xpath.XPathFactory;
25
 
26
import org.apache.log4j.Logger;
27
import org.w3c.dom.Element;
28
import org.w3c.dom.NodeList;
29
import org.xml.sax.InputSource;
30
 
3010 chandransh 31
public class EbsPaymentHandler implements IPaymentHandler {
2391 chandransh 32
 
33
	private static Logger log = Logger.getLogger(Class.class);
34
 
35
	public static final String TXN_ID = "transactionId";
36
	public static final String PAYMENT_ID = "paymentId";
37
	public static final String AMOUNT = "amount";
38
	public static final String DATE_TIME = "dateTime";
39
	public static final String MODE = "mode";
40
	public static final String REF_NO = "referenceNo";
41
	public static final String TXN_TYPE = "transactionType";
42
 
43
    private static String accountId;
44
    private static String secretKey;
45
 
46
	static{
47
		try {
48
			accountId = ConfigClient.getClient().get("ebs_account_id");
49
			secretKey = ConfigClient.getClient().get("ebs_secret_key");
50
		} catch (ConfigException e) {
51
			log.error("Unable to get EBS payment configuration.", e);
52
		}
53
	}
54
 
55
	/**
56
	 * Capture the amount which was authorized for this payment Id. Makes
57
	 * requests over the network and so internet connectivity is must for it to
58
	 * succeed.
59
	 * 
60
	 * @param amount
61
	 *            The amount to be captured. Must be the same value which was
62
	 *            authorized for this payment.
63
	 * @param paymentId
64
	 *            The payment ID generated by the gateway.
65
	 * @return A Map. The Map will definitely have status and will have error
66
	 *         information in case of error and txn information in case of
67
	 *         success. In case there is an error in processing, the returned
68
	 *         result map will be empty.
69
	 */
3010 chandransh 70
	public static Map<String, String> capturePayment(Payment payment){
71
	    double amount = payment.getAmount();
72
	    String paymentId = payment.getGatewayPaymentId();
2391 chandransh 73
		System.out.println("Capturing amount: Rs " + amount + " for payment Id: " + paymentId);
74
		URL url = null;
75
	    URLConnection urlConn = null;
76
	    DataOutputStream printout;
77
	    BufferedReader reader;
78
	    Map<String, String> resultMap = new HashMap<String, String>();
79
 
80
	    //Prepare resultMap to elicit failure behaviour in case anything goes wrong.
81
	    resultMap.put(STATUS, "");
82
 
83
		/*
84
		 * HDFC Insanity
85
		 * 
86
		 * If we don't set this property, all payments through HDFC will fail if
87
		 * the first payment is made through EBS.
88
		 * 
89
		 * The JAR file provided by HDFC requires that the instances of
90
		 * HttpsURLConnection returned by a call to URL.openConnection be an
91
		 * instance of com.sun.net.ssl.HttpsURLConnection. Java versions before
92
		 * 1.4 used to return an instance of this class which goes against the
93
		 * current policy of using instances of undocumented internal classes of
94
		 * JDK since they can change at any time. This behaviour was changed in
95
		 * JAVA 1.4 to return instances of javax.net.ssl.HttpsURLConnection.
96
		 * However, it appears, that to allow clients with JDK 1.4 and earlier,
97
		 * HDFC favours the use of the deprecated class.
98
		 */
13091 kshitij.so 99
	    System.setProperty("https.protocols", "TLSv1");
2391 chandransh 100
 
101
	    try {
102
		    // URL of CGI-Bin script.
11436 amit.gupta 103
			url = new URL("https://api.secure.ebs.in/api/1_0");
2391 chandransh 104
		    // URL connection channel.
105
		    urlConn = url.openConnection();
106
		    //urlConn.setRequestMethod("POST");
107
	    } catch (MalformedURLException e1) {
4421 mandeep.dh 108
	    	log.error(Errors.CAPTURE_FAILURE.message, e1);
109
			resultMap.put(ERR_CODE, Errors.CAPTURE_FAILURE.code);
110
			resultMap.put(ERROR, Errors.CAPTURE_FAILURE.message);
2391 chandransh 111
			return resultMap;
112
		} catch (IOException e) {
113
			log.error("Unable to initialize connection to EBS API server", e);
114
			resultMap.put(ERR_CODE, Errors.CONN_FAILURE.code);
115
			resultMap.put(ERROR, Errors.CONN_FAILURE.message);
116
			return resultMap;
117
		}
118
 
119
	    // Let the run-time system (RTS) know that we want input.
120
	    urlConn.setDoInput (true);
121
	    // Let the RTS know that we want to do output.
122
	    urlConn.setDoOutput (true);
123
	    // No caching, we want the real thing.
124
	    urlConn.setUseCaches (false);
125
	    // Specify the content type.
126
	    urlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
127
	    // Send POST output.
128
	    try {
129
			printout = new DataOutputStream (urlConn.getOutputStream ());
130
		    String content =
131
			    "Action=" + URLEncoder.encode("capture", "UTF-8") +
132
			    "&AccountID=" + URLEncoder.encode(accountId, "UTF-8") +
133
			    "&SecretKey=" + URLEncoder.encode(secretKey, "UTF-8") +
134
			    "&Amount=" + URLEncoder.encode(""+amount, "UTF-8") +
135
			    "&PaymentID=" + URLEncoder.encode(paymentId, "UTF-8") +
136
			    "&submitted=Submit";
137
		    printout.writeBytes (content);
138
		    printout.flush ();
139
		    printout.close ();
140
 
141
		    // Get response data.
142
		    reader = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
143
		    resultMap = parseCaptureOutput(reader);
144
		    reader.close ();
5364 mandeep.dh 145
	    }
146
	    catch(ConnectException e) {
147
            log.error("Unable to initialize connection to EBS API server", e);
148
            resultMap.put(ERR_CODE, Errors.CONN_FAILURE.code);
149
            resultMap.put(ERROR, Errors.CONN_FAILURE.message);
150
            return resultMap;
151
        } 
152
	    catch (IOException e) {
2391 chandransh 153
	    	log.error(Errors.CAPTURE_FAILURE.message, e);
154
			resultMap.clear();
155
			resultMap.put(STATUS, "");
156
			resultMap.put(ERR_CODE, Errors.CAPTURE_FAILURE.code);
157
			resultMap.put(ERROR, Errors.CAPTURE_FAILURE.message);
158
		}
5364 mandeep.dh 159
 
2391 chandransh 160
	    return resultMap;
161
	}
162
 
163
	/**
164
	 * Parses the given input stream and returns a map containing the
165
	 * transaction details
166
	 * 
167
	 * @param reader The reader containing the response of the capture request.
168
	 * @return A Map. The Map will definitely have status and will have error
169
	 *         information in case of error and txn information in case of
170
	 *         success.
171
	 */
172
	private static Map<String, String> parseCaptureOutput(BufferedReader reader){
173
		Map<String, String> resultMap = new HashMap<String, String>();
174
		resultMap.put(STATUS, "");
175
 
176
		String str = null;
177
		try {
178
			str = reader.readLine();
179
			log.info("Capture response: " + str);
180
		} catch (IOException e) {
181
			log.error("Error reading the capture response:", e);
182
			return resultMap;
183
		}
184
 
185
		InputSource inputSource = new InputSource(new StringReader(str));
186
		XPath xpath = XPathFactory.newInstance().newXPath();
187
		String expression = "/output";
188
		NodeList nodes = null;
189
		try {
190
			nodes = (NodeList) xpath.evaluate(expression, inputSource,	XPathConstants.NODESET);
191
		} catch(XPathExpressionException xpee) {
192
			log.error("Input couldn't be parsed. See capture response for more info.");
193
			return resultMap;
194
		}
195
 
196
		Element elem = (Element) nodes.item(0);
197
		String status = elem.getAttribute(STATUS);
198
		resultMap.put(STATUS, status);
199
		if("".equals(status) || !"Processing".equals(status)){
200
			//We've received an error. Retrieve the error values
201
			resultMap.put(ERR_CODE, elem.getAttribute(ERR_CODE));
202
			resultMap.put(ERROR, elem.getAttribute(ERROR));
203
		}else{
3010 chandransh 204
			resultMap.put(CAPTURE_TXN_ID, elem.getAttribute(TXN_ID));
2391 chandransh 205
			resultMap.put(PAYMENT_ID, elem.getAttribute(PAYMENT_ID));
206
			resultMap.put(AMOUNT, elem.getAttribute(AMOUNT));
3010 chandransh 207
			resultMap.put(CAPTURE_TIME, elem.getAttribute(DATE_TIME));
2391 chandransh 208
			resultMap.put(MODE, elem.getAttribute(MODE));
209
			resultMap.put(REF_NO, elem.getAttribute(REF_NO));
210
			resultMap.put(TXN_TYPE, elem.getAttribute(TXN_TYPE));
211
		}
212
 
213
		log.info("Parsed capture response:");
214
		for(Entry<String, String> entry : resultMap.entrySet()){
215
			log.info("Key: " + entry.getKey() + ", Value: " + entry.getValue());
216
		}
217
 
218
		return resultMap;
219
	}
6491 rajveer 220
 
221
	/**
222
	 * Refund the amount which was captured for this payment Id. Makes
223
	 * requests over the network and so internet connectivity is must for it to
224
	 * succeed.
225
	 * 
226
	 * @param amount
227
	 *            The amount to be refunded.
228
	 * @param paymentId
229
	 *            The payment ID generated by the gateway.
230
	 * @return A Map. The Map will definitely have status and will have error
231
	 *         information in case of error and txn information in case of
232
	 *         success. In case there is an error in processing, the returned
233
	 *         result map will be empty.
234
	 */
235
	public static Map<String, String> refundPayment(Payment payment, double amount){
236
	    String paymentId = payment.getGatewayPaymentId();
237
		System.out.println("Refunding amount: Rs " + amount + " for payment Id: " + paymentId);
238
		URL url = null;
239
	    URLConnection urlConn = null;
240
	    DataOutputStream printout;
241
	    BufferedReader reader;
242
	    Map<String, String> resultMap = new HashMap<String, String>();
243
 
244
	    //Prepare resultMap to elicit failure behaviour in case anything goes wrong.
245
	    resultMap.put(STATUS, "");
246
 
247
		/*
248
		 * HDFC Insanity
249
		 * 
250
		 * If we don't set this property, all payments through HDFC will fail if
251
		 * the first payment is made through EBS.
252
		 * 
253
		 * The JAR file provided by HDFC requires that the instances of
254
		 * HttpsURLConnection returned by a call to URL.openConnection be an
255
		 * instance of com.sun.net.ssl.HttpsURLConnection. Java versions before
256
		 * 1.4 used to return an instance of this class which goes against the
257
		 * current policy of using instances of undocumented internal classes of
258
		 * JDK since they can change at any time. This behaviour was changed in
259
		 * JAVA 1.4 to return instances of javax.net.ssl.HttpsURLConnection.
260
		 * However, it appears, that to allow clients with JDK 1.4 and earlier,
261
		 * HDFC favours the use of the deprecated class.
262
		 */
13091 kshitij.so 263
	    System.setProperty("https.protocols", "TLSv1");
6491 rajveer 264
 
265
	    try {
266
		    // URL of CGI-Bin script.
11436 amit.gupta 267
			url = new URL("https://api.secure.ebs.in/api/1_0");
6491 rajveer 268
		    // URL connection channel.
269
		    urlConn = url.openConnection();
270
		    //urlConn.setRequestMethod("POST");
271
	    } catch (MalformedURLException e1) {
272
	    	log.error(Errors.CAPTURE_FAILURE.message, e1);
273
			resultMap.put(ERR_CODE, Errors.CAPTURE_FAILURE.code);
274
			resultMap.put(ERROR, Errors.CAPTURE_FAILURE.message);
275
			return resultMap;
276
		} catch (IOException e) {
277
			log.error("Unable to initialize connection to EBS API server", e);
278
			resultMap.put(ERR_CODE, Errors.CONN_FAILURE.code);
279
			resultMap.put(ERROR, Errors.CONN_FAILURE.message);
280
			return resultMap;
281
		}
282
 
283
	    // Let the run-time system (RTS) know that we want input.
284
	    urlConn.setDoInput (true);
285
	    // Let the RTS know that we want to do output.
286
	    urlConn.setDoOutput (true);
287
	    // No caching, we want the real thing.
288
	    urlConn.setUseCaches (false);
289
	    // Specify the content type.
290
	    urlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
291
	    // Send POST output.
292
	    try {
293
			printout = new DataOutputStream (urlConn.getOutputStream ());
294
		    String content =
295
			    "Action=" + URLEncoder.encode("refund", "UTF-8") +
296
			    "&AccountID=" + URLEncoder.encode(accountId, "UTF-8") +
297
			    "&SecretKey=" + URLEncoder.encode(secretKey, "UTF-8") +
298
			    "&Amount=" + URLEncoder.encode(""+amount, "UTF-8") +
299
			    "&PaymentID=" + URLEncoder.encode(paymentId, "UTF-8") +
300
			    "&submitted=Submit";
301
		    printout.writeBytes (content);
302
		    printout.flush ();
303
		    printout.close ();
304
 
305
		    // Get response data.
306
		    reader = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
307
		    resultMap = parseCaptureOutput(reader);
308
		    resultMap.put(REFUND_TXN_ID, resultMap.get(CAPTURE_TXN_ID));
309
		    resultMap.put(REFUND_TIME, resultMap.get(CAPTURE_TIME));
310
		    resultMap.remove(CAPTURE_TXN_ID);
311
		    resultMap.remove(CAPTURE_TIME);
312
		    reader.close ();
313
	    }
314
	    catch(ConnectException e) {
315
            log.error("Unable to initialize connection to EBS API server", e);
316
            resultMap.put(ERR_CODE, Errors.CONN_FAILURE.code);
317
            resultMap.put(ERROR, Errors.CONN_FAILURE.message);
318
            return resultMap;
319
        } 
320
	    catch (IOException e) {
321
	    	log.error(Errors.CAPTURE_FAILURE.message, e);
322
			resultMap.clear();
323
			resultMap.put(STATUS, "");
324
			resultMap.put(ERR_CODE, Errors.CAPTURE_FAILURE.code);
325
			resultMap.put(ERROR, Errors.CAPTURE_FAILURE.message);
326
		}
327
 
328
	    return resultMap;
329
	}
330
 
2391 chandransh 331
	public static void main(String[] args){
13091 kshitij.so 332
	    Payment p = new Payment();
333
	    p.setGatewayPaymentId("30573297");
334
	    p.setAmount(20);
335
 
336
	    capturePayment(p);
2391 chandransh 337
	}
338
}