WeChat public platform payment development details, public platform details

Source: Internet
Author: User
Tags openid tojson

Public platform payment development details, public platform details

Public account payment is a function that calls up payment on the H5 page. You do not need to scan the QR code to make the payment. The first thing to do with this function is to make it clear that only the appid that matches the merchant's mch_id can be successfully paid. When the merchant ID is successfully registered, it will send the relevant information to the mailbox. The key to arousing payment is that openid can receive unified orders. Openid corresponds to appid one by one. That is to say, if the appid you log on to is not the appid of the public account, the obtained openid will not invoke the payment in the Public Account (the error of mismatch between the appid and the merchant account will occur ). I used to make a detour in this place, because the open platform can create website applications, there is also an appid and appsecreat, you can also log on with one click.

Business Process

The following is the official process, which seems a bit complicated. The key point is to get the json string returned by the unified order interface. The others are basically correct according to the official demo. The following describes several details.

Create order

Before calling the public account to pay, we must first create the order. For example, a recharge order. It is mainly to determine the amount before proceeding to the next step.

Public JsonResult CreateRecharegOrder (decimal money) {if (money <(decimal) 0.01) return Json (new PaymentResult ("the Recharge Amount is invalid! "); Var user = _ workContext. currentUser; var order = _ paymentService. createRechargeOrder (user. id, money); return Json (new PaymentResult (true) {OrderId = order. orderNumber });}

Unified order calling

After the order is successfully created, the page jumps to the payment page. At this time, prepay_id and paySign are obtained according to the official process. The demo provides a jsApiPay object. However, this object requires a page object initialization.

[LoginValid] public ActionResult H5Pay (string orderNumber) {var user = _ workContext. currentUser; var order = _ paymentService. getOrderByOrderNumber (orderNumber); // determines whether the order exists // whether the order has been paid var openid = user. openId; var jsApipay = new JsApiPayMvc (this. controllerContext. httpContext); jsApipay. openid = openid; jsApipay. total_limit = (int) order. amount * 100; WxPayData unifiedOrderResult = jsApipay. getuniiedorderresult (); ViewBag. wxJsApiParam = jsApipay. getJsApiParameters (); // obtain the js api parameter ViewBag. unigiedorder = unigiedorderresult. toPrintStr (); ViewBag. orderNumber = order. orderNumber; return View ();}

In MVC, we can simply change it. That is, you can replace the page Object with httpContext. Then the method can be used directly.

JsApiPayMvc:

Using System; using System. collections. generic; using System. web; using System. web. UI; using System. web. UI. webControls; using System. runtime. serialization; using System. IO; using System. text; using System. net; using System. web. security; using LitJson; namespace WxPayAPI {public class JsApiPayMvc {// <summary> // Save the page object, because the Request object of Page must be used in the class method // </summary> public HttpContextBase context {get; set ;} /// <summary> // openid is used to call the unified order interface // </summary> public string openid {get; set ;} /// <summary> // access_token is used to obtain the Receiving address. js function entry parameter. // </summary> public string access_token {get; set ;} /// <summary> // item amount, used for unified order /// </summary> public int total_detail {get; set ;} /// <summary> /// result returned by the unified order interface /// </summary> public WxPayData unifiedOrderResult {get; set;} public JsApiPayMvc (HttpContextBase _ context) {context = _ context;}/*** webpage authorization to obtain basic user information * For details, see webpage authorization to obtain basic user information: http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html * Step 1: Use url jump to get code * Step 2: Use code to get openid and access_token **/public void GetOpenidAndAccessToken (string code) {if (! String. isNullOrEmpty (code) {// obtain the code to obtain the openid and access_token Log. debug (this. getType (). toString (), "Get code:" + code); GetOpenidAndAccessTokenFromCode (code);} else {// construct the URL string host = context for webpage authorization to obtain code. request. url. host; string path = context. request. path; string redirect_uri = HttpUtility. urlEncode ("http: //" + host + path); WxPayData data = new WxPayData (); data. setValue ("appid", WxPayConfig. APPID); data. setValue ("redirect_uri", redirect_uri); data. setValue ("response_type", "code"); data. setValue ("scope", "snsapi_base"); data. setValue ("state", "STATE" + "# wechat_redirect"); string url =" https://open.weixin.qq.com/connect/oauth2/authorize ? "+ Data. toUrl (); Log. debug (this. getType (). toString (), "Will Redirect to URL:" + url); try {// trigger the return code context. response. redirect (url); // The Redirect function will throw a ThreadAbortException exception. You do not need to handle this exception} catch (System. threading. threadAbortException ex) {}}/*** Exchange code for the returned data of access_token and openid authorized on the webpage. If the returned data is correct, the JSON data packet is as follows: * {* "access_token ": "ACCESS_TOKEN", * "expires_in": 7200, * "refresh_token": "REFRESH_TOKEN", * "openid": "OPENID", * "scope": "SCOPE ", * "unionid ": "o6_bmasdasdsad6_2sgVt7hMZOPfL" *} * The access_token can be used to obtain the shared shipping address * openid is a required parameter for the unified order payment of the jsapi payment interface * For more details, refer to webpage authorization for basic user information: http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html * @ WxPayException thrown in case of failure */public void GetOpenidAndAccessTokenFromCode (string code) {try {// construct the url WxPayData = new WxPayData () for obtaining the openid and access_token; data. setValue ("appid", WxPayConfig. APPID); data. setValue ("secret", WxPayConfig. APPSECRET); data. setValue ("code", code); data. setValue ("grant_type", "authorization_code"); string url =" https://api.weixin.qq.com/sns/oauth2/access_token ? "+ Data. toUrl (); // request url to obtain data string result = HttpService. get (url); Log. debug (this. getType (). toString (), "GetOpenidAndAccessTokenFromCode response:" + result); // save access_token for Receiving address to obtain JsonData jd = JsonMapper. toObject (result); access_token = (string) jd ["access_token"]; // obtain the user's openid = (string) jd ["openid"]; Log. debug (this. getType (). toString (), "Get openid:" + openid); Log. debug (this. get Type (). toString (), "Get access_token:" + access_token);} catch (Exception ex) {Log. error (this. getType (). toString (), ex. toString (); throw new WxPayException (ex. toString ();}/*** unified order is called to obtain the order result * @ return unified order result * @ exception WxPayException thrown in case of failure */public WxPayData getuniuniiedorderresult () {// uniform order WxPayData data = new WxPayData (); data. setValue ("body", "test"); data. setValue ("attach", "test"); data. se TValue ("out_trade_no", WxPayApi. generateOutTradeNo (); data. setValue ("total_fee", total_fee); data. setValue ("time_start", DateTime. now. toString ("yyyyMMddHHmmss"); data. setValue ("time_expire", DateTime. now. addMinutes (10 ). toString ("yyyyMMddHHmmss"); data. setValue ("goods_tag", "test"); data. setValue ("trade_type", "JSAPI"); data. setValue ("openid", openid); WxPayData result = WxPayApi. unifiedOrder (da Ta); if (! Result. IsSet ("appid") |! Result. isSet ("prepay_id") | result. getValue ("prepay_id "). toString () = "") {Log. error (this. getType (). toString (), "UnifiedOrder response error! "); Throw new WxPayException (" UnifiedOrder response error! ");} UnifiedOrderResult = result; return result;}/***** obtain the parameters required for jsapi payment from the data returned by the unified order, * When the browser calls the JSAPI, the format of the input parameters is as follows: * {* "appId": "wx2421b1c4370ec43b", // The Name Of The Public Account, which is entered by the merchant * "timeStamp ": "1395712654", // timestamp, number of seconds since January 1, 1970 * "nonceStr": "success", // random string * "package": "prepay_id = u802345jgfjsdfgsdg888 ", * "signType": "MD5", // signature method: * "paySign": "70EA570631E4BB79628FBCA90534C63FF7FADD89" // signature *} * @ return string indicates the input parameter when JSAPI is called, parameters can be directly used in json format * For more details, refer to the page to call the payment API: http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7 **/Public string GetJsApiParameters () {Log. debug (this. getType (). toString (), "JsApiPay: GetJsApiParam is processing... "); WxPayData jsApiParam = new WxPayData (); jsApiParam. setValue ("appId", unifiedOrderResult. getValue ("appid"); jsApiParam. setValue ("timeStamp", WxPayApi. generateTimeStamp (); jsApiParam. setValue ("nonceStr", WxPayApi. generateNonceStr (); jsApiParam. setValue ("package", "prepay_id =" + unifiedOrderResult. getValue ("prepay_id"); jsApiParam. setValue ("signType", "MD5"); jsApiParam. setValue ("paySign", jsApiParam. makeSign (); string parameters = jsApiParam. toJson (); Log. debug (this. getType (). toString (), "Get jsApiParam:" + parameters); return parameters;}/*** Get the parameters of the Receiving address js function entry. For details, refer to the receiving address sharing interface: http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_9 * @ Return string the parameters required by the js function for sharing the shipping address. The json format can be directly used as parameters. */public string GetEditAddressParameters () {string parameter = ""; try {string host = context. request. url. host; string path = context. request. path; string queryString = context. request. url. query; // note that the signature is the complete url string url = "http: //" + host + path + queryString returned by the background when the webpage is authorized to obtain user information; // construct the WxPayData signData = new WxPayData (); signData. setValue ("appid", WxPayConfig. APPID); signData. setValue ("url", url); signData. setValue ("timestamp", WxPayApi. generateTimeStamp (); signData. setValue ("noncestr", WxPayApi. generateNonceStr (); signData. setValue ("accesstoken", access_token); string param = signData. toUrl (); Log. debug (this. getType (). toString (), "SHA1 encrypt param:" + param); // SHA1 encrypted string addrSign = FormsAuthentication. hashPasswordForStoringInConfigFile (param, "SHA1"); Log. debug (this. getType (). toString (), "SHA1 encrypt result:" + addrSign); // obtain the Receiving address. js function entry parameter WxPayData afterData = new WxPayData (); afterData. setValue ("appId", WxPayConfig. APPID); afterData. setValue ("scope", "jsapi_address"); afterData. setValue ("signType", "sha1"); afterData. setValue ("addrSign", addrSign); afterData. setValue ("timeStamp", signData. getValue ("timestamp"); afterData. setValue ("nonceStr", signData. getValue ("noncestr"); // convert to json format parameter = afterData. toJson (); Log. debug (this. getType (). toString (), "Get EditAddressParam:" + parameter);} catch (Exception ex) {Log. error (this. getType (). toString (), ex. toString (); throw new WxPayException (ex. toString () ;}return parameter ;}}}

This page can be debugged locally to easily confirm whether the parameters are OK.

Call for payment

An example of the official page is as follows: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php? Chapter = 7_7 & index = 6 but the main parameter (mark part) is generated by the background, that is, ViewBag. wxJsApiParam in the previous step.

Function onBridgeReady () {WeixinJSBridge. invoke ('getbrandwcpayrequest', {"appId": "wx2421b1c4370ec43b", // name of the Public Account, which is input by the merchant "timeStamp": "1395712654", // timeStamp, the number of seconds since January 1, 1970 "nonceStr": "success", // random string "package": "prepay_id = u802345jgfjsdfgsdg888", "signType": "MD5", // signature method: "paySign": "70EA570631E4BB79628FBCA90534C63FF7FADD89" // signature}, function (res) {if (res. err_msg = "get_bran D_wcpay_request: OK ") {}// determine the front-end return using the above method. The team solemnly prompts that res. err_msg will return OK after the user successfully pays, but it is not guaranteed to be absolutely reliable. });}

Therefore, write the following in MVC:

@ {ViewBag. Title = "Payment"; Layout = "~ /Views/Shared/_ Layout. cshtml ";}< div class =" page "id =" Wxpayment "> <div class =" content "> <div> order details: @ Html. raw (ViewBag. unifiedOrder) </div> <button id = "h5pay" onclick = "callpay () "> payment </button> </div> <input type =" hidden "value =" @ ViewBag. orderNumber "id =" ordernum "/> </div> <script type =" text/javascript "> // call the JS api to pay function jsApiCall () {WeixinJSBridge. invoke ('getbrandwcpayrequest', @ Html. raw (ViewBag. wxJsApiParam), // josn string function (res) {WeixinJSBridge. log (res. err_msg); // alert (res. err_code + res. err_desc + res. err_msg); if (res. err_msg = "get_brand_wcpay_request: OK") {var num = $ ("# ordernum "). val (); $. post ("/payment/WeiXinPaySuccess", {ordernumber: num}, function (data) {if (data. isSuccess = true) {alert ("Payment successful"); location. href = document. referrer;} else {}});} if (res. err_msg = 'get _ brand_wcpay_request: cancel ') {$ ('. button '). removeAttr ('submitting'); alert ('cancelling payers) ;}});} function callpay () {if (typeof WeixinJSBridge = "undefined ") {alert ("WeixinJSBridge ="); if (document. addEventListener) {document. addEventListener ('weixinjsbridgeready', jsApiCall, false);} else if (document. attachEvent) {document. attachEvent ('weixinjsbridgeready', jsApiCall); document. attachEvent ('onweixinjsbridgeready', jsApiCall) ;}} else {jsApiCall () ;}</script>

You must use Html. Raw. Otherwise, the json Parsing is incorrect and cannot be paid. Click the page at this time, the loading effect will appear, but don't be happy too early, it will still go wrong, there will be a "3 the current URL is not registered"

The reason is that you need to set the payment directory in the public account. This payment directory is case-sensitive, so you have to try it several times. The process is correct until the Password Input window pops up. After the payment is successful, you can immediately receive the callback in js. At this time, you can process your order and business logic.

Official documents: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php? Chapter = 7_3

Scan the code to pay demo: http://www.bkjia.com/article/103959.htm

Official demo: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php? Chapter = 11_1

The above is all the content of this article. I hope this article will help you in your study or work. I also hope to provide more support to the customer's home!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.