Subversion Repositories SmartDukaan

Rev

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