private async Task <bool> HasBeenCapturedPreviouslyAsync(HSOrder order, HSPaymentTransaction transaction) { var inquire = await _cardConnect.Inquire(new CardConnectInquireRequest { merchid = transaction.xp.CardConnectResponse.merchid, orderid = order.ID, set = "1", currency = order.xp.Currency.ToString(), retref = transaction.xp.CardConnectResponse.retref }); return(!string.IsNullOrEmpty(inquire.capturedate)); }
private async Task CapturePaymentAsync(HSOrder order, HSPayment payment, HSPaymentTransaction transaction) { try { var response = await _cardConnect.Capture(new CardConnectCaptureRequest { merchid = transaction.xp.CardConnectResponse.merchid, retref = transaction.xp.CardConnectResponse.retref, currency = order.xp.Currency.ToString() }); await _oc.Payments.CreateTransactionAsync(OrderDirection.Incoming, order.ID, payment.ID, CardConnectMapper.Map(payment, response)); } catch (CardConnectInquireException ex) { throw new PaymentCaptureJobException("Error inquiring payment. Message: {ex.ApiError.Message}, ErrorCode: {ex.ApiError.ErrorCode}", order.ID, payment.ID, transaction.ID); } catch (CardConnectCaptureException ex) { await _oc.Payments.CreateTransactionAsync(OrderDirection.Incoming, order.ID, payment.ID, CardConnectMapper.Map(payment, ex.Response)); throw new PaymentCaptureJobException($"Error capturing payment. Message: {ex.ApiError.Message}, ErrorCode: {ex.ApiError.ErrorCode}", order.ID, payment.ID, transaction.ID); } }
public virtual async Task HandleRefundTransaction(HSOrderWorksheet worksheet, HSPayment creditCardPayment, HSPaymentTransaction creditCardPaymentTransaction, decimal totalToRefund, RMA rma) { try { CardConnectRefundRequest requestedRefund = new CardConnectRefundRequest() { currency = worksheet.Order.xp.Currency.ToString(), merchid = creditCardPaymentTransaction.xp.CardConnectResponse.merchid, retref = creditCardPaymentTransaction.xp.CardConnectResponse.retref, amount = totalToRefund.ToString("F2"), }; CardConnectRefundResponse response = await _cardConnect.Refund(requestedRefund); HSPayment newCreditCardPayment = new HSPayment() { Amount = response.amount }; await _oc.Payments.CreateTransactionAsync(OrderDirection.Incoming, rma.SourceOrderID, creditCardPayment.ID, CardConnectMapper.Map(newCreditCardPayment, response)); } catch (CreditCardRefundException ex) { throw new CatalystBaseException(new ApiError { ErrorCode = "Payment.FailedToRefund", Message = ex.ApiError.Message }); } }
public virtual async Task HandleRefund(RMA rma, CosmosListPage <RMA> allRMAsOnThisOrder, HSOrderWorksheet worksheet, DecodedToken decodedToken) { // Get payment info from the order ListPage <HSPayment> paymentResponse = await _oc.Payments.ListAsync <HSPayment>(OrderDirection.Incoming, rma.SourceOrderID); HSPayment creditCardPayment = paymentResponse.Items.FirstOrDefault(payment => payment.Type == OrderCloud.SDK.PaymentType.CreditCard); if (creditCardPayment == null) { // Items were not paid for with a credit card. No refund to process via CardConnect. return; } HSPaymentTransaction creditCardPaymentTransaction = creditCardPayment.Transactions .OrderBy(x => x.DateExecuted) .LastOrDefault(x => x.Type == "CreditCard" && x.Succeeded); decimal purchaseOrderTotal = (decimal)paymentResponse.Items .Where(payment => payment.Type == OrderCloud.SDK.PaymentType.PurchaseOrder) .Select(payment => payment.Amount) .Sum(); // Refund via CardConnect CardConnectInquireResponse inquiry = await _cardConnect.Inquire(new CardConnectInquireRequest { merchid = creditCardPaymentTransaction.xp.CardConnectResponse.merchid, orderid = rma.SourceOrderID, set = "1", currency = worksheet.Order.xp.Currency.ToString(), retref = creditCardPaymentTransaction.xp.CardConnectResponse.retref }); decimal shippingRefund = rma.Type == RMAType.Cancellation ? GetShippingRefundIfCancellingAll(worksheet, rma, allRMAsOnThisOrder) : 0M; decimal lineTotalToRefund = rma.LineItems .Where(li => li.IsResolved && !li.IsRefunded && li.RefundableViaCreditCard && (li.Status == RMALineItemStatus.PartialQtyComplete || li.Status == RMALineItemStatus.Complete) ).Select(li => li.LineTotalRefund) .Sum(); decimal totalToRefund = lineTotalToRefund + shippingRefund; // Update Total Credited on RMA rma.TotalCredited += totalToRefund; // Transactions that are queued for capture can only be fully voided, and we are only allowing partial voids moving forward. if (inquiry.voidable == "Y" && inquiry.setlstat == QUEUED_FOR_CAPTURE) { throw new CatalystBaseException(new ApiError { ErrorCode = "Payment.FailedToVoidAuthorization", Message = "This customer's credit card transaction is currently queued for capture and cannot be refunded at this time. Please try again later." }); } // If voidable, but not refundable, void the refund amount off the original order total if (inquiry.voidable == "Y") { await HandleVoidTransaction(worksheet, creditCardPayment, creditCardPaymentTransaction, totalToRefund, rma); } // If refundable, but not voidable, do a refund if (inquiry.voidable == "N") { await HandleRefundTransaction(worksheet, creditCardPayment, creditCardPaymentTransaction, totalToRefund, rma); } }