小程序企业向个人支付案例

应用场景

微信支付并没有为小程序付款到零钱(企业付款到零钱)给出对应的Demo,所以写出demo供大家参考,大家可以根据自己的需求进行对应的更改以满足实际开发。

 

企业付款为企业提供付款至用户零钱的能力,支持通过API接口付款,或通过微信支付商户平台(pay.weixin.qq.com)网页操作付款。

应场景:小程序抽取红包,积分换取金额等

 

更多分布式微服务课程关注:www.majiaxueyuan.com

 

首先微信相关配置

public class WxPayConfig {
	// 小程序appid
	public static final String APP_ID = "APP_ID";
	// APP——Secret
	public static final String APP_SECRET = "APP_SECRET";
	// 微信支付的商户号
	public static final String MCH_ID = "MCH_ID";
	// 微信支付的商户秘钥
	public static final String KEY = "KEY ";
	// 支付成功后的服务器回调url
	public static final String notify_url = "notify_url";
	// 签名方式,固定值
	public static final String SIGNTYPE = "MD5";
	// 交易类型,小程序支付的固定值为JSAPI
	public static final String TRADETYPE = "JSAPI";
	// 微信统一下单接口地址
	public static final String pay_url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

	// 微信直接转账到个人请求
	public static final String TRANSFOR_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";

	public static final String STATIC_NUM = "a0A0b1B2c1C3d2D1e3E2f4F3g5G7h4H6i5Ij4J9k5K6l6Lm7M7n8N8o9Op0PqQrRsStTuUv9VwWxXy8YzZ";
}

证书下载

企业支付的话需要到支付平台去下载证书

微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->证书下载 

 

表4.2:证书文件说明

证书附件描述使用场景备注
pkcs12格式
(apiclient_cert.p12、
包含了私钥信息的证书文件,为p12(pfx)格式,由微信支付签发给您用来标识和界定您的身份撤销、退款申请API中调用windows上可以直接双击导入系统,导入过程中会提示输入证书密码,证书密码默认为您的商户ID(如:10010000)
证书pem格式
(apiclient_cert.pem)
从apiclient_cert.p12中导出证书部分的文件,为pem格式,请妥善保管不要泄漏和被他人复制PHP等不能直接使用p12文件,而需要使用pem,为了方便您使用,已为您直接提供您也可以使用openssl命令来自己导出:openssl pkcs12 -clcerts -nokeys -in apiclient_cert.p12 -out apiclient_cert.pem
证书密钥pem格式
(apiclient_key.pem)
从apiclient_key.pem中导出密钥部分的文件,为pem格式PHP等不能直接使用p12文件,而需要使用pem,为了方便您使用,已为您直接提供您也可以使用openssl命令来自己导出:openssl pkcs12 -nocerts -in apiclient_cert.p12 -out apiclient_key.pem

使用商户证书

  • ◆ apiclient_cert.p12是商户证书文件,除PHP外的开发均使用此证书文件。
  • ◆ 商户如果使用.NET环境开发,请确认Framework版本大于2.0,必须在操作系统上双击安装证书apiclient_cert.p12后才能被正常调用。
  • ◆ 商户证书调用或安装都需要使用到密码,该密码的值为微信商户号(mch_id)

商户证书安全

1.证书文件不能放在web服务器虚拟目录,应放在有访问权限控制的目录中,防止被他人下载;
2.建议将证书文件名改为复杂且不容易猜测的文件名;
3.商户服务器要做好病毒和木马防护工作,不被非法侵入者窃取证书文件。

 

参数说明

接口链接:https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers

请求需要双向证书。 详见证书使用

请求参数说明

 

字段名变量名必填示例值类型描述
商户账号appidmch_appidwx8888888888888888String申请商户号的appid或商户号绑定的appid
商户号mchid1900000109String(32)微信支付分配的商户号
设备号device_info013467007045764String(32)微信支付分配的终端设备号
随机字符串nonce_str5K8264ILTKCH16CQ2502SI8ZNMTM67VSString(32)随机字符串,不长于32位
签名signC380BEC2BFD727A4B6845133519F3AD6String(32)签名,详见签名算法
商户订单号partner_trade_no10000098201411111234567890String商户订单号,需保持唯一性
(只能是字母或者数字,不能包含有符号)
用户openidopenidoxTWIuGaIt6gTKsQRLau2M0yL16EString商户appid下,某用户的openid
校验用户姓名选项check_nameFORCE_CHECKStringNO_CHECK:不校验真实姓名 
FORCE_CHECK:强校验真实姓名
收款用户姓名re_user_name可选王小王String收款用户真实姓名。 
如果check_name设置为FORCE_CHECK,则必填用户真实姓名
金额amount10099int企业付款金额,单位为分
企业付款描述信息desc理赔String企业付款操作说明信息。必填。
Ip地址spbill_create_ip192.168.0.1String(32)该IP同在商户平台设置的IP白名单中的IP没有关联,该IP可传用户端或者服务端的IP。

这里要注意金额至少为一块(100分)

 

发送红包请求

(核心代码)

public static Map<String, String> sendRedPacket(String openId, Long money, String orderNo, String ipAddress)
			throws Exception {
		// 生成的随机字符串
		String nonce_str = getRandomStringByLength(32);

		String totleMoney = money + "";
		String desc = "现金红包测试";
		
		// 组装参数,用户生成统一下单接口的签名
		Map<String, String> packageParams = new HashMap<String, String>();
		packageParams.put("mch_appid", WxPayConfig.APP_ID);
		packageParams.put("mchid", WxPayConfig.MCH_ID);
		packageParams.put("nonce_str", nonce_str);
		packageParams.put("partner_trade_no", orderNo);// 商户订单号
		packageParams.put("openid", openId);
		packageParams.put("check_name", "NO_CHECK");
		packageParams.put("amount", totleMoney);
		packageParams.put("desc", desc);// 支付成功后的回调地址
		packageParams.put("spbill_create_ip", ipAddress);
		String prestr = PayUtil.createLinkString(packageParams);
		// MD5运算生成签名,这里是第一次签名,用于调用统一下单接口
		String mysign = PayUtil.sign(prestr, WxPayConfig.KEY, "utf-8").toUpperCase();
		packageParams.put("sign", mysign);

		String xml = "<xml><mch_appid>" + WxPayConfig.APP_ID + "</mch_appid><mchid>" + WxPayConfig.MCH_ID
				+ "</mchid><nonce_str>" + nonce_str + "</nonce_str><partner_trade_no>" + orderNo
				+ "</partner_trade_no><openid>" + openId + "</openid><check_name>NO_CHECK</check_name><amount>"
				+ totleMoney + "</amount><desc>" + desc + "</desc><spbill_create_ip>" + ipAddress
				+ "</spbill_create_ip><sign>" + mysign + "</sign></xml>";

		KeyStore keyStore = KeyStore.getInstance("PKCS12");
        // p12证书路径
		FileInputStream instream = new FileInputStream(new File("C:/Users/Liao/Desktop/dangj/cert/apiclient_cert.p12"));
        // 微信支付的商户号
		keyStore.load(instream, "商户号".toCharArray());

		instream.close();

        // 微信支付的商户号
		SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, "商户号".toCharArray()).build();

		SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,

				SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);

		CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();

		HttpPost httpost = new HttpPost(WxPayConfig.TRANSFOR_URL);

		httpost.addHeader("Connection", "keep-alive");

		httpost.addHeader("Accept", "*/*");

		httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");

		httpost.addHeader("Host", "api.mch.weixin.qq.com");

		httpost.addHeader("X-Requested-With", "XMLHttpRequest");

		httpost.addHeader("Cache-Control", "max-age=0");

		httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");

		httpost.setEntity(new StringEntity(xml, "UTF-8"));

		CloseableHttpResponse response = httpclient.execute(httpost);

		HttpEntity entity = response.getEntity();

		String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
		// 打印返回慘呼
		System.out.println(JSON.toJSONString(jsonStr));
		
		EntityUtils.consume(entity);
		
		return null;
	}

 

