ホームページ  >  記事  >  WeChat アプレット  >  WeChat決済開発-Senparc.Weixin.MPの詳細説明

WeChat決済開発-Senparc.Weixin.MPの詳細説明

高洛峰
高洛峰オリジナル
2017-02-13 13:14:203319ブラウズ

公式アカウント + WeChat 決済 SDK: Senparc.Weixin.MP.dll

エンタープライズアカウント SDK: Senparc.Weixin.QY.dll

オープンプラットフォーム SDK: Senparc.Weixin.Open.dll

公式アドレス: http:// weixin.senparc.com/

もちろん、パブリックアカウントの WeChat 支払い機能の開発を完了するには、公式のデモとチュートリアルを確認した後、WeChat 支払い関連の DLL を使用する必要があります。情報がロードされていないため、ソースコードを入手したら、それを自分で見つけることができます。

Senparc.Weixin.MP.sln を開きます。英語のフォルダー名の分類に基づいて、最初は WeChat 支払いが TenPayLib フォルダーにパッケージ化されていると判断できますが、その中に「TenPayLibV3」という名前のフォルダーがあることもわかりました。 、ではどうやって選べばいいのでしょうか?オンラインで検索した結果、2014 年 9 月 10 日より前に適用されたものはバージョン v2、それ以降に適用されたものはバージョン v3 であるという結論に達しました。 WeChat Pay のテストに使用したサービス アカウントは 2016 年に申請して検証に合格したばかりなので、思い切って V3 を使用してください。

TenPayLibV3 フォルダーを開きます:

微信支付开发-Senparc.Weixin.MP详解

ここには複数のクラス ライブラリがあります。それぞれは何をするものでしょうか。ここでは個別に説明しません。興味のある方は、各カテゴリのファイルのヘッダーに機能の説明と説明が記載されていますので、WeChat の公式の支払い手順に従って、直接支払いを開始してください。

WeChat公式アカウントを入力し、機能メニューでWeChat支払いをクリックします:そして、それに応じて使用方法チュートリアル-公式アカウント支払いをクリックします

微信支付开发-Senparc.Weixin.MP详解 微信支付开发-Senparc.Weixin.MP详解

文書の内容を素早く確認して参照し、Senparc.Weixin.MPへのインストールを容易にします。 dll 対応する関数を見つけます。

微信支付开发-Senparc.Weixin.MP详解

まず、支払い承認ディレクトリを設定し、支払いテスト ホワイトリストを追加します。サポートされる支払いディレクトリは 3 つだけであり、ドメイン名は ICP に登録されている必要があります。承認ディレクトリの機能は、WeChat 支払いリクエストを開始する場合、要求されたリンク アドレスが承認ディレクトリに存在する必要があることです。そうでない場合、ID は無効になり、支払いは成功しません。テスト ホワイトリストに追加された個人の WeChat アカウントのみが WeChat 支払いテスト ディレクトリで支払いのテストを完了できます。ホワイトリストに含まれていない人が支払い申請を開始した場合、支払いは成功しません。

設定が完了したら、どうやって呼び出すのですか?引き続き公式の説明を見てみましょう: H5 Call Up Payment API

「WeChat ブラウザで H5 Web ページを開き、JS を実行して、インターフェイスの入出力データ形式は JSON です。

注: WeixinJSBridge の組み込みオブジェクトは他のブラウザでは有効ではありません

リスト内のパラメータ名は大文字と小文字が区別され、大文字と小文字が間違っていると署名の検証が失敗します。第 2 に、パラメータは大文字と小文字が区別されます。第 3 に、データ形式は JSON です。

公式説明では、次のスクリプトがページ上で呼び出されている限り、WeChat 支払い機能をオンにすることができます:

function onBridgeReady(){
   WeixinJSBridge.invoke(
       'getBrandWCPayRequest', {
           "appId" : "wx2421b1c4370ec43b",     //公众号名称,由商户传入     
           "timeStamp":" 1395712654",         //时间戳,自1970年以来的秒数     
           "nonceStr" : "e61463f8efa94090b1f366cccfbbb444", //随机串     
           "package" : "prepay_id=u802345jgfjsdfgsdg888",     
           "signType" : "MD5",         //微信签名方式:     
           "paySign" : "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名 
       },
       function(res){     
           if(res.err_msg == "get_brand_wcpay_request:ok" ) {}     // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回    ok,但并不保证它绝对可靠。 
       }
   ); 
}
if (typeof WeixinJSBridge == "undefined"){
   if( document.addEventListener ){
       document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
   }else if (document.attachEvent){
       document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
       document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
   }
}else{
   onBridgeReady();
}

私の呼び出しコード: ボタンをクリックして支払いを確認した後、WeChat 支払いを呼び出す必要があるため後続の操作を行って、公式コードを送信してください。メソッドに移動します

