微信支付

​ 在做有关于微信支付之前,首先你需要让三方平台知道有一个这样的小程序,也就是在微信开发平台上注册一个开发者账号。并在里面创一个程序。我今天想要写下来的支付方式是关于小程序的,并且只有三种:免密支付,企业付款以及申请退款。获取到以下数值:

/**
 * 微信支付参数配置
 */
public class WXpayConfig {

    /**
     * appid
     */
    public static String APP_ID = "XXXXXXXXXXXXX";

    public static String APP_SECRET = "XXXXXXXXXXXXXXXXX";

    /**
     * 商户号
     */
    public static String MCH_ID = "XXXXXXXXXXXX";

    /**
     * API密钥,在商户平台设置 
     */
    public static String API_KEY = "XXXXXXXXXXXXXXXX";

    /**
     *模板id
     */
    public static  String PLAN_ID="122396";

    /**
     * 免密支付请求地址
     */
    public static  String FREE_PAY_URL="https://api.mch.weixin.qq.com/pay/pappayapply";

    /**
     * 企业退款
     */
    public static String COMPANY_PAY="https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";

    /**
     * 申请退款
     */
    public static String RE_BACK_PAY="https://api.mch.weixin.qq.com/secapi/pay/refund";
}
对应的微信支付文档:

​ 免密支付:

​ 开通免密:https://pay.weixin.qq.com/wiki/doc/api/pap.php?chapter=18_14&index=2

​ 申请扣款:https://pay.weixin.qq.com/wiki/doc/api/pap.php?chapter=18_3&index=7

​ 企业退款:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2

​ 申请退款:https://pay.weixin.qq.com/wiki/doc/api/pap.php?chapter=9_4&index=11

前期工作

​ 签名(sign)的生成:https://pay.weixin.qq.com/wiki/doc/api/pap.php?chapter=4_3

请求方法:

public static String postData(String urlStr, String data) {
      return postData(urlStr, data, null);
   }

   public static String postData(String urlStr, String data, String contentType) {
      BufferedReader reader = null;
      try {
         URL url = new URL(urlStr);
         URLConnection conn = url.openConnection();
         conn.setDoOutput(true);
         conn.setConnectTimeout(CONNECT_TIMEOUT);
         conn.setReadTimeout(CONNECT_TIMEOUT);
         if (contentType != null)
            conn.setRequestProperty("content-type", contentType);
         OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), DEFAULT_ENCODING);
         if (data == null)
            data = "";
         writer.write(data);
         writer.flush();
         writer.close();

         reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), DEFAULT_ENCODING));
         StringBuilder sb = new StringBuilder();
         String line = null;
         while ((line = reader.readLine()) != null) {
            sb.append(line);
            sb.append("\r\n");
         }
         return sb.toString();
      } catch (IOException e) {
//       ((Object) logger).error("Error connecting to " + urlStr + ": " + e.getMessage());
      } finally {
         try {
            if (reader != null)
               reader.close();
         } catch (IOException e) {
         }
      }
      return null;
   }

免密支付

开通/取消免密:
//获取用户信息
String authenticationid=(String)request.getAttribute(APIPrincipal.PORPERTITY_AUTHENTICATION);
		APIPrincipal principal=redisService.get(APIPrincipal.getCacheKey(authenticationid),APIPrincipal.class);
		HashMap<String,String> map=new HashMap<>();
		String contractCode=WeixinUtils.createContractCode();
		map.put("appid", WXpayConfig.APP_ID);
		//随机生成商户的签约协议号
		map.put("contract_code",contractCode);
		//随机生成请求序列号
		map.put("request_serial",(WeixinUtils.createRequestSerial()+"").trim());
		//回调地址(签约或者解约)
		map.put("notify_url",server+"/api/wallet/signOrTerminationFreePayment.json");
		//用户手机号
		map.put("contract_display_account",principal.getPhone());
		//商户号
		map.put("mch_id",WXpayConfig.MCH_ID);
		//模板id
		map.put("plan_id", WXpayConfig.PLAN_ID);
		//时间戳
		map.put("timestamp", WeixinUtils.getTimeStamp());
		//签名
		map.put("sign",WeixinUtils.sign( WeixinUtils.FormatBizQueryParaMapXCX(map, false),WXpayConfig.API_KEY));
免密支付:
       HashMap<String,Object> pay=new HashMap<>();
       //获取小数点后几位数值
       Double fee=totalFee.multiply(new BigDecimal(100)).doubleValue();
        pay.put("appid", WXpayConfig.APP_ID);
        //信息提示
        pay.put("body","XXXXXXXX");
        //委托代扣协议id
        pay.put("contract_id",contractId);
        pay.put("mch_id",WXpayConfig.MCH_ID);
        //随机生成字符串
        pay.put("nonce_str", WeixinUtils.createNoncestr());
        //回调地址
        pay.put("notify_url",server+"/api/wallet/freePayment.json");
        //订单号
        pay.put("out_trade_no",Sn);
        //终端IP
        pay.put("spbill_create_ip",host);
        //支付金额
        pay.put("total_fee",String.valueOf(fee.intValue()));
        pay.put("trade_type","PAP");
        //签名
        pay.put("sign",WeixinUtils.sign( WeixinUtils.FormatBizQueryMap(pay, false),WXpayConfig.API_KEY));
        HttpUtil.postData(WXpayConfig.FREE_PAY_URL,WeixinUtils.getXML(pay));

