/// <summary> /// Processes the callback from Authorize.NET after a customer authorizes a payment request. /// </summary> /// <param name="payment">The payment.</param> /// <remarks>Method communicates with Authorize.NET server and processes the auth_codes from the response. /// Normally the callback would do a redirect at the end. /// Instead we write the page directly to them. /// </remarks> public override void ProcessCallback(Payment payment) { if (payment.PaymentStatus.PaymentStatusId != (int)PaymentStatusCode.PendingAuthorization) { return; } var paymentStatus = PaymentStatusCode.Declined; var responseCodeParameter = GetParameter("x_response_code", "\"{0}\" cannot be null or empty"); var responseReasonCodeParameter = GetParameter("x_response_reason_code", "\"{0}\" cannot be null or empty"); var responseReasonTextParameter = GetParameter("x_response_reason_text", "\"{0}\" cannot be null or empty"); string transactParameter = HttpContext.Current.Request["x_trans_id"]; if (string.IsNullOrEmpty(transactParameter)) { throw new ArgumentException(@"transact must be present in query string."); } string transact = transactParameter; // If payment received OK, proceed with processing if (responseCodeParameter == "1") { const string format = "When using md5 \"{0}\" cannot be null or empty"; payment["auth_code"] = GetParameter("x_auth_code", format); var md5KeyParameter = GetParameter("x_MD5_Hash", format).ToLower(); var amountParameter = GetParameter("x_amount", format); // Configuration values string md5Hash = payment.PaymentMethod.DynamicProperty <string>().Md5Hash; string apiLogin = payment.PaymentMethod.DynamicProperty <string>().ApiLogin; bool instantAcquire = payment.PaymentMethod.DynamicProperty <bool>().InstantAcquire; var hashComputer = new AuthorizedotnetMd5Computer(); if (hashComputer.IsMatch(md5Hash, apiLogin, transact, amountParameter, md5KeyParameter)) { paymentStatus = instantAcquire ? PaymentStatusCode.Acquired : PaymentStatusCode.Authorized; } payment.PaymentStatus = PaymentStatus.Get((int)paymentStatus); payment.TransactionId = transact; ProcessPaymentRequest(new PaymentRequest(payment.PurchaseOrder, payment)); } // Configuration values string declineUrl = payment.PaymentMethod.DynamicProperty <string>().DeclineUrl; string acceptUrl = payment.PaymentMethod.DynamicProperty <string>().AcceptUrl; HttpContext.Current.Response.Write(paymentStatus == PaymentStatusCode.Declined ? DownloadPageContent(new Uri(_absoluteUrlService.GetAbsoluteUrl(declineUrl)) .AddQueryStringParameter("x_response_reason_code", responseReasonCodeParameter) .AddQueryStringParameter("x_response_reason_text", responseReasonTextParameter), payment) : DownloadPageContent(new Uri(_absoluteUrlService.GetAbsoluteUrl(acceptUrl)), payment)); }
protected override void BuildBody(StringBuilder page, PaymentRequest paymentRequest) { // Configuration values bool sandboxMode = paymentRequest.PaymentMethod.DynamicProperty <bool>().SandboxMode; bool testMode = paymentRequest.PaymentMethod.DynamicProperty <bool>().TestMode; bool instantAcquire = paymentRequest.PaymentMethod.DynamicProperty <bool>().InstantAcquire; bool itemizeReceipt = paymentRequest.PaymentMethod.DynamicProperty <bool>().ItemizeReceipt; string apiLogin = paymentRequest.PaymentMethod.DynamicProperty <string>().ApiLogin; string transactionKey = paymentRequest.PaymentMethod.DynamicProperty <string>().TransactionKey; string callbackUrl = paymentRequest.PaymentMethod.DynamicProperty <string>().CallbackUrl; string payType = paymentRequest.PaymentMethod.DynamicProperty <string>().PayType; string logoUrl = paymentRequest.PaymentMethod.DynamicProperty <string>().LogoUrl; page.Append(string.Format(@"<form method=""post"" action=""{0}"">", sandboxMode ? "https://test.authorize.net/gateway/transact.dll" : "https://secure.authorize.net/gateway/transact.dll")); AddHiddenField(page, "x_login", apiLogin); AddHiddenField(page, "x_type", instantAcquire ? "AUTH_CAPTURE" : "AUTH_ONLY"); AddHiddenField(page, "x_show_form", "PAYMENT_FORM"); AddHiddenField(page, "x_relay_response", "true"); AddHiddenField(page, "x_relay_url", _callbackUrl.GetCallbackUrl(callbackUrl, paymentRequest.Payment)); AddHiddenField(page, "x_delim_data", "FALSE"); AddHiddenField(page, "x_version", "3.1"); AddHiddenField(page, "x_method", payType); AddHiddenField(page, "x_invoice_num", paymentRequest.Payment.ReferenceId); OrderAddress billingAddress = paymentRequest.Payment.PurchaseOrder.BillingAddress; AddHiddenField(page, "x_first_name", billingAddress.FirstName); AddHiddenField(page, "x_last_name", billingAddress.LastName); AddHiddenField(page, "x_address", billingAddress.Line1 + (string.IsNullOrEmpty(billingAddress.Line2) ? "" : (", " + billingAddress.Line2))); AddHiddenField(page, "x_city", billingAddress.City); AddHiddenField(page, "x_zip", billingAddress.PostalCode); AddHiddenField(page, "x_country", billingAddress.Country.Name); AddHiddenField(page, "x_email", billingAddress.EmailAddress); AddHiddenField(page, "x_phone", billingAddress.PhoneNumber); AddHiddenField(page, "x_company", billingAddress.CompanyName); if (!string.IsNullOrEmpty(billingAddress.State)) { AddHiddenField(page, "x_state", billingAddress.State); } if (itemizeReceipt) { foreach (OrderLine line in paymentRequest.PurchaseOrder.OrderLines) { string fullSku = string.Format("{0}{1}", line.Sku, !string.IsNullOrEmpty(line.VariantSku) ? "-" + line.VariantSku : ""); AddHiddenField(page, "x_line_item", string.Format("{0}<|>{1}<|>{2}<|>{3}<|>{4}<|>N", HttpUtility.HtmlEncode(MaxThirtyChars(fullSku)), HttpUtility.HtmlEncode(MaxThirtyChars(fullSku)), HttpUtility.HtmlEncode(MaxThirtyChars(line.ProductName)), line.Quantity, (line.Price - line.UnitDiscount).ToInvariantString())); } } AddHiddenField(page, "x_header_html_payment_form", "<style type='text/css'>#imgMerchantLogo{}</style>"); if (!string.IsNullOrEmpty(logoUrl)) { AddHiddenField(page, "x_logo_url", logoUrl); } var amount = paymentRequest.Payment.Amount.ToInvariantString(); AddHiddenField(page, "x_amount", amount); AddHiddenField(page, "x_duplicate_window", 28800.ToString()); AddHiddenField(page, "x_customer_ip", HttpContext.Current.Request.UserHostAddress); // To get a transactionsid for authorizations Sandbox mode requires testmode not to be enabled if (testMode && !sandboxMode) { AddHiddenField(page, "x_test_request", "TRUE"); } var hashComputer = new AuthorizedotnetMd5Computer(); string sequence = paymentRequest.Payment.ReferenceId; AddHiddenField(page, "x_fp_sequence", sequence); TimeSpan timeSinceCreate = (paymentRequest.Payment.Created.ToUniversalTime() - new DateTime(1970, 1, 1)); string timestamp = ((int)timeSinceCreate.TotalSeconds).ToString(); AddHiddenField(page, "x_fp_timestamp", timestamp); AddHiddenField(page, "x_fp_hash", hashComputer.GetPreMd5Key(transactionKey, apiLogin, sequence, timestamp, amount)); if (Debug) { AddSubmitButton(page, "ac", "Post it"); } page.Append("</form>"); }