一点一滴开始搭建自己的项目框架之微信篇 微信支付

       不多废话直接开始今天的微信篇  其实对于微信来说  比支付宝是要稍微麻烦一点的  微信的基本单位是分  其实再这里我也推荐大家数据库使用的时候 用分来做金额单位  好处不少  1:不用担心精度丢失  Double的精度丢失 相信大家都知道  2:不用担心小数点的保留 不用那么多的数据操作  就是大家在使用的时候别搞错了单位   损失永远是自己的 微信支付还又一个比较安全一点的东西就是证书的安装 证书需要到自己的商铺下去下载  对于企业打款和原路返回都需要这个东西  还有这个东西最好放到一个安全的地方 不要放到项目中或则可以下载到的地方 不然你懂的 

       好的 照例文档我就不准备了 相信大家都看过  直接开始源码

      微信支付接口

/**
	 * 支付前调用,调用后,App拿着该接口的返回值参数去调取微信,发出支付请求
	 *
	 * @return
	 */
	@RequestMapping(value = "/fitPayWx", method = RequestMethod.POST,produces = "application/json;charset=UTF-8")
	@Transactional(readOnly = true)
	public @ResponseBody ResultModel fitPayWx(HttpServletRequest request, final PayModelVo payModelVo, final String addressId, final String cartIds, String mergeId, final String isDispatch, final String isMerge, final String logisticsId, String ProductList) {
		String token = request.getHeader("token");
		ResultModel resultModel = new ResultModel();
		try {
			if(payModelVo.getOutTradeNo()==null){
				payModelVo.setOutTradeNo(StrUtils.uuid());
			}
			String money = payModelVo.getMoney(); /// 变动金额
			String type = payModelVo.getType(); // 消费类型 用户充值 用户提现 商品出售  会员购买会员升级  询价单购买  待支付订单的支付(此类支付不需要预订单了)
			String paytype = "2"; // 支付方式 1:支付宝 2:微信  3:钱包 4,:额度,5,快捷支付
			payModelVo.setIncometype("2");// 1---收入,2---支出
			String out_trade_no = payModelVo.getOutTradeNo();
			payModelVo.setIncometype("1");
			payModelVo.setPaytype(paytype);
			
			String ip = "127.0.0.1";

			String conreason = payModelVo.getConreason();// 资金变动说明
			String detailid = payModelVo.getDetailid();// 订单id 或者 充值记录id
																// (关联性id、与对应的业务表主键id关联即可)
																// 3:银联
																// 4:钱包(充值的时候是充值方式、购买的时候是购买方式、收入的时候,写成钱包即可)
			String productId = "111112";                        //PC封装必须
			Map<String, String> mapParam = new HashMap<String, String>();
			mapParam.put("money", money);
			mapParam.put("type", type);
			mapParam.put("conreason", conreason);
			mapParam.put("product_id",productId);
			mapParam.put("detailid", detailid == null ? "" : detailid);
			mapParam.put("paytype", paytype);
			mapParam.put("incometype", payModelVo.getIncometype());
			mapParam.put("business", payModelVo.getBusiness());

			//将payModelVo中所有信息存入redis
//			RedisTool.setex("notify_"+out_trade_no,Bhyx.getPayresultExistTime(),JSON.toJSONString(payModelVo));
			// XX 订单状态未校验
			/**
			 * 封装微信请求参数(统一下单,的预订单信息。获取返回值,将返回值给App用来调出支付页面)
			 */
			try {
				HashMap<String, String> reqMap = new HashMap<String, String>();
				reqMap.put("appid", WXPayConfigImpl.getInstance().getAppID());
				reqMap.put("mch_id", WXPayConfigImpl.getInstance().getMchID());
				reqMap.put("nonce_str", WXPayUtil.generateUUID());
				// reqMap.put("detail", WeiChartConfig.subject); //非必填
				// 附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
				reqMap.put("out_trade_no", out_trade_no); // 商户系统内部的订单号,
				reqMap.put("fee_type", WXPayConstants.FEE_TYPE);// 非必填
				// 符合ISO
				// 4217标准的三位字母代码,默认人民币:CNY
				reqMap.put("total_fee", TaobusinessUtils.moneyUtilToFen(payModelVo.getMoney())); // 订单总金额,单位为分
				// reqMap.put("total_fee",MoneyUtils.moneyYuanToFen("0.01"));
				// //订单总金额,单位为分
				reqMap.put("spbill_create_ip", ip); // 用户端实际ip
				reqMap.put("time_start", String.valueOf(WXPayUtil.getCurrentTimestamp())); // 交易起始时间
				// 非必填
				// reqMap.put("time_expire", "172.16.40.18"); //交易结束时间
				// 非必填
				// reqMap.put("goods_tag", "172.16.40.18"); //商品标记 非必填
				reqMap.put("notify_url", WXPayConstants.NOTIFY_URL); // 回调地址
				reqMap.put("trade_type", payModelVo.getPayRole()); // 交易类型
				reqMap.put("body","支付说明");
				reqMap.put("limit_pay", "no_credit"); // 指定支付方式,no_credit
				// 指定不能使用信用卡支
				// 非必填
				reqMap.put("sign", WXPayUtil.generateSignature(reqMap, WXPayConfigImpl.getInstance().getKey()));// 生成签名
				reqMap.put("product_id",productId);
				/**
				 * 调取微信统一下单
				 */
				WXPay wxpay = new WXPay(WXPayConfigImpl.getInstance());
				Map<String, String> data = wxpay.unifiedOrder(reqMap);

				/**
				 * 判断是否下单成功
				 */
				if (data.containsKey("return_code") && WXPayConstants.SUCCESS.equals(data.get("return_code"))) {
					data.put("time_start", reqMap.get("time_start"));
					MyWxPay wxPay = new MyWxPay();
					Map<String, String> map = wxPay.doAppUnifiedOrder(data);
					map.put("orderNums",out_trade_no);
					resultModel = new ResultModel(200,"10104","预下单成功");
					resultModel.setResult(map);
				} else {
					resultModel = new ResultModel(500,"10105","预下单失败");
					resultModel.setResult(data.get("return_msg"));
				}
			}catch (Exception e){

			}
		} catch (Exception e) {
			log.error("微信支付异常", e);
			e.printStackTrace();
			resultModel = new ResultModel(500,"10107","微信订单异常");
		}
		log.error("微信支付:" + resultModel.getMsg());
		return resultModel;
	}

