Subversion Repositories SmartDukaan

Rev

Rev 13545 | 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
 
6050 anupam.sin 3
import in.shop2020.model.v1.order.RechargeOrder;
3578 mandeep.dh 4
import in.shop2020.payment.domain.Refund;
5
import in.shop2020.payment.handler.PaymentGatewayHandler;
6
import in.shop2020.payment.handler.PaymentHandler;
4008 mandeep.dh 7
import in.shop2020.payment.handler.PaymentRequiringExtraProcessingHandler;
3578 mandeep.dh 8
import in.shop2020.payment.handler.RefundHandler;
13352 amit.gupta 9
import in.shop2020.payment.service.handler.IPaymentHandler.Errors;
3578 mandeep.dh 10
import in.shop2020.payments.Attribute;
4008 mandeep.dh 11
import in.shop2020.payments.ExtraPaymentProcessingType;
3578 mandeep.dh 12
import in.shop2020.payments.Payment;
13
import in.shop2020.payments.PaymentException;
14
import in.shop2020.payments.PaymentGateway;
15
import in.shop2020.payments.PaymentService.Iface;
16
import in.shop2020.payments.PaymentStatus;
6050 anupam.sin 17
import in.shop2020.thrift.clients.TransactionClient;
3578 mandeep.dh 18
 
3010 chandransh 19
import java.text.SimpleDateFormat;
1946 chandransh 20
import java.util.ArrayList;
6448 rajveer 21
import java.util.Arrays;
1946 chandransh 22
import java.util.Date;
23
import java.util.HashMap;
24
import java.util.List;
25
import java.util.Map;
26
 
8618 rajveer 27
import org.apache.commons.logging.Log;
28
import org.apache.commons.logging.LogFactory;
1946 chandransh 29
import org.apache.thrift.TException;
30
import org.springframework.context.ApplicationContext;
31
import org.springframework.context.support.ClassPathXmlApplicationContext;
32
 
22576 amit.gupta 33
import com.mongodb.util.Hash;
34
 
