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> /// Finds a record in CardPaymentResult table by result access code. /// </summary> /// <param name="serviceAccountId">The service account ID. It guarantees only the account generates the result can retrieve the result.</param> /// <param name="resultAccessCode">The result access code.</param> /// <returns>The found record.</returns> public CardPaymentResult GetCardPaymentResultByResultAccessCode(string serviceAccountId, string resultAccessCode) { if (serviceAccountId == null) { throw new ArgumentNullException("serviceAccountId"); } if (resultAccessCode == null) { throw new ArgumentNullException("resultAccessCode"); } CardPaymentResult cardPaymentResult = null; using (SqlConnection connection = new SqlConnection(this.connectionString)) { connection.Open(); using (SqlCommand command = new SqlCommand(GetCardPaymentResultByResultAccessCodeSprocName, connection)) { command.CommandType = CommandType.StoredProcedure; command.Parameters.AddWithValue("@nvc_ServiceAccountId", serviceAccountId); command.Parameters.AddWithValue("@id_ResultAccessCode", resultAccessCode); using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { cardPaymentResult = new CardPaymentResult(); cardPaymentResult.EntryId = reader.GetGuid(reader.GetOrdinal("ENTRYID")).ToString(); cardPaymentResult.ResultAccessCode = reader.GetGuid(reader.GetOrdinal("RESULTACCESSCODE")).ToString(); cardPaymentResult.ResultData = GetString(reader, reader.GetOrdinal("RESULTDATA")); cardPaymentResult.Retrieved = reader.GetBoolean(reader.GetOrdinal("RETRIEVED")); } } } } return(cardPaymentResult); }
/// <summary> /// Inserts a record into CardPaymentResult table. /// </summary> /// <param name="cardPaymentResult">The record.</param> public void CreateCardPaymentResult(CardPaymentResult cardPaymentResult) { if (cardPaymentResult == null) { throw new ArgumentNullException("cardPaymentResult"); } using (SqlConnection connection = new SqlConnection(this.connectionString)) { connection.Open(); using (SqlCommand command = new SqlCommand(CreateCardPaymentResultSprocName, connection)) { command.CommandType = CommandType.StoredProcedure; command.Parameters.AddWithValue("@id_EntryId", cardPaymentResult.EntryId); command.Parameters.AddWithValue("@b_Retrieved", cardPaymentResult.Retrieved); command.Parameters.AddWithValue("@id_ResultAccessCode", cardPaymentResult.ResultAccessCode); command.Parameters.AddWithValue("@nvc_ResultData", cardPaymentResult.ResultData); command.Parameters.AddWithValue("@nvc_ServiceAccountId", cardPaymentResult.ServiceAccountId); command.ExecuteNonQuery(); } } }
/// <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); }
protected void Page_Load(object sender, EventArgs e) { // Enable Right-to-left for some cultures this.TextDirection = Thread.CurrentThread.CurrentUICulture.TextInfo.IsRightToLeft ? "rtl" : "ltr"; // Load custom styles this.LoadCustomStyles(); // Check payment entry ID if (string.IsNullOrEmpty(this.entryId)) { this.ShowErrorMessage(WebResources.CardPage_Error_MissingRequestId); return; } // Check payment entry if (this.entry == null) { this.ShowErrorMessage(WebResources.CardPage_Error_InvalidRequestId); } else if (this.entry.Used) { this.ShowErrorMessage(WebResources.CardPage_Error_UsedRequest); } else if (this.entry.IsExpired) { this.ShowErrorMessage(WebResources.CardPage_Error_RequestTimedOut); } else { if (!Page.IsPostBack) { bool isRetail = IndustryType.Retail.ToString().Equals(this.entry.IndustryType, StringComparison.OrdinalIgnoreCase); this.CardDetailsHeaderPanel.Visible = !isRetail; // Load card entry modes this.CardEntryModePanel.Visible = this.entry.SupportCardSwipe || this.entry.AllowVoiceAuthorization; if (this.CardEntryModePanel.Visible) { if (this.entry.SupportCardSwipe) { this.CardEntryModeDropDownList.Items.Add(new ListItem(WebResources.CardPage_CardEntryModeDropDownList_Swipe, "swipe")); } this.CardEntryModeDropDownList.Items.Add(new ListItem(WebResources.CardPage_CardEntryModeDropDownList_Manual, "manual")); if (this.entry.AllowVoiceAuthorization) { this.CardEntryModeDropDownList.Items.Add(new ListItem(WebResources.CardPage_CardEntryModeDropDownList_Voice, "voice")); } } this.CardHolderNamePanel.Visible = !isRetail; this.CardTypePanel.Visible = !isRetail; // Load card types if (this.CardTypePanel.Visible) { this.CardTypeDropDownList.Items.Add(new ListItem(WebResources.CardPage_CardTypeDropDownList_PleaseSelect, string.Empty)); string[] cardTypes = CardTypes.ToArray(this.entry.CardTypes); foreach (var ct in cardTypes) { if (CardTypes.Amex.Equals(ct, StringComparison.OrdinalIgnoreCase)) { this.CardTypeDropDownList.Items.Add(new ListItem(WebResources.CardPage_CardTypeDropDownList_AmericanExpress, CardTypes.Amex)); } else if (CardTypes.Discover.Equals(ct, StringComparison.OrdinalIgnoreCase)) { this.CardTypeDropDownList.Items.Add(new ListItem(WebResources.CardPage_CardTypeDropDownList_Discover, CardTypes.Discover)); } else if (CardTypes.MasterCard.Equals(ct, StringComparison.OrdinalIgnoreCase)) { this.CardTypeDropDownList.Items.Add(new ListItem(WebResources.CardPage_CardTypeDropDownList_MasterCard, CardTypes.MasterCard)); } else if (CardTypes.Visa.Equals(ct, StringComparison.OrdinalIgnoreCase)) { this.CardTypeDropDownList.Items.Add(new ListItem(WebResources.CardPage_CardTypeDropDownList_Visa, CardTypes.Visa)); } } } // Load month list this.ExpirationMonthDropDownList.Items.Add(new ListItem(WebResources.CardPage_ExpirationMonthDropDownList_PleaseSelect, "0")); string[] monthNames = CultureInfo.CurrentCulture.DateTimeFormat.MonthNames; for (int i = 1; i <= 12; i++) { this.ExpirationMonthDropDownList.Items.Add(new ListItem(monthNames[i - 1], string.Format(CultureInfo.InvariantCulture, "{0}", i))); } // Load year list this.ExpirationYearDropDownList.Items.Add(new ListItem(WebResources.CardPage_ExpirationYearDropDownList_PleaseSelect)); int currentYear = DateTime.UtcNow.Year; for (int i = 0; i < 20; i++) { this.ExpirationYearDropDownList.Items.Add(new ListItem(string.Format(CultureInfo.InvariantCulture, "{0}", currentYear + i))); } // Show/hide security code and voice authorization code this.SecurityCodePanel.Visible = false; this.VoiceAuthorizationCodePanel.Visible = false; TransactionType transactionType = (TransactionType)Enum.Parse(typeof(TransactionType), this.entry.TransactionType, true); if (transactionType == TransactionType.Authorize || transactionType == TransactionType.Capture) { this.SecurityCodePanel.Visible = true; if (this.entry.AllowVoiceAuthorization) { this.VoiceAuthorizationCodePanel.Visible = true; } } this.ZipPanel.Visible = isRetail; this.BillingAddressPanel.Visible = !isRetail; if (this.BillingAddressPanel.Visible) { // Load country list // Note: the value of country/region must be two-letter ISO code. // TO DO: Filter the countries down to the list you support. this.CountryRegionDropDownList.Items.Add(new ListItem(WebResources.CardPage_CountryRegionDropDownList_PleaseSelect, string.Empty)); var dataManager = new DataManager(); IEnumerable <CountryOrRegion> countries = dataManager.GetCountryRegionListByLocale(this.entry.EntryLocale); countries = countries.OrderBy(c => c.LongName).ToList(); foreach (var country in countries) { this.CountryRegionDropDownList.Items.Add(new ListItem(country.LongName, country.TwoLetterCode)); } // Populate default values if (this.CardHolderNamePanel.Visible) { this.CardHolderNameTextBox.Text = this.entry.DefaultCardHolderName; } if (this.entry.ShowSameAsShippingAddress) { this.SameAsShippingPanel.Visible = true; this.DefaultStreetHiddenField.Value = this.entry.DefaultStreet1; this.DefaultCityHiddenField.Value = this.entry.DefaultCity; this.DefaultStateProvinceHiddenField.Value = this.entry.DefaultStateOrProvince; this.DefaultZipHiddenField.Value = this.entry.DefaultPostalCode; this.DefaultCountryRegionHiddenField.Value = this.entry.DefaultCountryCode; } else { this.SameAsShippingPanel.Visible = false; this.StreetTextBox.Text = this.entry.DefaultStreet1; this.CityTextBox.Text = this.entry.DefaultCity; this.StateProvinceTextBox.Text = this.entry.DefaultStateOrProvince; this.ZipTextBox1.Text = this.entry.DefaultPostalCode; this.CountryRegionDropDownList.SelectedValue = this.entry.DefaultCountryCode; } } this.HostPageOriginHiddenField.Value = this.entry.HostPageOrigin; } else { bool.TryParse(this.IsSwipeHiddenField.Value, out this.isSwipe); // Validate inputs if (this.ValidateInputs()) { if (this.isSwipe) { this.track1 = this.CardTrack1HiddenField.Value; this.track2 = this.CardTrack2HiddenField.Value; this.cardNumber = this.CardNumberHiddenField.Value; } else { this.cardNumber = this.CardNumberTextBox.Text.Trim(); } if (this.CardTypePanel.Visible) { this.cardType = this.CardTypeDropDownList.SelectedItem.Value; } else { this.cardType = this.CardTypeHiddenField.Value; } this.cardExpirationMonth = int.Parse(this.ExpirationMonthDropDownList.SelectedItem.Value, CultureInfo.InvariantCulture); this.cardExpirationYear = int.Parse(this.ExpirationYearDropDownList.SelectedItem.Text, CultureInfo.InvariantCulture); this.cardSecurityCode = this.SecurityCodeTextBox.Text.Trim(); this.voiceAuthorizationCode = this.VoiceAuthorizationCodeTextBox.Text.Trim(); if (this.CardHolderNamePanel.Visible) { this.cardHolderName = this.CardHolderNameTextBox.Text.Trim(); } else { this.cardHolderName = this.CardHolderNameHiddenField.Value.Trim(); } this.cardStreet1 = this.StreetTextBox.Text.Trim(); this.cardCity = this.CityTextBox.Text.Trim(); this.cardStateOrProvince = this.StateProvinceTextBox.Text.Trim(); if (this.BillingAddressPanel.Visible) { this.cardPostalCode = this.ZipTextBox1.Text.Trim(); } else { this.cardPostalCode = this.ZipTextBox2.Text.Trim(); } this.cardCountryOrRegion = this.CountryRegionDropDownList.SelectedValue; if (!string.IsNullOrEmpty(this.PaymentAmountHiddenField.Value)) { this.paymentAmount = decimal.Parse(this.PaymentAmountHiddenField.Value, NumberStyles.Number, Thread.CurrentThread.CurrentCulture); } // Process payment, e.g. tokenize, authorize, capture. try { CardPaymentResult result = this.ProcessPayment(this.entry); if (result != null) { // Save the payment result var dataManager = new DataManager(); dataManager.CreateCardPaymentResult(result); // Set request access code in hidden field this.ResultAccessCodeHiddenField.Value = result.ResultAccessCode; } } catch (CardPaymentException ex) { // Return the errors from UX this.InputErrorsHiddenField.Value = JsonConvert.SerializeObject(ex.PaymentErrors); } } } } }