Ejemplo n.º 1
0
        public Response RetrievePaymentAcceptResult([FromBody] Request request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            if (request.Properties == null)
            {
                throw new ArgumentException("request.Properties cannot be null.");
            }

            // Initialize response
            var errorList = new List <PaymentError>();
            var response  = new Response()
            {
                Locale = request.Locale,
            };

            // Validate merchant information
            ValidateMerchantAccount(request, errorList);

            // Get result access code from request
            var    requestProperties = PaymentProperty.ConvertToHashtable(request.Properties);
            string serviceAccountId  = GetPropertyStringValue(
                requestProperties,
                GenericNamespace.MerchantAccount,
                MerchantAccountProperties.ServiceAccountId,
                required: true,
                errors: errorList);
            string resultAccessCode = GetPropertyStringValue(
                requestProperties,
                GenericNamespace.TransactionData,
                TransactionDataProperties.PaymentAcceptResultAccessCode,
                required: true,
                errors: errorList);

            if (errorList.Count > 0)
            {
                response.Errors = errorList.ToArray();
                return(response);
            }

            // Retrieve payment result if no errors
            var dataManager = new DataManager();
            CardPaymentResult cardPaymentResult = dataManager.GetCardPaymentResultByResultAccessCode(serviceAccountId, resultAccessCode);

            if (cardPaymentResult == null)
            {
                // Result does not exist.
                errorList.Add(new PaymentError(ErrorCode.InvalidRequest, "Invalid payment result access code."));
                response.Errors = errorList.ToArray();
                return(response);
            }

            // Success
            response = JsonConvert.DeserializeObject <Response>(cardPaymentResult.ResultData);
            return(response);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Gets the string value of a payment property.
        /// </summary>
        /// <param name="propertyHashtable">The property hashtable.</param>
        /// <param name="propertyNamespace">The namespace.</param>
        /// <param name="propertyName">The name.</param>
        /// <param name="required">The flag indicating whether the property is required.</param>
        /// <param name="errors">The error list in case the property is required but not found.</param>
        /// <returns>The string value.</returns>
        private static string GetPropertyStringValue(Dictionary <string, object> propertyHashtable, string propertyNamespace, string propertyName, bool required, List <PaymentError> errors)
        {
            string propertyValue;
            bool   found = PaymentProperty.GetPropertyValue(
                propertyHashtable,
                propertyNamespace,
                propertyName,
                out propertyValue);

            if (!found && required)
            {
                var error = new PaymentError(ErrorCode.InvalidRequest, string.Format(CultureInfo.InvariantCulture, "Property '{0}' is null or not set", propertyName));
                errors.Add(error);
            }

            return(propertyValue);
        }
        /// <summary>
        /// Sets the request properties.
        /// </summary>
        /// <param name="value">The property array.</param>
        public void SetProperties(object[] value)
        {
            List <PaymentProperty> list = new List <PaymentProperty>();

            if (value != null)
            {
                object[] objArray = value;
                for (int i = 0; i < objArray.Length; i++)
                {
                    PaymentProperty property = objArray[i] as PaymentProperty;
                    if (property != null)
                    {
                        list.Add(property);
                    }
                }
            }

            this.properties = list.ToArray();
        }
Ejemplo n.º 4
0
        private static CardPaymentEntry ConvertRequestToCardPaymentEntry(Request request, List <PaymentError> errorList)
        {
            string locale = request.Locale;

            if (string.IsNullOrWhiteSpace(locale))
            {
                errorList.Add(new PaymentError(ErrorCode.LocaleNotSupported, "Locale is not specified."));
            }

            var requestProperties = PaymentProperty.ConvertToHashtable(request.Properties);

            string serviceAccountId = GetPropertyStringValue(
                requestProperties,
                GenericNamespace.MerchantAccount,
                MerchantAccountProperties.ServiceAccountId,
                required: true,
                errors: errorList);

            string industryType = GetPropertyStringValue(
                requestProperties,
                GenericNamespace.TransactionData,
                TransactionDataProperties.IndustryType,
                required: false,
                errors: errorList);
            IndustryType industryTypeEnum;

            if (string.IsNullOrEmpty(industryType) || !Enum.TryParse(industryType, true, out industryTypeEnum))
            {
                industryTypeEnum = IndustryType.Ecommerce;
            }

            string transactionType = GetPropertyStringValue(
                requestProperties,
                GenericNamespace.TransactionData,
                TransactionDataProperties.TransactionType,
                required: true,
                errors: errorList);
            TransactionType transactionTypeEnum = TransactionType.None;

            if (!Enum.TryParse(transactionType, true, out transactionTypeEnum) ||
                (transactionTypeEnum != TransactionType.None && transactionTypeEnum != TransactionType.Authorize && transactionTypeEnum != TransactionType.Capture))
            {
                errorList.Add(new PaymentError(ErrorCode.InvalidRequest, "The transaction type is not suppoted."));
            }

            string supportCardSwipeString = GetPropertyStringValue(
                requestProperties,
                GenericNamespace.TransactionData,
                TransactionDataProperties.SupportCardSwipe,
                required: false,
                errors: errorList);
            bool supportCardSwipe = false;

            if (!string.IsNullOrWhiteSpace(supportCardSwipeString))
            {
                bool.TryParse(supportCardSwipeString, out supportCardSwipe);
            }

            string supportCardTokenizationString = GetPropertyStringValue(
                requestProperties,
                GenericNamespace.TransactionData,
                TransactionDataProperties.SupportCardTokenization,
                required: false,
                errors: errorList);
            bool supportCardTokenization = false;

            if (!string.IsNullOrWhiteSpace(supportCardTokenizationString))
            {
                bool.TryParse(supportCardTokenizationString, out supportCardTokenization);
            }

            // When transaction type is None, support card tokenization must be enabled.
            if (transactionTypeEnum == TransactionType.None && !supportCardTokenization)
            {
                errorList.Add(new PaymentError(ErrorCode.InvalidRequest, "When transaction type is None, support card tokenization must be enabled."));
            }

            string allowVoiceAuthorizationString = GetPropertyStringValue(
                requestProperties,
                GenericNamespace.TransactionData,
                TransactionDataProperties.AllowVoiceAuthorization,
                required: false,
                errors: errorList);
            bool allowVoiceAuthorization = false;

            if (!string.IsNullOrWhiteSpace(allowVoiceAuthorizationString))
            {
                bool.TryParse(allowVoiceAuthorizationString, out allowVoiceAuthorization);
            }

            string hostPageOrigin = GetPropertyStringValue(
                requestProperties,
                GenericNamespace.TransactionData,
                TransactionDataProperties.HostPageOrigin,
                required: true,
                errors: errorList);

            if (string.IsNullOrWhiteSpace(hostPageOrigin))
            {
                errorList.Add(new PaymentError(ErrorCode.InvalidRequest, "The host page origin is not specified."));
            }

            string cardTypes = GetPropertyStringValue(
                requestProperties,
                GenericNamespace.PaymentCard,
                PaymentCardProperties.CardType,
                required: false,
                errors: errorList);

            string defaultCardHolderName = GetPropertyStringValue(
                requestProperties,
                GenericNamespace.PaymentCard,
                PaymentCardProperties.Name,
                required: false,
                errors: errorList);

            string defaultStreet1 = GetPropertyStringValue(
                requestProperties,
                GenericNamespace.PaymentCard,
                PaymentCardProperties.StreetAddress,
                required: false,
                errors: errorList);

            string defaultStreet2 = GetPropertyStringValue(
                requestProperties,
                GenericNamespace.PaymentCard,
                PaymentCardProperties.StreetAddress2,
                required: false,
                errors: errorList);

            string defaultCity = GetPropertyStringValue(
                requestProperties,
                GenericNamespace.PaymentCard,
                PaymentCardProperties.City,
                required: false,
                errors: errorList);

            string defaultStateOrProvince = GetPropertyStringValue(
                requestProperties,
                GenericNamespace.PaymentCard,
                PaymentCardProperties.State,
                required: false,
                errors: errorList);

            string defaultPostalCode = GetPropertyStringValue(
                requestProperties,
                GenericNamespace.PaymentCard,
                PaymentCardProperties.PostalCode,
                required: false,
                errors: errorList);

            string defaultCountryCode = GetPropertyStringValue(
                requestProperties,
                GenericNamespace.PaymentCard,
                PaymentCardProperties.Country,
                required: false,
                errors: errorList);

            string showSameAsShippingAddressString = GetPropertyStringValue(
                requestProperties,
                GenericNamespace.PaymentCard,
                PaymentCardProperties.ShowSameAsShippingAddress,
                required: false,
                errors: errorList);

            bool showSameAsShippingAddress = false;

            if (!string.IsNullOrWhiteSpace(showSameAsShippingAddressString))
            {
                bool.TryParse(showSameAsShippingAddressString, out showSameAsShippingAddress);
            }

            string entryData = JsonConvert.SerializeObject(request);

            // Create the request in database with an unique entry ID
            var cardPaymentEntry = new CardPaymentEntry()
            {
                AllowVoiceAuthorization = allowVoiceAuthorization,
                CardTypes              = CardTypes.GetSupportedCardTypes(cardTypes),
                DefaultCardHolderName  = defaultCardHolderName,
                DefaultCity            = defaultCity,
                DefaultCountryCode     = defaultCountryCode,
                DefaultPostalCode      = defaultPostalCode,
                DefaultStateOrProvince = defaultStateOrProvince,
                DefaultStreet1         = defaultStreet1,
                DefaultStreet2         = defaultStreet2,
                EntryData              = entryData,
                EntryId                   = CommonUtility.NewGuid().ToString(),
                EntryLocale               = locale,
                EntryUtcTime              = DateTime.UtcNow,
                HostPageOrigin            = hostPageOrigin,
                IndustryType              = industryTypeEnum.ToString(),
                ServiceAccountId          = serviceAccountId,
                ShowSameAsShippingAddress = showSameAsShippingAddress,
                SupportCardSwipe          = supportCardSwipe,
                SupportCardTokenization   = supportCardTokenization,
                TransactionType           = transactionType,
                Used = false,
            };

            return(cardPaymentEntry);
        }
        /// <summary>
        /// Combines various responses into one.
        /// </summary>
        /// <param name="tokenizeResponse">The tokenize response.</param>
        /// <param name="authorizeResponse">The authorize response.</param>
        /// <param name="captureResponse">The capture response.</param>
        /// <param name="voidResponse">The void response.</param>
        /// <returns>The combined response.</returns>
        private Response CombineResponses(Response tokenizeResponse, Response authorizeResponse, Response captureResponse, Response voidResponse)
        {
            Response paymentResponse = new Response();
            var      properties      = new List <PaymentProperty>();
            var      errors          = new List <PaymentError>();

            if (tokenizeResponse != null)
            {
                // Start with tokenize response
                paymentResponse.Locale = tokenizeResponse.Locale;

                if (tokenizeResponse.Properties != null)
                {
                    properties.AddRange(tokenizeResponse.Properties);
                }

                if (tokenizeResponse.Errors != null)
                {
                    errors.AddRange(tokenizeResponse.Errors);
                }

                // Merge with authorize response
                if (authorizeResponse != null)
                {
                    if (authorizeResponse.Properties != null)
                    {
                        var             authorizeResponseProperties    = PaymentProperty.ConvertToHashtable(authorizeResponse.Properties);
                        PaymentProperty innerAuthorizeResponseProperty = PaymentProperty.GetPropertyFromHashtable(
                            authorizeResponseProperties,
                            GenericNamespace.AuthorizationResponse,
                            AuthorizationResponseProperties.Properties);
                        properties.Add(innerAuthorizeResponseProperty);
                    }

                    if (authorizeResponse.Errors != null)
                    {
                        errors.AddRange(authorizeResponse.Errors);
                    }
                }
            }
            else if (authorizeResponse != null)
            {
                // Start with Authorize response
                paymentResponse.Locale = authorizeResponse.Locale;

                if (authorizeResponse.Properties != null)
                {
                    properties.AddRange(authorizeResponse.Properties);
                }

                if (authorizeResponse.Errors != null)
                {
                    errors.AddRange(authorizeResponse.Errors);
                }
            }

            // Merge with authorize response
            if (captureResponse != null)
            {
                if (captureResponse.Properties != null)
                {
                    var             captureResponseProperties    = PaymentProperty.ConvertToHashtable(captureResponse.Properties);
                    PaymentProperty innerCaptureResponseProperty = PaymentProperty.GetPropertyFromHashtable(
                        captureResponseProperties,
                        GenericNamespace.CaptureResponse,
                        CaptureResponseProperties.Properties);
                    properties.Add(innerCaptureResponseProperty);
                }

                if (captureResponse.Errors != null)
                {
                    errors.AddRange(captureResponse.Errors);
                }
            }

            // Merge with void response
            if (voidResponse != null)
            {
                if (voidResponse.Properties != null)
                {
                    var             voidResponseProperties    = PaymentProperty.ConvertToHashtable(voidResponse.Properties);
                    PaymentProperty innerVoidResponseProperty = PaymentProperty.GetPropertyFromHashtable(
                        voidResponseProperties,
                        GenericNamespace.VoidResponse,
                        VoidResponseProperties.Properties);
                    properties.Add(innerVoidResponseProperty);
                }

                if (voidResponse.Errors != null)
                {
                    errors.AddRange(voidResponse.Errors);
                }
            }

            if (properties.Count > 0)
            {
                paymentResponse.Properties = properties.ToArray();
            }

            if (errors.Count > 0)
            {
                paymentResponse.Errors = errors.ToArray();
            }

            return(paymentResponse);
        }
        /// <summary>
        /// Process the card payment, e.g. Tokenize, Authorize, Capture.
        /// </summary>
        /// <param name="paymentEntry">The card payment entry.</param>
        /// <returns>The payment result.</returns>
        private CardPaymentResult ProcessPayment(CardPaymentEntry paymentEntry)
        {
            // Get payment processor
            var processor = new SampleConnector();

            // Prepare payment request
            var paymentRequest = new Request();

            paymentRequest.Locale = paymentEntry.EntryLocale;

            // Get payment properties from payment entry which contains the merchant information.
            Request entryData = JsonConvert.DeserializeObject <Request>(paymentEntry.EntryData);

            PaymentProperty[] entryPaymentProperties = entryData.Properties;
            var requestProperties = new List <PaymentProperty>();

            // Filter payment card properties (they are default card data, not final card data)
            foreach (var entryPaymentProperty in entryPaymentProperties)
            {
                if (entryPaymentProperty.Namespace != GenericNamespace.PaymentCard)
                {
                    requestProperties.Add(entryPaymentProperty);
                }
            }

            // Add final card data
            PaymentProperty property;

            if (this.isSwipe)
            {
                property = new PaymentProperty(
                    GenericNamespace.PaymentCard,
                    PaymentCardProperties.CardEntryType,
                    CardEntryTypes.MagneticStripeRead.ToString());
                requestProperties.Add(property);

                if (!string.IsNullOrWhiteSpace(this.track1))
                {
                    property = new PaymentProperty(
                        GenericNamespace.PaymentCard,
                        PaymentCardProperties.Track1,
                        this.track1);
                    requestProperties.Add(property);
                }

                if (!string.IsNullOrWhiteSpace(this.track2))
                {
                    property = new PaymentProperty(
                        GenericNamespace.PaymentCard,
                        PaymentCardProperties.Track2,
                        this.track2);
                    requestProperties.Add(property);
                }
            }
            else
            {
                property = new PaymentProperty(
                    GenericNamespace.PaymentCard,
                    PaymentCardProperties.CardEntryType,
                    CardEntryTypes.ManuallyEntered.ToString());
                requestProperties.Add(property);
            }

            property = new PaymentProperty(
                GenericNamespace.PaymentCard,
                PaymentCardProperties.CardType,
                this.cardType);
            requestProperties.Add(property);

            property = new PaymentProperty(
                GenericNamespace.PaymentCard,
                PaymentCardProperties.CardNumber,
                this.cardNumber);
            requestProperties.Add(property);

            property = new PaymentProperty(
                GenericNamespace.PaymentCard,
                PaymentCardProperties.ExpirationMonth,
                this.cardExpirationMonth);
            requestProperties.Add(property);

            property = new PaymentProperty(
                GenericNamespace.PaymentCard,
                PaymentCardProperties.ExpirationYear,
                this.cardExpirationYear);
            requestProperties.Add(property);

            if (!string.IsNullOrWhiteSpace(this.cardSecurityCode))
            {
                property = new PaymentProperty(
                    GenericNamespace.PaymentCard,
                    PaymentCardProperties.AdditionalSecurityData,
                    this.cardSecurityCode);
                requestProperties.Add(property);
            }

            property = new PaymentProperty(
                GenericNamespace.PaymentCard,
                PaymentCardProperties.Name,
                this.cardHolderName);
            requestProperties.Add(property);

            property = new PaymentProperty(
                GenericNamespace.PaymentCard,
                PaymentCardProperties.StreetAddress,
                this.cardStreet1);
            requestProperties.Add(property);

            property = new PaymentProperty(
                GenericNamespace.PaymentCard,
                PaymentCardProperties.City,
                this.cardCity);
            requestProperties.Add(property);

            property = new PaymentProperty(
                GenericNamespace.PaymentCard,
                PaymentCardProperties.State,
                this.cardStateOrProvince);
            requestProperties.Add(property);

            property = new PaymentProperty(
                GenericNamespace.PaymentCard,
                PaymentCardProperties.PostalCode,
                this.cardPostalCode);
            requestProperties.Add(property);

            property = new PaymentProperty(
                GenericNamespace.PaymentCard,
                PaymentCardProperties.Country,
                this.cardCountryOrRegion);
            requestProperties.Add(property);

            // Tokenize the card if requested
            Response tokenizeResponse = null;

            if (paymentEntry.SupportCardTokenization)
            {
                paymentRequest.Properties = requestProperties.ToArray();
                tokenizeResponse          = processor.GenerateCardToken(paymentRequest, null);
                if (tokenizeResponse.Errors != null && tokenizeResponse.Errors.Any())
                {
                    // Tokenization failure, Throw an exception and stop the payment.
                    throw new CardPaymentException("Tokenization failure.", tokenizeResponse.Errors);
                }
            }

            // Authorize and Capture if requested
            // Do not authorize if tokenization failed.
            Response        authorizeResponse = null;
            Response        captureResponse   = null;
            Response        voidResponse      = null;
            TransactionType transactionType   = (TransactionType)Enum.Parse(typeof(TransactionType), paymentEntry.TransactionType, true);

            if (transactionType == TransactionType.Authorize || transactionType == TransactionType.Capture)
            {
                // Add request properties for Authorize and Capture
                if (!string.IsNullOrWhiteSpace(this.voiceAuthorizationCode))
                {
                    property = new PaymentProperty(
                        GenericNamespace.PaymentCard,
                        PaymentCardProperties.VoiceAuthorizationCode,
                        this.voiceAuthorizationCode);
                    requestProperties.Add(property);
                }

                property = new PaymentProperty(
                    GenericNamespace.TransactionData,
                    TransactionDataProperties.Amount,
                    this.paymentAmount);
                requestProperties.Add(property);

                // Authorize payment
                paymentRequest.Properties = requestProperties.ToArray();
                authorizeResponse         = processor.Authorize(paymentRequest, null);
                if (authorizeResponse.Errors != null && authorizeResponse.Errors.Any())
                {
                    // Authorization failure, Throw an exception and stop the payment.
                    throw new CardPaymentException("Authorization failure.", authorizeResponse.Errors);
                }

                if (transactionType == TransactionType.Capture)
                {
                    // Check authorization result
                    var             authorizeResponseProperties    = PaymentProperty.ConvertToHashtable(authorizeResponse.Properties);
                    PaymentProperty innerAuthorizeResponseProperty = PaymentProperty.GetPropertyFromHashtable(
                        authorizeResponseProperties,
                        GenericNamespace.AuthorizationResponse,
                        AuthorizationResponseProperties.Properties);

                    var innerAuthorizeResponseProperties = PaymentProperty.ConvertToHashtable(innerAuthorizeResponseProperty.PropertyList);

                    string authorizationResult = null;
                    PaymentProperty.GetPropertyValue(
                        innerAuthorizeResponseProperties,
                        GenericNamespace.AuthorizationResponse,
                        AuthorizationResponseProperties.AuthorizationResult,
                        out authorizationResult);

                    // TO DO: In this sample, we only check the authorization results. CVV2 result and AVS result are ignored.
                    if (AuthorizationResult.Success.ToString().Equals(authorizationResult, StringComparison.OrdinalIgnoreCase))
                    {
                        // Authorize success...
                        // Get authorized amount
                        decimal authorizedAmount = 0m;
                        PaymentProperty.GetPropertyValue(
                            innerAuthorizeResponseProperties,
                            GenericNamespace.AuthorizationResponse,
                            AuthorizationResponseProperties.ApprovedAmount,
                            out authorizedAmount);

                        // Update capture amount for partial authorization
                        if (this.paymentAmount != authorizedAmount)
                        {
                            foreach (var requestProperty in requestProperties)
                            {
                                if (GenericNamespace.TransactionData.Equals(requestProperty.Namespace) &&
                                    TransactionDataProperties.Amount.Equals(requestProperty.Name))
                                {
                                    requestProperty.DecimalValue = authorizedAmount;
                                    break;
                                }
                            }
                        }

                        // Capture payment
                        property = new PaymentProperty(
                            GenericNamespace.AuthorizationResponse,
                            AuthorizationResponseProperties.Properties,
                            innerAuthorizeResponseProperty.PropertyList);
                        requestProperties.Add(property);

                        paymentRequest.Properties = requestProperties.ToArray();
                        captureResponse           = processor.Capture(paymentRequest);

                        // Check capture result
                        var             captureResponseProperties    = PaymentProperty.ConvertToHashtable(captureResponse.Properties);
                        PaymentProperty innerCaptureResponseProperty = PaymentProperty.GetPropertyFromHashtable(
                            captureResponseProperties,
                            GenericNamespace.CaptureResponse,
                            CaptureResponseProperties.Properties);

                        var innerCaptureResponseProperties = PaymentProperty.ConvertToHashtable(innerCaptureResponseProperty.PropertyList);

                        string captureResult = null;
                        PaymentProperty.GetPropertyValue(
                            innerCaptureResponseProperties,
                            GenericNamespace.CaptureResponse,
                            CaptureResponseProperties.CaptureResult,
                            out captureResult);

                        if (!CaptureResult.Success.ToString().Equals(captureResult, StringComparison.OrdinalIgnoreCase))
                        {
                            // Capture failure, we have to void authorization and return the payment result.
                            voidResponse = processor.Void(paymentRequest);
                        }
                    }
                    else
                    {
                        // Authorization failure, Throw an exception and stop the payment.
                        var errors = new List <PaymentError>();
                        errors.Add(new PaymentError(ErrorCode.AuthorizationFailure, "Authorization failure."));
                        throw new CardPaymentException("Authorization failure.", errors);
                    }
                }
            }

            // Combine responses into one.
            Response paymentResponse = this.CombineResponses(tokenizeResponse, authorizeResponse, captureResponse, voidResponse);

            // Save payment result
            CardPaymentResult result = null;

            if (paymentResponse != null)
            {
                // Success
                paymentResponse.Properties = PaymentProperty.RemoveDataEncryption(paymentResponse.Properties);

                result                  = new CardPaymentResult();
                result.EntryId          = paymentEntry.EntryId;
                result.ResultAccessCode = CommonUtility.NewGuid().ToString();
                result.ResultData       = JsonConvert.SerializeObject(paymentResponse);
                result.Retrieved        = false;
                result.ServiceAccountId = paymentEntry.ServiceAccountId;
            }
            else
            {
                this.InputErrorsHiddenField.Value = WebResources.CardPage_Error_InvalidCard;
            }

            return(result);
        }