# bootcdn 網站 https://www.bootcdn.cn/
qrious
php
https://www.bootcdn.cn/qrious/ https://github.com/neocotic/qrious https://cdnjs.cloudflare.com/ajax/libs/qrious/3.0.1/qrious.min.js
Field | Type | Description | Default | Read Only |
---|---|---|---|---|
background | String | Background color of the QR code | "white" |
No |
backgroundAlpha | Number | Background alpha of the QR code | 1.0 |
No |
element | Element | Element to render the QR code | <canvas> |
Yes |
foreground | String | Foreground color of the QR code | "black" |
No |
foregroundAlpha | Number | Foreground alpha of the QR code | 1.0 |
No |
level | String | Error correction level of the QR code (L, M, Q, H) | "L" |
No |
mime | String | MIME type used to render the image for the QR code | "image/png" |
No |
padding | Number | Padding for the QR code (pixels) | null (auto) |
No |
size | Number | Size of the QR code (pixels) | 100 |
No |
value | String | Value encoded within the QR code | "" |
No |
element 頁面容納二維碼的元素,必須是 <canvas> 或者 <img> 。只讀,經過構造器傳入。 value 二維碼錶示的信息 background 背景色 backgroundAlpha 背景色透明度 [0, 1] 0:徹底透明 1:徹底不透明 foreground 前景色 foregroundAlpha 前景色透明度 [0, 1] 0:徹底透明 1:徹底不透明 level 容錯級別 padding 填充 size 大小 (包括填充在內) mime 指定生成二維碼的 mime 類型
<!DOCTYPE html> <html> <head> <title>二維碼入門小demo</title> </head> <body> <div > <!-- <canvas id="qrious"></canvas> --> <img id="qrious" > </div> <script src="js/QRious.js"></script> <script> var qr = new QRious({ element: document.getElementById('qrious') }); qr.value = 'https://github.com/neocotic/qrious'; qr.background = 'pink'; qr.backgroundAlpha = 0.5;//背景色透明度爲 0.5 qr.foreground = 'orange'; qr.foregroundAlpha = 1; qr.level = 'H'; qr.padding = 20; qr.size = 400; </script> </body> </html>
qrcode
html
https://www.bootcdn.cn/qrcode-generator/
appid=wx8397f8696b538317 微信公衆帳號或開放平臺 APP 的惟一標識 partner=1473426802 財付通平臺的商戶帳號 partnerkey=T6m9iK73b0kn9g5v426MKfHQH7X8rKwb 財付通平臺的商戶密鑰 notifyurl=http://a31ef7db.ngrok.io/WeChatPay/WeChatPayNotify 回調地址
# 微信支付文檔導航 微信支付 > 幫助中心 > 開發文檔 > Native 支付 https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1 # 微信開發者社區 https://developers.weixin.qq.com/community/develop/mixflow
SDK 與 DEMO 下載,下載的 zip 是一個 maven 項目,使用集成開發環境打開,並執行 maven install ,將 SDK 安裝到本地倉庫。java
https://pay.weixin.qq.com/wiki/doc/api/download/WxPayAPI_JAVA.zip
<dependency> <groupId>com.github.wxpay</groupId> <artifactId>wxpay-sdk</artifactId> <version>3.0.9</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.3</version> </dependency>
https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=4_3
Tunnel a31ef7db.ngrok.io not found
<xml> <return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[XML格式錯誤]]></return_msg> </xml> <!-- param.put("total_fee", String.valueOf(0.01)); --> <xml> <return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[invalid total_fee]]></return_msg> </xml>
package com.mozq.wxpay.demo; import com.github.wxpay.sdk.WXPayUtil; import java.util.HashMap; import java.util.Map; public class WXPayOrderDemo { public static void main(String[] args) throws Exception { //參數 Map<String, String> param = new HashMap<>(); param.put("appid", "wx8397f8696b538317"); param.put("mch_id", "1473426802"); String nonceStr = WXPayUtil.generateNonceStr(); param.put("nonce_str", nonceStr); param.put("body", "凡人修仙充值中心-凡人仙院充值"); param.put("out_trade_no", "201907280001"); param.put("total_fee", String.valueOf(1)); param.put("spbill_create_ip", "123.12.12.123"); param.put("notify_url", "http://a31ef7db.ngrok.io/WeChatPay/WeChatPayNotify"); param.put("trade_type", "NATIVE"); HttpClient httpClient = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder"); //生成簽名 String xmlParam = WXPayUtil.generateSignedXml(param, "T6m9iK73b0kn9g5v426MKfHQH7X8rKwb"); httpClient.setXmlParam(xmlParam); httpClient.setHttps(false); //請求 httpClient.post(); //解析結果 String content = httpClient.getContent(); Map<String, String> resultMap = WXPayUtil.xmlToMap(content); System.out.println(resultMap); } }
{ nonce_str=OUPjKBzycEz8cz10, code_url=weixin://wxpay/bizpayurl?pr=gh8wAgg, appid=wx8397f8696b538317, sign=CDAD758D394BC2DA2484E89617022736, trade_type=NATIVE, return_msg=OK, result_code=SUCCESS, mch_id=1473426802, return_code=SUCCESS, prepay_id=wx282236255907477d09cfe0341493615900 }
<xml> <return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg> <appid><![CDATA[wx2421b1c4370ec43b]]></appid> <mch_id><![CDATA[10000100]]></mch_id> <nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str> <openid><![CDATA[oUpF8uMuAJO_M2pxb1Q9zNjWeS6o]]></openid> <sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign> <result_code><![CDATA[SUCCESS]]></result_code> <prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id> <trade_type><![CDATA[JSAPI]]></trade_type> </xml>
package com.mozq.wxpay.demo; import java.io.IOException; import java.security.GeneralSecurityException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.text.ParseException; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLException; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.apache.http.Consts; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLContextBuilder; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.conn.ssl.X509HostnameVerifier; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; /** * http請求客戶端 * * @author Administrator * */ public class HttpClient { private String url; private Map<String, String> param; private int statusCode; private String content; private String xmlParam; private boolean isHttps; public boolean isHttps() { return isHttps; } public void setHttps(boolean isHttps) { this.isHttps = isHttps; } public String getXmlParam() { return xmlParam; } public void setXmlParam(String xmlParam) { this.xmlParam = xmlParam; } public HttpClient(String url, Map<String, String> param) { this.url = url; this.param = param; } public HttpClient(String url) { this.url = url; } public void setParameter(Map<String, String> map) { param = map; } public void addParameter(String key, String value) { if (param == null) param = new HashMap<String, String>(); param.put(key, value); } public void post() throws ClientProtocolException, IOException { HttpPost http = new HttpPost(url); setEntity(http); execute(http); } public void put() throws ClientProtocolException, IOException { HttpPut http = new HttpPut(url); setEntity(http); execute(http); } public void get() throws ClientProtocolException, IOException { if (param != null) { StringBuilder url = new StringBuilder(this.url); boolean isFirst = true; for (String key : param.keySet()) { if (isFirst) url.append("?"); else url.append("&"); url.append(key).append("=").append(param.get(key)); } this.url = url.toString(); } HttpGet http = new HttpGet(url); execute(http); } /** * set http post,put param */ private void setEntity(HttpEntityEnclosingRequestBase http) { if (param != null) { List<NameValuePair> nvps = new LinkedList<NameValuePair>(); for (String key : param.keySet()) nvps.add(new BasicNameValuePair(key, param.get(key))); // 參數 http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 設置參數 } if (xmlParam != null) { http.setEntity(new StringEntity(xmlParam, Consts.UTF_8)); } } private void execute(HttpUriRequest http) throws ClientProtocolException, IOException { CloseableHttpClient httpClient = null; try { if (isHttps) { SSLContext sslContext = new SSLContextBuilder() .loadTrustMaterial(null, new TrustStrategy() { // 信任全部 public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { return true; } }).build(); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslContext); httpClient = HttpClients.custom().setSSLSocketFactory(sslsf) .build(); } else { httpClient = HttpClients.createDefault(); } CloseableHttpResponse response = httpClient.execute(http); try { if (response != null) { if (response.getStatusLine() != null) statusCode = response.getStatusLine().getStatusCode(); HttpEntity entity = response.getEntity(); // 響應內容 content = EntityUtils.toString(entity, Consts.UTF_8); } } finally { response.close(); } } catch (Exception e) { e.printStackTrace(); } finally { httpClient.close(); } } public int getStatusCode() { return statusCode; } public String getContent() throws ParseException, IOException { return content; } }
下單後,並無返回 transaction_id ,因此這個值是我先用 out_trade_no 查詢後知道的。git
package com.mozq.wxpay.demo; import com.github.wxpay.sdk.WXPayUtil; import java.util.HashMap; import java.util.Map; public class WXPayQueryPayStatus { public static void main(String[] args) throws Exception { //查詢參數 Map<String, String> param = new HashMap<>(); param.put("appid", "wx8397f8696b538317"); param.put("mch_id", "1473426802"); String nonceStr = WXPayUtil.generateNonceStr(); param.put("nonce_str", nonceStr); //發現下單後,並無返回 transaction_id ,因此這個值是我先用 out_trade_no 查詢後知道的。 param.put("transaction_id", "4200000344201907286520086822"); // param.put("out_trade_no", "201907280001"); String url = "https://api.mch.weixin.qq.com/pay/orderquery"; HttpClient httpClient = new HttpClient(url); //生成簽名 String xmlParam = WXPayUtil.generateSignedXml(param, "T6m9iK73b0kn9g5v426MKfHQH7X8rKwb"); httpClient.setXmlParam(xmlParam); httpClient.setHttps(false); //請求 httpClient.post(); //解析結果 String content = httpClient.getContent(); Map<String, String> resultMap = WXPayUtil.xmlToMap(content); System.out.println(resultMap); } }
param.put("transaction_id", "wx282236255907477d09cfe0341493615900"); {return_msg=transaction_id參數長度有誤, return_code=FAIL}
{ transaction_id=4200000344201907286520086822, nonce_str=zY9Kxhrt5oGxYZSW, trade_state=SUCCESS, bank_type=CFT, openid=oNpSGwYhk9R8kJz6MqLz79KvTaM4, sign=A0B8AFA851CAA0AB5A33953FD9E454E8, return_msg=OK, fee_type=CNY, mch_id=1473426802, cash_fee=1, out_trade_no=201907280001, appid=wx8397f8696b538317, total_fee=1, trade_state_desc=支付成功, trade_type=NATIVE, result_code=SUCCESS, attach=, time_end=20190728223947, is_subscribe=N, return_code=SUCCESS }
<xml> <return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg> <appid><![CDATA[wx2421b1c4370ec43b]]></appid> <mch_id><![CDATA[10000100]]></mch_id> <device_info><![CDATA[1000]]></device_info> <nonce_str><![CDATA[TN55wO9Pba5yENl8]]></nonce_str> <sign><![CDATA[BDF0099C15FF7BC6B1585FBB110AB635]]></sign> <result_code><![CDATA[SUCCESS]]></result_code> <openid><![CDATA[oUpF8uN95-Ptaags6E_roPHg7AG0]]></openid> <is_subscribe><![CDATA[Y]]></is_subscribe> <trade_type><![CDATA[MICROPAY]]></trade_type> <bank_type><![CDATA[CCB_DEBIT]]></bank_type> <total_fee>1</total_fee> <fee_type><![CDATA[CNY]]></fee_type> <transaction_id><![CDATA[1008450740201411110005820873]]></transaction_id> <out_trade_no><![CDATA[1415757673]]></out_trade_no> <attach><![CDATA[訂單額外描述]]></attach> <time_end><![CDATA[20141111170043]]></time_end> <trade_state><![CDATA[SUCCESS]]></trade_state> </xml>
package com.pinyougou.pay.service.impl; import com.alibaba.dubbo.config.annotation.Service; import com.github.wxpay.sdk.WXPayUtil; import com.pinyougou.pay.service.WeixinPayService; import org.springframework.beans.factory.annotation.Value; import util.HttpClient; import java.util.HashMap; import java.util.Map; @Service public class WeixinPayServiceImpl implements WeixinPayService { @Value("${appid}") private String appid; @Value("${partner}") private String partner; @Value("${partnerkey}") private String partnerkey; @Value("${notifyurl}") private String notifyurl; @Override public Map<String, String> createNative(String out_trade_no, String total_fee) { Map<String, String> paramMap = new HashMap<>(); paramMap.put("appid", appid);//公衆號 paramMap.put("mch_id", partner);//商戶號 paramMap.put("nonce_str", WXPayUtil.generateNonceStr());//隨機字符串 paramMap.put("body", "品優購充值");//訂單描述 paramMap.put("out_trade_no", out_trade_no);//商戶訂單號 paramMap.put("total_fee", total_fee);//總金額(分) paramMap.put("spbill_create_ip", "123.12.12.123");// IP paramMap.put("notify_url", "http://a31ef7db.ngrok.io/WeChatPay/WeChatPayNotify");//回調地址 paramMap.put("trade_type", "NATIVE");//交易類型 System.out.println(paramMap); String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//支付接口 try { HttpClient httpClient = new HttpClient(url); //生成簽名 String xmlParamMap = WXPayUtil.generateSignedXml(paramMap, partnerkey); httpClient.setXmlParam(xmlParamMap); httpClient.setHttps(true); //請求 httpClient.post(); //解析結果 String content = httpClient.getContent(); Map<String, String> resultMap = WXPayUtil.xmlToMap(content); System.out.println(resultMap); Map<String, String> result = new HashMap<>(); result.put("code_url", resultMap.get("code_url"));//支付 url result.put("out_trade_no", out_trade_no);//訂單號 result.put("total_fee", total_fee);//總金額 return result; } catch (Exception e) { e.printStackTrace(); return new HashMap<>(); } } @Override public Map<String, String> queryPayStatus(String out_trade_no) { //查詢參數 Map<String, String> param = new HashMap<>(); param.put("appid", appid); param.put("mch_id", partner); param.put("nonce_str", WXPayUtil.generateNonceStr()); param.put("out_trade_no", out_trade_no); String url = "https://api.mch.weixin.qq.com/pay/orderquery"; try { HttpClient httpClient = new HttpClient(url); //生成簽名 String xmlParam = WXPayUtil.generateSignedXml(param, partnerkey); httpClient.setXmlParam(xmlParam); httpClient.setHttps(true); //請求 httpClient.post(); //解析結果 String content = httpClient.getContent(); Map<String, String> resultMap = WXPayUtil.xmlToMap(content); System.out.println(resultMap); return resultMap; } catch (Exception e) { e.printStackTrace(); } return null; } }
# weixinpay.properties 文件 appid=wx8397f8696b538317 partner=1473426802 partnerkey=T6m9iK73b0kn9g5v426MKfHQH7X8rKwb notifyurl=http://a31ef7db.ngrok.io/WeChatPay/WeChatPayNotify