JAVA接入微信扫码支付,实测有效

       不得不说,微信支付接入比支付宝做的差多了,支付宝支付接入给人的感觉是简单,优雅。微信支付接入给人的感觉恶心,烦躁,想吐槽,踩了不少坑,最后发现使用完全使用官方提供的sdk肯定接入不成功,采用了自己的方式请求调用接口,终于调通了。

       接入微信支付扫码支付,微信支付官方提供了两种模式,模式一商户必须在公众平台后台设置支付回调URL。URL实现的功能:接收用户扫码后微信支付系统回调的productid和openid;模式二,流程更为简单,不依赖设置的回调支付URL。商户后台系统先调用微信支付的统一下单接口,微信后台系统返回链接参数code_url,商户后台系统将code_url值生成二维码图片,用户使用微信客户端扫码后发起支付。注意:code_url有效期为2小时,过期后扫码不能再发起支付。本次接入采用模式二:

多说无用,直接晒代码:

1、微信官方下载微信支付接入sdk

2、配置WXPayConfig,自定义MyWXPayConfig继承sdk中WXPayConfig

import java.io.InputStream;

public class MyWXPayConfig extends WXPayConfig{

    @Override
    String getAppID() {
        // TODO Auto-generated method stub
        return "wxcf1*******";
//        return "wx839******";
    }

    @Override
    String getMchID() {
        // TODO Auto-generated method stub
        return "1557******";
//        return "147*****";
    }

    @Override
    String getKey() {
        // TODO Auto-generated method stub
        return "Xq1crLeoFeOxL6*******";
//        return "8A627A457********";
    }

    @Override
    InputStream getCertStream() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    IWXPayDomain getWXPayDomain() {
        IWXPayDomain iwxPayDomain = new IWXPayDomain() {
            
            public void report(String domain, long elapsedTimeMillis, Exception ex) {
        
            }
    
            public DomainInfo getDomain(WXPayConfig config) {
                return new IWXPayDomain.DomainInfo(WXPayConstants.DOMAIN_API, true);
            }
        };
        return iwxPayDomain;
    }

}
 

3、自定义微信支付服务

import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import com.alibaba.fastjson.JSONObject;

public class WXPayService {

//获取微信扫码支付二维码链接
    public static Map<String, String>  getWXPay(TSecurityOrderEntity order) throws Exception{
        WXPayConfig config = new MyWXPayConfig();
        WXPay wxpay = new WXPay(config);
        String tradeNo = “aaabbbccc”;  //随机字符串
        Map<String, String> data = new LinkedHashMap<String, String>();
        data.put("appid", config.getAppID());
        data.put("body", "订阅支付");
        data.put("mch_id", config.getMchID());
        data.put("nonce_str", WXPayUtil.generateNonceStr());
        data.put("notify_url", "http://a31ef7db.ngrok.io/WeChatPay/WeChatPayNotify");
        data.put("out_trade_no", tradeNo);
        data.put("spbill_create_ip", "127.0.0.1");
        data.put("total_fee", “100”);
        data.put("trade_type", "NATIVE");  // 此处指定为扫码支付
        data.put("product_id", "12235413214070356458058");
        
      //2.生成要发送的xml 
        String xmlParam = WXPayUtil.generateSignedXml(data, config.getKey());
        System.out.println(xmlParam);    
        HttpClient client=new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
        client.setHttps(true);
        client.setXmlParam(xmlParam);
        client.post();        
        //3.获得结果 
        String result = client.getContent();
        System.out.println(result);
        Map<String, String> map = WXPayUtil.xmlToMap(result);    
//            report(reportParams.toString());
        if (map.get("return_code").toString().equals("SUCCESS") && map.get("result_code").toString().equals("SUCCESS") ) {
            String urlCode = (String) map.get("code_url");
            System.out.println(urlCode);
            map.put("tradeNo", tradeNo);
            return map;
        }
        return null;
        
    }
    //根据返回订单号tradeNo查询订单支付状态
    public static boolean tradeQuery(String tradeNo) throws Exception{
        WXPayConfig config = new MyWXPayConfig();
        Map param=new HashMap();
        param.put("appid", config.getAppID());//公众账号ID
        param.put("mch_id", config.getMchID());//商户号
        param.put("out_trade_no", tradeNo);//订单号
        param.put("nonce_str", WXPayUtil.generateNonceStr());//随机字符串
        String url="https://api.mch.weixin.qq.com/pay/orderquery";        
        
        String xmlParam = WXPayUtil.generateSignedXml(param, config.getKey());    
        HttpClient client=new HttpClient(url);
        client.setHttps(true);
        client.setXmlParam(xmlParam);
        client.post();
        String result = client.getContent();            
        Map<String, String> map = WXPayUtil.xmlToMap(result);
        if (map.get("return_code").toString().equals("SUCCESS") && map.get("result_code").toString().equals("SUCCESS")
                && "SUCCESS".equals(map.get("trade_state").toString())) {
            System.out.println("支付成功");  
            return true;
         }
        return false;    
        
    }
    public static void main(String[] args) throws Exception {
        Map<String, String> map = getWXPay(new TSecurityOrderEntity());
        while(true){
            boolean flag = tradeQuery(map.get("tradeNo"));
            if(flag){
                System.out.println("支付成功");
            }else{
                System.out.println("未支付");
            }
            Thread.sleep(3000);
        }
    }
}

4、请求微信支付接口工具类

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;
    }

}
5、根据返回链接生成图片二维码代码

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
 
import javax.imageio.ImageIO;
import javax.swing.filechooser.FileSystemView;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
 
public class QrCodeUtil {
    public static void main(String[] args) {
        String url = "https://qr.alipay.com/bax03926jk9mvqchcxon00ec";
        String path = FileSystemView.getFileSystemView().getHomeDirectory() + File.separator + "testQrcode";
        String fileName = "temp.jpg";
        createQrCode(url, path, fileName);
    }
 
    public static String createQrCode(String url, String path, String fileName) {
        try {
            Map<EncodeHintType, String> hints = new HashMap<>();
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            BitMatrix bitMatrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, 400, 400, hints);
            File file = new File(path, fileName);
            if (file.exists() || ((file.getParentFile().exists() || file.getParentFile().mkdirs()) && file.createNewFile())) {
                writeToFile(bitMatrix, "jpg", file);
                System.out.println("搞定:" + file);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
 
    static void writeToFile(BitMatrix matrix, String format, File file) throws IOException {
        BufferedImage image = toBufferedImage(matrix);
        if (!ImageIO.write(image, format, file)) {
            throw new IOException("Could not write an image of format " + format + " to " + file);
        }
    }
 
    static void writeToStream(BitMatrix matrix, String format, OutputStream stream) throws IOException {
        BufferedImage image = toBufferedImage(matrix);
        if (!ImageIO.write(image, format, stream)) {
            throw new IOException("Could not write an image of format " + format);
        }
    }
 
    private static final int BLACK = 0xFF000000;
    private static final int WHITE = 0xFFFFFFFF;
 
    private static BufferedImage toBufferedImage(BitMatrix matrix) {
        int width = matrix.getWidth();
        int height = matrix.getHeight();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
            }
        }
        return image;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值