1946 chandransh 35
public class PaymentServiceHandler implements Iface {
3010 chandransh 36
 
8618 rajveer 37
    private static final Log logger = LogFactory.getLog(PaymentServiceHandler.class);
38
 
3010 chandransh 39
 
40
    /**
41
     * Enum of all statuses that can be returned by the HDFC gateway
42
     * 
43
     * @author Chandranshu
44
     * 
45
     */
8907 rajveer 46
    public enum HdfcPaymentReturnStatus{
3010 chandransh 47
        APPROVED("APPROVED"),
48
        NOT_APPROVED("NOT APPROVED"),
49
        CAPTURED("CAPTURED"),
50
        NOT_CAPTURED ("NOT CAPTURED"),
51
        CANCELLED ("CANCELLED"),
52
        DENIED_BY_RISK("DENIED BY RISK"),
8907 rajveer 53
        HOST_TIMEOUT("HOST TIMEOUT"),
54
        SUCCESS("SUCCESS"),
55
        FAILURE("FAILURE");
3010 chandransh 56
        private String value;
57
        HdfcPaymentReturnStatus(String value) {
58
            this.value = value;
59
        }
60
        public String value(){
61
            return this.value;
62
        }
63
    }
64
 
2391 chandransh 65
	public static final long PAYMENT_NOT_CREATED = -1;
66
 
3010 chandransh 67
	private static final long HDFC_GATEWAY_ID = 1;
68
	private static final long EBS_GATEWAY_ID = 2;
13286 amit.gupta 69
	private static final long PAYU_GATEWAY_ID = 19;
8208 amar.kumar 70
	private static final long EBAY_GATEWAY_ID = 16;
8488 amar.kumar 71
	private static final long SNAPDEAL_GATEWAY_ID = 18;
7042 amar.kumar 72
	private static final List<Long> HDFC_EMI_GATEWAY_IDS = Arrays.asList(5L,10L,11L,12L,14L);
22576 amit.gupta 73
	private static final long WALLET_GATEWAY_ID = 8;
3010 chandransh 74
 
4651 rajveer 75
	ApplicationContext context = new ClassPathXmlApplicationContext("context.xml");
1946 chandransh 76
	PaymentHandler paymentHandler = (PaymentHandler) context.getBean("paymentHandler");
4008 mandeep.dh 77
    PaymentRequiringExtraProcessingHandler paymentRequiringExtraProcessingHandler =
78
        (PaymentRequiringExtraProcessingHandler) context.getBean("paymentRequiringExtraProcessingHandler");
79
 
80
    PaymentGatewayHandler paymentGatewayHandler = (PaymentGatewayHandler) context.getBean("paymentGatewayHandler");
2747 chandransh 81
	RefundHandler refundHandler = (RefundHandler) context.getBean("refundHandler");
1946 chandransh 82
 
4651 rajveer 83
	public void setDataSourceUrl(String dbHost){
84
		org.apache.commons.dbcp.BasicDataSource ds = (org.apache.commons.dbcp.BasicDataSource)context.getBean("dataSource");
85
		ds.setUrl(dbHost);
86
	}
87
 
88
	public String getDataSourceUrl(){
89
		org.apache.commons.dbcp.BasicDataSource ds = (org.apache.commons.dbcp.BasicDataSource)context.getBean("dataSource");
90
		return ds.getUrl();
91
	}
92
 
1946 chandransh 93
	@Override
6050 anupam.sin 94
	public long createPayment(long userId, double amount, long gatewayId, long txnId, boolean isDigital) throws PaymentException, TException {
3010 chandransh 95
	    logger.info("Creating payment corresponding to our txn id:" + txnId);
1946 chandransh 96
		in.shop2020.payment.domain.Payment payment = new in.shop2020.payment.domain.Payment();
97
		payment.setUserId(userId);
98
		payment.setAmount(amount);
99
		payment.setGatewayId(gatewayId);
100
		payment.setMerchantTxnId(txnId);
101
		payment.setStatus(PaymentStatus.INIT.getValue());
6050 anupam.sin 102
		payment.setDigital(isDigital);
1946 chandransh 103
 
104
		return paymentHandler.insertPayment(payment);
105
	}
106
 
107
	@Override
108
	public List<Payment> getPaymentsForUser(long userId, long fromTime, long toTime, PaymentStatus status, long gatewayId) throws PaymentException, TException {
3010 chandransh 109
	    logger.info("Getting payments from " + fromTime + " to " + toTime + " for user: " + userId);
2291 chandransh 110
		int statusValue = -1;
111
		if(status != null)
112
			statusValue = status.getValue();
113
		else
114
			statusValue = -1;
115
		return getThriftPayments(paymentHandler.getPaymentsForUser(userId, fromTime, toTime, statusValue, gatewayId));
1946 chandransh 116
	}
117
 
118
	@Override
119
	public List<Payment> getPayments(long fromTime, long toTime, PaymentStatus status, long gatewayId) throws PaymentException,	TException {
3010 chandransh 120
	    logger.info("Getting payments from " + fromTime + " to " + toTime);
2291 chandransh 121
		int statusValue = -1;
122
		if(status != null)
123
			statusValue = status.getValue();
124
		else
125
			statusValue = -1;
126
		return getThriftPayments(paymentHandler.getPayments(fromTime, toTime, statusValue, gatewayId));
1946 chandransh 127
	}
4141 chandransh 128
 
129
	@Override
130
	public List<Payment> getPaymentsByCapturedDate(long fromTime, long toTime, long gatewayId) throws PaymentException, TException {
131
		logger.info("Getting payments from " + fromTime + " to " + toTime + " for " + gatewayId);
132
		return getThriftPayments(paymentHandler.getPaymentsByCapturedDate(fromTime, toTime, gatewayId));
133
	}
1946 chandransh 134
 
135
	@Override
136
	public PaymentGateway getPaymentGateway(long id) throws PaymentException, TException {
3010 chandransh 137
	    logger.info("Getting payment gateway with id:" + id);
2291 chandransh 138
		return paymentGatewayHandler.getPaymentGateway(id).getThriftPaymentGateway();
1946 chandransh 139
	}
4600 varun.gupt 140
 
1946 chandransh 141
	@Override
4600 varun.gupt 142
	public List<PaymentGateway> getActivePaymentGateways() throws PaymentException, TException {
143
	    logger.info("Getting all active payment gateways");
144
	    return getThriftPaymentGateways(paymentGatewayHandler.getActivePaymentGateways());
145
	}
146
 
147
	@Override
1946 chandransh 148
	public Payment getPayment(long id) throws PaymentException, TException {
3010 chandransh 149
	    logger.info("Getting payment with id: " + id);
1946 chandransh 150
		return paymentHandler.getPayment(id).getThriftPayment();
151
	}
152
 
153
	@Override
154
	public List<Payment> getPaymentForTxnId(long txnId) throws PaymentException, TException {
3010 chandransh 155
	    logger.info("Getting payment for the txn id: " + txnId);
1946 chandransh 156
		return getThriftPayments(paymentHandler.getPaymentForTxn(txnId));
157
	}
4600 varun.gupt 158
 
159
	@Override
7049 anupam.sin 160
    public List<Payment> getPaymentForRechargeTxnId(long txnId) throws PaymentException, TException {
161
        logger.info("Getting payment for the txn id: " + txnId);
162
        return getThriftPayments(paymentHandler.getPaymentForRechargeTxn(txnId));
163
    }
164
 
165
	@Override
4600 varun.gupt 166
	public Payment getSuccessfulPaymentForTxnId(long txnId) throws PaymentException, TException {
167
 
168
		for (Payment payment: getPaymentForTxnId(txnId))	{
169
			if (payment.getStatus() == PaymentStatus.SUCCESS || payment.getStatus() == PaymentStatus.PARTIALLY_CAPTURED)	{
170
				return payment;
171
			}
172
		}
173
		return null;
174
	}
1946 chandransh 175
 
176
	@Override
177
	public boolean updatePaymentDetails(long id, String gatewayPaymentId,
178
			String sessionId, String gatewayTxnStatus, String description,
179
			String gatewayTxnId, String authCode, String referenceCode,
180
			String errorCode, PaymentStatus status, String gatewayTxnDate,
181
			List<Attribute> attributes) throws PaymentException, TException {
3010 chandransh 182
	    logger.info("Updating details of payment id: " + id);
1946 chandransh 183
		in.shop2020.payment.domain.Payment payment = paymentHandler.getPayment(id);
184
		payment.setGatewayPaymentId(gatewayPaymentId);
185
		payment.setSessionId(sessionId);
186
		payment.setGatewayTxnStatus(gatewayTxnStatus);
187
		payment.setDescription(description);
188
		payment.setGatewayTxnId(gatewayTxnId);
189
		payment.setAuthCode(authCode);
190
		payment.setReferenceCode(referenceCode);
191
		payment.setErrorCode(errorCode);
192
		if(status!=null){
193
			payment.setStatus(status.getValue());
194
			if(status.equals(PaymentStatus.SUCCESS))
195
				payment.setSuccessTimestamp(new Date());
3578 mandeep.dh 196
			else if(status.equals(PaymentStatus.FAILED)) {
197
			    payment.setErrorTimestamp(new Date());
4421 mandeep.dh 198
			    persistPaymentRequiringExtraProcessing(payment, ExtraPaymentProcessingType.FAILED_PAYMENTS);
3578 mandeep.dh 199
			}
4421 mandeep.dh 200
			else if (status.equals(PaymentStatus.PROVISIONALLY_CAPTURED)) {
201
			    // FIXME different column to note provisional capture timestamp
202
			    // FIXME Requires extra processing at Crm end for actual manual capture
203
			    payment.setProvisionalCaptureTimestamp(new Date());
204
			    persistPaymentRequiringExtraProcessing(payment, ExtraPaymentProcessingType.PENDING_CAPTURE);
205
			}
1946 chandransh 206
		}
207
 
208
		payment.setGatewayTxnDate(gatewayTxnDate);
209
 
210
		Map<String, String> attrMap = new HashMap<String, String>();
2272 rajveer 211
		if(attributes != null){
212
			for(Attribute attribute : attributes){
213
				attrMap.put(attribute.getName(), attribute.getValue());
214
			}
1946 chandransh 215
		}
216
 
217
		paymentHandler.updatePayment(payment, attrMap);
218
		return true;
219
	}
220
 
3649 mandeep.dh 221
	/**
4008 mandeep.dh 222
	 * Persists a given payment Id in another table for future processing by CRM etc.
223
	 * Failed payments generally require a follow-up to help customers through our
224
	 * CRM-Outbound team.
3649 mandeep.dh 225
	 *
226
	 * @param payment  the payment object that failed.
4421 mandeep.dh 227
	 * @param type TODO
3649 mandeep.dh 228
	 */
4421 mandeep.dh 229
	private void persistPaymentRequiringExtraProcessing(in.shop2020.payment.domain.Payment payment, ExtraPaymentProcessingType type) {
4008 mandeep.dh 230
	    try {
4421 mandeep.dh 231
            paymentRequiringExtraProcessingHandler.insert(payment.getId(), type);
4008 mandeep.dh 232
        } catch (Exception e) {
233
            logger.error("Could not persist payment: " + payment.getId(), e);
3578 mandeep.dh 234
        }
235
    }
236
 
237
    @Override
1946 chandransh 238
	public List<Double> getSuccessfulPaymentsAmountRange() throws TException {
3010 chandransh 239
	    logger.info("Getting the range of successful payments.");
1946 chandransh 240
		List<Double> minMaxAmounts = new ArrayList<Double>();
241
		Map<String, Float> minMax = paymentHandler.getMinMaxPaymentAmount();
242
		minMaxAmounts.add(Double.parseDouble(Float.toString(minMax.get("MIN"))));
243
		minMaxAmounts.add(Double.parseDouble(Float.toString(minMax.get("MAX"))));
244
		return minMaxAmounts;
245
	}
246
 
6050 anupam.sin 247
    @Override
10269 amit.gupta 248
    public String initializeHdfcPayment(long merchantPaymentId, boolean isMobile) throws PaymentException, TException {
6050 anupam.sin 249
        logger.info("Initializing HDFC payment with id: " + merchantPaymentId);
250
        in.shop2020.payment.domain.Payment payment = paymentHandler.getPayment(merchantPaymentId);
251
        String redirectURL;
252
        try {
10269 amit.gupta 253
            redirectURL = HdfcPaymentHandler.initializeHdfcPayment(payment, this, isMobile);
6050 anupam.sin 254
        } catch (Exception e) {
255
            throw new PaymentException(102, "Error while initiliazing payment. Check service log for more details.");
256
        }
257
        return redirectURL;
258
    }
259
 
260
    @Override
10269 amit.gupta 261
	public String doHdfcPaymentForDigitalOrder(long merchantPaymentId, long rechargeOrderId, String phone, boolean isMobile) throws PaymentException, TException {
6050 anupam.sin 262
        logger.info("Initializing HDFC payment with id: " + merchantPaymentId);
10968 amit.gupta 263
        logger.info("doHdfcPaymentForDigitalOrder phone---- " + phone);
264
 
6050 anupam.sin 265
        in.shop2020.payment.domain.Payment payment = paymentHandler.getPayment(merchantPaymentId);
266
        TransactionClient tc = new TransactionClient();
267
        String redirectURL;
268
        RechargeOrder rechargeOrder;
269
        try {
270
            rechargeOrder = tc.getClient().getRechargeOrder(rechargeOrderId);
10269 amit.gupta 271
            redirectURL = HdfcPaymentHandler.initializeHdfcPayment(payment, rechargeOrder, phone, this, isMobile);
6050 anupam.sin 272
        } catch (Exception e) {
273
            throw new PaymentException(102, "Error while initiliazing payment. Check service log for more details.");
274
        }
275
 
276
        return redirectURL;
277
    }
2391 chandransh 278
 
279
	@Override
10269 amit.gupta 280
    public String initializeHdfcEmiPayment(long merchantPaymentId, boolean isMobile) throws PaymentException, TException {
3616 chandransh 281
        logger.info("Initializing HDFC payment with id: " + merchantPaymentId);
282
        in.shop2020.payment.domain.Payment payment = paymentHandler.getPayment(merchantPaymentId);
283
        String redirectURL;
284
        try {
10470 amit.gupta 285
            redirectURL = HdfcEmiPaymentHandler.initializeHdfcPayment(payment, this, isMobile);
3616 chandransh 286
        } catch (Exception e) {
287
            throw new PaymentException(102, "Error while initiliazing payment. Check service log for more details.");
288
        }
289
        return redirectURL;
290
    }
291
 
6486 rajveer 292
	@Override
293
	public synchronized boolean refundPayment(long merchantTxnId, double amount, boolean isDigital) throws PaymentException, TException {
6482 rajveer 294
        logger.info("Attempting to refund payment of amount " + amount + " corresponding to our transaction " + merchantTxnId);
8409 rajveer 295
        List<in.shop2020.payment.domain.Payment> payments;
296
        if(isDigital){
297
        	payments = paymentHandler.getPaymentForRechargeTxn(merchantTxnId);
298
        }else{
299
        	payments = paymentHandler.getPaymentForTxn(merchantTxnId);
300
        }
6482 rajveer 301
        if(payments ==null || payments.isEmpty())
302
            throw new PaymentException(104, "No payments found corresponding to the merchant txn " + merchantTxnId);
303
 
6486 rajveer 304
        if(payments ==null || payments.isEmpty())
305
            throw new PaymentException(104, "No payments found corresponding to the merchant txn " + merchantTxnId);
306
 
6482 rajveer 307
        in.shop2020.payment.domain.Payment payment = payments.get(0);
6486 rajveer 308
 
309
        if(payment.getAmount() < amount){
310
        	logger.warn("Refund amount is more than payment amount.");
311
            return false;
312
        }
313
 
6482 rajveer 314
        switch(PaymentStatus.findByValue(payment.getStatus())){
315
        case PENDING:
316
            logger.error("Attempt to refund a non-authorized payment");
317
            return false;
318
        case INIT:
319
            logger.warn("Attempt to refund a non-authorized payment");
320
            return false;
321
        case AUTHORIZED:
322
        	logger.warn("Attempt to refund a non-captured payment");
323
            return false;
324
        case CAPTURE_IN_PROCESS:
325
        	logger.warn("Attempt to refund a non-captured payment");
326
            return false;
327
        case PROVISIONALLY_CAPTURED:
328
        	logger.warn("Attempt to refund a non-captured payment");
329
            return false;
6486 rajveer 330
        case REFUNDED:
331
        	logger.warn("Attempt to refund a refunded payment");
332
            return false;
6482 rajveer 333
        case SUCCESS:
334
            break;
335
        case FAILED:
336
            logger.error("Attempting to capture a failed payment");
337
            return false;
338
        }
339
 
340
        long gatewayId = payment.getGatewayId();
341
 
342
        if(gatewayId == HDFC_GATEWAY_ID){
6491 rajveer 343
            //Refund the HDFC payment
6482 rajveer 344
            return refundHdfcPayment(payment, amount);
6491 rajveer 345
        }else if (gatewayId == EBS_GATEWAY_ID){
346
            //Refund the EBS payment
347
            return refundEbsPayment(payment, amount);
6482 rajveer 348
        } 
6491 rajveer 349
        else if (HDFC_EMI_GATEWAY_IDS.contains(gatewayId)){
350
             //Capture and update the HDFC EMI payment
351
            return refundHdfcEmiPayment(payment, amount);
13518 amit.gupta 352
        }else if (gatewayId == PAYU_GATEWAY_ID) {
353
        	//Refund PayU
354
        	return refundPayUPayment(payment, amount);
355
 
22576 amit.gupta 356
        } 
357
        /*else if(gatewayId == WALLET_GATEWAY_ID) {
358
        	return refundWalletPayment(payment, amount);
359
        }*/
6482 rajveer 360
 
361
        logger.error("We have an captured payment from unknown gateway: " + gatewayId);
362
        return false;
363
    }
364
 
365
 
22576 amit.gupta 366
	private boolean refundWalletPayment(in.shop2020.payment.domain.Payment payment, double amount) throws PaymentException {
367
		//TransactionClient tc = new TransactionClient();
368
		Map<String, String> captureResult = new HashMap<String, String>();
369
		payment.setGatewayTxnStatus("Refunded to wallet");
370
		payment.setStatus(PaymentStatus.REFUNDED.getValue());
371
		payment.setRefundAmount(amount);
372
 
373
 
374
        SimpleDateFormat captureTimeDateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
375
        captureResult.put(IPaymentHandler.REFUND_TXN_ID, captureResult.get(IPaymentHandler.REFUND_TXN_ID));
376
        captureResult.put(IPaymentHandler.REFUND_TIME, captureTimeDateFormatter.format(new Date()));
377
 
378
		return true;
379
	}
380
 
13518 amit.gupta 381
	private boolean refundPayUPayment (
382
			in.shop2020.payment.domain.Payment payment, double amount) throws PaymentException{
383
		Map<String, String> captureResult = PayuPaymentHandler.refundPayment(payment, amount);
384
		if(captureResult.containsKey(IPaymentHandler.ERROR)){
385
            payment.setDescription(captureResult.get(IPaymentHandler.ERROR));
386
            payment.setErrorCode(captureResult.get(IPaymentHandler.ERR_CODE));
387
            payment.setErrorTimestamp(new Date());
388
        	if(captureResult.get(IPaymentHandler.ERR_CODE).equals(Errors.CAPTURE_FAILURE)) {
389
                paymentHandler.updatePayment(payment, captureResult);
390
                persistPaymentRequiringExtraProcessing(payment, ExtraPaymentProcessingType.FAILED_PAYMENTS);
391
        	} else {
13545 amit.gupta 392
        		logger.error("Refund attempt failed for Payu payment with id: " + payment.getId());
393
        		/*payment.setStatus(PaymentStatus.CAPTURE_IN_PROCESS.getValue());
13518 amit.gupta 394
        		paymentHandler.updatePayment(payment, captureResult);
13545 amit.gupta 395
        		throw new PaymentException(106, captureResult.get(IPaymentHandler.ERROR));*/
13518 amit.gupta 396
        	}
397
        	return false;
398
        } else {
399
 
400
        	payment.setGatewayTxnStatus("Refund initiated");
401
            payment.setStatus(PaymentStatus.REFUNDED.getValue());
402
            payment.setRefundAmount(amount);
403
 
404
            SimpleDateFormat captureTimeDateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
405
            captureResult.put(IPaymentHandler.REFUND_TXN_ID, captureResult.get(IPaymentHandler.REFUND_TXN_ID));
406
            captureResult.put(IPaymentHandler.REFUND_TIME, captureTimeDateFormatter.format(new Date()));
407
            paymentHandler.updatePayment(payment, captureResult);
408
            return true;
409
        }
410
	}
411
 
3616 chandransh 412
	@Override
2689 chandransh 413
    public long createRefund(long orderId, long merchantTxnId, double amount) throws PaymentException, TException{
6482 rajveer 414
		logger.info("Attempting to create a refund for order: " + orderId);
6488 rajveer 415
//		if(!refundPayment(merchantTxnId, amount, false)){
416
//			logger.warn("Not able to refund corresponding to the merchant txn " + merchantTxnId);
417
//		}
2689 chandransh 418
		List<in.shop2020.payment.domain.Payment> payments = paymentHandler.getPaymentForTxn(merchantTxnId);
419
		if(payments ==null || payments.isEmpty())
420
			throw new PaymentException(104, "No payments found corresponding to the merchant txn " + merchantTxnId);
421
 
3010 chandransh 422
		in.shop2020.payment.domain.Payment payment = payments.get(0);
2689 chandransh 423
		if(payment.getStatus() != PaymentStatus.SUCCESS.getValue())
424
			throw new PaymentException(104, "No successful payments found corresponding to the merchant txn " + merchantTxnId);
425
 
2747 chandransh 426
		Refund refund = new Refund();
427
		refund.setOrderId(orderId);
428
		refund.setPaymentId(payment.getId());
429
		refund.setGatewayId(payment.getGatewayId());
430
		refund.setAmount(amount);
431
		refund.setAttempts(0);
432
		return refundHandler.createRefund(refund);
2689 chandransh 433
    }
434
 
3010 chandransh 435
    @Override
8618 rajveer 436
    public synchronized boolean capturePayment(long merchantTxnId, boolean isDigital) throws PaymentException, TException {
437
        logger.info("Attempting to capture payment corresponding to our transaction " + merchantTxnId + " and Is Digital is:" + isDigital);
438
        List<in.shop2020.payment.domain.Payment> payments;
439
        if(isDigital){
440
        	payments = paymentHandler.getPaymentForRechargeTxn(merchantTxnId);
441
        }else{
442
        	payments = paymentHandler.getPaymentForTxn(merchantTxnId);
443
        }
3010 chandransh 444
        if(payments ==null || payments.isEmpty())
445
            throw new PaymentException(104, "No payments found corresponding to the merchant txn " + merchantTxnId);
446
 
447
        in.shop2020.payment.domain.Payment payment = payments.get(0);
448
        switch(PaymentStatus.findByValue(payment.getStatus())){
449
        case PENDING:
450
            logger.error("Attempt to capture a non-authorized payment");
451
            return false;
452
        case INIT:
453
            logger.warn("Attempt to capture a non-authorized payment");
454
            return false;
455
        case AUTHORIZED:
4421 mandeep.dh 456
        case CAPTURE_IN_PROCESS:
3010 chandransh 457
            //Actual work to be done in this case. Let the call proceed.
458
            break;
4421 mandeep.dh 459
        case PROVISIONALLY_CAPTURED:
460
            logger.info("Attempting to capture a payment that is provisonally captured but we can let the client proceed.");
461
            return true;
3010 chandransh 462
        case SUCCESS:
463
            logger.warn("Attempting to capture an already captured payment but we can let the client proceed.");
464
            return true;
465
        case FAILED:
466
            logger.error("Attempting to capture a failed payment");
467
            return false;
468
        }
469
 
470
        long gatewayId = payment.getGatewayId();
471
 
472
        if(gatewayId == HDFC_GATEWAY_ID){
473
            //Capture and update the HDFC payment
474
            return captureAndUpdateHdfcPayment(payment);
475
        } else if (gatewayId == EBS_GATEWAY_ID){
476
            //Capture and update the EBS payment
477
            return captureAndUpdateEbsPayment(payment);
6449 rajveer 478
        } else if (HDFC_EMI_GATEWAY_IDS.contains(gatewayId)){
3583 chandransh 479
            //Capture and update the HDFC EMI payment
480
            return captureAndUpdateHdfcEmiPayment(payment);
8488 amar.kumar 481
        } else if (gatewayId == EBAY_GATEWAY_ID || gatewayId == SNAPDEAL_GATEWAY_ID) {
8208 amar.kumar 482
        	return true;
13286 amit.gupta 483
        } else if (gatewayId == PAYU_GATEWAY_ID) {
13352 amit.gupta 484
        	return captureAndUpdatePayuPayment(payment);
3010 chandransh 485
        }
486
 
487
        logger.error("We have an authorized payment from unknown gateway: " + gatewayId);
488
        return false;
489
    }
490
 
13352 amit.gupta 491
    private boolean captureAndUpdatePayuPayment(in.shop2020.payment.domain.Payment payment)  throws PaymentException{
492
    	long merchantPaymentId = payment.getId();
493
 
494
        logger.info("Capturing Payu payment with id: " + merchantPaymentId);
495
        Map<String, String> attrMap = new HashMap<String, String>();
496
        Map<String, String> captureResult = PayuPaymentHandler.captureTransaction(merchantPaymentId + "", payment.getGatewayTxnId());
497
        if(captureResult.containsKey(IPaymentHandler.ERROR)){
498
            payment.setDescription(captureResult.get(IPaymentHandler.ERROR));
499
            payment.setErrorCode(captureResult.get(IPaymentHandler.ERR_CODE));
500
            payment.setErrorTimestamp(new Date());
501
        	if(captureResult.get(IPaymentHandler.ERR_CODE).equals(Errors.CAPTURE_FAILURE)) {
502
                payment.setStatus(PaymentStatus.FAILED.getValue());
503
                paymentHandler.updatePayment(payment, attrMap);
504
                persistPaymentRequiringExtraProcessing(payment, ExtraPaymentProcessingType.FAILED_PAYMENTS);
505
        	} else {
13518 amit.gupta 506
        		logger.error("Capture attempt failed for Payu payment with id: " + merchantPaymentId);
13352 amit.gupta 507
        		payment.setStatus(PaymentStatus.CAPTURE_IN_PROCESS.getValue());
508
        		paymentHandler.updatePayment(payment, attrMap);
509
        		throw new PaymentException(106, captureResult.get(IPaymentHandler.ERROR));
510
        	}
511
        	return false;
512
        } else {
513
        	logger.info("Capture attempt successful for HDFC payment with id: " + merchantPaymentId);
514
            payment.setDescription("Payment Captured");
515
            payment.setGatewayTxnStatus("captured");
516
            payment.setStatus(PaymentStatus.SUCCESS.getValue());
517
            payment.setSuccessTimestamp(new Date());           
518
            payment.setReferenceCode(captureResult.get(PayuPaymentHandler.REF_NO));
519
            attrMap.put(IPaymentHandler.CAPTURE_TXN_ID, captureResult.get(IPaymentHandler.CAPTURE_TXN_ID));
520
            attrMap.put(IPaymentHandler.CAPTURE_REF_ID, captureResult.get(IPaymentHandler.CAPTURE_REF_ID));
521
            attrMap.put(IPaymentHandler.CAPTURE_AUTH_ID, captureResult.get(IPaymentHandler.CAPTURE_AUTH_ID));
522
 
523
            SimpleDateFormat captureTimeDateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
524
            attrMap.put(HdfcPaymentHandler.CAPTURE_TIME, captureTimeDateFormatter.format(new Date()));
525
 
526
            paymentHandler.updatePayment(payment, attrMap);
527
            return true;
528
        }
13286 amit.gupta 529
	}
530
 
531
	@Override
3956 chandransh 532
    public boolean partiallyCapturePayment(long merchantTxnId, double amount, String xferBy, String xferTxnId, long xferDate) throws PaymentException, TException {
533
        logger.info("Attempting to partially capture payment corresponding to our transaction " + merchantTxnId);
534
        List<in.shop2020.payment.domain.Payment> payments = paymentHandler.getPaymentForTxn(merchantTxnId);
535
        if(payments ==null || payments.isEmpty())
536
            throw new PaymentException(104, "No payments found corresponding to the merchant txn " + merchantTxnId);
537
 
538
        in.shop2020.payment.domain.Payment payment = payments.get(0);
539
        switch(PaymentStatus.findByValue(payment.getStatus())){
540
        case PENDING:
541
            // COD payments lie in this state before settlement.
542
        case INIT:
543
        case PARTIALLY_CAPTURED:
544
        case AUTHORIZED:
545
            // COD payments would not be in this state but we are processing
546
            // payments in this state as well for forward compatibility since
547
            // someday we'd want to be able to capture authorized CC payments
548
            // partially.
549
            break;
550
        case SUCCESS:
551
            logger.warn("Attempting to capture an already captured payment but we can let the client proceed.");
552
            return true;
553
        case FAILED:
554
            logger.error("Attempting to capture a failed payment");
555
            return false;
556
        }
557
        SimpleDateFormat mysqlDateFormatter = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
558
        String xferDateStr = mysqlDateFormatter.format(new Date(xferDate));
559
 
560
        return settleAndUpdateCodPayment(payment, amount, xferBy, xferTxnId, xferDateStr);
561
    }
562
 
3010 chandransh 563
    /**
564
     * Capture the HDFC payment represented by the given payment object. If the
565
     * capture attempt is not successful, we mark this payment as failed. We
566
     * don't retry or anything. We'll add the support of multiple attempts later
567
     * on.
568
     * 
569
     * @param payment The payment which has to be captured.
570
     * @return True if the payment attempt is successful, false if not.
4421 mandeep.dh 571
     * @throws PaymentException 
3010 chandransh 572
     */
4421 mandeep.dh 573
    private boolean captureAndUpdateHdfcPayment(in.shop2020.payment.domain.Payment payment) throws PaymentException {
3010 chandransh 574
        long merchantPaymentId = payment.getId();
575
        logger.info("Capturing HDFC payment with id: " + merchantPaymentId);
576
        Map<String, String> captureResult = HdfcPaymentHandler.capturePayment(payment);
577
        String captureStatus = captureResult.get(IPaymentHandler.STATUS);
578
        String gatewayStatus = captureResult.get(IPaymentHandler.GATEWAY_STATUS);
579
 
580
        Map<String, String> attrMap = new HashMap<String, String>();
581
        if (!captureStatus.trim().equals("0") 
582
                || !HdfcPaymentReturnStatus.CAPTURED.value().equals(gatewayStatus)) {
583
            // Failure
3616 chandransh 584
            logger.error("Capture attempt failed for HDFC payment with id: " + merchantPaymentId);
3010 chandransh 585
            String description = captureResult.get(IPaymentHandler.ERROR);
586
            String errorCode = captureResult.get(IPaymentHandler.ERR_CODE);
587
 
588
            payment.setDescription(description);
589
            payment.setErrorCode(errorCode);
590
            payment.setErrorTimestamp(new Date());
4421 mandeep.dh 591
 
592
            if (IPaymentHandler.Errors.CONN_FAILURE.code.equals(errorCode)) {
593
                payment.setStatus(PaymentStatus.CAPTURE_IN_PROCESS.getValue());
594
                paymentHandler.updatePayment(payment, attrMap);
595
                throw new PaymentException(106, "Could not capture due to connection issue");
596
            }
597
            else {
598
                payment.setStatus(PaymentStatus.FAILED.getValue());
599
                paymentHandler.updatePayment(payment, attrMap);
600
                persistPaymentRequiringExtraProcessing(payment, ExtraPaymentProcessingType.FAILED_PAYMENTS);
601
            }
602
 
3010 chandransh 603
            return false;
604
        } else {
605
            // Success
3616 chandransh 606
            logger.info("Capture attempt successful for HDFC payment with id: " + merchantPaymentId);
3010 chandransh 607
            payment.setDescription("Payment Captured");
608
            payment.setGatewayTxnStatus(gatewayStatus);
609
            payment.setStatus(PaymentStatus.SUCCESS.getValue());
610
            payment.setSuccessTimestamp(new Date());           
611
 
612
            attrMap.put(IPaymentHandler.CAPTURE_TXN_ID, captureResult.get(IPaymentHandler.CAPTURE_TXN_ID));
613
            attrMap.put(IPaymentHandler.CAPTURE_REF_ID, captureResult.get(IPaymentHandler.CAPTURE_REF_ID));
614
            attrMap.put(IPaymentHandler.CAPTURE_AUTH_ID, captureResult.get(IPaymentHandler.CAPTURE_AUTH_ID));
615
 
616
            SimpleDateFormat captureTimeDateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
617
            attrMap.put(HdfcPaymentHandler.CAPTURE_TIME, captureTimeDateFormatter.format(new Date()));
618
 
619
            paymentHandler.updatePayment(payment, attrMap);
620
            return true;
621
          }
622
    }
623
 
624
    /**
3583 chandransh 625
     * Capture the HDFC EMI payment represented by the given payment object. If
626
     * the capture attempt is not successful, we mark this payment as failed. We
627
     * don't retry or anything. We'll add the support of multiple attempts later
628
     * on.
629
     * 
630
     * @param payment
631
     *            The payment which has to be captured.
632
     * @return True if the payment attempt is successful, false if not.
4421 mandeep.dh 633
     * @throws PaymentException 
3583 chandransh 634
     */
4421 mandeep.dh 635
    private boolean captureAndUpdateHdfcEmiPayment(in.shop2020.payment.domain.Payment payment) throws PaymentException{
3583 chandransh 636
        long merchantPaymentId = payment.getId();
637
        logger.info("Capturing HDFC payment with id: " + merchantPaymentId);
638
        Map<String, String> captureResult = HdfcEmiPaymentHandler.capturePayment(payment);
639
        String captureStatus = captureResult.get(IPaymentHandler.STATUS);
640
        String gatewayStatus = captureResult.get(IPaymentHandler.GATEWAY_STATUS);
641
 
642
        Map<String, String> attrMap = new HashMap<String, String>();
643
        if (!captureStatus.trim().equals("0") 
644
                || !HdfcPaymentReturnStatus.CAPTURED.value().equals(gatewayStatus)) {
645
            // Failure
3616 chandransh 646
            logger.error("Capture attempt failed for HDFC payment with id: " + merchantPaymentId);
3583 chandransh 647
            String description = captureResult.get(IPaymentHandler.ERROR);
648
            String errorCode = captureResult.get(IPaymentHandler.ERR_CODE);
649
 
650
            payment.setDescription(description);
651
            payment.setErrorCode(errorCode);
4421 mandeep.dh 652
            payment.setErrorTimestamp(new Date());                
653
 
654
            // Not marking payments as failed in case of connection issues
655
            if (IPaymentHandler.Errors.CONN_FAILURE.code.equals(errorCode)) {
656
                payment.setStatus(PaymentStatus.CAPTURE_IN_PROCESS.getValue());
657
                paymentHandler.updatePayment(payment, attrMap);
658
                throw new PaymentException(106, "Could not capture due to connection issue");
659
            }
660
            else {
661
                payment.setStatus(PaymentStatus.FAILED.getValue());
662
                paymentHandler.updatePayment(payment, attrMap);
663
                persistPaymentRequiringExtraProcessing(payment, ExtraPaymentProcessingType.FAILED_PAYMENTS);
664
            }
665
 
3583 chandransh 666
            return false;
667
        } else {
668
            // Success
3616 chandransh 669
            logger.info("Capture attempt successful for HDFC payment with id: " + merchantPaymentId);
3583 chandransh 670
            payment.setDescription("Payment Captured");
671
            payment.setGatewayTxnStatus(gatewayStatus);
672
            payment.setStatus(PaymentStatus.SUCCESS.getValue());
4421 mandeep.dh 673
            payment.setSuccessTimestamp(new Date());
3583 chandransh 674
 
675
            attrMap.put(IPaymentHandler.CAPTURE_TXN_ID, captureResult.get(IPaymentHandler.CAPTURE_TXN_ID));
676
            attrMap.put(IPaymentHandler.CAPTURE_REF_ID, captureResult.get(IPaymentHandler.CAPTURE_REF_ID));
677
            attrMap.put(IPaymentHandler.CAPTURE_AUTH_ID, captureResult.get(IPaymentHandler.CAPTURE_AUTH_ID));
678
 
679
            SimpleDateFormat captureTimeDateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
680
            attrMap.put(HdfcPaymentHandler.CAPTURE_TIME, captureTimeDateFormatter.format(new Date()));
681
 
682
            paymentHandler.updatePayment(payment, attrMap);
683
            return true;
684
          }
685
    }
686
 
687
    /**
3010 chandransh 688
     * Capture the EBS payment represented by the given payment object. If the
689
     * capture attempt is not successful, we mark this payment as failed. We
690
     * don't retry or anything. We'll add the support of multiple attempts later
691
     * on.
692
     * 
693
     * @param payment The payment which has to be captured.
694
     * @return True if the payment attempt is successful, false if not.
4421 mandeep.dh 695
     * @throws PaymentException 
3010 chandransh 696
     */
4421 mandeep.dh 697
    private boolean captureAndUpdateEbsPayment(in.shop2020.payment.domain.Payment payment) throws PaymentException{
3010 chandransh 698
        Map<String, String> captureResult = EbsPaymentHandler.capturePayment(payment);
699
        String captureStatus = captureResult.get(EbsPaymentHandler.STATUS);
8650 anupam.sin 700
        for(String key : captureResult.keySet()) {
701
            logger.info("key : " + key + " value : " + captureResult.get(key));
702
        }
3010 chandransh 703
 
8650 anupam.sin 704
        logger.info("capture status : " + captureStatus);
705
 
3010 chandransh 706
        Map<String, String> attrMap = new HashMap<String, String>();
707
        if("".equals(captureStatus)){
708
            //Failure
3616 chandransh 709
            logger.error("Capture attempt failed for EBS payment with id: " + payment.getId());
3010 chandransh 710
            String description = captureResult.get(EbsPaymentHandler.ERROR);
711
            String errorCode = captureResult.get(EbsPaymentHandler.ERR_CODE);
4421 mandeep.dh 712
 
3010 chandransh 713
            payment.setDescription(description);
714
            payment.setErrorCode(errorCode);
715
            payment.setErrorTimestamp(new Date());
4421 mandeep.dh 716
 
717
            if (IPaymentHandler.Errors.CONN_FAILURE.code.equals(errorCode)) {
718
                payment.setStatus(PaymentStatus.CAPTURE_IN_PROCESS.getValue());            
719
                paymentHandler.updatePayment(payment, attrMap);
720
                throw new PaymentException(106, "Could not capture due to connection issue");
721
            }
722
            else {
723
                payment.setStatus(PaymentStatus.FAILED.getValue());            
724
                paymentHandler.updatePayment(payment, attrMap);
725
                persistPaymentRequiringExtraProcessing(payment, ExtraPaymentProcessingType.FAILED_PAYMENTS);
726
            }
727
 
3010 chandransh 728
            return false;
729
        }else{
730
            //Success
3616 chandransh 731
            logger.info("Capture attempt successful for EBS payment with id: " + payment.getId());
3010 chandransh 732
            payment.setGatewayTxnStatus(captureStatus);
733
            payment.setStatus(PaymentStatus.SUCCESS.getValue());
734
            payment.setSuccessTimestamp(new Date());
735
 
736
            attrMap.put(IPaymentHandler.CAPTURE_TXN_ID, captureResult.get(IPaymentHandler.CAPTURE_TXN_ID));
737
            attrMap.put(IPaymentHandler.CAPTURE_TIME, captureResult.get(IPaymentHandler.CAPTURE_TIME));
738
            paymentHandler.updatePayment(payment, attrMap);
739
            return true;
740
        }
741
    }
742
 
6482 rajveer 743
 
3010 chandransh 744
    /**
6482 rajveer 745
     * Refund the HDFC payment represented by the given payment object. If the
746
     * refund attempt is not successful, will not any action.
747
     * 
748
     * @param payment The payment which has to be captured.
749
     * @amount amount to be refunded
750
     * @return True if the payment attempt is successful, false if not.
751
     * @throws PaymentException 
752
     */
753
    private boolean refundHdfcPayment(in.shop2020.payment.domain.Payment payment, double amount) throws PaymentException {
754
        long merchantPaymentId = payment.getId();
755
        logger.info("Refunding HDFC payment with id: " + merchantPaymentId);
756
        Map<String, String> refundResult = HdfcPaymentHandler.refundPayment(payment, amount);
6486 rajveer 757
        String refundStatus = refundResult.get(IPaymentHandler.STATUS);
6482 rajveer 758
        String gatewayStatus = refundResult.get(IPaymentHandler.GATEWAY_STATUS);
759
 
760
        Map<String, String> attrMap = new HashMap<String, String>();
6486 rajveer 761
        if (!refundStatus.trim().equals("0") 
6482 rajveer 762
                || !HdfcPaymentReturnStatus.CAPTURED.value().equals(gatewayStatus)) {
6486 rajveer 763
 
764
        	logger.error("Refund attempt failed for HDFC payment with id: " + merchantPaymentId);
765
            String description = refundResult.get(IPaymentHandler.ERROR);
766
            String errorCode = refundResult.get(IPaymentHandler.ERR_CODE);
767
 
768
            payment.setDescription(description);
769
            payment.setErrorCode(errorCode);
770
            payment.setErrorTimestamp(new Date());
771
 
772
            if (IPaymentHandler.Errors.CONN_FAILURE.code.equals(errorCode)) {
773
                //payment.setStatus(PaymentStatus.CAPTURE_IN_PROCESS.getValue());
774
                //paymentHandler.updatePayment(payment, attrMap);
775
                throw new PaymentException(106, "Could not capture due to connection issue. Try Later");
776
            }
777
            else {
6491 rajveer 778
//                payment.setStatus(PaymentStatus.FAILED.getValue());
779
//                paymentHandler.updatePayment(payment, attrMap);
6486 rajveer 780
                persistPaymentRequiringExtraProcessing(payment, ExtraPaymentProcessingType.FAILED_PAYMENTS);
781
            }
782
 
6482 rajveer 783
            return false;
784
        } else {
785
            // Success
786
            logger.info("Refund attempt successful for HDFC payment with id: " + merchantPaymentId);
787
            payment.setDescription("Payment Refunded");
788
            payment.setGatewayTxnStatus(gatewayStatus);
6503 rajveer 789
            payment.setStatus(PaymentStatus.REFUNDED.getValue());    
790
            payment.setRefundAmount(amount);
6482 rajveer 791
 
6486 rajveer 792
            attrMap.put(IPaymentHandler.REFUND_TXN_ID, refundResult.get(IPaymentHandler.REFUND_TXN_ID));
793
            attrMap.put(IPaymentHandler.REFUND_REF_ID, refundResult.get(IPaymentHandler.REFUND_REF_ID));
794
            attrMap.put(IPaymentHandler.REFUND_AUTH_ID, refundResult.get(IPaymentHandler.REFUND_AUTH_ID));
6503 rajveer 795
            attrMap.put(IPaymentHandler.REFUND_AMNT, refundResult.get(IPaymentHandler.REFUND_AMNT));
796
 
6482 rajveer 797
            SimpleDateFormat captureTimeDateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
6486 rajveer 798
            attrMap.put(HdfcPaymentHandler.REFUND_TIME, captureTimeDateFormatter.format(new Date()));
6482 rajveer 799
 
800
            paymentHandler.updatePayment(payment, attrMap);
801
            return true;
802
          }
803
    }
804
 
805
 
6491 rajveer 806
    /**
807
     * Refund the HDFC EMI payment represented by the given payment object. If
808
     * the capture attempt is not successful, we will not do anything.
809
     * 
810
     * @param payment
811
     *            The payment which has to be captured.
812
     * @return True if the payment attempt is successful, false if not.
813
     * @throws PaymentException 
814
     */
815
    private boolean refundHdfcEmiPayment(in.shop2020.payment.domain.Payment payment, double amount) throws PaymentException{
816
        long merchantPaymentId = payment.getId();
817
        logger.info("Refunding HDFC payment with id: " + merchantPaymentId);
818
        Map<String, String> refundResult = HdfcEmiPaymentHandler.refundPayment(payment, amount);
819
        String refundStatus = refundResult.get(IPaymentHandler.STATUS);
820
        String gatewayStatus = refundResult.get(IPaymentHandler.GATEWAY_STATUS);
821
 
822
        Map<String, String> attrMap = new HashMap<String, String>();
823
        if (!refundStatus.trim().equals("0") 
824
                || !HdfcPaymentReturnStatus.CAPTURED.value().equals(gatewayStatus)) {
825
            // Failure
826
            logger.error("Refund attempt failed for HDFC payment with id: " + merchantPaymentId);
827
            String description = refundResult.get(IPaymentHandler.ERROR);
828
            String errorCode = refundResult.get(IPaymentHandler.ERR_CODE);
829
 
830
            payment.setDescription(description);
831
            payment.setErrorCode(errorCode);
832
            payment.setErrorTimestamp(new Date());                
833
 
834
            // Not marking payments as failed in case of connection issues
835
            if (IPaymentHandler.Errors.CONN_FAILURE.code.equals(errorCode)) {
836
             //   payment.setStatus(PaymentStatus.CAPTURE_IN_PROCESS.getValue());
837
             //   paymentHandler.updatePayment(payment, attrMap);
838
                throw new PaymentException(106, "Could not capture due to connection issue");
839
            }
840
            else {
841
              //  payment.setStatus(PaymentStatus.FAILED.getValue());
842
              //  paymentHandler.updatePayment(payment, attrMap);
843
                persistPaymentRequiringExtraProcessing(payment, ExtraPaymentProcessingType.FAILED_PAYMENTS);
844
            }
845
 
846
            return false;
847
        } else {
848
            // Success
849
            logger.info("Refund attempt successful for HDFC payment with id: " + merchantPaymentId);
850
            payment.setDescription("Payment Refunded");
851
            payment.setGatewayTxnStatus(gatewayStatus);
852
            payment.setStatus(PaymentStatus.REFUNDED.getValue());           
6503 rajveer 853
            payment.setRefundAmount(amount);
6491 rajveer 854
 
855
            attrMap.put(IPaymentHandler.REFUND_TXN_ID, refundResult.get(IPaymentHandler.REFUND_TXN_ID));
856
            attrMap.put(IPaymentHandler.REFUND_REF_ID, refundResult.get(IPaymentHandler.REFUND_REF_ID));
857
            attrMap.put(IPaymentHandler.REFUND_AUTH_ID, refundResult.get(IPaymentHandler.REFUND_AUTH_ID));
6503 rajveer 858
            attrMap.put(IPaymentHandler.REFUND_AMNT, refundResult.get(IPaymentHandler.REFUND_AMNT));
859
 
6491 rajveer 860
            SimpleDateFormat captureTimeDateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
861
            attrMap.put(HdfcPaymentHandler.REFUND_TIME, captureTimeDateFormatter.format(new Date()));
862
 
863
            paymentHandler.updatePayment(payment, attrMap);
864
            return true;
865
          }
866
    }
6482 rajveer 867
 
868
    /**
6491 rajveer 869
     * Refund the EBS payment represented by the given payment object. If the
870
     * capture attempt is not successful, we will ignore. We don't retry or anything. 
871
     * We'll add the support of multiple attempts later on.
872
     * 
873
     * @param payment The payment which has to be captured.
874
     * @amount Amount to be refunded
875
     * @return True if the payment attempt is successful, false if not.
876
     * @throws PaymentException 
877
     */
878
    private boolean refundEbsPayment(in.shop2020.payment.domain.Payment payment, double amount) throws PaymentException{
879
        Map<String, String> refundResult = EbsPaymentHandler.refundPayment(payment, amount);
880
        String refundStatus = refundResult.get(EbsPaymentHandler.STATUS);
881
 
882
        Map<String, String> attrMap = new HashMap<String, String>();
883
        if("".equals(refundStatus)){
884
            //Failure
885
            logger.error("Refund attempt failed for EBS payment with id: " + payment.getId());
886
            String description = refundResult.get(EbsPaymentHandler.ERROR);
887
            String errorCode = refundResult.get(EbsPaymentHandler.ERR_CODE);
888
 
889
            payment.setDescription(description);
890
            payment.setErrorCode(errorCode);
891
            payment.setErrorTimestamp(new Date());
892
 
893
            if (IPaymentHandler.Errors.CONN_FAILURE.code.equals(errorCode)) {
894
//                payment.setStatus(PaymentStatus.CAPTURE_IN_PROCESS.getValue());            
895
//                paymentHandler.updatePayment(payment, attrMap);
896
                throw new PaymentException(106, "Could not capture due to connection issue");
897
            }
898
            else {
899
//                payment.setStatus(PaymentStatus.FAILED.getValue());            
900
//                paymentHandler.updatePayment(payment, attrMap);
901
                persistPaymentRequiringExtraProcessing(payment, ExtraPaymentProcessingType.FAILED_PAYMENTS);
902
            }
903
 
904
            return false;
905
        }else{
906
            //Success
907
            logger.info("Refund attempt successful for EBS payment with id: " + payment.getId());
908
            payment.setGatewayTxnStatus(refundStatus);
909
            payment.setStatus(PaymentStatus.REFUNDED.getValue());
6503 rajveer 910
            payment.setRefundAmount(amount);
6491 rajveer 911
 
912
            attrMap.put(IPaymentHandler.REFUND_TXN_ID, refundResult.get(IPaymentHandler.REFUND_TXN_ID));
913
            attrMap.put(IPaymentHandler.REFUND_TIME, refundResult.get(IPaymentHandler.REFUND_TIME));
914
            paymentHandler.updatePayment(payment, attrMap);
915
            return true;
916
        }
917
    }
918
 
919
 
920
    /**
3956 chandransh 921
     * Updates the settlement details of COD payments. Sets payment status as
922
     * either PARTIALLY CAPTURED or SUCCESS depending on whether the complete
923
     * amount has been captured. Other parameters are set as attributes.
924
     * 
925
     * @param payment
926
     *            The payment which needs to be updated.
927
     * @param amount
928
     *            Amount that has been captured.
929
     * @param xferBy
930
     *            Entity which transferred the money.
931
     * @param xferTxnId
932
     *            Transaction Id of the transfer.
933
     * @param xferDateStr
934
     *            Date on which the transfer took place.
935
     * @return true if the payment details were updated successfully.
936
     * @throws PaymentException
937
     *             if the captured amount will become more than the actual
938
     *             amount after this update.
939
     */
940
    private boolean settleAndUpdateCodPayment(in.shop2020.payment.domain.Payment payment, double amount, String xferBy, String xferTxnId, String xferDateStr) throws PaymentException{
941
        Map<String, String> attrMap = payment.getAttributeMap();
942
 
943
        double captureAmount = 0;
944
        String captureAmntStr = attrMap.get(IPaymentHandler.CAPTURE_AMNT);
945
        if(captureAmntStr != null)
946
            captureAmount = Double.parseDouble(captureAmntStr);
947
        captureAmount += amount;
5051 rajveer 948
        // If capture amount higher than payment amount by more than 50 paisa,
949
        // there is some issue and we should raise exception.
950
        if(captureAmount - payment.getAmount() > 0.5){
951
        	throw new PaymentException(105, "We've got a settlement request for an amount which is more than the transaction value.");
952
        }
3956 chandransh 953
 
5051 rajveer 954
        // If capture amount differs from payment amount by less than 50 paisa, lets mark the payment as successful. 
955
        // Else we can safely assume there will be some more orders for the payment, leading to make the payment as partially captured.
956
        if(Math.abs(captureAmount - payment.getAmount()) < 0.5){
957
        	payment.setStatus(PaymentStatus.SUCCESS.getValue());
958
        }else {
959
        	payment.setStatus(PaymentStatus.PARTIALLY_CAPTURED.getValue());   
3956 chandransh 960
        }
961
        payment.setSuccessTimestamp(new Date());
962
        attrMap.put(IPaymentHandler.CAPTURE_AMNT, captureAmount + "");
963
        attrMap.put(IPaymentHandler.XFER_TXN_ID, xferTxnId);
964
        attrMap.put(IPaymentHandler.XFER_TXN_DATE, xferDateStr);
965
        attrMap.put(IPaymentHandler.XFER_BY, xferBy);
966
        paymentHandler.updatePayment(payment, attrMap);
967
        return true;
968
    }
969
 
970
    /**
3010 chandransh 971
     * Creates a list of thrift payment objects corresponding to a list of
972
     * payment data objects.
973
     * 
974
     * @param daoPayments
975
     *            A list of payment DAO.
976
     * @return A list of Thrift payment objects.
977
     */
978
    private List<Payment> getThriftPayments(List<in.shop2020.payment.domain.Payment> daoPayments){
979
 
980
        List<Payment> payments = new ArrayList<Payment>();
981
        for(in.shop2020.payment.domain.Payment payment : daoPayments){
982
            payments.add(payment.getThriftPayment());
983
        }
984
        return payments;
985
    }
3375 rajveer 986
 
4600 varun.gupt 987
    /**
988
     * Creates a list of thrift payment gateway objects corresponding to a list of
989
     * payment gateway data objects.
990
     * 
991
     * @param daoPaymentGateways
992
     *            A list of payment gateway DAO.
993
     * @return A list of Thrift payment gateway objects.
994
     */
995
    private List<PaymentGateway> getThriftPaymentGateways(List<in.shop2020.payment.domain.PaymentGateway> daoPaymentGateways){
996
 
997
        List<PaymentGateway> paymentGateways = new ArrayList<PaymentGateway>();
998
        for(in.shop2020.payment.domain.PaymentGateway paymentGateway : daoPaymentGateways){
999
            paymentGateways.add(paymentGateway.getThriftPaymentGateway());
1000
        }
1001
        return paymentGateways;
1002
    }
4619 mandeep.dh 1003
 
3375 rajveer 1004
	@Override
4619 mandeep.dh 1005
	public boolean isAlive() {
1006
	    try {
1007
            return !paymentGatewayHandler.getActivePaymentGateways().isEmpty();
1008
        } catch (Exception e) {
1009
            logger.error("Could not fetch payment gateways", e);
1010
        }
1011
 
1012
        return false;
3375 rajveer 1013
	}
3956 chandransh 1014
 
1015
 
1016
    @Override
1017
    public void closeSession() throws TException {
1018
        // TODO Auto-generated method stub      
1019
    }
4008 mandeep.dh 1020
 
1021
    @Override
1022
    public List<Long> getPaymentsRequiringExtraProcessing (
1023
            ExtraPaymentProcessingType category) throws TException {
1024
        return paymentRequiringExtraProcessingHandler.getPaymentIds(category);
1025
    }
1026
 
1027
    @Override
1028
    public void markPaymentAsProcessed(long paymentId,
1029
            ExtraPaymentProcessingType category) throws TException {
1030
        paymentRequiringExtraProcessingHandler.delete(paymentId, category);
1031
    }
4141 chandransh 1032
 
8907 rajveer 1033
	@Override
8914 rajveer 1034
	public PaymentStatus getPaymentStatusAtGateway(long merchantTxnId, double amount, boolean isDigital) throws PaymentException, TException {
8907 rajveer 1035
	        logger.info("Attempting to get status of payment of amount " + amount + " corresponding to our transaction " + merchantTxnId);
1036
	        List<in.shop2020.payment.domain.Payment> payments;
1037
	        if(isDigital){
1038
	        	payments = paymentHandler.getPaymentForRechargeTxn(merchantTxnId);
1039
	        }else{
1040
	        	payments = paymentHandler.getPaymentForTxn(merchantTxnId);
1041
	        }
1042
	        if(payments ==null || payments.isEmpty())
1043
	            throw new PaymentException(104, "No payments found corresponding to the merchant txn " + merchantTxnId);
1044
 
1045
	        if(payments ==null || payments.isEmpty())
1046
	            throw new PaymentException(104, "No payments found corresponding to the merchant txn " + merchantTxnId);
1047
 
1048
	        in.shop2020.payment.domain.Payment payment = payments.get(0);
1049
	        long gatewayId = payment.getGatewayId();
1050
 
1051
	        if(gatewayId == HDFC_GATEWAY_ID){
1052
	            return HdfcPaymentHandler.validateHdfcPayment(payment, amount);
1053
	        }else if (gatewayId == EBS_GATEWAY_ID){
1054
	            //return validateEbsPayment(payment, amount);
1055
	        } 
1056
	        else if (HDFC_EMI_GATEWAY_IDS.contains(gatewayId)){
1057
	            //return validateHdfcEmiPayment(payment, amount);
1058
	        }
1059
 
1060
	        logger.error("We have an payment from unknown gateway: " + gatewayId);
8914 rajveer 1061
	        return PaymentStatus.INIT;
8907 rajveer 1062
	    }
1063
 
1064
 
1946 chandransh 1065
}