需要注意下 paytype这个参数 他是区别与APP和PC的参数 APP:APP PC:NATIVE 唯一的区别是 返回值中有个url 再PC支付的时候 PC可以直接进行二维码的生成

微信回调

/**
	 * @Title: notify
	 * @Description: TODO(微信回调,微信充值 回调,App支付成功后,微信服务器会访问这个接口八次来给后台确认支付成功)
	 * @date 2018-2-6 下午2:12:08
	 * @param rep
	 */
	@RequestMapping(value = "/notify", produces = "application/json;charset=UTF-8")
	@Transactional(readOnly = true)
	public void wx_notifyA(HttpServletRequest req, HttpServletResponse rep) {
		log.info("微信支付回调开始---------------notify()---------------->");
		String rtn = "";
		String xml = "";
		String total_fee = "";
		String outtradeno = "";
		InputStream inputStream;
		Map<String, String> resultMap = new HashMap<String, String>();
		try {
			inputStream = req.getInputStream();
			SAXReader reader = new SAXReader();
			Document document = reader.read(inputStream);
			resultMap = WXPayUtil.xmlToMap(document.asXML());
			outtradeno = resultMap.get("out_trade_no");
			PayModelVo paymodel = (PayModelVo) new Gson().fromJson(RedisTool.get("notify_"+outtradeno), PayModelVo.class);
			// 验证签名是否正确
			if (WXPayUtil.isSignatureValid(resultMap, WXPayConfigImpl.getInstance().getKey())) {
				rtn = resultMap.get("result_code");
				 total_fee = resultMap.get("total_fee");
				if (rtn != null && "SUCCESS".equals(rtn)) {
					xml = "<xml><return_code>SUCCESS</return_code><return_msg>OK</return_msg></xml>";
					// 数据锁进行并发控制,以避免函数重入造成的数据混乱
					synchronized (outtradeno.intern()) {
						// 是否已经回调,避免重复查询数据库
						// 添加支付状态的缓存
						if (RedisTool.exists("notify_" + outtradeno)) {
							//查询数据库是否已经充值成功避免重复充值(本次回调访问不一定是微信第几次访问的)
//							WalletTran walletTrans = walletTranMapper.findAllByNo(outtradeno);
							// 判断该充值详情是否已经存在,不存在则继续
//							if (walletTrans == null) {
							if (true) {
								// 更新业务数据
								String str = TaobusinessUtils.moneyUtilToFen(paymodel.getMoney());
								if(!total_fee.equals(str)){
									//金额数目不对
									xml = "<xml><return_code>FAIL</return_code><return_msg>应支付金额和实际金额不符</return_msg></xml>";
									writeMessageToResponse(rep, xml);
									return;
								}
								/**
								 * TODO 回调成功 开始实现业务
								 */
//								ResultModel resultModel = new ResultModel();
//								payService.business(paymodel,resultModel);
								if(paymodel.getPaytype().equals("7")){//通联微信购买,需要向pc推送
									try {
										goeasy(paymodel,"true");
									} catch (Exception e) {
										e.printStackTrace();
									}
								}
								xml = "<xml><return_code>SUCCESS</return_code><return_msg>OK</return_msg></xml>";
								RedisTool.expire("WX" + outtradeno,  60 * 60 * 2);
								writeMessageToResponse(rep, xml);
								log.info("微信返回值"+JsonUtil.toJson(rep));
								log.info("微信支付回调结束---------------notify()---------------->");
								return;
							}else {
								log.info("微信重复调用!!!");
								xml = "<return_code><![CDATA[SUCCESS]]></return_code>";
							}
							RedisTool.expire("WX" + outtradeno,  60 * 60 * 2);
						}
					}
				} else {
					xml = "<xml><return_code>FAIL</return_code><return_msg>" + resultMap.get("err_code_des")
							+ "</return_msg></xml>";
					 log.error("执行了微信支付回调" + resultMap.get("err_code_des"));
				}
			} else {
				xml = "<xml><return_code>FAIL</return_code><return_msg>签名验证失败!</return_msg></xml>";
				 log.error("执行了微信支付回调,签名验证失败!");
			}
			// 同步微信通知
		} catch (Exception e) {
			xml = "<xml><return_code>FAIL</return_code><return_msg>" + resultMap.get("err_code_des")
											+ "</return_msg></xml>";
			RedisTool.setex("notify_" + outtradeno, DateTools.getDatelinetoInt(),"业务处理失败");
			log.error("执行了微信支付回调,抛出异常!", e);
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
		}
		writeMessageToResponse(rep, xml);
 		log.info("微信返回值"+JsonUtil.toJson(rep));
		log.info("微信支付回调结束---------------notify()---------------->");
	}

