服务商模式下调用单次分账接口

接上一章,完成服务商模式下的微信支付之后,进行服务商分账。微信单次分账文档地址
首先在进行单次分账之前,需要设置一个分账比例,步骤如下:
登录特约商户号–产品中心–我授权的产品–服务商分账–产品配置
在这里插入图片描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/20190822105110224.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zOTQxNjEwMQ==,size_16,color_FFFFFF,t_70在这里插入图片描述
这里分账比例需要解释一下:
一般情况下,只能采用低比例分账,最大设置30%,顾客付款100元,其中最多30元进行分账,剩余70元分账之后解冻资金后进入子商户中(特约商户);如需使用高比例分账,只能想办法联系到微信支付运营人员(BD)开通。
单次分账成功后,剩余资金自动解冻,不能继续进行分账操作,如需多次分账请调用多次分账接口。
接下来就是需要拿到服务商商户号的证书和api密钥,登录到服务商商户号–账户中心–API安全–申请证书和设置密钥
在这里插入图片描述
接下来就是上代码时间了
老规矩,先在小程序中写个按钮
在这里插入图片描述
然后js代码如下:

profitSharing:function(){//进行分账
    var that = this;
    this.req('/interfaceController/profitSharing', {
      openId: this.data.openid
    }, function (res) {
      
    });
  },

然后是后台代码:

/**请求单次分账接口*/
	public static final String profitSharingUrl="https://api.mch.weixin.qq.com/secapi/pay/profitsharing";
/**
	 * 请求单次分账
	 * @return
	 */
	@RequestMapping("/profitSharing")
	public R profitSharing(HttpServletRequest request,String openId){
		try {
			
			
			JSONArray jsonArray = new JSONArray();
			JSONObject jsonObject = new JSONObject();
			jsonObject.put("type", "PERSONAL_WECHATID");
			jsonObject.put("account", "");//个人的微信号,需要事先添加分账接收人
			jsonObject.put("amount", 29);//分账金额单位是分,注意不要超过最大分账比例
			jsonObject.put("description", "分给个人");
			jsonArray.put(jsonObject);
			
	    	List<NameValuePair> nvps = new ArrayList<NameValuePair>();
	    	// 调用请求单次分账接口必需传的参数
	    	nvps.add(new NameValuePair("appid",""));//服务商对应公众号appid
			nvps.add(new NameValuePair("mch_id",""));//服务商商户号
			nvps.add(new NameValuePair("nonce_str","ibuaiVcKdpRxkhJA"));
			nvps.add(new NameValuePair("out_order_no",CommonUtil.getUID()));//商户分账单号
			nvps.add(new NameValuePair("receivers",jsonArray.toString()));
			nvps.add(new NameValuePair("sub_mch_id",""));//特约商户号
			nvps.add(new NameValuePair("transaction_id",""));//微信支付订单号(注意是微信的不是商户的)
			
	    	StringBuffer sb = new StringBuffer();
	    	
	    	for (NameValuePair nvp : nvps) {
	    		sb.append(nvp.getName() + "=" + nvp.getValue() + "&");
	    	}
	    	String signA = sb.toString(); // 根据签名格式组装数据,详见微信支付api
	    	String stringSignTemp = signA + "key=asjdkkashdkjashkd"; // 根据签名格式组装数据,key是服务商商户号中的api密钥
	    	
	    	String sign = HMACSHA256(stringSignTemp, "asjdkkashdkjashkd");//第二个参数是服务商商户号中的api密钥
	    	nvps.add(new NameValuePair("sign", sign)); // 把签名后的数据组装成参数
	    	String xml = toXml(nvps);
	    	String  result = HttpClientUtils.executeBySslPost(profitSharingUrl,xml,"","");//发送http请求 参数一:请求地址  参数二:请求参数 参数三:证书地址  参数四:服务商商户号
	    	String return_code = "";
	    	String return_msg = "";
	    	String result_code = "";
	    	String err_code = "OK";
	    	JSONObject xmlJSONObj = XML.toJSONObject(result);
			JSONArray childNodes = JSONML.toJSONObject(result.toString()).getJSONArray("childNodes");  
			int len = childNodes.length() - 1;  
			for (int i = len; i > -1; i--) {  
				JSONObject js = childNodes.getJSONObject(i);  
				if(!"".equals(return_code) && !"".equals(return_msg)){
					break;
				}
				if (js.get("tagName").equals("return_code")) {  
					return_code = js.getJSONArray("childNodes").getString(0);  
				}  
				if (js.get("tagName").equals("result_code")) {  
					result_code = js.getJSONArray("childNodes").getString(0);  
				}  
				if (js.get("tagName").equals("return_msg")) {  
					return_msg = js.getJSONArray("childNodes").getString(0);  
				} 
				if (js.get("tagName").equals("err_code")) {  
					err_code = js.getJSONArray("childNodes").getString(0);  
				} 
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return R.ok();
	}

httpclient代码:

public class HttpClientUtils {

	public static String executeBySslPost(String url, String body,String certificatePath,String password) throws Exception {
        String result = "";
        //商户id
        //指定读取证书格式为PKCS12
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        //读取本机存放的PKCS12证书文件
        FileInputStream instream = new FileInputStream(new File(certificatePath));
        try {
            //指定PKCS12的密码(商户ID)
            keyStore.load(instream, password.toCharArray());
        } finally {
            instream.close();
        }
        SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, password.toCharArray()).build();
        //指定TLS版本
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}, null, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
        //设置httpclient的SSLSocketFactory
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        try {
            HttpPost httppost = new HttpPost(url);
            StringEntity reqEntity = new StringEntity(body, "UTF-8");
            httppost.setEntity(reqEntity);

            System.out.println("Executing request: " + httppost.getRequestLine());
            CloseableHttpResponse response = null;
            try {
                response = httpclient.execute(httppost);
                result = EntityUtils.toString(response.getEntity(),"UTF-8");
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            } finally {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally {
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

}

其他用到的工具类代码

// 转换成xml格式
		private String toXml(List<NameValuePair> params) {
			StringBuilder sb = new StringBuilder();
			sb.append("<xml>");
			for (int i = 0; i < params.size(); i++) {
				sb.append("<" + params.get(i).getName() + ">");
				sb.append((params.get(i)).getValue());
				sb.append("</" + params.get(i).getName() + ">");
			}
			sb.append("</xml>");
			//System.out.println("xml数据=" + sb.toString());
			return sb.toString();
		}
	    /**
	     * 生成 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();
	    }

以上就是全部内容,大家如果有不懂的地方评论。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值