微信支付接口参数讲解

JSAPI支付

一、通过微信统一下单接口下单预支付
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
二、JSAPI调起支付接口
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6

统一下单接口

必填参数

        Map<String, Object> map = new HashMap<>();
        map.put("appid", appid);
        map.put("mch_id", mchId);
        map.put("nonce_str", UUID.randomUUID().toString().replaceAll("-", ""));
        map.put("body", requestParam.getBody());
        map.put("out_trade_no", requestParam.getOutTradeNo());
        map.put("fee_type", requestParam.getFeeType());
        map.put("total_fee", requestParam.getTotalFee());
        map.put("spbill_create_ip", Inet4Address.getLocalHost().getHostAddress());
        map.put("notify_url", redirectUrl);
        map.put("trade_type", requestParam.getTradeType());
        //签名放到最后,前面的参数都已经存储进来
        map.put("sign", SignUtil.md5Sign(map));
        //sign_type不参与签名
        map.put("sign_type", "MD5");
        String xmlBody = Map2XmlUtil.map2Xml(map);
参数 描述 获取值
spbill_create_ip 系统服务器ip地址 Inet4Address.getLocalHost().getHostAddress()
sign 签名 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3

JSAPI调起支付接口

必填参数设置
①在Java中将各个参数设置好值

        Map<String, Object> map = new HashMap<>();
        map.put("appId", appid);
        map.put("timeStamp", System.currentTimeMillis()/1000);
        map.put("nonceStr", UUID.randomUUID().toString().replaceAll("-", ""));
        //统一下单接口返回的prepay_id值
        map.put("package", "prepay_id=123456789");
        map.put("paySign", SignUtil.md5Sign(map));
        //此处需要与统一下单的签名类型一致,sign_type参数不参与签名
        map.put("signType", "MD5");
        String jsonBody = Map2JsonUtil.map2Json(map);

②传到html中调起支付

function onBridgeReady(){
   WeixinJSBridge.invoke(
      'getBrandWCPayRequest', {
         "appId":"wx2421b1c4370ec43b",     //公众号ID,由商户传入     
         "timeStamp":"1395712654",         //时间戳,自1970年以来的秒数     
         "nonceStr":"e61463f8efa94090b1f366cccfbbb444", //随机串     
         "package":"prepay_id=u802345jgfjsdfgsdg888",     
         "signType":"MD5",         //微信签名方式:     
         "paySign":"70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名 
      },
      function(res){
      if(res.err_msg == "get_brand_wcpay_request:ok" ){
      // 使用以上方式判断前端返回,微信团队郑重提示:
            //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
      } 
   }); 
}
if (typeof WeixinJSBridge == "undefined"){
   if( document.addEventListener ){
       document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
   }else if (document.attachEvent){
       document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
       document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
   }
}else{
   onBridgeReady();
}

退款

微信v2版本在退款的时候,需要在客户端添加api证书(如下OkHttp3Util)。
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
必填参数设置

        Map<String, Object> map = new HashMap<>();
        map.put("appId", appid);
        map.put("mch_id", mchId);
        map.put("nonceStr", UUID.randomUUID().toString().replaceAll("-", ""));
        map.put("out_trade_no", refundRequest.getOutTradeNo());
        map.put("out_refund_no", refundRequest.getOutRefundNo());
        map.put("total_fee", refundRequest.getTotalFee());
        map.put("refund_fee", refundRequest.getRefundFee());
        map.put("refund_fee_type", "CNY");
        //签名放到最后,前面的参数都已经存储进来
        map.put("sign", SignUtil.md5Sign(map));
        //sign_type参数不参与签名
        map.put("signType", "MD5");
        String xmlBody = Map2XmlUtil.map2Xml(map);

备注:以上接口都是微信v2版本接口,请求数据都是xml格式v2版本接口地址;
v3版本的接口是为json格式v3版本接口地址

工具SignUtil,Map2XmlUtil,OkHttp3Util,SslFactoryUtil

public class SignUtil {

