Subversion Repositories SmartDukaan

Rev

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