PayUtils签名算法

public class PayUtil {
	/**
	 * 签名字符串
	 * 
	 * @param text需要签名的字符串
	 * @param key
	 *            密钥
	 * @param input_charset编码格式
	 * @return 签名结果
	 */
	public static String sign(String text, String key, String input_charset) {
		text = text + "&key=" + key;
		return DigestUtils.md5Hex(getContentBytes(text, input_charset));
	}

	/**
	 * 签名字符串
	 * 
	 * @param text需要签名的字符串
	 * @param sign
	 *            签名结果
	 * @param key密钥
	 * @param input_charset
	 *            编码格式
	 * @return 签名结果
	 */
	public static boolean verify(String text, String sign, String key, String input_charset) {
		text = text + "&key=" + key;
		String mysign = DigestUtils.md5Hex(getContentBytes(text, input_charset));
		if (mysign.equals(sign)) {
			return true;
		} else {
			return false;
		}
	}
}

随机数生成方法

public static String getRandomStringByLength(int length) {
		String base = "abcdefghijklmnopqrstuvwxyz0123456789";
		Random random = new Random();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < length; i++) {
			int number = random.nextInt(base.length());
			sb.append(base.charAt(number));
		}
		return sb.toString();
	}

 

调用发送红包

public static void main(String[] args) {
		try {
			sendRedPacket("openId", 100L, "orderNo", "192.168.0.1");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

 

错误信息处理

如果出现CA证书错误,查看证书路径和支付商户号是否正确

错误NOAUTH,提示产品权限验证失败。需要到微信支付平台->产品中心->企业付款到零钱,开通企业付款到零钱,开通需求:微信支付商户后台需要90天、连续正常交易流水30天,才可以申请开通“企业付款到零钱”产品。

 

更多的错误信息点击微信支付官方链接查看

https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SoXiaTea

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值