微信提现(1)---企业现金红包方式
1、准备工作:
开通商户平台,并且在商户平台-产品中心-现金红包 点击申请开通现金红包。
2、商户平台-账户中心-API安全-下载证书,并把证书放到服务器的E盘(这个放哪里自己喜欢了),如图:
3、引入jar包:
4、直接上代码:
package com.wp.index.user;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.KeyStore;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.net.ssl.SSLContext;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import com.jfinal.core.Controller;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.weixin.sdk.kit.IpKit;
import com.jfinal.weixin.sdk.kit.PaymentKit;
import com.jfinal.weixin.sdk.utils.JsonUtils;
import com.wp.common.model.Member;
public class WeixinRedPacketController extends Controller {
// 商户相关资料
private static String appid = PropKit.get("appid");
private static String partner = PropKit.get("partner");
private static String paternerKey = PropKit.get("paternerKey");
private static String redPack = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";//现金普通红包接口
/**
* 公众号支付js-sdk(公众号的微信支付)
*/
public void ajaxRedPacket() {
String id = getCookie(Member.USER_LOGIN_ID_COOKIE);
if (StringUtils.isEmpty(id)) {
renderText("参数错误");
return;
}
Member m = Member.dao.findById(Long.parseLong(id));
if (m == null) {
renderText("参数错误");
return;
}
// openId,采用 网页授权获取 access_token API:SnsAccessTokenApi获取
String openId = m.getOpenId();
//生成订单号
String mchBillNo = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
//用户电脑ip
String ip = IpKit.getRealIp(getRequest());
if (StrKit.isBlank(ip)) {
ip = "127.0.0.1";
}
// 发普通红包接口文档:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_4&index=3
Map<String, String> params = new HashMap<String, String>();
params.put("nonce_str", UUID.randomUUID().toString().replaceAll("-", ""));//随机字符串
params.put("mch_billno", mchBillNo);// 商户订单号
params.put("mch_id", partner);//商户号
params.put("wxappid", appid);//公众号id
params.put("send_name", "王者猜猜猜"); //商户名称
params.put("re_openid", openId);//用户公众号唯一识别
params.put("total_amount", "100");// 因为微信的total_amount的单位是分,所有需要乘以100
params.put("total_num", "1");// 红包发放总人数
params.put("wishing", "祝您开心!");// 祝福语
params.put("client_ip", ip);// Ip地址
params.put("act_name", "财币兑换");// 活动名称
params.put("remark", "王者猜猜猜兑大奖");//备注
params.put("scene_id", "PRODUCT_5");// 场景id,需要在商户平台-产品中心-现金红包-产品设置里面设置,发放红包使用场景,红包金额大于200时必传。PRODUCT_1:商品促销;PRODUCT_2:抽奖;PRODUCT_3:虚拟物品兑奖 ;PRODUCT_4:企业内部福利;PRODUCT_5:渠道分润;PRODUCT_6:保险回馈;PRODUCT_7:彩票派奖;PRODUCT_8:税务刮奖
String sign = PaymentKit.createSign(params, paternerKey);
params.put("sign", sign);
String xml = PaymentKit.toXml(params);//得到签名之后的xml
String xmlResult = ssl(redPack,xml);//HttpUtils.post(redPack, xml);
System.out.println(xmlResult);
Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
String return_code = result.get("return_code");
String return_msg = result.get("return_msg");
if (StrKit.isBlank(return_code) || !"SUCCESS".equals(return_code)) {
renderText(return_msg);
return;
}
String result_code = result.get("result_code");
if (StrKit.isBlank(result_code) || !"SUCCESS".equals(result_code)) {
renderText(return_msg);
return;
}
String jsonStr = JsonUtils.toJson(result);
renderText(jsonStr);
}
//这方法是用于带上刚刚下载的证书调动发红包接口
private String ssl(String url,String data){
StringBuffer message = new StringBuffer();
try {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
FileInputStream instream = new FileInputStream(new File("E:/cert/apiclient_cert.p12"));
keyStore.load(instream, partner.toCharArray());
// Trust own CA and all self-signed certs
SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, partner.toCharArray()).build();
// Allow TLSv1 protocol only
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(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(data, "UTF-8"));
System.out.println("executing request" + httpost.getRequestLine());
CloseableHttpResponse response = httpclient.execute(httpost);
try {
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
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.printStackTrace();
} finally {
response.close();
}
} catch (Exception e1) {
e1.printStackTrace();
}
return message.toString();
}
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
package com.jfinal.weixin.sdk.kit;
import com.jfinal.kit.HashKit;
import com.jfinal.kit.StrKit;
import com.jfinal.weixin.sdk.utils.Charsets;
import com.jfinal.weixin.sdk.utils.XmlHelper;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
/**
* 微信支付的统一下单工具类
* @author L.cm
*/
public class PaymentKit {
/**
* 组装签名的字段
* @param params 参数
* @param urlEncoder 是否urlEncoder
* @return String
*/
public static String packageSign(Map<String, String> params, boolean urlEncoder) {
// 先将参数以其参数名的字典序升序进行排序
TreeMap<String, String> sortedParams = new TreeMap<String, String>(params);
// 遍历排序后的字典,将所有参数按"key=value"格式拼接在一起
StringBuilder sb = new StringBuilder();
boolean first = true;
for (Entry<String, String> param : sortedParams.entrySet()) {
String value = param.getValue();
if (StrKit.isBlank(value)) {
continue;
}
if (first) {
first = false;
} else {
sb.append("&");
}
sb.append(param.getKey()).append("=");
if (urlEncoder) {
try { value = urlEncode(value); } catch (UnsupportedEncodingException e) {}
}
sb.append(value);
}
return sb.toString();
}
/**
* urlEncode
* @param src 微信参数
* @return String
* @throws UnsupportedEncodingException 编码错误
*/
public static String urlEncode(String src) throws UnsupportedEncodingException {
return URLEncoder.encode(src, Charsets.UTF_8.name()).replace("+", "%20");
}
/**
* 生成签名
* @param params 参数
* @param paternerKey 支付密钥
* @return sign
*/
public static String createSign(Map<String, String> params, String paternerKey) {
// 生成签名前先去除sign
params.remove("sign");
String stringA = packageSign(params, false);
String stringSignTemp = stringA + "&key=" + paternerKey;
return HashKit.md5(stringSignTemp).toUpperCase();
}
/**
* 支付异步通知时校验sign
* @param params 参数
* @param paternerKey 支付密钥
* @return {boolean}
*/
public static boolean verifyNotify(Map<String, String> params, String paternerKey){
String sign = params.get("sign");
String localSign = PaymentKit.createSign(params, paternerKey);
return sign.equals(localSign);
}
/**
* 微信下单,map to xml
* @param params 参数
* @return String
*/
public static String toXml(Map<String, String> params) {
StringBuilder xml = new StringBuilder();
xml.append("<xml>");
for (Entry<String, String> entry : params.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
// 略过空值
if (StrKit.isBlank(value)) continue;
xml.append("<").append(key).append(">");
xml.append(entry.getValue());
xml.append("</").append(key).append(">");
}
xml.append("</xml>");
return xml.toString();
}
/**
* 针对支付的xml,没有嵌套节点的简单处理
* @param xmlStr xml字符串
* @return map集合
*/
public static Map<String, String> xmlToMap(String xmlStr) {
XmlHelper xmlHelper = XmlHelper.of(xmlStr);
return xmlHelper.toMap();
}
}
温馨提示:
微信现金红包有一点特别坑:设置金额的时候,因为其金额的单位是分,不能设置成100.00分,而非要设置成100分,这个有时候确实很难发现,
其报错信息为:<return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[签名错误]]></return_msg><result_code><![CDATA[FAIL]]></result_code>
微信提现(1)---企业现金红包方式相关推荐
- php商城微信提现,PHP实现微信提现(企业付款到零钱)
搜索热词 怎么开通企业付款到零钱?@H_404_1@ 有的商户号的产品中心是没有这个功能的,不过,该功能的pid(product id)是5,只要随便进去某一个产品,在地址栏把pid改为5.@H_40 ...
- PHP微信商户支付 - 企业付款到零钱功能(即提现)技术资料汇总
PHP实现微信开发中提现功能(企业付款到用户零钱) 一.实现该功能目的 这几天在小程序里要实现用户从系统中提现到零钱的功能,查了一下文档可以使用 企业付款到用户零钱 来实现: 官方文档:https:/ ...
- 微信企业付款到零钱(微信提现)
由于项目中要用到微信提现,参考网上代码和官方文档写了提现的工具类 用到的相关类库 dom4j commons-lang3 httpclient-4.4.1 具体相关流程可以看微信企业付款到零钱的开发文 ...
- php实现微信清粉功能,PHP实现微信提现功能
PHP实现微信提现功能 来源:中文源码网 浏览: 次 日期:2019年11月5日 [下载文档: PHP实现微信提现功能.txt ] (友情提示:右键点上行txt文档名->目标另存为 ...
- php实现金币提现,PHP实现微信提现功能
本文实例为大家分享了PHP实现微信提现功能的具体代码,供大家参考,具体内容如下 一.实现功能 这几天在小程序里要实现用户从系统中提现到零钱的功能,查了一下文档可以使用 企业付款到用户零钱 来实现: 官 ...
- php微信绑定银行卡_PHP实现微信提现功能
本文实例为大家分享了PHP实现微信提现功能的具体代码,供大家参考,具体内容如下 一.实现功能 这几天在小程序里要实现用户从系统中提现到零钱的功能,查了一下文档可以使用 企业付款到用户零钱 来实现: 官 ...
- 微信支付商户发放现金红包操作说明
一. 现金红包简介 微信红包,2014年春节一经推出即受到广大用户好评,引发全民抢红包热潮.现将微信红包打造成"现金红包",成为一款定向资金发放的营销工具,供商户使用. 二. 什么 ...
- 拼团功能实现 php_PHP实现微信提现功能
提现必须得用双向证书.所以大家一定要在微信的商户平台找到相应的地方去设置.因为做这个提现已经有一段时间了.所以设置微信商户平台的那几个地方没有图的情况.也说不清楚.下次再做提现的时候.给大家分享如何设 ...
- java开发微信提现_java 微信提现至零钱
需要用户绑定微信,获取用户openid,通过openid调取微信接口企业付款到零钱接口: package com.framework.loippi.plugins.wxapppay.withdrawa ...
最新文章
- 1.MySQL基本体系
- 10件开发者和老板都要知道的HTML5的那些事
- Vue开发规范1.0
- Stanford NLP
- Bootstrap——table标签使用横向滚动条解决方案
- 微型计算机及接口技术笔记,微机原理与接口技术笔记(一)
- 两张趣图助你理解状态码的含义~
- android获取应用安装通知消息,如何在Android 11 上获取已安装应用列表
- 安卓Java虚拟机大小_虚拟机为安卓流畅度背锅,是因为关系数十万程序员饭碗?...
- 小米超大杯旗舰不叫12 Ultra:或命名为MIX 5 Pro
- 怎么修改某一软件的服务器,怎样设置一个软件服务器地址
- sping boot demo解释
- office工具包开源了,使用Excel导入导出非常方便
- slice 和splice 的区别 js
- 心形函数的几种表达式
- 这么连接计算机网络,详细教您手机怎么连接电脑上网
- 华为HCNA实验学习
- HashMap的四种同步方式
- 《深度学习推荐系统》
- 浅谈地面生产系统智能化配电室的应用与研究