工具类

WXPayConfigImpl
package com.bing.wxPay.sdk;

import java.io.InputStream;


/**
 * 配置文件
 */
public class WXPayConfigImpl  implements com.github.wxpay.sdk.WXPayConfig{

	private static WXPayConfigImpl INSTANCE;

	public static WXPayConfigImpl getInstance() throws Exception {
		if (INSTANCE == null) {
			synchronized (WXPayConfigImpl.class) {
				if (INSTANCE == null) {
					INSTANCE = new WXPayConfigImpl();
				}
			}
		}
		return INSTANCE;
	}
	
	public String getAppID() {
		return "";	//appid
	}

	public String getMchID() {
		return "";		//商户号
	}
	
	public String getKey() {
		return "";		//API密钥
	}
	
	public String getSSLPath(){
		return "apiclient_cert.p12";
	}//证书所在服务器的盘符路径
	
	public String getPosUrl(){
		return "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
	}

	public String getReFulUrl(){
		return "https://api.mch.weixin.qq.com/secapi/pay/refund";
	}

	public int getHttpConnectTimeoutMs() {
		return 2000;
	}
	
	public int getHttpReadTimeoutMs() {
		return 10000;
	}
	
	public IWXPayDomain getWXPayDomain() {
		return WXPayDomainSimpleImpl.instance();
	}

	public String getPrimaryDomain() {
		return "api.mch.weixin.qq.com";			
	}

	public String getAlternateDomain() {
		return "api2.mch.weixin.qq.com";
	}

	public int getReportWorkerNum() {
		return 1;
	}

	public int getReportBatchSize() {
		return 2;
	}
	