申请退款、企业付款

​ 申请退款与企业付款两者之间最大的相同之处就在于都需要证书。因此,在发起支付接口的时候,需要考虑到证书,也就是说,要读取证书里面的内容。我在网上查找到很多有关于这一方面的文章,其链接具体如下:

参考文章:

  1. https://blog.csdn.net/uknowzxt/article/details/80694609
  2. https://blog.csdn.net/qq_31482599/article/details/79131680
  3. https://blog.csdn.net/jrainbow/article/details/50266391

我的代码:

//企业付款到微信零钱
	public static String sendSSL(String url,String data){
		StringBuffer message=new StringBuffer();
		try{
			KeyStore keyStore=KeyStore.getInstance("PKCS12","SunJSSE");
			//这里需要注意的是,文件所放置的位置
			FileInputStream fileInputStream=new FileInputStream(new File("/opt/certs/apiclient_cert.p12"));
			keyStore.load(fileInputStream, WXpayConfig.MCH_ID.toCharArray());
			SSLContext sslContext= SSLContexts.custom()
					.loadKeyMaterial(keyStore,WXpayConfig.MCH_ID.toCharArray())
					.build();
			SSLConnectionSocketFactory sslConnectionSocketFactory=new SSLConnectionSocketFactory(
					sslContext,
					new String[]{"TLSv1"},
					null,
					SSLConnectionSocketFactory.getDefaultHostnameVerifier());
			CloseableHttpClient httpClient= HttpClients.custom()
					.setSSLSocketFactory(sslConnectionSocketFactory)
					.build();
			HttpPost httpPost=new HttpPost(url);
			httpPost.addHeader("Connection","keep-alive");
			httpPost.addHeader("Accept", "*/*");
			httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
			httpPost.addHeader("Host", "api.mch.weixin.qq.com");
			httpPost.addHeader("X-Requested-With", "XMLHttpRequest");
			httpPost.addHeader("Cache-Control", "max-age=0");
			httpPost.addHeader("Connection","keep-alive");
			httpPost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
			httpPost.setEntity(new StringEntity(data, "UTF-8"));
			CloseableHttpResponse response=httpClient.execute(httpPost);
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
				String text;
				while ((text = bufferedReader.readLine()) != null) {
					message.append(text);
				}
			}
				EntityUtils.consume(entity);
		}catch (IOException e){
			e.getStackTrace();
		} catch (CertificateException e1) {
			e1.printStackTrace();
		} catch (NoSuchAlgorithmException e1) {
			e1.printStackTrace();
		} catch (UnrecoverableKeyException e1) {
			e1.printStackTrace();
		} catch (KeyStoreException e1) {
			e1.printStackTrace();
		} catch (KeyManagementException e1) {
			e1.printStackTrace();
		} catch (NoSuchProviderException e) {
			e.printStackTrace();
		}
		return  message.toString();
	}

这个方法是我从网上参考了其他博主的代码,但是实现原理都是一致的

申请退款

public static String Refunds(String server,String Sn,BigDecimal money){
        //获取小数点后几位数值
       Double fee=money.multiply(new BigDecimal(100)).doubleValue();
        HashMap<String,Object> pay=new HashMap<>();
        pay.put("appid", WXpayConfig.APP_ID);
        pay.put("mch_id",WXpayConfig.MCH_ID);
        pay.put("nonce_str", WeixinUtils.createNoncestr());
        pay.put("notify_url",server+"/api/wallet/getBackMsg.json");
        pay.put("out_trade_no",Sn);
        pay.put("out_refund_no",Sn);
        pay.put("total_fee",String.valueOf(fee.intValue()));
        pay.put("refund_fee",String.valueOf(fee.intValue()));
        pay.put("refund_desc","退款");
        pay.put("sign",WeixinUtils.sign( WeixinUtils.FormatBizQueryMap(pay, false),WXpayConfig.API_KEY));
        return HttpUtil.sendSSL(WXpayConfig.RE_BACK_PAY,WeixinUtils.getXML(pay));
}

企业付款

public static String resultCompany(APIPrincipal principal, String Sn, BigDecimal profit,String host){
         //获取小数点后几位数值
        Double fee=profit.multiply(new BigDecimal(100)).doubleValue();
        HashMap<String,Object> pay=new HashMap<>();
        pay.put("mch_appid", WXpayConfig.APP_ID);
        pay.put("mchid",WXpayConfig.MCH_ID);
        pay.put("nonce_str", WeixinUtils.createNoncestr());
        pay.put("partner_trade_no",Sn);
        pay.put("openid",principal.getOpenId());
        pay.put("check_name","FORCE_CHECK");
        pay.put("re_user_name",principal.getUsername());
        pay.put("spbill_create_ip",host);
        pay.put("amount",String.valueOf(fee.intValue()));
        pay.put("desc","收益提现");
        pay.put("sign",WeixinUtils.sign( WeixinUtils.FormatBizQueryMap(pay, false),WXpayConfig.API_KEY));
        return HttpUtil.sendSSL(WXpayConfig.COMPANY_PAY,WeixinUtils.getXML(pay));
}

你可能感兴趣的:(微信支付)