>위챗 애플릿 >위챗 개발 >.NET을 사용하여 WeChat 결제를 구문 분석하는 구현 방법

.NET을 사용하여 WeChat 결제를 구문 분석하는 구현 방법

高洛峰
高洛峰원래의
2017-03-17 15:21:341651검색

WeChat의 광범위한 사용으로 인해 WeChat을 기반으로 개발된 일련의 제품이 등장했습니다. 이 기사에서는 주로 WeChat 결제(.NET 버전)를 구문 분석하는 구현 방법을 소개합니다.

얼마 전에 웹 버전의 WeChat 결제를 했는데 많은 문제가 발생했지만 마침내 해결되었습니다. 이제 다른 사람들에게 참고할 수 있도록 개발 과정과 지침을 여기에 기록하겠습니다.

1. 준비

우선 위챗 결제 기능을 활성화해야 합니다. 예전에는 위챗 결제를 활성화하려면 30,000원의 보증금이 필요했는데 지금은 그렇습니다. 더 이상 필요하지 않으므로... 이 기능을 만들었습니다.

위챗 결제를 개발하려면 공식 계정 백엔드와 위챗 가맹점 백엔드에서 관련 설정을 해야 합니다.

1. 개발 디렉터리 구성

위챗 결제는 공식 계정 백그라운드에서 결제 승인 디렉터리를 구성해야 합니다(위챗 결제 = "개발 구성"). 여기에서 승인된 디렉토리는 온라인 주소, 즉 인터넷을 통해 접근할 수 있는 주소여야 합니다. WeChat 결제 시스템은 인터넷을 통해 귀하의 주소에 접근할 수 있어야 합니다.

WeChat 승인 디렉터리는 두 번째 또는 세 번째 수준 디렉터리까지 정확해야 합니다. 예: 결제 시작 링크가 http://www.hxfspace.net/weixin/WeXinPay/WeXinPay인 경우 구성된 디렉터리를 선택하세요. http://www.hxfspace.net/weixin/WeXinPay/여야 합니다. 여기서 http://www.hxfspace.net은 도메인 이름이고 weixin은 컨트롤러인 WeXinPay 가상 디렉터리입니다. WeXinPay의 액션.

.NET을 사용하여 WeChat 결제를 구문 분석하는 구현 방법

                                          결제 요청에 콜백하여 승인 코드(코드)를 받으므로 여기서 승인 도메인 이름을 설정해야 합니다. 물론 여기의 도메인 이름은 결제 승인 디렉터리의 도메인 이름과 동일해야 합니다. 이거 설정하는거 잊지마세요 그냥 설정하는걸 깜빡하고 한참 울다가 이유를 찾다가 죽었어요.

3. 관련 매개변수 준비

.NET을 사용하여 WeChat 결제를 구문 분석하는 구현 방법
WeChat 결제를 호출하려면 다음을 통해 WeChat 결제 시스템에 결제 요청을 시작해야 합니다. 매개변수 설명은

WeChat 공식 웹사이트 결제 플랫폼

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6

패키지 및 paySign 생성에는 개발자 키 AppSecret(애플리케이션 키), 위챗 가맹점 계정, 위챗 결제 키가 필요합니다
2. 프로세스

.NET을 사용하여 WeChat 결제를 구문 분석하는 구현 방법

정리한 후 프로세스에 대해 이야기해 보겠습니다.

1. WeChat 인증 콜백을 통해 인증 코드 받기
2. 웹페이지 인증 access_token 및 openid를 통해


통합 주문 인터페이스를 호출하여 prepayId


설정합니다. jsapi WeChat 결제 요청 매개변수 및 결제 시작


5. 후속 작업에 대한 WeChat 결제 콜백 수신


3. 특정 개발(위 코드)


위챗 결제만 가능 온라인 환경에서는 디버깅이 매우 불편하므로 처음 개발을 시작할 때 주요 위치마다 로그를 기록해 두는 것이 가장 좋습니다.

1. WeChat 인증 콜백을 통해 인증 코드를 받습니다
먼저 WeChat 결제가 성공한 후 초기 결제 주소 및 관련 매개변수를 전달합니다. 수령 및 확인이 완료되면 지불 주소를 요청하고 인증 코드를 가져오세요.


