微信APIV3支付示例

这是一个支付的示例 仅供参考 ,传参和返回要根据情况修正,支付的其他接口只需改url和传参即可

官方文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3/index.shtml

相较于的之前微信支付API,主要区别是:
遵循统一的Restful的设计风格
使用JSON作为数据交互的格式,不再使用XML
使用基于非对称密钥的SHA256-RSA的数字签名算法,不再使用MD5或HMAC-SHA256
不再要求HTTPS客户端证书
使用AES-256-GCM,对回调中的关键信息进行加密保护

微信官方httpClient 自动处理签名和验签(使用WechatPayHttpClientBuilder需要调用withWechatpay设置微信支付平台证书,而平台证书又只能通过调用获取平台证书接口下载。为了解开"死循环",可以跳过签名的验证)

官方客服解答: 微信支付v3版本的密钥和v2的密钥独立,更新v3的密钥不会影响到已对接的v2的支付通道,支付证书有且只有一个

        <!-- 微信-->
        <dependency>
            <groupId>com.github.wechatpay-apiv3</groupId>
            <artifactId>wechatpay-apache-httpclient</artifactId>
            <version>0.2.2</version>
        </dependency>
        <!-- OKHttp3依赖 -->
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>3.8.1</version>
        </dependency>
package com.huayun.pay.service.thrid;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Map;
import okhttp3.HttpUrl;
import java.security.Signature;
import java.util.Base64;
import java.util.UUID;

/**
 * 微信小程序支付
 * APIV3接口
 */

@Service("WxAppLetPayService")
public class WxAppLetPayV3Service {

    // appid。
    @Value("#{config['hl.appid']}")
    private String appid;

    // merchantId商户号。
    @Value("#{config['hl.merchantId']}")
    private String merchantId;

    //merchantSerialNumber商户证书的证书序列号,请参考什么是证书序列号和如何查看证书序列号。
    @Value("#{config['hl.merchantSerialNumber']}")
    private String merchantSerialNumber;

    //merchantPrivateKey字符串格式的商户私钥,也就是通过证书工具得到的apiclient_key.pem文件中的内容。
    @Value("#{config['hl.merchantPrivateKey']}")
    private PrivateKey merchantPrivateKey;

    //wechatpayCertificates微信支付平台证书的实例列表,用于应答签名的验证。你也可以使用后面章节提到的“自动更新证书功能”。
    @Value("#{config['hl.wechatpayCertificates']}")
    private List<X509Certificate> wechatpayCertificates;

    @Value("#{config['hl.wxurl.pay']}")
    private String pay;
    @Value("#{config['hl.wxurl.notifyurl']}")
    private String notifyurl;






    //小程序支付统一下单
    public void CreateOrder(Map<String,Object> map) throws Exception{
        //请求URL
        HttpPost httpPost = new HttpPost(pay);
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type","application/json; charset=utf-8");
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectMapper objectMapper = new ObjectMapper();
        ObjectNode rootNode = objectMapper.createObjectNode();
        rootNode.put("mchid",merchantId)
                .put("appid", appid)
                .put("description", "Image形象店-深圳腾大-QQ公仔")
                .put("notify_url", notifyurl)
                .put("out_trade_no", "1217752501201407033233368018");
        rootNode.putObject("amount")
                .put("total", 1);
        rootNode.putObject("payer")
                .put("openid", "oUpF8uMuAJO_M2pxb1Q9zNjWeS6o");

        objectMapper.writeValue(bos, rootNode);
        //签名
//        httpPost.addHeader("Authorization",getToken("POST", HttpUrl.parse(pay),rootNode.toString()));
        httpPost.setEntity(new StringEntity(bos.toString("UTF-8")));
        CloseableHttpClient  httpClient=getHttpClient();
        //完成签名并执行请求
        CloseableHttpResponse response = httpClient.execute(httpPost);
        try {
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == 200) {
                //业务处理在这里

                System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));
            } else if (statusCode == 204) {
                System.out.println("success");
            } else {
                System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));
                throw new IOException("request failed");
            }
        } finally {
            response.close();
        }
    }


    /**
     * merchantId商户号。
     * merchantSerialNumber商户证书的证书序列号,请参考什么是证书序列号和如何查看证书序列号。
     * merchantPrivateKey字符串格式的商户私钥,也就是通过证书工具得到的apiclient_key.pem文件中的内容。
     * wechatpayCertificates微信支付平台证书的实例列表,用于应答签名的验证。你也可以使用后面章节提到的“自动更新证书功能”。
     * @return
     */
    //获取httpClient
    public CloseableHttpClient getHttpClient() {
        WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                .withMerchant(merchantId, merchantSerialNumber, merchantPrivateKey)
                .withWechatpay(wechatpayCertificates);
        // 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签
        CloseableHttpClient httpClient = builder.build();

        return httpClient;
    }
    //获取httpClient(不验证返回签名)
    public CloseableHttpClient getHttpClientNo() {
    CloseableHttpClient httpClient = WechatPayHttpClientBuilder.create()
            .withMerchant(merchantId, merchantSerialNumber, merchantPrivateKey)
            .withValidator(response -> true) // NOTE: 设置一个空的应答签名验证器,**不要**用在业务请求
            .build();
        return httpClient;
    }
    //不需要传入微信支付证书,将会自动更新
//    public CloseableHttpClient getHttpClientVerifier() {
//    AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
//            new WechatPay2Credentials(merchantId, new PrivateKeySigner(merchantSerialNumber, merchantPrivateKey)),
//            apiV3Key.getBytes("utf-8"));
//    WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
//            .withMerchant(merchantId, merchantSerialNumber, merchantPrivateKey)
//            .withValidator(new WechatPay2Validator(verifier));
//        CloseableHttpClient httpClient = builder.build();
//        return httpClient;
//    }




    //获取签名请求头
    // Authorization:
//    public String getToken(String method, HttpUrl url, String body) throws Exception{
//        String nonceStr = UUID.randomUUID().toString().replace("-","");
//        long timestamp = System.currentTimeMillis() / 1000;
//        String message = buildMessage(method, url, timestamp, nonceStr, body);
//        String signature = sign(message.getBytes("utf-8"));
//        return "mchid=\"" + merchantId + "\","
//                + "nonce_str=\"" + nonceStr + "\","
//                + "timestamp=\"" + timestamp + "\","
//                + "serial_no=\"" + merchantSerialNumber + "\","
//                + "signature=\"" + signature + "\"";
//    }
//
//    public String sign(byte[] message) throws Exception{
//        Signature sign = Signature.getInstance("SHA256withRSA");
//        sign.initSign(merchantPrivateKey);
//        sign.update(message);
//
//        return Base64.getEncoder().encodeToString(sign.sign());
//    }
//
//    public String buildMessage(String method, HttpUrl url, long timestamp, String nonceStr, String body) {
//        String canonicalUrl = url.encodedPath();
//        if (url.encodedQuery() != null) {
//            canonicalUrl += "?" + url.encodedQuery();
//        }
//        return method + "\n"
//                + canonicalUrl + "\n"
//                + timestamp + "\n"
//                + nonceStr + "\n"
//                + body + "\n";
//    }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值