码迷,mamicode.com
首页 > 微信 > 详细

微信支付

时间:2019-07-29 19:06:29      阅读:248      评论:0      收藏:0      [点我收藏+]

标签:ons   framework   ugo   strust   over   gre   mat   final   can   

二维码生成的 js 插件

# bootcdn 网站
https://www.bootcdn.cn/

qrious

qrious 下载

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

qrious 参数和演示

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

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

SDK 与 DEMO 下载,下载的 zip 是一个 maven 项目,使用集成开发环境打开,并执行 maven install ,将 SDK 安装到本地仓库。

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 查询后知道的。

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

微信支付

标签:ons   framework   ugo   strust   over   gre   mat   final   can   

原文地址:https://www.cnblogs.com/mozq/p/11265712.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!