예를 들어 저는

 //判断是否网页授权,获取授权code,没有代表没有授权,构造网页授权获取code,并重新请求
      if (string.IsNullOrEmpty(Request.QueryString["code"]))
      {
        string redirectUrl = _weChatPaySerivce.GetAuthorizeUrl(account.AppId, account.RedquestUrl,
          "STATE" + "#wechat_redirect", "snsapi_base");
        return Redirect(redirectUrl);
      }


WeChat 웹페이지 승인 Url 방식 연결


public string GetAuthorizeUrl(string appId, string redirectUrl, string state, string scope)
    {
      string url = string.Format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope={2}&state={3}",
          appId, HttpUtility.UrlEncode(redirectUrl), scope, state);
      /* 这一步发送之后,客户会得到授权页面,无论同意或拒绝,都会返回redirectUrl页面。
       * 如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。这里的code用于换取access_token(和通用接口的access_token不通用)
       * 若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数redirect_uri?state=STATE
       */
      AppLog.Write("获取到授权url:", AppLog.LogMessageType.Debug); 
      return url;
    }


2. 웹페이지 인증 access_token과 openid


인증코드를 1단계에서 획득한 후, 웹페이지 인증 요청 URL을 결합하여 access_token 및 openid


 public Tuple<string, string> GetOpenidAndAccessTokenFromCode(string appId, string code, string appSecret)
    {
      Tuple<string, string> tuple = null;
      try
      {
        string url = string.Format("https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code", appId, appSecret, code);
        string result = WeChatPayHelper.Get(url);
        AppLog.Write("微信支付-获取openid和access_token 请求Url:" + url + "result:" + result, AppLog.LogMessageType.Debug);
        if (!string.IsNullOrEmpty(result))
        {
          var jd=Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, string>>(result);
          tuple = new Tuple<string, string>(jd["openid"],jd["access_token"]);
          AppLog.Write("微信支付-获取openid和access_token成功", AppLog.LogMessageType.Debug);
        }
      }
      catch (Exception ex)
      {
        AppLog.Write("微信支付:获取openid和access_tokenu异常", AppLog.LogMessageType.Debug,ex);
      }
      return tuple;
    }


3. 통합 주문 인터페이스를 호출하여 prepayId를 얻습니다.


여기 RequestHandler는 다른 사람들이 온라인으로 패키지한 DLL로, 서명 생성 및 일부 확인 요청을 패키지하는 데 도움이 됩니다. dll은 공식 웹사이트 http://weixin.senparc.com/


//创建支付应答对象
      RequestHandler packageReqHandler = new RequestHandler(null);
      //初始化
      packageReqHandler.Init();
      //时间戳
      string timeStamp = TenPayUtil.GetTimestamp();
      //随机字符串
      string nonceStr = TenPayUtil.GetNoncestr();
      //设置package订单参数 生成prepayId预支付Id
      packageReqHandler.SetParameter("appid", account.AppId);     //公众账号ID
      packageReqHandler.SetParameter("mch_id", account.PartnertId);     //商户号
      packageReqHandler.SetParameter("nonce_str", nonceStr);          //随机字符串
      packageReqHandler.SetParameter("body", account.Body);
      packageReqHandler.SetParameter("out_trade_no", account.OrderSerialId);    //商家订单号
      packageReqHandler.SetParameter("total_fee", account.TotalAmount);          //商品金额,以分为单位(money * 100).ToString()
      packageReqHandler.SetParameter("spbill_create_ip", account.RequestIp);  //用户的公网ip,不是商户服务器IP
      packageReqHandler.SetParameter("notify_url", account.NotifyUrl);      //接收财付通通知的URL
      packageReqHandler.SetParameter("trade_type", "JSAPI");            //交易类型
      packageReqHandler.SetParameter("openid", account.OpenId);            //用户的openId
      string sign = packageReqHandler.CreateMd5Sign("key", account.PaySignKey);
      packageReqHandler.SetParameter("sign", sign);            //签名
      string prepayId = string.Empty;
      try
      {
        string data = packageReqHandler.ParseXML();
        var result = TenPayV3.Unifiedorder(data);
        MailHelp.SendMail("调用统一下单接口,下单结果:--"+result+"请求参数:"+data);
        var res = XDocument.Parse(result);
        prepayId = res.Element("xml").Element("prepay_id").Value;
        AppLog.Write("调用统一下单接口获取预支付prepayId成功", AppLog.LogMessageType.Debug);
      }
      catch (Exception ex)
      {
        AppLog.Write("获取到openid和access_tokenu异常", AppLog.LogMessageType.Debug, ex);
        MailHelp.SendMail("调用统一下单接口获取预支付prepayid异常:", ex);
        return null;
      }


