2013-05-14 49 views
0

我繼承了使用的Cyber​​Source作爲信用卡處理公司的應用程序。它目前使用Cyber​​Source API,我試圖將其轉換爲使用他們的託管訂單頁面 - 特別是無聲訂單發佈方法。這個例子給Cyber​​Source的運行它如下:回覆於與一個iframe

<form action="https://orderpagetest.ic3.com/hop/ProcessOrder.do" method="POST"> 
    <% insertSignature3("10", "USD", "sale"); %> 
     <h2>Payment Information</h2> 
     Card Type:  <select name="card_cardType"><br> 
          <option value=""> 
          <option value="001">Visa 
          <option value="002">MasterCard 
          <option value="003">American Express 
         </select><br> 
     Card Number:  <input type="text" name="card_accountNumber"><br> 
     Expiration Month: <input type="text" name="card_expirationMonth"> (mm)<br> 
     Expiration Year: <input type="text" name="card_expirationYear"> (yyyy)<br><br> 

    <h2>Ready to Check Out!</h2> 
          <input type="submit" name="submit" value="Buy Now"> 

</form> 

的insertSignature方法的代碼如下:當我在測試應用程序運行它

public void insertSignature3(String amount, String currency, String orderPage_transactionType) 
    { 
     try 
     { 
      TimeSpan timeSpanTime = DateTime.UtcNow - new DateTime(1970, 1, 1); 
      String[] arrayTime = timeSpanTime.TotalMilliseconds.ToString().Split('.'); 
      String time = arrayTime[0]; 
      String merchantID = GetMerchantID(); 
      if (merchantID.Equals("")) 
       Response.Write("<b>Error:</b> <br>The current security script (HOP.cs) doesn't contain your merchant information. Please login to the <a href='https://ebc.cybersource.com/ebc/hop/HOPSecurityLoad.do'>CyberSource Business Center</a> and generate one before proceeding further. Be sure to replace the existing HOP.cs with the newly generated HOP.cs.<br><br>"); 
      String data = merchantID + amount + currency + time + orderPage_transactionType; 
      String pub = GetSharedSecret(); 
      String serialNumber = GetSerialNumber(); 
      byte[] byteData = System.Text.Encoding.UTF8.GetBytes(data); 
      byte[] byteKey = System.Text.Encoding.UTF8.GetBytes(pub); 
      HMACSHA1 hmac = new HMACSHA1(byteKey); 
      String publicDigest = Convert.ToBase64String(hmac.ComputeHash(byteData)); 
      publicDigest = publicDigest.Replace("\n", ""); 
      System.Text.StringBuilder sb = new System.Text.StringBuilder(); 
      sb.Append("<input type=\"hidden\" name=\"amount\" value=\""); 
      sb.Append(amount); 
      sb.Append("\">\n<input type=\"hidden\" name=\"currency\" value=\""); 
      sb.Append(currency); 
      sb.Append("\">\n<input type=\"hidden\" name=\"orderPage_timestamp\" value=\""); 
      sb.Append(time); 
      sb.Append("\">\n<input type=\"hidden\" name=\"merchantID\" value=\""); 
      sb.Append(merchantID); 
      sb.Append("\">\n<input type=\"hidden\" name=\"orderPage_transactionType\" value=\""); 
      sb.Append(orderPage_transactionType); 
      sb.Append("\">\n<input type=\"hidden\" name=\"orderPage_signaturePublic\" value=\""); 
      sb.Append(publicDigest); 
      sb.Append("\">\n<input type=\"hidden\" name=\"orderPage_version\" value=\"4\">\n"); 
      sb.Append("<input type=\"hidden\" name=\"orderPage_serialNumber\" value=\""); 
      sb.Append(serialNumber); 
      sb.Append("\">\n"); 
      Response.Write(sb.ToString()); 
     } 
     catch (Exception e) 
     { 
      Response.Write(e.StackTrace.ToString()); 
     } 
    } 

一切正常。但是,我無法在主應用程序中使用表單標籤,因爲母版頁中的所有內容都包含在表單標記中,這會導致嵌套的表單標記。我曾嘗試將表單塊放入iframe中,但無法通過來自insertSignature(...)方法的Response.Write調用來傳遞附加信息。