function onBridgeReady() {
            WeixinJSBridge.invoke(
                'getBrandWCPayRequest', {
                    "appId": $('#APPID').val(),     //公众号名称,由商户传入     
                    "timeStamp": $('#Timestamp').val(),         //时间戳,自1970年以来的秒数     
                    "nonceStr": $('#Noncestr').val(), //随机串     
                    "package": $('#package').val(),
                    "signType": "MD5",         //微信签名方式:     
                    "paySign": $('#paySign').val() //微信签名 
                },
                function (res) {
                    if (res.err_msg == "get_brand_wcpay_request:ok") {
                        //支付成功,后续自行处理
                        
                    }
                    else
                    {
                        //支付取消,或者其他错误,自行处理
                    }
                }
            );
        }

さて、これらのパラメータはどこから来て、何ですか? 1つずつ分析してみましょう:

appId: WeChatを開発する人なら誰でもこれを知っているはずです

公式アカウントは開発者メニューにあります

timeStamp: タイムスタンプ、公式の説明は「1970年からの秒数」です。心配しないでください、間違いなく支払いライブラリから見つけることができます

nonceStr: 公式の説明はランダムな文字列「e61463f8efa94090b1f366cccfbbb444」です どういう意味ですか?詳細については、乱数生成アルゴリズムを参照してください。これは、一連の暗号化ルールとアルゴリズムであることがわかります。URL リクエスト インターフェイスを使用したことがある方は、一部の企業の JSON 文字列署名メソッドがこれに似ていることを知っているはずです。

パッケージ: 前払い ID、公式 API 統合注文インターフェイスを呼び出すことで取得できます

SignType: String "MD5"

PaySign: 公式の説明は WeChat の署名「70EA570631E4BB79628FBCA90534C63FF7FADD89」です、わかりました、我慢できません、署名を見てみましょう 生成アルゴリズムは鳥のランダムな文字列のようです

この時点で、公式インターフェイスの説明は非常に明確に理解できたので、次のステップは WeChat 支払いの呼び出しパラメータを解決することです。 Senparc.Weixin.MP.dll 経由 どのように使用する必要がありますか?まず統合注文インターフェイスを呼び出して前払い注文 ID を取得する必要があるため、まずこの ID を取得する方法を検討しましょう。

  官方给出了详细说明,我们不在赘述,各参数研究按照上述接口的方式自行研究解决,唯一区别在于,调用官方接口需要传入一个XML,那很好办,拼接一下就可以了,预支付调用方法如下:

//这里通过官方的一个实体,用户自行使用,我这里是直接读取的CONFIG文件
private static Senparc.Weixin.MP.TenPayLibV3.TenPayV3Info tenPayV3Info = new Senparc.Weixin.MP.TenPayLibV3.TenPayV3Info(ConfigurationManager.AppSettings["corpId"], ConfigurationManager.AppSettings["corpSecret"], ConfigurationManager.AppSettings["mch_id"]
                    , ConfigurationManager.AppSettings["key"], ConfigurationManager.AppSettings["v3url"]);

        /// <summary>
        /// 微信预支付
        /// </summary>
        /// <param name="attach"></param>
        /// <param name="body"></param>
        /// <param name="openid"></param>
        /// <param name="price"></param>
        /// <param name="orderNum"></param>
        /// <returns></returns>
        public static string PayInfo(string attach, string body, string openid, string price, string orderNum = "1833431773763549")
        {
            RequestHandler requestHandler = new RequestHandler(HttpContext.Current);
            //微信分配的公众账号ID(企业号corpid即为此appId)
            requestHandler.SetParameter("appid", tenPayV3Info.AppId);
            //附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
            requestHandler.SetParameter("attach", attach);
            //商品或支付单简要描述
            requestHandler.SetParameter("body", body);
            //微信支付分配的商户号
            requestHandler.SetParameter("mch_id", tenPayV3Info.MchId);
            //随机字符串,不长于32位。
            requestHandler.SetParameter("nonce_str", TenPayUtil.GetNoncestr());
            //接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。
            requestHandler.SetParameter("notify_url", tenPayV3Info.TenPayV3Notify);
            //trade_type=JSAPI,此参数必传,用户在商户公众号appid下的唯一标识。
            requestHandler.SetParameter("openid", openid);
            //商户系统内部的订单号,32个字符内、可包含字母,自己生成
            requestHandler.SetParameter("out_trade_no", orderNum);
            //APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP。
            requestHandler.SetParameter("spbill_create_ip", "127.0.0.1");
            //订单总金额,单位为分,做过银联支付的朋友应该知道,代表金额为12位,末位分分
            requestHandler.SetParameter("total_fee", price);
            //取值如下:JSAPI,NATIVE,APP,我们这里使用JSAPI
            requestHandler.SetParameter("trade_type", "JSAPI");
            //设置KEY
            requestHandler.SetKey(tenPayV3Info.Key);

            requestHandler.CreateMd5Sign();
            requestHandler.GetRequestURL();
            requestHandler.CreateSHA1Sign();
            string data = requestHandler.ParseXML();
            requestHandler.GetDebugInfo();

            //获取并返回预支付XML信息
            return TenPayV3.Unifiedorder(data);
        }
    }

