0

Cyber​​source をクレジット カード処理会社として使用するアプリケーションを継承しました。現在、Cyber​​Source API を使用しており、ホストされている注文ページ、特にサイレント オーダー ポスト メソッドを使用するように変換しようとしています。それを実行するための Cyber​​Source の例は次のとおりです。

<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 呼び出しを介して追加情報を渡す方法がわかりません。

任意の提案をいただければ幸いです。

4

1 に答える 1

1

私はちょうどこの同じ問題を経験しました。また、iframe アプローチも採用しました。ページの読み込み時 (ポストバックの場合) に、特定のアイテムをリクエストに書き出す必要があります (ViewState を除く)。以下の例は、すべての項目 (ViewState を除く) を書き出すことを示しています。これは、JavaScript を介して取得できる ccInfo スパンにラップされます。

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」クラス名があるため、iframe に ccInfo スパンのすべての要素を追加できます。この 1 つのライナーは、サーバー側のコードを使用して書き出したすべての要素を親ページに押し込みます。親ページには、Cyber​​Source から返されたすべての情報が含まれています。

私たちの請求ページ (親ページ) では、Cyber​​Source クレジット カード以外の他の支払いが可能であるため、基本的には、Cyber​​Source からすべてが正常に戻ってきたと仮定して、メイン ページで送信を行います。ユーザーが Cyber​​Source で支払っていない場合、請求ページにメインの送信ボタンを表示します。そうであれば、メインの送信ボタンを非表示にし、代わりに iframe の送信ボタンを表示します。次に、何か問題が発生した場合は iframe にエラー メッセージを表示するか、iframe から親ページにデータを転送した後、親ページでフォーム送信を行います。

最後に、親ページは、Request.Form を確認することにより、サーバー側コードを介してすべてのデータにアクセスできます。

うまくいけば、これが役立つか、少なくとも正しい方向に進むことができます. この質問は 1 か月以上前のものであり、先に進んだ可能性がありますが、他の誰かの助けになるかもしれません。

于 2013-07-01T13:27:06.647 に答える