에서 다운로드할 수 있습니다. 4. 설정 jsapi WeChat 결제 요청 매개변수 업, 결제 시작

我这里是首先组装好微信支付所需要的参数,然后再创建调用js脚本    


//生成JsAPI支付参数
      RequestHandler paySignReqHandler = new RequestHandler(null);
      paySignReqHandler.SetParameter("appId", account.AppId);
      paySignReqHandler.SetParameter("timeStamp", timeStamp);
      paySignReqHandler.SetParameter("nonceStr", nonceStr);
      paySignReqHandler.SetParameter("package", string.Format("prepay_id={0}", prepayId));
      paySignReqHandler.SetParameter("signType", "MD5");
      string paySign = paySignReqHandler.CreateMd5Sign("key", account.PaySignKey);
      WeChatJsPayRequestModel resultModel = new WeChatJsPayRequestModel
      {
        AppId = account.AppId,
        NonceStr = nonceStr,
        TimeStamp = timeStamp,
        Package = string.Format("prepay_id={0}", prepayId),
        PaySign = paySign,
        SignType = "MD5"
      };


创建调用脚本


private string CreateWeixinJs(WeChatJsPayRequestModel model)
    {
      string js = @"<script type=&#39;text/javascript&#39;>
                callpay();
                function jsApiCall(){
                 WeixinJSBridge.invoke(
                  &#39;getBrandWCPayRequest&#39;, {
                    requestParam
                  },
                  function (res) {
                    if(res.err_msg == &#39;get_brand_wcpay_request:ok&#39; ){
                        window.location.href = &#39;successUrl&#39;;
                    }else{
                        window.location.href = &#39;failUrl&#39;;
                    }
                  }
                 ); 
                }
               function callpay()
                {
                  if (typeof WeixinJSBridge == &#39;undefined&#39;){
                    if( document.addEventListener ){
                      document.addEventListener(&#39;WeixinJSBridgeReady&#39;, jsApiCall, false);
                    }else if (document.attachEvent){
                      document.attachEvent(&#39;WeixinJSBridgeReady&#39;, jsApiCall); 
                      document.attachEvent(&#39;onWeixinJSBridgeReady&#39;, jsApiCall);
                    }
                  }else{
                    jsApiCall();
                  }
                }
            </script>";
      string requestParam = string.Format(@"&#39;appId&#39;: &#39;{0}&#39;,&#39;timeStamp&#39;: &#39;{1}&#39;,&#39;nonceStr&#39;: &#39;{2}&#39;,&#39;package&#39;: &#39;{3}&#39;,&#39;signType&#39;: &#39;{4}&#39;,&#39;paySign&#39;: &#39;{5}&#39;",
        model.AppId, model.TimeStamp, model.NonceStr, model.Package, model.SignType, model.PaySign);
      js = js.Replace("requestParam", requestParam)
        .Replace("successUrl", model.JumpUrl + "&result=1")
        .Replace("failUrl", model.JumpUrl + "&result=0");
      AppLog.Write("生成可执行脚本成功", AppLog.LogMessageType.Debug);
      return js;
    }


 5、接收微信支付回调进行后续操作

回调的时候首先需要验证签名是否正确,保证安全性,签名验证通过之后再进行后续的操作,订单状态、通知啥的。 


ResponseHandler resHandler = new ResponseHandler(System.Web.HttpContext.Current);
      bool isSuccess = _weChatPaySerivce.ProcessNotify(resHandler);
      if (isSuccess)
      {
        string result = @"<xml>
                  <return_code><![CDATA[SUCCESS]]></return_code>
                  <return_msg><![CDATA[支付成功]]></return_msg>
                 </xml>";
        HttpContext.Response.Write(result);
        HttpContext.Response.End();
      }
      return new EmptyResult();


这里有一点需要注意,就是微信支付回调的时候微信会通知八次,好像是这个数吧,所以你需要在第一次收到通知之后,把收到请求这个状态以xml的格式响应给微信支付接口。当然你不进行这个操作也是可以的,再回调的时候 每次去判断该订单是否已经回调成功,回调成功则不进行处理就可以了。


위 내용은 .NET을 사용하여 WeChat 결제를 구문 분석하는 구현 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.