Java SPRINGMVC Implementation of PC-side web page micro-Scan code payment (full version) _java

Source: Internet
Author: User
Tags http post openid uuid

One: Early micro-credit to pay literacy knowledge

The prerequisite is that there is already a public number that has applied for the micro-credit payment function, and then we need to get the public number AppID and the micro-letter merchant number, which can be found on the micro-credit and micro-mail payment merchant platform respectively. In fact, after you apply for a successful payment function, the micro-mail will be emailed to you, with this information, we can go to the micro-credit Payment service Support page: https://pay.weixin.qq.com/service_provider/index.shtml

Open this page, click on the top right link "development document" will go to the API Document description page, looks like the following

Select the red circle of the sweep code payment is that we have to do access, the mouse to move to the above will prompt you to view the development of the document, if this does not know how to view, you can wash your sleep, you really do not fit to do programmers, the address is as follows:

Https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1 is opened in the browser and will see

What we want to focus on and read, I've already labeled it in the Red Oval, first read the "interface rules" inside the protocol specification, joking this is not read you want to do micro-letter payment, this is like you want to go to the girls, you have to collect some basic background information, understand each other's characteristics, or how to communicate below. It turns out that only programmers who pick up girls are good sellers. Digress we next want to look at the "scene introduction" in the case and norms, only look at remember to be sure to micro-letter payment logo download down, is to finally put on our own sweep code Payment page, so that looks more professional. Then focus on "mode two"

We are here to use mode two way to achieve the PC-side page sweep code payment function.

The micro-letter official interpretation of mode two is such "merchant backend system first call micro-letter payment of the unified next single interface, micro-letter backend system return link parameters code_url, merchant background system will code_url value generated two-dimensional code picture, users use micro-letter client scan code after the launch of payment." Note: The Code_url is valid for 2 hours, and will not be able to initiate payment after the expiration of the scan code. See, that's it. We first want to call the micro-letter to provide a unified next single interface, get a key information Code_url (as for this code_url is what ghost, I do not know), and then we use their own program to generate this URL a two-dimensional code, Generate a two-dimensional code I used Google's zxing library here. Then you can display this two-dimensional code on your PC-side page. So that the end user will pay for a sweep of the code, the payment is complete, see here you must be very excited, found that the micro-letter payment is so simple, and so on there is another thing we do not know, the customer knows to pay, we do not know the server side, to the micro-credit development personnel IQ they have already thought of this problem, So when you call the unified next single interface, one of the required parameters is the callback URL, that is, if the client is successful after the payment of the micro-trust through the URL to our own server to submit some data, and then we analyze the data in the background, to complete our own operation. This way we know if the customer has actually paid through the micro-letter. So the whole process ends, and this is mode two. Micro credit A timeline diagram that represents this process.

The expression is more complex, looks more laborious, summed up in fact, our server should do the following things:

1. Through the unified next single interface to pass the correct parameters (including our callback URL, of course) and signature verification, from the return data to get code_url corresponding data

2. Based on the Code_url data, we generate a two-dimensional code picture, which is displayed on the browser Web page.

3. Add our own business logic processing to the URL of the callback.

This is the end of literacy, you finally know what the sweep code to pay what kind of process, the following we will pick it up the relevant API use, do a good job in each step.

II: Development process

Before you develop your code, prepare a few things.

1. Add zxing maven Dependencies

2. Add jdom maven Dependencies

3. Download the Java version of the SDK demo program, address here

Https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1

We need Md5util.java and Xmlutil.java two files.

4. We use the HttpClient version is 4.5.1, remember to add Maven dependencies

After the preparation work is done, continue to look down:

First we want to invoke the micro-letter unified Next single interface, we click on "API List" in the unified order will see this page:

I call the actual situation as an example, the following parameters are required, for everyone's convenience I have turned it into a Pojo object, the code is as follows:

public class Unifiedorderdto implements weixinconstants {private string AppID, private string body, private string Devic
E_info;
Private String mch_id;
Private String nonce_str;
Private String Notify_url;
Private String openId;
Private String out_trade_no;
Private String spbill_create_ip;
private int total_fee;
Private String Trade_type;
Private String product_id;
Private String sign; Public Unifiedorderdto () {this.appid = AppID; this.mch_id = wxpaymentaccount; this.device_info = Device_info_web; this.no
Tify_url = Callback_url;
This.trade_type = trade_type_native; public string Getappid () {return AppID.} public void Setappid (String appid) {this.appid = AppID;} public string Getb Ody () {return body;} public void Setbody (string body) {this.body = body;} public string Getdevice_info () {return Devi
Ce_info; public void Setdevice_info (String device_info) {this.device_info = Device_info;} public String getmch_id () {return MC
h_id; } public void setmch_id (String mch_id) {this.mch_id = mch_id; Public String Getnonce_str () {return nonce_str.} public void Setnonce_str (String nonce_str) {this.nonce_str = nonce_s
Tr Public String Getnotify_url () {return notify_url.} public void Setnotify_url (String notify_url) {This.notify_url = no
Tify_url; Public String Getopenid () {"Return OpenID"} public void Setopenid (String OpenID) {This.openid = OpenID; G Getout_trade_no () {return out_trade_no.} public void Setout_trade_no (String out_trade_no) {this.out_trade_no = Out_tr
Ade_no; public string Getspbill_create_ip () {return spbill_create_ip.} public void Setspbill_create_ip (string spbill_create_i P) {this.spbill_create_ip = spbill_create_ip} public int Gettotal_fee () {return total_fee;} public void Settotal_fee ( int Total_fee) {this.total_fee = total_fee} public String Gettrade_type () {return trade_type;} public void settrade_t Ype (String trade_type) {this.trade_type = Trade_type;} public String getsign () {return sign;} public VoiD setsign (string sign) {this.sign = sign;} public String getproduct_id () {return product_id;} public void Setproduct_i D (String product_id) {this.product_id = product_id} public string Generatexmlcontent () {string xml = ' <xml> + ' "+ This.appid +" </appid> "+" "+ This.body +" "+" <device_info>WEB</device_info> "+" <mch_id&gt  ; "+ this.mch_id +" </mch_id> "+" <nonce_str> "+ this.nonce_str +" </nonce_str> "+" <notify_url> " + This.notify_url + "</notify_url>" + "<out_trade_no>" + this.out_trade_no + "</out_trade_no>" + " ;p roduct_id> "+ this.product_id +" </product_id> "+" <spbill_create_ip> "+ this.spbill_create_ip+" </ Spbill_create_ip> "+" <total_fee> "+ string.valueof (this.total_fee) +" </total_fee> "+" <trade_type&
gt; "+ This.trade_type +" </trade_type> "+" <sign> "+ this.sign +" </sign> "+" </xml> ";
return XML; Public String makesign () {String content = "appid=" + this.appid + "&body=" + this.body + "&device_info=web" + "&mch_id=" + THIS.MC 
h_id + "&nonce_str=" + This.nonce_str + "? ify_url=" + This.notify_url + "&out_trade_no=" + This.out_trade_no + "&product_id=" + this.product_id + "&spbill_create_ip=" + this.spbill_create_ip+ "&total_fee=" +
String.valueof (This.total_fee) + "&trade_type=" + this.trade_type;
Content = content + "&key=" + weixinconstants.md5_api_key;
String esignature = weixinpaymentutil.md5encode (content, "utf-8");
return Esignature.touppercase (); }
}

The explanation of the individual member variables can be seen in the "Unified single Interface" description.

After this we need to set up the content to fill in, to call the interface to get the return data, get Code_url data and then generate a two-dimensional picture, the image of the address returned to the PC side page, and then it will be displayed, here to specifically explain, Our own PC Web page will call our own backstage Springmvc via Ajax when clicking on the micro-mail payment. Controller then, in the corresponding method of controller, the Code_url value of the XML data returned by the httpclient of the micro-letter Unified single Interface invocation is completed, and then the two-dimensional code is returned to the foreground page. The code implemented in controller is as follows:

Map<string,object> result=new hashmap<string,object> ();
Unifiedorderdto dto = new Unifiedorderdto (); if (cash = NULL | |
"". Equals (Cash)) {result.put ("error", "cash could not to zero");
return result;
int totalfee = 100*integer.parseint (cash);
Logger.info ("Total recharge cash:" + totalfee);
DTO.SETPRODUCT_ID (String.valueof (System.currenttimemillis ()));
Dto.setbody ("Repair");
Dto.setnonce_str (String.valueof (System.nanotime ()));
Logininfo logininfo = Logininfoutil.getlogininfo ();
Through our backstage order number +uuid for the identification sign DTO.SETOUT_TRADE_NO ("Your order number + key information, after the micro-letter callback returns, you can verify");
Dto.settotal_fee (Totalfee);
Dto.setspbill_create_ip ("127.0.0.1");
Generate Signature Dto.setsign (Dto.makesign ());
Logger.info ("sign:" + dto.makesign ());
Logger.info ("XML content:" + dto.generatexmlcontent ()); 
try {httpclient httpclient = httpclientbuilder.create (). build ();
HttpPost post = new HttpPost (Weixinconstants.unifiedorder_url); Post.addheader ("Content-type", "text/xml;
Charset=utf-8 "); Stringentity xmlentity = new Stringentity (Dto.generatexmlcontent (), contenttype.text_xml);
Post.setentity (xmlentity);
HttpResponse HttpResponse = Httpclient.execute (POST);
String responsexml = entityutils.tostring (Httpresponse.getentity (), "UTF-8");
Logger.info ("Response XML content:" + responsexml); Parse Code_url CONTENT map<string, string= "" > Resultmap = (map<string, string= "" >) Xmlutil.doxmlparse (
Responsexml);
Logger.info ("Response code_url:" + resultmap.get ("Code_url"));
String Codeurl = Resultmap.get ("Code_url"); if (Codeurl!= null &&! "". Equals (Codeurl)) {String ImageUrl = Generateqrcode (Codeurl); Result.put ("Qrimage", ImageUrl);} post.releaseconnection
();
catch (Exception e) {e.printstacktrace ();} result.put ("Success", "1"); Return result;</string,></string,></string,object></string,object>

The code that generates the two-dimensional code is as follows:

private string Generateqrcode (String codeurl) {
file Foldler = new File (basepath + "QRCode");
if (!foldler.exists ()) {
foldler.mkdirs ();
}
String f_name = uuidutil.uuid () + ". png";
try {
file F = new file (BasePath + "QRCode", f_name);
FileOutputStream Fio = new FileOutputStream (f);
Multiformatwriter multiformatwriter = new Multiformatwriter ();
Map hints = new HashMap ();
Hints.put (Encodehinttype.character_set, "UTF-8"); Sets the character set encoding type
Bitmatrix Bitmatrix = null;
Bitmatrix = Multiformatwriter.encode (Codeurl, Barcodeformat.qr_code, 300,hints);
BufferedImage image = Tobufferedimage (Bitmatrix);
Output two-dimensional code picture stream
imageio.write (image, "png", FIO);
Return ("qrcode/" + f_name);
} catch (Exception E1) {
e1.printstacktrace ();
return null;
} 
}

At this point how the client micro-mail scan code, the micro-letter will be through the callback we create a URL to return the data to us. To do our own processing in the callback method, it is important to note that your callback interface must be implemented via the HTTP POST method, or you will not be able to accept XML data. The code for callback processing is as follows:

@RequestMapping (value = "/your_callback_url", method = Requestmethod.post) @ResponseBody the public void Finishpayment ( HttpServletRequest request, HttpServletResponse response) {try {logger.info ("start to callback from Weixin server:" + R
Equest.getremotehost ());
Map<string, string= "" > resultmap = new hashmap<string, string= "" > ();
InputStream InputStream = Request.getinputstream ();
Read the input stream Saxbuilder saxbuilder= new Saxbuilder ();
Document document = Saxbuilder.build (InputStream);
Gets the XML root element root = Document.getrootelement ();
Gets all the child nodes of the root element list = Root.getchildren ();
Iterator it = List.iterator ();
while (It.hasnext ()) {Element E = (Element) it.next ();
String k = E.getname ();
String v = "";
List children = E.getchildren ();
if (Children.isempty ()) {v = e.gettextnormalize ();} else {v = Xmlutil.getchildrentext (children);} resultmap.put (k, v);
}//VERIFY signature!!!
/* string[] keys = Resultmap.keyset (). ToArray (new string[0));
Arrays.sort (keys);
String kvparams = ""; For (inT i=0; i<keys.length; i++) = "" {= "" "" "" "Keys[i].equals (" esign ") =" "continue;=" "}=" "Signature Algorithm =" "if (i=" = "0) =" "kvparams=" "+ +" (keys[i) "" = "+ result
Map.get (Keys[i]));
else {kvparams + = ("&" = "keys[i]=" "&key=" + weixinconstants.md5_api_key; String md5esign = Weixinpaymentutil.md5encode (esign, "utf-8"); = "" if (!md5esign.equals (Resultmap.get ("sign")) = "" return;= "}*=" "Close stream =" "Release resource =" "inputstream.close (); =" inputstream= "NULL;" string= "" Returncode= "Resultmap.get (" Return_code ");" outtradeno= "Resultmap.get (" Out_trade_no ");" to be divided into units = "" int= "" Nfee= "Integer.parseint (" Resultmap.get ") (" Total_fee "));" Logger.info ("out=" "trade=" "no=" ": =" "outtradeno); =" "Logger.info (" total_fee= "" nfee); = "" Business process Process = "" If ("Success". Equals (ReturnCode)) = "todo:=" "your=" "business=" "process=" "add=" "here=" "Response.getwriter" (). Print ( Xmlutil.getretresultxml (Resultmap.get ("Return_code"), = "" Resultmap.get ("Return_code")); = "Else=" "Resultmap.get ("return_msg")); = "" Catch (ioexception= "" ioe) = "" Ioe.prinTstacktrace (); = "" Catch= "(jdomexception=" "e1) =" "e1.printstacktrace (); =" "} 

Two classes of Xmlutil and Md5util used in the official Java demo of micro-credit remember to take it over and change it, the demo code can be found on its official demo page, and the related MAVEN dependencies are as follows:

<dependency>
<groupid>jdom</groupid>
jdom</artifactid>
<version>1.1 </version>
</dependency>
<dependency>
<groupid>com.google.zxing</ groupid>
core</artifactid>
<version>3.3.0</version>
</dependency>

The last thing to pay special attention to is about the signature, signature generation MD5 Class I am from the micro-letter website directly download the Java version of the demo program to get, suggest you also, because this is to ensure that MD5 signature is the best choice for the same. The specific generation of signature algorithm can be viewed in the micro-credit Official document, here also strongly recommended that you must be official API to explain that you are in the development of a variety of problems encountered 90% because you do not read the official document, but credulous someone blog! This is the real purpose and intention of my writing this article, according to the official document, with my Java code implementation, micro-trust PC-side web page sweep code payment must be in your Web application to fly up.

The above is a small series to introduce the Java Springmvc to realize the PC-side web page micro-letter sweep code payment (full version), I hope to help you, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!

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.