Subversion Repositories SmartDukaan

Rev

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

Rev Author Line No. Line
1946 chandransh 1
package in.shop2020.payment.service.handler;
2
 
3578 mandeep.dh 3
import in.shop2020.payment.domain.Refund;
4
import in.shop2020.payment.handler.PaymentGatewayHandler;
5
import in.shop2020.payment.handler.PaymentHandler;
4008 mandeep.dh 6
import in.shop2020.payment.handler.PaymentRequiringExtraProcessingHandler;
3578 mandeep.dh 7
import in.shop2020.payment.handler.RefundHandler;
8
import in.shop2020.payments.Attribute;
4008 mandeep.dh 9
import in.shop2020.payments.ExtraPaymentProcessingType;
3578 mandeep.dh 10
import in.shop2020.payments.Payment;
11
import in.shop2020.payments.PaymentException;
12
import in.shop2020.payments.PaymentGateway;
13
import in.shop2020.payments.PaymentService.Iface;
14
import in.shop2020.payments.PaymentStatus;
15
 
3010 chandransh 16
import java.text.SimpleDateFormat;
1946 chandransh 17
import java.util.ArrayList;
18
import java.util.Date;
19
import java.util.HashMap;
20
import java.util.List;
21
import java.util.Map;
22
 
23
import org.apache.thrift.TException;
3010 chandransh 24
import org.slf4j.Logger;
25
import org.slf4j.LoggerFactory;
1946 chandransh 26
import org.springframework.context.ApplicationContext;
27
import org.springframework.context.support.ClassPathXmlApplicationContext;
28
 
