protected virtual void RecordTransaction(ref int?aTranNbr, CCTranType aTranType, CCProcTran aTran, CCProcessingCenter aProcCenter) { //Add later - use ProcessCenter to fill ExpirationDate aTran.ProcessingCenterID = aProcCenter.ProcessingCenterID; aTran.TranType = CCTranTypeCode.GetTypeCode(aTranType); aTran.CVVVerificationStatus = CVVVerificationStatusCode.RelyOnPriorVerification; bool cvvVerified = false; bool needCvvVerification = isCvvVerificationRequired(aTranType); if (needCvvVerification) { bool isStored; CCProcTran verifyTran = this.findCVVVerifyingTran(aTran.PMInstanceID, out isStored); if (verifyTran != null) { cvvVerified = true; } if (!cvvVerified) { aTran.CVVVerificationStatus = CVVVerificationStatusCode.NotVerified; } } aTran.TranNbr = null; aTran.StartTime = aTran.EndTime = PXTimeZoneInfo.Now; if (aTranType != CCTranType.AuthorizeOnly) { aTran.ExpirationDate = null; } aTran.TranStatus = CCTranStatusCode.Approved; aTran.ProcStatus = CCProcStatus.Finalized; aTran = _repository.InsertCCProcTran(aTran); _repository.Save(); aTranNbr = aTran.TranNbr; }
public virtual bool Authorize(ICCPayment aPmtInfo, bool aCapture, ref int aTranNbr) { Customer customer; CustomerPaymentMethod pmInstance = this.findPMInstance(aPmtInfo.PMInstanceID, out customer); if (pmInstance == null) { throw new PXException(Messages.CreditCardWithID_0_IsNotDefined, aPmtInfo.PMInstanceID); } CCProcessingCenter procCenter = _repository.FindProcessingCenter(pmInstance.PMInstanceID, null); if (procCenter == null) { throw new PXException(Messages.ERR_CCProcessingCenterIsNotSpecified, pmInstance.Descr); } if (!(procCenter.IsActive ?? false)) { throw new PXException(Messages.ERR_CCProcessingIsInactive, procCenter.ProcessingCenterID); } if (!IsValidForProcessing(pmInstance, customer)) { return(false); } CCTranType tranType = aCapture ? CCTranType.AuthorizeAndCapture : CCTranType.AuthorizeOnly; CCProcTran tran = new CCProcTran(); tran.Copy(aPmtInfo); return(this.DoTransaction(ref aTranNbr, tranType, tran, null, customer.AcctCD, procCenter)); }
public V2.ProcessingInput GetProcessingInput(CCTranType aTranType, TranProcessingInput inputData) { if (inputData == null) { throw new ArgumentNullException(nameof(inputData)); } V2.CCTranType tranType = V2Converter.ConvertTranTypeToV2(aTranType); V2.ProcessingInput result = new V2.ProcessingInput() { TranType = tranType, Amount = inputData.Amount, CuryID = inputData.CuryID, OrigTranID = aTranType == CCTranType.CaptureOnly ? null : inputData.OrigRefNbr, AuthCode = aTranType == CCTranType.CaptureOnly ? inputData.OrigRefNbr : null }; if (FillCardData) { result.CardData = GetCardData(_provider.GetCardDataReader()); result.CardData.AddressData = GetAddressData(_provider.GetCustomerDataReader()); } if (FillCustomerData) { result.CustomerData = GetCustomerData(_provider.GetCustomerDataReader()); } result.DocumentData = new V2.DocumentData(); result.DocumentData.DocType = inputData.DocType; result.DocumentData.DocRefNbr = inputData.DocRefNbr; FillDocumentData(result); return(result); }
private void RunCallbacks(IBqlTable table, CCTranType tranType, bool success) { foreach (var callback in afterProcessCallbacks) { callback(table, tranType, success); } }
protected virtual void RecordCapture(ICCPayment doc, V2.TransactionData tranData) { var procGraph = PXGraph.CreateInstance <CCPaymentProcessingGraph>(); TranRecordData tranRecordData = FormatTranRecord(tranData); CCTranType tranType = CCTranType.CaptureOnly; if (tranData.TranType == V2.CCTranType.AuthorizeAndCapture) { tranType = CCTranType.AuthorizeAndCapture; procGraph.RecordCapture(doc, tranRecordData); } else if (tranData.TranType == V2.CCTranType.PriorAuthorizedCapture) { tranType = CCTranType.PriorAuthorizedCapture; procGraph.RecordPriorAuthorizedCapture(doc, tranRecordData); } else { procGraph.RecordCaptureOnly(doc, tranRecordData); } foreach (AfterTranProcDelegate callback in GetAfterCaptureActions()) { callback((IBqlTable)doc, tranType, true); } if (ReleaseAfterCapture) { ReleaseARDocument((IBqlTable)doc, tranType, true); } }
public static string GetTypeCode(CCTranType tranType) { if (!_typeCodes.Where(i => i.Item1 == tranType).Any()) { throw new InvalidOperationException(); } return(_typeCodes.Where(i => i.Item1 == tranType).First().Item2); }
public static void CaptureCCPayment <TNode>(TNode doc, PXSelectBase <CCProcTran> ccProcTran, CCPaymentEntry.ReleaseDelegate aReleaseDelegate, UpdateDocStateDelegate aDocStateUpdater, ICCTransactionsProcessor processor = null) where TNode : class, IBqlTable, ICCPayment, new() { if (processor == null) { processor = CCTransactionsProcessor.GetCCTransactionsProcessor(); } if (doc != null && doc.PMInstanceID != null && doc.CuryDocBal != null) { if (CCProcTranHelper.HasOpenCCTran(ccProcTran)) { throw new PXException(Messages.ERR_CCTransactionCurrentlyInProgress); } CCPaymentState paymentState = CCProcTranHelper.ResolveCCPaymentState(ccProcTran.Select()); if ((paymentState & (CCPaymentState.Captured)) > 0) { throw new PXException(Messages.ERR_CCAuthorizedPaymentAlreadyCaptured); } if (doc.Released == false) { ccProcTran.View.Graph.Actions.PressSave(); } CCProcTran authTran = CCProcTranHelper.FindCCPreAthorizing(ccProcTran.Select()); TNode toProc = PXCache <TNode> .CreateCopy(doc); CCProcTran authTranCopy = null; if (authTran != null && !CCProcTranHelper.IsExpired(authTran)) { authTranCopy = PXCache <CCProcTran> .CreateCopy(authTran); } CCTranType operation = (authTranCopy) != null ? CCTranType.PriorAuthorizedCapture : CCTranType.AuthorizeAndCapture; PXLongOperation.StartOperation(ccProcTran.View.Graph, delegate() { try { processor.ProcessCCTransaction(toProc, authTranCopy, operation); } finally { //Update doc state in any case if (aDocStateUpdater != null) { aDocStateUpdater(doc, operation); } } if (aReleaseDelegate != null) { aReleaseDelegate(toProc); //On Success Only } }); } }
public void CaptureCCpayment(ICCPayment doc, IExternalTransactionAdapter paymentTransaction) { if (doc == null || doc.CuryDocBal == null) { return; } ExternalTransactionState state = ExternalTranHelper.GetActiveTransactionState(graph, paymentTransaction.Select()); if (ExternalTranHelper.HasOpenCCProcTran(graph, state.ExternalTransaction)) { throw new PXException(Messages.ERR_CCTransactionCurrentlyInProgress); } if (state.IsCaptured) { throw new PXException(Messages.ERR_CCAuthorizedPaymentAlreadyCaptured); } if (doc.Released == false) { graph.Actions.PressSave(); } ICCPayment toProc = graph.Caches[doc.GetType()].CreateCopy(doc) as ICCPayment; IExternalTransaction tranCopy = null; if (state.IsPreAuthorized && !ExternalTranHelper.IsExpired(state.ExternalTransaction)) { tranCopy = graph.Caches[state.ExternalTransaction.GetType()].CreateCopy(state.ExternalTransaction) as IExternalTransaction; } CCTranType operation = tranCopy != null ? CCTranType.PriorAuthorizedCapture : CCTranType.AuthorizeAndCapture; PXLongOperation.StartOperation(graph, delegate() { bool success = true; try { if (operation == CCTranType.PriorAuthorizedCapture) { TransactionProcessor.ProcessPriorAuthorizedCapture(toProc, tranCopy); } else { TransactionProcessor.ProcessAuthorizeCapture(toProc, tranCopy); } } catch { success = false; throw; } finally { RunCallbacks((IBqlTable)doc, operation, success); } }); }
public static void RecordCCPayment <TNode>(TNode doc, string aExtPCTranNbr, string aPCAuthNbr, PXSelectBase <CCProcTran> ccProcTran, CCPaymentEntry.ReleaseDelegate aReleaseDelegate, UpdateDocStateDelegate aDocStateUpdater) where TNode : class, IBqlTable, ICCPayment, new() { if (doc != null && doc.PMInstanceID != null && doc.CuryDocBal != null) { if (CCProcTranHelper.HasOpenCCTran(ccProcTran)) { throw new PXException(Messages.ERR_CCTransactionCurrentlyInProgress); } if (string.IsNullOrEmpty(aExtPCTranNbr)) { throw new PXException(Messages.ERR_PCTransactionNumberOfTheOriginalPaymentIsRequired); } CCPaymentState paymentState = CCProcTranHelper.ResolveCCPaymentState(ccProcTran.Select()); if ((paymentState & (CCPaymentState.Captured)) > 0) { throw new PXException(Messages.ERR_CCAuthorizedPaymentAlreadyCaptured); } if (doc.Released == false) { ccProcTran.View.Graph.Actions.PressSave(); } TNode toProc = PXCache <TNode> .CreateCopy(doc); CCProcTran authTran = CCProcTranHelper.FindCCPreAthorizing(ccProcTran.Select()); CCTranType operation = CCTranType.AuthorizeAndCapture; PXLongOperation.StartOperation(ccProcTran.View.Graph, delegate() { try { var graph = PXGraph.CreateInstance <CCPaymentProcessingGraph>(); int?tranID = 0; string extTranID = aExtPCTranNbr; graph.RecordCapture(doc, extTranID, aPCAuthNbr, null, ref tranID); } finally { //Update doc state in any case if (aDocStateUpdater != null) { aDocStateUpdater(doc, operation); } } if (aReleaseDelegate != null) { aReleaseDelegate(toProc); //On Success Only } }); } }
public static void RecordCCCredit <TNode>(TNode doc, string aRefPCTranNbr, string aExtPCTranNbr, string aPCAuthNbr, PXSelectBase <CCProcTran> ccProcTran, CCPaymentEntry.ReleaseDelegate aReleaseDelegate, UpdateDocStateDelegate aDocStateUpdater) where TNode : class, IBqlTable, ICCPayment, new() { if (doc != null && doc.PMInstanceID != null && doc.CuryDocBal != null) { if (CCPaymentEntry.HasOpenCCTran(ccProcTran)) { throw new PXException(Messages.ERR_CCTransactionCurrentlyInProgress); } if (string.IsNullOrEmpty(aExtPCTranNbr)) { throw new PXException(Messages.ERR_PCTransactionNumberOfTheOriginalPaymentIsRequired); } CCPaymentState paymentState = CCPaymentEntry.ResolveCCPaymentState(ccProcTran.Select()); if ((paymentState & (CCPaymentState.Refunded)) > 0) { throw new PXException(Messages.ERR_CCPaymentIsAlreadyRefunded); } ccProcTran.View.Graph.Actions.PressSave(); TNode toProc = PXCache <TNode> .CreateCopy(doc); CCTranType operation = CCTranType.Credit; PXLongOperation.StartOperation(ccProcTran.View.Graph, delegate() { try { CCPaymentProcessing ccProcGraph = PXGraph.CreateInstance <CCPaymentProcessing>(); int?tranID; if (ccProcGraph.RecordCredit(doc, aRefPCTranNbr, aExtPCTranNbr, aPCAuthNbr, out tranID)) { } } finally { //Update doc state in any case if (aDocStateUpdater != null) { aDocStateUpdater(doc, operation); } } if (aReleaseDelegate != null) { aReleaseDelegate(toProc); //On Success Only } }); } }
public void RecordCCCredit(ICCPayment doc, ICCManualInputPaymentInfo info, IExternalTransactionAdapter paymentTransaction) { if (doc == null || doc.CuryDocBal == null) { return; } ExternalTransactionState state = ExternalTranHelper.GetActiveTransactionState(graph, paymentTransaction.Select()); if (ExternalTranHelper.HasOpenCCProcTran(graph, state.ExternalTransaction)) { throw new PXException(Messages.ERR_CCTransactionCurrentlyInProgress); } if (string.IsNullOrEmpty(info.PCTranNumber)) { throw new PXException(Messages.ERR_PCTransactionNumberOfTheOriginalPaymentIsRequired); } if (state.IsRefunded) { throw new PXException(Messages.ERR_CCPaymentIsAlreadyRefunded); } if (doc.Released == false) { graph.Actions.PressSave(); } ICCPayment toProc = graph.Caches[doc.GetType()].CreateCopy(doc) as ICCPayment; CCTranType operation = CCTranType.Credit; PXLongOperation.StartOperation(graph, delegate() { bool success = true; try { var procGraph = PXGraph.CreateInstance <CCPaymentProcessingGraph>(); TranRecordData recordData = new TranRecordData(); recordData.RefExternalTranId = toProc.RefTranExtNbr; recordData.ExternalTranId = info.PCTranNumber; recordData.AuthCode = info.AuthNumber; procGraph.RecordCredit(doc, recordData); } catch { success = false; throw; } finally { RunCallbacks((IBqlTable)doc, operation, success); } }); }
public static void CheckForHeldForReviewStatusAfterProc(IBqlTable aTable, CCTranType procTran, bool success) { ICCPayment doc = aTable as ICCPayment; if (doc != null && success) { var graph = PXGraph.CreateInstance <ARPaymentEntry>(); var query = new PXSelect <ExternalTransaction, Where <ExternalTransaction.docType, Equal <Required <ExternalTransaction.docType> >, And <ExternalTransaction.refNbr, Equal <Required <ExternalTransaction.refNbr> > > >, OrderBy <Desc <ExternalTransaction.transactionID> > >(graph); var result = query.Select(doc.DocType, doc.RefNbr); ExternalTransactionState state = ExternalTranHelper.GetActiveTransactionState(graph, result.RowCast <ExternalTransaction>()); if (state.IsOpenForReview) { throw new PXSetPropertyException(AR.Messages.CCProcessingTranHeldWarning, PXErrorLevel.RowWarning); } } }
public TranProcessingResult DoTransaction(CCTranType aTranType, TranProcessingInput inputData) { V2.ICCTransactionProcessor processor = GetProcessor <V2.ICCTransactionProcessor>(); var inputGenerator = new V2ProcessingInputGenerator(_provider); var processingInput = inputGenerator.GetProcessingInput(aTranType, inputData); V2.ProcessingResult v2Result = processor.DoTransaction(processingInput); TranProcessingResult result = V2Converter.ConvertTranProcessingResult(v2Result); V2.ICCTranStatusGetter tranStatusGetter = _plugin.CreateProcessor <V2.ICCTranStatusGetter>(null); if (tranStatusGetter != null) { V2.CCTranStatus tranStatus = tranStatusGetter.GetTranStatus(v2Result); result.TranStatus = V2Converter.ConvertTranStatus(tranStatus); } return(result); }
public static void ReleaseARDocument(IBqlTable aTable, CCTranType procTran, bool success) { AR.ARRegister doc = aTable as AR.ARRegister; if (doc != null && success) { ExternalTransaction tran = null; PXGraph graph = null; if (doc.DocType == ARDocType.CashSale || doc.DocType == ARDocType.CashReturn) { ARCashSaleEntry cashSaleGraph = PXGraph.CreateInstance <ARCashSaleEntry>(); cashSaleGraph.Document.Current = PXSelect <ARCashSale, Where <ARCashSale.docType, Equal <Required <ARCashSale.docType> >, And <ARCashSale.refNbr, Equal <Required <ARCashSale.refNbr> > > > > .SelectWindowed(cashSaleGraph, 0, 1, doc.DocType, doc.RefNbr); tran = cashSaleGraph.ExternalTran.SelectSingle(doc.DocType, doc.RefNbr); graph = cashSaleGraph; } else { ARPaymentEntry paymentGraph = PXGraph.CreateInstance <ARPaymentEntry>(); paymentGraph.Document.Current = PXSelect <AR.ARPayment, Where <AR.ARPayment.docType, Equal <Required <AR.ARPayment.docType> >, And <AR.ARPayment.refNbr, Equal <Required <AR.ARPayment.refNbr> > > > > .SelectWindowed(paymentGraph, 0, 1, doc.DocType, doc.RefNbr); tran = paymentGraph.ExternalTran.SelectSingle(doc.DocType, doc.RefNbr); graph = paymentGraph; } if (tran != null) { ExternalTransactionState state = ExternalTranHelper.GetTransactionState(graph, tran); if (!state.IsDeclined && !state.IsOpenForReview) { ReleaseARDocument(aTable); } } } }
public static void ProcessCCTransaction(ICCPayment aDoc, CCProcTran refTran, CCTranType aTranType) { if (aDoc != null && aDoc.PMInstanceID != null && aDoc.CuryDocBal != null) { CCPaymentProcessing processBO = new CCPaymentProcessing(); int tranID = 0; bool result = false; bool processed = false; if (aTranType == CCTranType.AuthorizeOnly || aTranType == CCTranType.AuthorizeAndCapture) { bool doCapture = (aTranType == CCTranType.AuthorizeAndCapture); result = processBO.Authorize(aDoc, doCapture, ref tranID); processed = true; } if (aTranType == CCTranType.PriorAuthorizedCapture) { if (refTran == null) { throw new PXException(Messages.ERR_CCTransactionMustBeAuthorizedBeforeCapturing); } result = processBO.Capture(aDoc.PMInstanceID, refTran.TranNbr, aDoc.CuryID, aDoc.CuryDocBal, ref tranID); processed = true; } if (aTranType == CCTranType.Void) { if (refTran == null) { throw new PXException(Messages.ERR_CCOriginalTransactionNumberIsRequiredForVoiding); } result = processBO.Void(aDoc.PMInstanceID, refTran.TranNbr, ref tranID); processed = true; } if (aTranType == CCTranType.VoidOrCredit) { if (refTran == null) { throw new PXException(Messages.ERR_CCOriginalTransactionNumberIsRequiredForVoidingOrCrediting); } result = processBO.VoidOrCredit(aDoc.PMInstanceID, refTran.TranNbr, ref tranID); processed = true; } if (aTranType == CCTranType.Credit) { if (refTran == null) { throw new PXException(Messages.ERR_CCOriginalTransactionNumberIsRequiredForCrediting); } if (refTran.TranNbr.HasValue) { result = processBO.Credit(aDoc, refTran.TranNbr.Value, ref tranID); } else { result = processBO.Credit(aDoc, refTran.PCTranNumber, ref tranID); } processed = true; } if (aTranType == CCTranType.CaptureOnly) { //Uses Authorization Number received from Processing center in a special way (for example, by phone) if (refTran == null || string.IsNullOrEmpty(refTran.AuthNumber)) { throw new PXException(Messages.ERR_CCExternalAuthorizationNumberIsRequiredForCaptureOnlyTrans); } result = processBO.CaptureOnly(aDoc, refTran.AuthNumber, ref tranID); processed = true; } if (!processed) { throw new PXException(Messages.ERR_CCUnknownOperationType); } if (!result) { throw new PXException(Messages.ERR_CCTransactionWasNotAuthorizedByProcCenter, tranID); } } }
abstract public bool DoTransaction(CCTranType aType, ProcessingInput aInputData, ProcessingResult aResult);
abstract public bool IsSupported(CCTranType aType);
protected static bool isCvvVerificationRequired(CCTranType aType) { return(aType == CCTranType.AuthorizeOnly || aType == CCTranType.AuthorizeAndCapture); }
protected virtual bool DoTransaction(ref int aTranNbr, CCTranType aTranType, CCProcTran aTran, CCProcTran aRefTran, string aCustomerCD, CCProcessingCenter aProcCenter) { if (aProcCenter == null) { aProcCenter = _repository.FindProcessingCenter(aTran.PMInstanceID, aTran.CuryID); } if (aProcCenter == null || string.IsNullOrEmpty(aProcCenter.ProcessingTypeName)) { throw new PXException(Messages.ERR_ProcessingCenterForCardNotConfigured); } CashAccount cashAccount = _repository.GetCashAccount(aProcCenter.CashAccountID); if (cashAccount.CuryID != aTran.CuryID) { throw new PXException(Messages.ProcessingCenterCurrencyDoesNotMatch, aTran.CuryID, cashAccount.CuryID); } aTran.ProcessingCenterID = aProcCenter.ProcessingCenterID; aTran.TranType = CCTranTypeCode.GetTypeCode(aTranType); aTran.CVVVerificationStatus = CVVVerificationStatusCode.RelyOnPriorVerification; bool cvvVerified = false; bool needCvvVerification = isCvvVerificationRequired(aTranType); if (needCvvVerification) { bool isStored; CCProcTran verifyTran = this.findCVVVerifyingTran(aTran.PMInstanceID, out isStored); if (verifyTran != null) { cvvVerified = true; if (!isStored) { this.UpdateCvvVerificationStatus(verifyTran); } } if (!cvvVerified) { aTran.CVVVerificationStatus = CVVVerificationStatusCode.NotVerified; } } aTran = this.StartTransaction(aTran, aProcCenter.OpenTranTimeout); aTranNbr = aTran.TranNbr.Value; ProcessingInput inputData = new ProcessingInput(); Copy(inputData, aTran); if (!string.IsNullOrEmpty(aCustomerCD)) { inputData.CustomerCD = aCustomerCD; } if (aRefTran != null) { inputData.OrigRefNbr = (aTranType == CCTranType.CaptureOnly) ? aRefTran.AuthNumber : aRefTran.PCTranNumber; } if (needCvvVerification) { inputData.VerifyCVV = !cvvVerified; } CCProcessingContext context = new CCProcessingContext() { callerGraph = _repository.Graph, processingCenter = aProcCenter, aCustomerCD = aCustomerCD, aPMInstanceID = inputData.PMInstanceID, aDocType = inputData.DocType, aRefNbr = inputData.DocRefNbr, }; var processor = GetProcessingWrapper(context); ProcessingResult result = new ProcessingResult(); bool hasError = false; try { result = processor.DoTransaction(aTranType, inputData); PXTrace.WriteInformation($"CCPaymentProcessing.DoTransaction. PCTranNumber:{result.PCTranNumber}; PCResponseCode:{result.PCResponseCode}; PCResponseReasonCode:{result.PCResponseReasonCode}; PCResponseReasonText:{result.PCResponseReasonText}; ErrorText:{result.ErrorText}"); } catch (V2.CCProcessingException procException) { hasError = true; result.ErrorSource = CCErrors.CCErrorSource.ProcessingCenter; string errorMessage = String.Empty; if (procException.Message.Equals(procException?.InnerException?.Message)) { errorMessage = procException.Message; } else { errorMessage = procException.Message + "; " + procException?.InnerException?.Message; } result.ErrorText = errorMessage; result.PCResponseReasonText += errorMessage; PXTrace.WriteInformation($"CCPaymentProcessing.DoTransaction.V2.CCProcessingException. ErrorSource:{result.ErrorSource}; ErrorText:{result.ErrorText}"); } catch (WebException webExn) { hasError = true; result.ErrorSource = CCErrors.CCErrorSource.Network; result.ErrorText = webExn.Message; PXTrace.WriteInformation($"CCPaymentProcessing.DoTransaction.WebException. ErrorSource:{result.ErrorSource}; ErrorText:{result.ErrorText}"); } catch (Exception exn) { hasError = true; result.ErrorSource = CCErrors.CCErrorSource.Internal; result.ErrorText = exn.Message; throw new PXException(Messages.ERR_CCPaymentProcessingInternalError, aTranNbr, exn.Message); } finally { CCProcTran tran = this.EndTransaction(aTranNbr, result, (hasError ? CCProcStatus.Error : CCProcStatus.Finalized)); if (!hasError) { this.ProcessTranResult(tran, aRefTran, result); } } return(result.isAuthorized); }
public static string GetTypeCode(CCTranType aType) { return(_typeCodes[(int)aType]); }
public override bool IsSupported(CCTranType aType) { return(false); }
public override bool DoTransaction(CCTranType aType, ProcessingInput aInputData, ProcessingResult aResult) { return(false); }
public static V2.CCTranType ConvertTranTypeToV2(CCTranType tranType) { return(Mapper.Map <V2.CCTranType>(tranType)); }