	@Override
	public InputStream getCertStream() {
		// TODO Auto-generated method stub
		return null;
	}
}
WXPayUtil
package com.bing.wxPay.sdk;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.*;
import java.security.MessageDigest;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import com.github.wxpay.sdk.WXPayConstants.SignType;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class WXPayUtil {

    public static final Logger log = LoggerFactory.getLogger(WXPayUtil.class);

    /**
     * XML格式字符串转换为Map
     *
     * @param strXML XML字符串
     * @return XML数据转换后的Map
     * @throws Exception
     */
    public static Map<String, String> xmlToMap(String strXML) throws Exception {
        try {
            Map<String, String> data = new HashMap<String, String>();
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
            org.w3c.dom.Document doc = documentBuilder.parse(stream);
            doc.getDocumentElement().normalize();
            NodeList nodeList = doc.getDocumentElement().getChildNodes();
            for (int idx = 0; idx < nodeList.getLength(); ++idx) {
                Node node = nodeList.item(idx);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    org.w3c.dom.Element element = (org.w3c.dom.Element) node;
                    data.put(element.getNodeName(), element.getTextContent());
                }
            }
            try {
                stream.close();
            } catch (Exception ex) {
                // do nothing
            }
            return data;
        } catch (Exception ex) {
            WXPayUtil.getLogger().warn("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML);
            throw ex;
        }

    }

    /**
     * 将Map转换为XML格式的字符串
     *
     * @param data Map类型数据
     * @return XML格式的字符串
     * @throws Exception
     */
    public static String mapToXml(Map<String, String> data) throws Exception {
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder= documentBuilderFactory.newDocumentBuilder();
        org.w3c.dom.Document document = documentBuilder.newDocument();
        org.w3c.dom.Element root = document.createElement("xml");
        document.appendChild(root);
        for (String key: data.keySet()) {
            String value = data.get(key);
            if (value == null) {
                value = "";
            }
            value = value.trim();
            org.w3c.dom.Element filed = document.createElement(key);
            filed.appendChild(document.createTextNode(value));
            root.appendChild(filed);
        }
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer transformer = tf.newTransformer();
        DOMSource source = new DOMSource(document);
        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        StringWriter writer = new StringWriter();
        StreamResult result = new StreamResult(writer);
        transformer.transform(source, result);
        String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", "");
        try {
            writer.close();
        }
        catch (Exception ex) {
        }
        return output;
    }


    /**
     * 生成带有 sign 的 XML 格式字符串
     *
     * @param data Map类型数据
     * @param key API密钥
     * @return 含有sign字段的XML
     */
    public static String generateSignedXml(final Map<String, String> data, String key) throws Exception {
        return generateSignedXml(data, key, SignType.MD5);
    }

    /**
     * 生成带有 sign 的 XML 格式字符串
     *
     * @param data Map类型数据
     * @param key API密钥
     * @param signType 签名类型
     * @return 含有sign字段的XML
     */
    public static String generateSignedXml(final Map<String, String> data, String key, SignType signType) throws Exception {
        String sign = generateSignature(data, key, signType);
        data.put(WXPayConstants.FIELD_SIGN, sign);
        return mapToXml(data);
    }


    /**
     * 判断签名是否正确
     *
     * @param xmlStr XML格式数据
     * @param key API密钥
     * @return 签名是否正确
     * @throws Exception
     */
    public static boolean isSignatureValid(String xmlStr, String key) throws Exception {
        Map<String, String> data = xmlToMap(xmlStr);
        if (!data.containsKey(WXPayConstants.FIELD_SIGN) ) {
            return false;
        }
        String sign = data.get(WXPayConstants.FIELD_SIGN);
        return generateSignature(data, key).equals(sign);
    }

    /**
     * 判断签名是否正确,必须包含sign字段,否则返回false。使用MD5签名。
     *
     * @param data Map类型数据
     * @param key API密钥
     * @return 签名是否正确
     * @throws Exception
     */
    public static boolean isSignatureValid(Map<String, String> data, String key) throws Exception {
        return isSignatureValid(data, key, SignType.MD5);
    }

    /**
     * 判断签名是否正确,必须包含sign字段,否则返回false。
     *
     * @param data Map类型数据
     * @param key API密钥
     * @param signType 签名方式
     * @return 签名是否正确
     * @throws Exception
     */
    public static boolean isSignatureValid(Map<String, String> data, String key, SignType signType) throws Exception {
        if (!data.containsKey(WXPayConstants.FIELD_SIGN) ) {
            return false;
        }
        String sign = data.get(WXPayConstants.FIELD_SIGN);
        return generateSignature(data, key, signType).equals(sign);
    }

    /**
     * 生成签名
     *
     * @param data 待签名数据
     * @param key API密钥
     * @return 签名
     */
    public static String generateSignature(final Map<String, String> data, String key) throws Exception {
        return generateSignature(data, key, SignType.MD5);
    }

    /**
     * 生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。
     *
     * @param data 待签名数据
     * @param key API密钥
     * @param signType 签名方式
     * @return 签名
     */
    public static String generateSignature(final Map<String, String> data, String key, SignType signType) throws Exception {
        Set<String> keySet = data.keySet();
        String[] keyArray = keySet.toArray(new String[keySet.size()]);
        Arrays.sort(keyArray);
        StringBuilder sb = new StringBuilder();
        for (String k : keyArray) {
            if (k.equals(WXPayConstants.FIELD_SIGN)) {
                continue;
            }
            if (data.get(k).trim().length() > 0) // 参数值为空,则不参与签名
                sb.append(k).append("=").append(data.get(k).trim()).append("&");
        }
        sb.append("key=").append(key);
        if (SignType.MD5.equals(signType)) {
            return MD5(sb.toString()).toUpperCase();
        }
        else if (SignType.HMACSHA256.equals(signType)) {
            return HMACSHA256(sb.toString(), key);
        }
        else {
            throw new Exception(String.format("Invalid sign_type: %s", signType));
        }
    }


    /**
     * 获取随机字符串 Nonce Str
     *
     * @return String 随机字符串
     */
    public static String generateNonceStr() {
        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
    }


    /**
     * 生成 MD5
     *
     * @param data 待处理数据
     * @return MD5结果
     */
    public static String MD5(String data) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] array = md.digest(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString().toUpperCase();
    }

    /**
     * 生成 HMACSHA256
     * @param data 待处理数据
     * @param key 密钥
     * @return 加密结果
     * @throws Exception
     */
    public static String HMACSHA256(String data, String key) throws Exception {
        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
        sha256_HMAC.init(secret_key);
        byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString().toUpperCase();
    }

    /**
     * 日志
     * @return
     */
    public static Logger getLogger() {
        Logger logger = LoggerFactory.getLogger("wxpay java sdk");
        return logger;
    }

    /**
     * 获取当前时间戳,单位秒
     * @return
     */
    public static long getCurrentTimestamp() {
        return System.currentTimeMillis()/1000;
    }

    /**
     * 获取当前时间戳,单位毫秒
     * @return
     */
    public static long getCurrentTimestampMs() {
        return System.currentTimeMillis();
    }

    /**
     * 生成 uuid, 即用来标识一笔单,也用做 nonce_str
     * @return
     */
    public static String generateUUID() {
        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
    }

}
MyWxPay
package com.bing.wxPay.servcie;