29
public class PaymentServiceHandler implements Iface {
3010 chandransh 30
 
31
    private static Logger logger = LoggerFactory.getLogger(PaymentServiceHandler.class);
32
 
33
    /**
34
     * Enum of all statuses that can be returned by the HDFC gateway
35
     * 
36
     * @author Chandranshu
37
     * 
38
     */
39
    private enum HdfcPaymentReturnStatus{
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
        HdfcPaymentReturnStatus(String value) {
49
            this.value = value;
50
        }
51
        public String value(){
52
            return this.value;
53
        }
54
    }
55
 
2391 chandransh 56
	public static final long PAYMENT_NOT_CREATED = -1;
57
 
3010 chandransh 58
	private static final long HDFC_GATEWAY_ID = 1;
59
	private static final long EBS_GATEWAY_ID = 2;
3583 chandransh 60
	private static final long HDFC_EMI_GATEWAY_ID = 5;
3010 chandransh 61
 
4651 rajveer 62
	ApplicationContext context = new ClassPathXmlApplicationContext("context.xml");
1946 chandransh 63
	PaymentHandler paymentHandler = (PaymentHandler) context.getBean("paymentHandler");
4008 mandeep.dh 64
    PaymentRequiringExtraProcessingHandler paymentRequiringExtraProcessingHandler =
65
        (PaymentRequiringExtraProcessingHandler) context.getBean("paymentRequiringExtraProcessingHandler");
66
 
67
    PaymentGatewayHandler paymentGatewayHandler = (PaymentGatewayHandler) context.getBean("paymentGatewayHandler");
2747 chandransh 68
	RefundHandler refundHandler = (RefundHandler) context.getBean("refundHandler");
1946 chandransh 69
 
4651 rajveer 70
	public void setDataSourceUrl(String dbHost){
71
		org.apache.commons.dbcp.BasicDataSource ds = (org.apache.commons.dbcp.BasicDataSource)context.getBean("dataSource");
72
		ds.setUrl(dbHost);
73
	}
74
 
75
	public String getDataSourceUrl(){
76
		org.apache.commons.dbcp.BasicDataSource ds = (org.apache.commons.dbcp.BasicDataSource)context.getBean("dataSource");
77
		return ds.getUrl();
78
	}
79
 
1946 chandransh 80
	@Override
81
	public long createPayment(long userId, double amount, long gatewayId, long txnId) throws PaymentException, TException {
3010 chandransh 82
	    logger.info("Creating payment corresponding to our txn id:" + txnId);
1946 chandransh 83
		in.shop2020.payment.domain.Payment payment = new in.shop2020.payment.domain.Payment();
84
		payment.setUserId(userId);
85
		payment.setAmount(amount);
86
		payment.setGatewayId(gatewayId);
87
		payment.setMerchantTxnId(txnId);
88
		payment.setStatus(PaymentStatus.INIT.getValue());
89
 
90
		return paymentHandler.insertPayment(payment);
91
	}
92
 
93
	@Override
94
	public List<Payment> getPaymentsForUser(long userId, long fromTime, long toTime, PaymentStatus status, long gatewayId) throws PaymentException, TException {
3010 chandransh 95
	    logger.info("Getting payments from " + fromTime + " to " + toTime + " for user: " + userId);
2291 chandransh 96
		int statusValue = -1;
97
		if(status != null)
98
			statusValue = status.getValue();
99
		else
100
			statusValue = -1;
101
		return getThriftPayments(paymentHandler.getPaymentsForUser(userId, fromTime, toTime, statusValue, gatewayId));
1946 chandransh 102
	}
103
 
104
	@Override
105
	public List<Payment> getPayments(long fromTime, long toTime, PaymentStatus status, long gatewayId) throws PaymentException,	TException {
3010 chandransh 106
	    logger.info("Getting payments from " + fromTime + " to " + toTime);
2291 chandransh 107
		int statusValue = -1;
108
		if(status != null)
109
			statusValue = status.getValue();
110
		else
111
			statusValue = -1;
112
		return getThriftPayments(paymentHandler.getPayments(fromTime, toTime, statusValue, gatewayId));
1946 chandransh 113
	}
4141 chandransh 114
 
115
	@Override
116
	public List<Payment> getPaymentsByCapturedDate(long fromTime, long toTime, long gatewayId) throws PaymentException, TException {
117
		logger.info("Getting payments from " + fromTime + " to " + toTime + " for " + gatewayId);
118
		return getThriftPayments(paymentHandler.getPaymentsByCapturedDate(fromTime, toTime, gatewayId));
119
	}
1946 chandransh 120
 
121
	@Override
122
	public PaymentGateway getPaymentGateway(long id) throws PaymentException, TException {
3010 chandransh 123
	    logger.info("Getting payment gateway with id:" + id);
2291 chandransh 124
		return paymentGatewayHandler.getPaymentGateway(id).getThriftPaymentGateway();
1946 chandransh 125
	}
4600 varun.gupt 126
 
1946 chandransh 127
	@Override
4600 varun.gupt 128
	public List<PaymentGateway> getActivePaymentGateways() throws PaymentException, TException {
129
	    logger.info("Getting all active payment gateways");
130
	    return getThriftPaymentGateways(paymentGatewayHandler.getActivePaymentGateways());
131
	}
132
 
133
	@Override
1946 chandransh 134
	public Payment getPayment(long id) throws PaymentException, TException {
3010 chandransh 135
	    logger.info("Getting payment with id: " + id);
1946 chandransh 136
		return paymentHandler.getPayment(id).getThriftPayment();
137
	}
138
 
139
	@Override
140
	public List<Payment> getPaymentForTxnId(long txnId) throws PaymentException, TException {
3010 chandransh 141
	    logger.info("Getting payment for the txn id: " + txnId);
1946 chandransh 142
		return getThriftPayments(paymentHandler.getPaymentForTxn(txnId));
143
	}
4600 varun.gupt 144
 
145
	@Override
146
	public Payment getSuccessfulPaymentForTxnId(long txnId) throws PaymentException, TException {
147
 
148
		for (Payment payment: getPaymentForTxnId(txnId))	{
149
			if (payment.getStatus() == PaymentStatus.SUCCESS || payment.getStatus() == PaymentStatus.PARTIALLY_CAPTURED)	{
150
				return payment;
151
			}
152
		}
153
		return null;
154
	}
1946 chandransh 155
 
156
	@Override
157
	public boolean updatePaymentDetails(long id, String gatewayPaymentId,
158
			String sessionId, String gatewayTxnStatus, String description,
159
			String gatewayTxnId, String authCode, String referenceCode,
160
			String errorCode, PaymentStatus status, String gatewayTxnDate,
161
			List<Attribute> attributes) throws PaymentException, TException {
3010 chandransh 162
	    logger.info("Updating details of payment id: " + id);
1946 chandransh 163
		in.shop2020.payment.domain.Payment payment = paymentHandler.getPayment(id);
164
		payment.setGatewayPaymentId(gatewayPaymentId);
165
		payment.setSessionId(sessionId);
166
		payment.setGatewayTxnStatus(gatewayTxnStatus);
167
		payment.setDescription(description);
168
		payment.setGatewayTxnId(gatewayTxnId);
169
		payment.setAuthCode(authCode);
170
		payment.setReferenceCode(referenceCode);
171
		payment.setErrorCode(errorCode);
172
		if(status!=null){
173
			payment.setStatus(status.getValue());
174
			if(status.equals(PaymentStatus.SUCCESS))
175
				payment.setSuccessTimestamp(new Date());
3578 mandeep.dh 176
			else if(status.equals(PaymentStatus.FAILED)) {
177
			    payment.setErrorTimestamp(new Date());
4421 mandeep.dh 178
			    persistPaymentRequiringExtraProcessing(payment, ExtraPaymentProcessingType.FAILED_PAYMENTS);
3578 mandeep.dh 179
			}
4421 mandeep.dh 180
			else if (status.equals(PaymentStatus.PROVISIONALLY_CAPTURED)) {
181
			    // FIXME different column to note provisional capture timestamp
182
			    // FIXME Requires extra processing at Crm end for actual manual capture
183
			    payment.setProvisionalCaptureTimestamp(new Date());
184
			    persistPaymentRequiringExtraProcessing(payment, ExtraPaymentProcessingType.PENDING_CAPTURE);
185
			}
1946 chandransh 186
		}
187
 
188
		payment.setGatewayTxnDate(gatewayTxnDate);
189
 
190
		Map<String, String> attrMap = new HashMap<String, String>();
2272 rajveer 191
		if(attributes != null){
192
			for(Attribute attribute : attributes){
193
				attrMap.put(attribute.getName(), attribute.getValue());
194
			}
1946 chandransh 195
		}
196
 
197
		paymentHandler.updatePayment(payment, attrMap);
198
		return true;
199
	}
200
 
3649 mandeep.dh 201
	/**
4008 mandeep.dh 202
	 * Persists a given payment Id in another table for future processing by CRM etc.
203
	 * Failed payments generally require a follow-up to help customers through our
204
	 * CRM-Outbound team.
3649 mandeep.dh 205
	 *
206
	 * @param payment  the payment object that failed.
4421 mandeep.dh 207
	 * @param type TODO
3649 mandeep.dh 208
	 */
4421 mandeep.dh 209
	private void persistPaymentRequiringExtraProcessing(in.shop2020.payment.domain.Payment payment, ExtraPaymentProcessingType type) {
4008 mandeep.dh 210
	    try {
4421 mandeep.dh 211
            paymentRequiringExtraProcessingHandler.insert(payment.getId(), type);
4008 mandeep.dh 212
        } catch (Exception e) {
213
            logger.error("Could not persist payment: " + payment.getId(), e);
3578 mandeep.dh 214
        }
215
    }
216
 
217
    @Override
1946 chandransh 218
	public List<Double> getSuccessfulPaymentsAmountRange() throws TException {
3010 chandransh 219
	    logger.info("Getting the range of successful payments.");
1946 chandransh 220
		List<Double> minMaxAmounts = new ArrayList<Double>();
221
		Map<String, Float> minMax = paymentHandler.getMinMaxPaymentAmount();
222
		minMaxAmounts.add(Double.parseDouble(Float.toString(minMax.get("MIN"))));
223
		minMaxAmounts.add(Double.parseDouble(Float.toString(minMax.get("MAX"))));
224
		return minMaxAmounts;
225
	}
226
 
2391 chandransh 227
	@Override
228
	public String initializeHdfcPayment(long merchantPaymentId) throws PaymentException, TException {
3010 chandransh 229
	    logger.info("Initializing HDFC payment with id: " + merchantPaymentId);
2391 chandransh 230
		in.shop2020.payment.domain.Payment payment = paymentHandler.getPayment(merchantPaymentId);
231
		String redirectURL;
232
		try {
233
			redirectURL = HdfcPaymentHandler.initializeHdfcPayment(payment, this);
234
		} catch (Exception e) {
235
			throw new PaymentException(102, "Error while initiliazing payment. Check service log for more details.");
236
		}
237
		return redirectURL;
238
	}
239
 
240
	@Override
3616 chandransh 241
    public String initializeHdfcEmiPayment(long merchantPaymentId) throws PaymentException, TException {
242
        logger.info("Initializing HDFC payment with id: " + merchantPaymentId);
243
        in.shop2020.payment.domain.Payment payment = paymentHandler.getPayment(merchantPaymentId);
244
        String redirectURL;
245
        try {
246
            redirectURL = HdfcEmiPaymentHandler.initializeHdfcPayment(payment, this);
247
        } catch (Exception e) {
248
            throw new PaymentException(102, "Error while initiliazing payment. Check service log for more details.");
249
        }
250
        return redirectURL;
251
    }
252
 
253
	@Override
2689 chandransh 254
    public long createRefund(long orderId, long merchantTxnId, double amount) throws PaymentException, TException{
3010 chandransh 255
	    logger.info("Attempting to create a refund for order: " + orderId);
2689 chandransh 256
		List<in.shop2020.payment.domain.Payment> payments = paymentHandler.getPaymentForTxn(merchantTxnId);
257
		if(payments ==null || payments.isEmpty())
258
			throw new PaymentException(104, "No payments found corresponding to the merchant txn " + merchantTxnId);
259
 
3010 chandransh 260
		in.shop2020.payment.domain.Payment payment = payments.get(0);
2689 chandransh 261
		if(payment.getStatus() != PaymentStatus.SUCCESS.getValue())
262
			throw new PaymentException(104, "No successful payments found corresponding to the merchant txn " + merchantTxnId);
263
 
2747 chandransh 264
		Refund refund = new Refund();
265
		refund.setOrderId(orderId);
266
		refund.setPaymentId(payment.getId());
267
		refund.setGatewayId(payment.getGatewayId());
268
		refund.setAmount(amount);
269
		refund.setAttempts(0);
270
		return refundHandler.createRefund(refund);
2689 chandransh 271
    }
272
 
3010 chandransh 273
    @Override
4253 mandeep.dh 274
    public synchronized boolean capturePayment(long merchantTxnId) throws PaymentException, TException {
3010 chandransh 275
        logger.info("Attempting to capture payment corresponding to our transaction " + merchantTxnId);
276
        List<in.shop2020.payment.domain.Payment> payments = paymentHandler.getPaymentForTxn(merchantTxnId);
277
        if(payments ==null || payments.isEmpty())
278
            throw new PaymentException(104, "No payments found corresponding to the merchant txn " + merchantTxnId);
279
 
280
        in.shop2020.payment.domain.Payment payment = payments.get(0);
281
        switch(PaymentStatus.findByValue(payment.getStatus())){
282
        case PENDING:
283
            logger.error("Attempt to capture a non-authorized payment");
284
            return false;
285
        case INIT:
286
            logger.warn("Attempt to capture a non-authorized payment");
287
            return false;
288
        case AUTHORIZED:
4421 mandeep.dh 289
        case CAPTURE_IN_PROCESS:
3010 chandransh 290
            //Actual work to be done in this case. Let the call proceed.
291
            break;
4421 mandeep.dh 292
        case PROVISIONALLY_CAPTURED:
293
            logger.info("Attempting to capture a payment that is provisonally captured but we can let the client proceed.");
294
            return true;
3010 chandransh 295
        case SUCCESS:
296
            logger.warn("Attempting to capture an already captured payment but we can let the client proceed.");
297
            return true;
298
        case FAILED:
299
            logger.error("Attempting to capture a failed payment");
300
            return false;
301
        }
302
 
303
        long gatewayId = payment.getGatewayId();
304
 
305
        if(gatewayId == HDFC_GATEWAY_ID){
306
            //Capture and update the HDFC payment
307
            return captureAndUpdateHdfcPayment(payment);
308
        } else if (gatewayId == EBS_GATEWAY_ID){
309
            //Capture and update the EBS payment
310
            return captureAndUpdateEbsPayment(payment);
3583 chandransh 311
        } else if (gatewayId == HDFC_EMI_GATEWAY_ID){
312
            //Capture and update the HDFC EMI payment
313
            return captureAndUpdateHdfcEmiPayment(payment);
3010 chandransh 314
        }
315
 
316
        logger.error("We have an authorized payment from unknown gateway: " + gatewayId);
317
        return false;
318
    }
319
 
3956 chandransh 320
    @Override
321
    public boolean partiallyCapturePayment(long merchantTxnId, double amount, String xferBy, String xferTxnId, long xferDate) throws PaymentException, TException {
322
        logger.info("Attempting to partially capture payment corresponding to our transaction " + merchantTxnId);
323
        List<in.shop2020.payment.domain.Payment> payments = paymentHandler.getPaymentForTxn(merchantTxnId);
324
        if(payments ==null || payments.isEmpty())
325
            throw new PaymentException(104, "No payments found corresponding to the merchant txn " + merchantTxnId);
326
 
327
        in.shop2020.payment.domain.Payment payment = payments.get(0);
328
        switch(PaymentStatus.findByValue(payment.getStatus())){
329
        case PENDING:
330
            // COD payments lie in this state before settlement.
331
        case INIT:
332
        case PARTIALLY_CAPTURED:
333
        case AUTHORIZED:
334
            // COD payments would not be in this state but we are processing
335
            // payments in this state as well for forward compatibility since
336
            // someday we'd want to be able to capture authorized CC payments
337
            // partially.
338
            break;
339
        case SUCCESS:
340
            logger.warn("Attempting to capture an already captured payment but we can let the client proceed.");
341
            return true;
342
        case FAILED:
343
            logger.error("Attempting to capture a failed payment");
344
            return false;
345
        }
346
        SimpleDateFormat mysqlDateFormatter = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
347
        String xferDateStr = mysqlDateFormatter.format(new Date(xferDate));
348
 
349
        return settleAndUpdateCodPayment(payment, amount, xferBy, xferTxnId, xferDateStr);
350
    }
351
 
3010 chandransh 352
    /**
353
     * Capture the HDFC payment represented by the given payment object. If the
354
     * capture attempt is not successful, we mark this payment as failed. We
355
     * don't retry or anything. We'll add the support of multiple attempts later
356
     * on.
357
     * 
358
     * @param payment The payment which has to be captured.
359
     * @return True if the payment attempt is successful, false if not.
4421 mandeep.dh 360
     * @throws PaymentException 
3010 chandransh 361
     */
4421 mandeep.dh 362
    private boolean captureAndUpdateHdfcPayment(in.shop2020.payment.domain.Payment payment) throws PaymentException {
3010 chandransh 363
        long merchantPaymentId = payment.getId();
364
        logger.info("Capturing HDFC payment with id: " + merchantPaymentId);
365
        Map<String, String> captureResult = HdfcPaymentHandler.capturePayment(payment);
366
        String captureStatus = captureResult.get(IPaymentHandler.STATUS);
367
        String gatewayStatus = captureResult.get(IPaymentHandler.GATEWAY_STATUS);
368
 
369
        Map<String, String> attrMap = new HashMap<String, String>();
370
        if (!captureStatus.trim().equals("0") 
371
                || !HdfcPaymentReturnStatus.CAPTURED.value().equals(gatewayStatus)) {
372
            // Failure
3616 chandransh 373
            logger.error("Capture attempt failed for HDFC payment with id: " + merchantPaymentId);
3010 chandransh 374
            String description = captureResult.get(IPaymentHandler.ERROR);
375
            String errorCode = captureResult.get(IPaymentHandler.ERR_CODE);
376
 
377
            payment.setDescription(description);
378
            payment.setErrorCode(errorCode);
379
            payment.setErrorTimestamp(new Date());
4421 mandeep.dh 380
 
381
            if (IPaymentHandler.Errors.CONN_FAILURE.code.equals(errorCode)) {
382
                payment.setStatus(PaymentStatus.CAPTURE_IN_PROCESS.getValue());
383
                paymentHandler.updatePayment(payment, attrMap);
384
                throw new PaymentException(106, "Could not capture due to connection issue");
385
            }
386
            else {
387
                payment.setStatus(PaymentStatus.FAILED.getValue());
388
                paymentHandler.updatePayment(payment, attrMap);
389
                persistPaymentRequiringExtraProcessing(payment, ExtraPaymentProcessingType.FAILED_PAYMENTS);
390
            }
391
 
3010 chandransh 392
            return false;
393
        } else {
394
            // Success
3616 chandransh 395
            logger.info("Capture attempt successful for HDFC payment with id: " + merchantPaymentId);
3010 chandransh 396
            payment.setDescription("Payment Captured");
397
            payment.setGatewayTxnStatus(gatewayStatus);
398
            payment.setStatus(PaymentStatus.SUCCESS.getValue());
399
            payment.setSuccessTimestamp(new Date());           
400
 
401
            attrMap.put(IPaymentHandler.CAPTURE_TXN_ID, captureResult.get(IPaymentHandler.CAPTURE_TXN_ID));
402
            attrMap.put(IPaymentHandler.CAPTURE_REF_ID, captureResult.get(IPaymentHandler.CAPTURE_REF_ID));
403
            attrMap.put(IPaymentHandler.CAPTURE_AUTH_ID, captureResult.get(IPaymentHandler.CAPTURE_AUTH_ID));
404
 
405
            SimpleDateFormat captureTimeDateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
406
            attrMap.put(HdfcPaymentHandler.CAPTURE_TIME, captureTimeDateFormatter.format(new Date()));
407
 
408
            paymentHandler.updatePayment(payment, attrMap);
409
            return true;
410
          }
411
    }
412
 
413
    /**
3583 chandransh 414
     * Capture the HDFC EMI payment represented by the given payment object. If
415
     * the capture attempt is not successful, we mark this payment as failed. We
416
     * don't retry or anything. We'll add the support of multiple attempts later
417
     * on.
418
     * 
419
     * @param payment
420
     *            The payment which has to be captured.
421
     * @return True if the payment attempt is successful, false if not.
4421 mandeep.dh 422
     * @throws PaymentException 
3583 chandransh 423
     */
4421 mandeep.dh 424
    private boolean captureAndUpdateHdfcEmiPayment(in.shop2020.payment.domain.Payment payment) throws PaymentException{
3583 chandransh 425
        long merchantPaymentId = payment.getId();
426
        logger.info("Capturing HDFC payment with id: " + merchantPaymentId);
427
        Map<String, String> captureResult = HdfcEmiPaymentHandler.capturePayment(payment);
428
        String captureStatus = captureResult.get(IPaymentHandler.STATUS);
429
        String gatewayStatus = captureResult.get(IPaymentHandler.GATEWAY_STATUS);
430
 
431
        Map<String, String> attrMap = new HashMap<String, String>();
432
        if (!captureStatus.trim().equals("0") 
433
                || !HdfcPaymentReturnStatus.CAPTURED.value().equals(gatewayStatus)) {
434
            // Failure
3616 chandransh 435
            logger.error("Capture attempt failed for HDFC payment with id: " + merchantPaymentId);
3583 chandransh 436
            String description = captureResult.get(IPaymentHandler.ERROR);
437
            String errorCode = captureResult.get(IPaymentHandler.ERR_CODE);
438
 
439
            payment.setDescription(description);
440
            payment.setErrorCode(errorCode);
4421 mandeep.dh 441
            payment.setErrorTimestamp(new Date());                
442
 
443
            // Not marking payments as failed in case of connection issues
444
            if (IPaymentHandler.Errors.CONN_FAILURE.code.equals(errorCode)) {
445
                payment.setStatus(PaymentStatus.CAPTURE_IN_PROCESS.getValue());
446
                paymentHandler.updatePayment(payment, attrMap);
447
                throw new PaymentException(106, "Could not capture due to connection issue");
448
            }
449
            else {
450
                payment.setStatus(PaymentStatus.FAILED.getValue());
451
                paymentHandler.updatePayment(payment, attrMap);
452
                persistPaymentRequiringExtraProcessing(payment, ExtraPaymentProcessingType.FAILED_PAYMENTS);
453
            }
454
 
3583 chandransh 455
            return false;
456
        } else {
457
            // Success
3616 chandransh 458
            logger.info("Capture attempt successful for HDFC payment with id: " + merchantPaymentId);
3583 chandransh 459
            payment.setDescription("Payment Captured");
460
            payment.setGatewayTxnStatus(gatewayStatus);
461
            payment.setStatus(PaymentStatus.SUCCESS.getValue());
4421 mandeep.dh 462
            payment.setSuccessTimestamp(new Date());
3583 chandransh 463
 
464
            attrMap.put(IPaymentHandler.CAPTURE_TXN_ID, captureResult.get(IPaymentHandler.CAPTURE_TXN_ID));
465
            attrMap.put(IPaymentHandler.CAPTURE_REF_ID, captureResult.get(IPaymentHandler.CAPTURE_REF_ID));
466
            attrMap.put(IPaymentHandler.CAPTURE_AUTH_ID, captureResult.get(IPaymentHandler.CAPTURE_AUTH_ID));
467
 
468
            SimpleDateFormat captureTimeDateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
469
            attrMap.put(HdfcPaymentHandler.CAPTURE_TIME, captureTimeDateFormatter.format(new Date()));
470
 
471
            paymentHandler.updatePayment(payment, attrMap);
472
            return true;
473
          }
474
    }
475
 
476
    /**
3010 chandransh 477
     * Capture the EBS payment represented by the given payment object. If the
478
     * capture attempt is not successful, we mark this payment as failed. We
479
     * don't retry or anything. We'll add the support of multiple attempts later
480
     * on.
481
     * 
482
     * @param payment The payment which has to be captured.
483
     * @return True if the payment attempt is successful, false if not.
4421 mandeep.dh 484
     * @throws PaymentException 
3010 chandransh 485
     */
4421 mandeep.dh 486
    private boolean captureAndUpdateEbsPayment(in.shop2020.payment.domain.Payment payment) throws PaymentException{
3010 chandransh 487
        Map<String, String> captureResult = EbsPaymentHandler.capturePayment(payment);
488
        String captureStatus = captureResult.get(EbsPaymentHandler.STATUS);
489
 
490
        Map<String, String> attrMap = new HashMap<String, String>();
491
        if("".equals(captureStatus)){
492
            //Failure
3616 chandransh 493
            logger.error("Capture attempt failed for EBS payment with id: " + payment.getId());
3010 chandransh 494
            String description = captureResult.get(EbsPaymentHandler.ERROR);
495
            String errorCode = captureResult.get(EbsPaymentHandler.ERR_CODE);
4421 mandeep.dh 496
 
3010 chandransh 497
            payment.setDescription(description);
498
            payment.setErrorCode(errorCode);
499
            payment.setErrorTimestamp(new Date());
4421 mandeep.dh 500
 
501
            if (IPaymentHandler.Errors.CONN_FAILURE.code.equals(errorCode)) {
502
                payment.setStatus(PaymentStatus.CAPTURE_IN_PROCESS.getValue());            
503
                paymentHandler.updatePayment(payment, attrMap);
504
                throw new PaymentException(106, "Could not capture due to connection issue");
505
            }
506
            else {
507
                payment.setStatus(PaymentStatus.FAILED.getValue());            
508
                paymentHandler.updatePayment(payment, attrMap);
509
                persistPaymentRequiringExtraProcessing(payment, ExtraPaymentProcessingType.FAILED_PAYMENTS);
510
            }
511
 
3010 chandransh 512
            return false;
513
        }else{
514
            //Success
3616 chandransh 515
            logger.info("Capture attempt successful for EBS payment with id: " + payment.getId());
3010 chandransh 516
            payment.setGatewayTxnStatus(captureStatus);
517
            payment.setStatus(PaymentStatus.SUCCESS.getValue());
518
            payment.setSuccessTimestamp(new Date());
519
 
520
            attrMap.put(IPaymentHandler.CAPTURE_TXN_ID, captureResult.get(IPaymentHandler.CAPTURE_TXN_ID));
521
            attrMap.put(IPaymentHandler.CAPTURE_TIME, captureResult.get(IPaymentHandler.CAPTURE_TIME));
522
            paymentHandler.updatePayment(payment, attrMap);
523
            return true;
524
        }
525
    }
526
 
527
    /**
3956 chandransh 528
     * Updates the settlement details of COD payments. Sets payment status as
529
     * either PARTIALLY CAPTURED or SUCCESS depending on whether the complete
530
     * amount has been captured. Other parameters are set as attributes.
531
     * 
532
     * @param payment
533
     *            The payment which needs to be updated.
534
     * @param amount
535
     *            Amount that has been captured.
536
     * @param xferBy
537
     *            Entity which transferred the money.
538
     * @param xferTxnId
539
     *            Transaction Id of the transfer.
540
     * @param xferDateStr
541
     *            Date on which the transfer took place.
542
     * @return true if the payment details were updated successfully.
543
     * @throws PaymentException
544
     *             if the captured amount will become more than the actual
545
     *             amount after this update.
546
     */
547
    private boolean settleAndUpdateCodPayment(in.shop2020.payment.domain.Payment payment, double amount, String xferBy, String xferTxnId, String xferDateStr) throws PaymentException{
548
        Map<String, String> attrMap = payment.getAttributeMap();
549
 
550
        double captureAmount = 0;
551
        String captureAmntStr = attrMap.get(IPaymentHandler.CAPTURE_AMNT);
552
        if(captureAmntStr != null)
553
            captureAmount = Double.parseDouble(captureAmntStr);
554
        captureAmount += amount;
555
        if(captureAmount > payment.getAmount())
556
            throw new PaymentException(105, "We've got a settlement request for an amount which is more than the transaction value.");
557
 
558
        if(captureAmount < payment.getAmount()){
559
            payment.setStatus(PaymentStatus.PARTIALLY_CAPTURED.getValue());
560
        } else {
561
            payment.setStatus(PaymentStatus.SUCCESS.getValue());
562
        }
563
        payment.setSuccessTimestamp(new Date());
564
        attrMap.put(IPaymentHandler.CAPTURE_AMNT, captureAmount + "");
565
        attrMap.put(IPaymentHandler.XFER_TXN_ID, xferTxnId);
566
        attrMap.put(IPaymentHandler.XFER_TXN_DATE, xferDateStr);
567
        attrMap.put(IPaymentHandler.XFER_BY, xferBy);
568
        paymentHandler.updatePayment(payment, attrMap);
569
        return true;
570
    }
571
 
572
    /**
3010 chandransh 573
     * Creates a list of thrift payment objects corresponding to a list of
574
     * payment data objects.
575
     * 
576
     * @param daoPayments
577
     *            A list of payment DAO.
578
     * @return A list of Thrift payment objects.
579
     */
580
    private List<Payment> getThriftPayments(List<in.shop2020.payment.domain.Payment> daoPayments){
581
 
582
        List<Payment> payments = new ArrayList<Payment>();
583
        for(in.shop2020.payment.domain.Payment payment : daoPayments){
584
            payments.add(payment.getThriftPayment());
585
        }
586
        return payments;
587
    }
3375 rajveer 588
 
4600 varun.gupt 589
    /**
590
     * Creates a list of thrift payment gateway objects corresponding to a list of
591
     * payment gateway data objects.
592
     * 
593
     * @param daoPaymentGateways
594
     *            A list of payment gateway DAO.
595
     * @return A list of Thrift payment gateway objects.
596
     */
597
    private List<PaymentGateway> getThriftPaymentGateways(List<in.shop2020.payment.domain.PaymentGateway> daoPaymentGateways){
598
 
599
        List<PaymentGateway> paymentGateways = new ArrayList<PaymentGateway>();
600
        for(in.shop2020.payment.domain.PaymentGateway paymentGateway : daoPaymentGateways){
601
            paymentGateways.add(paymentGateway.getThriftPaymentGateway());
602
        }
603
        return paymentGateways;
604
    }
4619 mandeep.dh 605
 
3375 rajveer 606
	@Override
4619 mandeep.dh 607
	public boolean isAlive() {
608
	    try {
609
            return !paymentGatewayHandler.getActivePaymentGateways().isEmpty();
610
        } catch (Exception e) {
611
            logger.error("Could not fetch payment gateways", e);
612
        }
613
 
614
        return false;
3375 rajveer 615
	}
3956 chandransh 616
 
617
 
618
    @Override
619
    public void closeSession() throws TException {
620
        // TODO Auto-generated method stub      
621
    }
4008 mandeep.dh 622
 
623
    @Override
624
    public List<Long> getPaymentsRequiringExtraProcessing (
625
            ExtraPaymentProcessingType category) throws TException {
626
        return paymentRequiringExtraProcessingHandler.getPaymentIds(category);
627
    }
628
 
629
    @Override
630
    public void markPaymentAsProcessed(long paymentId,
631
            ExtraPaymentProcessingType category) throws TException {
632
        paymentRequiringExtraProcessingHandler.delete(paymentId, category);
633
    }
4141 chandransh 634
 
1946 chandransh 635
}