공식 계정 + WeChat 결제 SDK: Senparc.Weixin.MP.dll
기업 계정 SDK: Senparc.Weixin.QY.dll
오픈 플랫폼 SDK: Senparc.Weixin.Open. dll
공식 주소: http://weixin.senparc.com/
물론, 공식 계정의 위챗 결제 기능 개발을 완료하려면 다음을 사용해야 합니다. DLL Senparc.Weixin.MP.dll , 공식 DEMO 및 튜토리얼을 확인했지만 WeChat 결제와 관련된 지침은 없습니다. 이제 소스 코드가 있으므로 직접 찾을 수 있습니다.
Senparc.Weixin.MP.sln을 열어보세요. 영어 폴더명 분류를 보면 처음에는 TenPayLib 폴더에 WeChat 결제가 캡슐화되어 있다고 판단할 수 있는데, " TenPayLibV3" " 폴더, 어떻게 선택하나요? 인터넷으로 검색해본 결과, 2014년 9월 10일 이전에 적용된 것이 v2 버전이고, 그 이후에 적용된 것이 v3이라는 결론에 이르렀습니다. 제가 위챗페이를 테스트할 때 사용한 서비스 계정은 2016년에 막 신청해서 인증을 통과했으니 과감히 V3를 사용하세요.
TenPayLibV3 폴더를 엽니다.
여기에는 여러 클래스 라이브러리가 있으며 각각의 기능은 무엇입니까? 여기에서는 하나씩 설명하지 않으며, 관심 있는 친구는 다운로드하여 살펴볼 수 있습니다. 각 카테고리의 파일 헤더에는 WeChat의 공식 결제 지침에 따라 직접 결제가 시작됩니다.
WeChat 공식 계정을 입력하고 기능 메뉴에서 WeChat 결제를 클릭한 후 튜토리얼을 클릭하세요. 그에 따라 공식 계정 결제
빠르게 검토하세요. 문서 내용을 검토하고 Senparc.Weixin.MP.dll에서 해당 기능을 찾으십시오.
먼저 결제 승인 디렉터리를 구성하고 결제 테스트 화이트리스트를 추가하세요. 결제 디렉터리는 3개만 지원되며 도메인 이름은 ICP에 등록되어 있어야 합니다. 인증 디렉토리의 기능은 WeChat 결제 요청을 시작하려는 경우 요청한 링크 주소가 인증 디렉토리에 있어야 한다는 것입니다. 그렇지 않으면 신원이 유효하지 않으며 결제가 성공할 수 없습니다. 테스트 화이트리스트에 추가된 개인 WeChat 계정만 WeChat 결제 테스트 디렉터리에서 결제 테스트를 완료할 수 있습니다. 화이트리스트에 없는 사람이 결제 신청을 시작하면 결제가 완료되지 않습니다.
구성이 완료된 후 어떻게 호출하나요? 계속해서 공식 설명을 살펴보겠습니다. H5 결제 API 호출
“WeChat 브라우저에서 H5 웹페이지를 열고 JS를 실행하여 결제를 호출합니다.
참고: WeixinJSBridge 내장 객체는 다른 브라우저에서 유효하지 않습니다.
목록의 매개변수 이름은 크기에 민감하며 대소문자가 올바르지 않으면 서명 확인이 실패합니다. > 자, 여기서 몇 가지 설명하겠습니다. 첫 번째는 WeChat 브라우저입니다. 둘째, 매개변수는 대소문자를 구분합니다. 셋째, 데이터 형식은 JSON입니다.
공식 설명: 페이지에서 다음 스크립트를 호출하면 위챗 결제 기능을 활성화할 수 있습니다.
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(); }
내 호출 코드: 위챗 결제를 클릭한 후 호출하고 싶기 때문입니다. 버튼을 눌러 후속 작업을 수행하고 공식 코드를
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 { //支付取消,或者其他错误,自行处理 } } ); }
메소드에 입력하세요. 그렇다면 이 매개변수는 어디서 왔고, 무엇인가요? 하나씩 분석해 보겠습니다.
appId: WeChat을 개발하는 모든 사람은 이것을 알아야 합니다. 공식 계정은 개발자 메뉴
timeStamp: timestamp에서 찾을 수 있으며 공식 설명은 “since 1970입니다. "Seconds", 걱정하지 마세요. 결제 라이브러리
nonceStr에서 찾을 수 있습니다. 공식 설명은 임의의 문자열 "e61463f8efa94090b1f366cccfbbb444"입니다. 자세한 내용은 난수 생성 알고리즘을 참조하세요. 이는 암호화 규칙 및 알고리즘 집합으로 밝혀졌습니다. URL 요청 인터페이스를 수행한 친구는 일부 회사의 JSON 문자열 서명 방법이 이와 유사하다는 것을 알아야 합니다.
패키지: 공식 API 통합 주문 인터페이스를 호출하여 얻을 수 있는 선불 ID
signType: 문자열 "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数据中,我们获取到了
我们继续,来看一下支付接口需要用到的参数如何获取:
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中文网!