import java.util.Date;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import com.bing.wxPay.sdk.WXPayConfigImpl;
import com.bing.wxPay.sdk.WXPayConstants;
import com.bing.wxPay.sdk.WXPayUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.github.wxpay.sdk.WXPay;




/**
 * @author Administrator
 * @date 2016.9.9
 * @since JDK 1.7
 * 
 *        WxPay: 微信支付业务
 */
@Component
public class MyWxPay {

	protected static final Logger logger = LoggerFactory.getLogger(MyWxPay.class);
    private WXPay wxpay;
    private WXPayConfigImpl config;

    public MyWxPay() throws Exception {
        config = WXPayConfigImpl.getInstance();
        wxpay = new WXPay(config);
    }

    /**
    * @Title: doWebUnifiedOrder
    * @Description: TODO(网页扫码支付)
    * @param data
    * @return
    */
    public  Map<String, String> doWebUnifiedOrder(Map<String, String> data) {
        data.put("fee_type", WXPayConstants.FEE_TYPE);
        data.put("notify_url", WXPayConstants.NOTIFY_URL);
        data.put("time_start", String.valueOf(WXPayUtil.getCurrentTimestamp()));
        try {
            Map<String, String> r = wxpay.unifiedOrder(data);
            r.put("timestamp", data.get("time_start"));
            return r;
        } catch (Exception e) {
            return null;
        }
		
    }
    
    /**
    * @Title: doAppUnifiedOrder
    * @Description: TODO(app微信支付)
    * @param data
    * @return
    */
    public  Map<String, String> doAppUnifiedOrder(Map<String, String> data) {
//        data.put("fee_type", WXPayConstants.FEE_TYPE);
//        data.put("notify_url", WXPayConstants.NOTIFY_URL);
//        data.put("time_start", String.valueOf(WXPayUtil.getCurrentTimestamp()));
        try {
            //重新生成新的签名 返回客户端APP
            SortedMap<String, String> signData = new TreeMap<String, String>();
            if(data.get("trade_type").equals("NATIVE")){
                signData.put("code_url",data.get("code_url"));
            }
            signData.put("appid", data.get("appid"));
            signData.put("partnerid",data.get("mch_id"));
            signData.put("prepayid", data.get("prepay_id"));
            signData.put("package","Sign=WXPay");
            signData.put("noncestr", data.get("nonce_str"));
            String timestamp = String.valueOf(new Date().getTime());
            signData.put("timestamp", timestamp.substring(0, timestamp.length() - 3));
			String paySign = WXPayUtil.generateSignature(signData, config.getKey());
			signData.put("sign", paySign);
            return signData;
        } catch (Exception e) {
            return null;
        }
		
    }
    
}

OK 其实微信支付和支付宝支付的逻辑相差不大 差的就是对与代码的理解  有问题欢迎评论

下一篇:微信企业打款

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值