好的,拿到预支付订单的返回数据,一切又都好办了,根据返回参数的不同,自行解决,我们只关心调用正确的过程,操作继续,在返回的正确XML数据中,我们获取到了 88a638634f96c4d5385af75458953c57be5c8d72abc5b0647c20ab3ed87e8a806688e7ad0e17c5b2c6aa450a6c842cf4(官方示例),好的,开始在页面做支付吧!

这里,我封装了一个实体,用来传输常用的数据,当然,各位也可以参考Senparc.Weixin.MP.dll提供的实体类。

public class ShareInfo
    {
        string corpId = string.Empty;
        public string CorpId
        {
            get { return corpId; }
            set { corpId = value; }
        }
        string ticket = string.Empty;

        public string Ticket
        {
            get { return ticket; }
            set { ticket = value; }
        }
        string noncestr = string.Empty;

        public string Noncestr
        {
            get { return noncestr; }
            set { noncestr = value; }
        }
        string timestamp = string.Empty;

        public string Timestamp
        {
            get { return timestamp; }
            set { timestamp = value; }
        }

        private string paySign = string.Empty;
        public string PaySign
        {
            get { return paySign; }
            set { paySign = value; }
        }

        private string package = string.Empty;

        public string Package
        {
            get { return package; }
            set { package = value; }
        }
    }

我们继续,来看一下支付接口需要用到的参数如何获取:

public static ShareInfo GetPayInfo(string prepayid)
        {
            shareInfo = new ShareInfo();
            //检查是否已经注册jssdk
            if (!JsApiTicketContainer.CheckRegistered(corpId))
            {
                JsApiTicketContainer.Register(corpId, corpSecret);
            }
            JsApiTicketResult jsApiTicket = JsApiTicketContainer.GetTicketResult(corpId);
            JSSDKHelper jssdkHelper = new JSSDKHelper();
            shareInfo.Ticket = jsApiTicket.ticket;
            shareInfo.CorpId = corpId.ToLower();
            shareInfo.Noncestr = JSSDKHelper.GetNoncestr().ToLower();
            shareInfo.Timestamp = JSSDKHelper.GetTimestamp().ToLower();
            shareInfo.Package="prepay_id=" + prepayid.ToLower();

            RequestHandler requestHandler = new RequestHandler(HttpContext.Current);

            requestHandler.SetParameter("appId", shareInfo.CorpId);
            requestHandler.SetParameter("timeStamp", shareInfo.Timestamp);
            requestHandler.SetParameter("nonceStr", shareInfo.Noncestr);
            requestHandler.SetParameter("package", shareInfo.Package);
            requestHandler.SetParameter("signType", "MD5");

            requestHandler.SetKey(tenPayV3Info.Key);
            requestHandler.CreateMd5Sign();
            requestHandler.GetRequestURL();
            requestHandler.CreateSHA1Sign();
            shareInfo.PaySign = (requestHandler.GetAllParameters()["sign"]).ToString();
            return shareInfo;
        }

这样,支付接口需要用到的参数,就都封装在ShareInfo里了,好吧,调用之后,我们回到页面的后置代码中,或者你采用的ORM对应代码中去,将参数输出到页面

//处理页面支付调用信息
                    ShareInfo shareInfo = TenPayModule.GetPayInfo(prepayid);
                    System.Web.HttpContext.Current.Response.Write(string.Format("<input type=\"hidden\" id=\"Noncestr\" runat=\"server\" value=\"{0}\" />", shareInfo.Noncestr));
                    System.Web.HttpContext.Current.Response.Write(string.Format("<input type=\"hidden\" id=\"Timestamp\" runat=\"server\" value=\"{0}\" />", shareInfo.Timestamp));
                    System.Web.HttpContext.Current.Response.Write(string.Format("<input type=\"hidden\" id=\"APPID\" runat=\"server\" value=\"{0}\" />", shareInfo.CorpId));
                    System.Web.HttpContext.Current.Response.Write(string.Format("<input type=\"hidden\" id=\"paySign\" runat=\"server\" value=\"{0}\" />", shareInfo.PaySign));
                    System.Web.HttpContext.Current.Response.Write(string.Format("<input type=\"hidden\" id=\"package\" runat=\"server\" value=\"{0}\" />", shareInfo.Package));

好的,写到这里,大家参照上面的JS代码,就可以完成整个的支付功能了。最后,再附送一个生成商家订单号的方法,代码如下:

public string GetOrderNumber()
        {
            string Number = DateTime.Now.ToString("yyMMddHHmmss");
            return Number + Next(1000, 1).ToString();
        }
        private static int Next(int numSeeds, int length)
        {
            byte[] buffer = new byte[length]; 
            System.Security.Cryptography.RNGCryptoServiceProvider Gen = new System.Security.Cryptography.RNGCryptoServiceProvider();
            Gen.GetBytes(buffer);
            uint randomResult = 0x0; 
            for (int i = 0; i < length; i++)
            {
                randomResult |= ((uint)buffer[i] << ((length - 1 - i) * 8));
            }
            return (int)(randomResult % numSeeds);
        }

更多微信支付开发-Senparc.Weixin.MP详解 相关文章请关注PHP中文网!

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。