This article mainly introduces the implementation methods and steps of public account payment in development. It has good reference value. let's take a look at it below. This article mainly introduces the implementation methods and steps of public account payment in development. It has good reference value. let's take a look at it together with the small editor.
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 {////// Save the Page object because you need to use the Page Request object in the class method ///Public HttpContextBase context {get; set ;}////// Openid is used to call the unified order interface ///Public string openid {get; set ;}////// Access_token is used to obtain the receiving address. js function Entry parameters ///Public string access_token {get; set ;}////// Item amount for unified order ///Public int total_detail {get; set ;}////// The result returned by the unified order interface ///Public WxPayData unifiedOrderResult {get; set;} public JsApiPayMvc (HttpContextBase _ context) {context = _ context ;} /***** the entire process of 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 ";}
Order Details: @ Html. Raw (ViewBag. unifiedOrder)
Payment