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); }
/// <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(); }
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); }