任何建議表示讚賞。

回答

1

我只是通過這個同樣的問題去了。我們也採用了iframe方法。在頁面加載(如果回發),你會想寫出請求中的特定項目(不包括ViewState)。下面的例子顯示了寫出所有項目(ViewState除外)。這包裹在ccInfo範圍內,然後我們可以通過JavaScript獲取。

protected virtual void Page_Load(Object sender, EventArgs e) 
{ 

    if (!Page.IsPostBack) 
    { 
     //Do any page binding, etc that needs to be done on intitial page load 
    } 
    else 
    { 
     //We came back from CyberSource ... 

     //Will need to get from stored client hidden field ... 
     string decision = Request.Form["decision"]; 

     if (verifyTransactionSignature(Request)) 
     { 
      //Make sure we are only processing in the TEST environment if the particular setting 
      //is set to test (Site_Settings.CYBERSOURCE_API_URL contains 'test' in it) 
      string apiUrl = Settings.GetSetting(LocalConnectionString, "CYBERSOURCE_API_URL"); 
      //API isn't test, but CyberSource is (someone hacking?) 
      if (!apiUrl.ToLower().Contains("test") && Request.Form["orderPage_environment"].ToLower().Contains("test")) 
      { 
       lblError.Text = "Unable to verify credit card. Request is in test mode, but the site is not. Contact Customer Service."; 
      } 

      Response.Write("<span class='ccInfo hide'>"); 
      for (int i = 0; i < Request.Form.Count; i++) 
      { 
       var key = Request.Form.GetKey(i); 

       if (key != "__VIEWSTATE") 
       { 
        Response.Write("<input type='hidden' id='" + key + "' name='" + key + "' value='" + Request.Form[i] + "' class='hide' />"); 
       } 
      } 
      Response.Write("</span>"); 

      if (decision != "ACCEPT") 
      { 
       string reasonCode = Request.Form["reasonCode"]; 

       lblError.Text = "Unable to verify credit card (" + reasonCode + ") "; 
       if (reasonCode == "102") 
       { 
        lblError.Text += "<br />One or more fields in the request contains invalid data. Typically this is the expiration date"; 
       } 
      } 
     } 
     else 
     { 
      lblError.Text = "Unable to verify credit card. Transaction Signature not valid. Contact Customer Service."; 
     } 
    } 
} 

JavaScript中,我們用它來獲取數據,然後發送到父頁面如下:

$(document).ready(function() { 
    var decision = $('#decision'); 

    if (decision.length > 0) { 
     if (decision.val() === "ACCEPT") { 
      //pass in requestId, etc to the billing page 
      parent.$('.checkoutform').append($('.ccInfo').children()); 

      //call billing.aspx submit function 
      parent.submitBillingPage(); 

      return; 
     } else { 
      //change from loading animation to iframe 
      parent.toggleIframe(true); 
     } 
    } 
}); 

父頁面「checkoutForm的」類的名字,所以我們可以添加的所有元素ccInfo跨度在我們的iframe中。這一行代碼將我們使用服務器端代碼寫出的所有元素都推送到父頁面。現在,父頁面擁有從Cyber​​Source返回的所有信息。

我們的結算頁面(父頁面)允許除了Cyber​​Source的信用卡其他款項,所以我們基本上做到假設一切的主網頁上提交來自Cyber​​Source的回成功。當用戶沒有使用Cyber​​Source付款時,我們會在結算頁面上顯示主要提交按鈕。如果是,我們隱藏主要提交按鈕,而是顯示iframe中的提交按鈕。然後,如果出現錯誤,我們會在iframe中顯示錯誤消息,或者在將數據從iframe傳輸到父頁面後,我們會在父頁面上進行表單提交。

最後,父頁的通過查看的Request.Form訪問所有通過服務器端代碼中的數據。

希望這有助於或至少可以讓你在正確的方向前進。我知道這個問題已經過去了一個多月,你可能已經開始了,但也許它會幫助其他人。