    private static String signKey = "1234567890";

    /**
     * md5签名
     *
     * @return
     */
    public static String md5Sign(Map<String, Object> signParam) {
        //对参数按照key=value的格式,并按照参数名ASCII字典序排序
        List<String> keySet = signParam.keySet().stream().sorted().collect(Collectors.toList());
        StringBuilder stringA = new StringBuilder();
        for (String key : keySet) {
            stringA.append(key).append("=").append(signParam.get(key)).append("&");
        }
        //拼接API密钥
        String stringSignTemp = stringA.append("key=").append(signKey).toString();
        System.out.println("签名参数[" + stringSignTemp + "]");
        //apache的md5工具
        return DigestUtils.md5DigestAsHex(stringSignTemp.getBytes()).toUpperCase();
    }
}
public class Map2XmlUtil {
    
    /**
     * md5签名
     *
     * @return
     */
    public static String map2Xml(Map<String, Object> signParam) {
        StringBuilder sb = new StringBuilder("");
        for(String key : signParam.keySet()) {
            sb.append("<" + key + ">");
            sb.append(signParam.get(key).toString());
            sb.append(" + key + ">");
        }
        sb.append("");
        System.out.println("map转xml后的数据[" + sb.toString() + "]");
        return sb.toString();
    }
}
public class OkHttp3Util {
	/**
	 * 交易客户端
	 */
	public static OkHttpClient httpClient = new OkHttpClient.Builder()
			//忽略hostname验证
			.hostnameVerifier((s, sslSession) -> true)
			.connectTimeout(60, TimeUnit.SECONDS)
			.readTimeout(60, TimeUnit.SECONDS)
			.build();
	/**
	 * 退款客户端
	 *
	 * @return
	 */
	public static OkHttpClient sslHttpClient = new OkHttpClient.Builder()
				//忽略hostname验证
				.hostnameVerifier((s, sslSession) -> true)
				.connectTimeout(60, TimeUnit.SECONDS)
				.readTimeout(60, TimeUnit.SECONDS)
			    //退款需要api证书
				.sslSocketFactory(SslFactoryUtil.createSSLSocketFactory(), SslFactoryUtil.createNoTrustManager())
				.build();
}

@Slf4j
public class SslFactoryUtil {
	/**
	 * 文件位置:/resources/cert/wx_isv.p12
	 */
	private static final String wxIsvCertPath = "/cert/wx_isv.p12";
	/**
	 * mchId值
	 */
	private static final String wxIsvCertPassword = "mchId";
	/**
	 * 初始化证书容器
	 *
	 * @return
	 */
	public static SSLSocketFactory createSSLSocketFactory() {
		try {
			KeyStore keyStore = KeyStore.getInstance("PKCS12");
			keyStore.load(SslFactoryUtil.class.getResourceAsStream(wxIsvCertPath), wxIsvCertPassword.toCharArray());
			KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
			keyManagerFactory.init(keyStore, wxIsvCertPassword.toCharArray());
			SSLContext serverContext = SSLContext.getInstance("TLS");
			serverContext.init(keyManagerFactory.getKeyManagers(), null, new SecureRandom());
			return serverContext.getSocketFactory();
		} catch (Exception e) {
			log.error("初始化证书失败!");
			throw new RuntimeException("初始化SSLContext失败", e);
		}
	}
	/**
	 * 证书管理器
	 *
	 * @return
	 */
	public static X509TrustManager createNoTrustManager() {
		try {
			TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
			trustManagerFactory.init((KeyStore) null);
			TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
			if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
				throw new IllegalStateException("非默认管理器:" + Arrays.toString(trustManagers));
			}
			return (X509TrustManager) trustManagers[0];
		} catch (Exception e) {
			log.error("初始化证书失败", e);
			throw new RuntimeException("初始化证书失败", e);
		}
	}
}

更多文章请关注我的微信公众号
微信支付接口参数讲解_第1张图片

你可能感兴趣的:(笔记,java,接口)