您的位置:首页 > 移动开发 > 微信开发

微信开发之现金红包

2017-01-04 20:53 288 查看
此项目已开源欢迎Start、PR、发起Issues一起讨论交流共同进步

https://github.com/Javen205/IJPay

http://git.oschina.net/javen205/IJPay

文章首发地址:http://www.jianshu.com/p/c06120bc1f5c

微信极速开发系列文章:点击这里

前几篇文章介绍了微信支付。 公众号支付微信扫码支付刷卡支付微信买单

此文来聊聊微信商户中的支付工具—-现金红包



准备工作

【官方文档】

一、开通现金红包权限

在使用现金红包之前,请前往开通现金红包功能。操作路径:【登录微信支付商户平台——>产品中心——>现金红包——>开通】。

二、下载API证书

商户调用微信红包接口时,服务器会进行证书验证,请在商户平台下载证书





有人要问这么多证书到底使用那个呢?跟开发语言有关系吗?

什么语言使用什么证书,以及如何使用可以参考截图中的
证书说明.txt


内容如下:

欢迎使用微信支付!
微信支付API共四份(证书pkcs12格式、证书pem格式、证书密钥pem格式、CA证书),为接口中强制要求时需携带的证书文件。
证书属于敏感信息,请妥善保管不要泄露和被他人复制。
不同开发语言下的证书格式不同,以下为说明指引:
证书pkcs12格式(apiclient_cert.p12)
包含了私钥信息的证书文件,为p12(pfx)格式,由微信支付签发给您用来标识和界定您的身份
部分安全性要求较高的API需要使用该证书来确认您的调用身份
windows上可以直接双击导入系统,导入过程中会提示输入证书密码,证书密码默认为您的商户ID(如:10010000)
证书pem格式(apiclient_cert.pem)
从apiclient_cert.p12中导出证书部分的文件,为pem格式,请妥善保管不要泄漏和被他人复制
部分开发语言和环境,不能直接使用p12文件,而需要使用pem,所以为了方便您使用,已为您直接提供
您也可以使用openssl命令来自己导出:openssl pkcs12 -clcerts -nokeys -in apiclient_cert.p12 -out apiclient_cert.pem
证书密钥pem格式(apiclient_key.pem)
从apiclient_cert.p12中导出密钥部分的文件,为pem格式
部分开发语言和环境,不能直接使用p12文件,而需要使用pem,所以为了方便您使用,已为您直接提供
您也可以使用openssl命令来自己导出:openssl pkcs12 -nocerts -in apiclient_cert.p12 -out apiclient_key.pem
CA证书(rootca.pem)
微信支付api服务器上也部署了证明微信支付身份的服务器证书,您在使用api进行调用时也需要验证所调用服务器及域名的真实性
该文件为签署微信支付证书的权威机构的根证书,可以用来验证微信支付服务器证书的真实性
某些环境和工具已经内置了若干权威机构的根证书,无需引用该证书也可以正常进行验证,这里提供给您在未内置所必须根证书的环境中载入使用


三、充值

在发放现金红包之前,请确保你的资金充足。如若不足,请充值。操作路径:【登录商户平台——>账户中心——>资金管理——>充值】

每个红包的平均金额必须在1.00元到200.00元之间



四、获取openid

目前支持向指定微信用户的openid发放指定金额红包。(获取openid参见之前写的文章:极速开发微信公众号之授权获取用户信息

五、相关参数设置

和红包相关的参数【主要是安全方面:绑定IP、防止用户盗刷】,你可以在页面上自主设置和更改。

操作路径如下:【登录商户平台——>产品中心——>现金红包——>产品设置】(注:“产品设置”操作按钮仅当你开通现金红包功能之后才会出现)。

你可以设置和更改以下参数:



说明:

1、 调用IP地址:设置之后,仅有已设置的IP地址可以调用,其余的IP调用会报错;

2、用户领取上限:限制同一openid同一日领取的个数

3、防刷等级:防刷是指微信风控针对微信小号、僵尸号、机器号等的拦截,你可以通过更改防刷等级控制防刷的强度。

4、 同时,你也可以申请更改红包额度。但是需要经过微信支付的审核,审核通过之后才会生效。

现金红包类别

现金红包分为两类:

1、普通红包 【官方文档】

2、裂变红包 【官方文档】

两者部分参数不同

发送现金红包

1、发送普通红包接口
com.javen.weixin.api.RedPackApi.java


params, String certPath, String partner) {
return HttpUtils.postSSL(sendRedPackUrl, PaymentKit.toXml(params), certPath, partner);
}" data-snippet-id="ext.ca806eccd4ed6f40fde300822ba15def" data-snippet-saved="false" data-codota-status="done">[code]private static String sendRedPackUrl = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";

/**
* 发送红包
* @param params 请求参数
* @param certPath 证书文件目录
* @param partner 证书密码
* @return {String}
*/
public static String sendRedPack(Map<String, String> params, String certPath, String partner) {
return HttpUtils.postSSL(sendRedPackUrl, PaymentKit.toXml(params), certPath, partner);
}


2、发送裂变红包接口
com.javen.weixin.api.RedPackApi.java


params, String certPath, String partner) {
return HttpUtils.postSSL(sendGroupRedPackUrl, PaymentKit.toXml(params), certPath, partner);
}" data-snippet-id="ext.b6bc7fa04419395210fc3700f703e979" data-snippet-saved="false" data-codota-status="done">[code]private static String sendGroupRedPackUrl = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendgroupredpack";

/**
* 发送裂变红包
* @param params 请求参数
* @param certPath 证书文件目录
* @param partner 证书密码
* @return {String}
*/
public static String sendGroupRedPack(Map<String, String> params, String certPath, String partner) {
return HttpUtils.postSSL(sendGroupRedPackUrl, PaymentKit.toXml(params), certPath, partner);
}


具体实现封装
com.javen.utils.ReadPackUtils.java


1、普通红包

params = new HashMap();
// 随机字符串
params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
// 商户订单号
params.put("mch_billno", mchBillno);
// 商户号
params.put("mch_id", partner);
// 公众账号ID
params.put("wxappid", wxappid);
// 商户名称
params.put("send_name", sendName);
// 用户OPENID
params.put("re_openid", reOpenid);
// 付款现金(单位分)
params.put("total_amount", total_amount);
// 红包发放总人数
params.put("total_num", total_num);
// 红包祝福语
params.put("wishing", wishing);
// 终端IP
params.put("client_ip", ip);
// 活动名称
params.put("act_name", act_name );
// 备注
params.put("remark", remark);
//创建签名
String sign = PaymentKit.createSign(params, paternerKey);
params.put("sign", sign);

String xmlResult = RedPackApi.sendRedPack(params, certPath, partner);
Map result = PaymentKit.xmlToMap(xmlResult);
log.warn(JsonKit.toJson(result));
//此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断
String return_code = result.get("return_code");
//业务结果
String result_code = result.get("result_code");

if (StrKit.isBlank(return_code) || !"SUCCESS".equals(return_code)) {
return false;
}
if (StrKit.notBlank(result_code) && "SUCCESS".equals(result_code)) {

return true;
}
return false;
}
" data-snippet-id="ext.9f8df943e8d6001a6d004e7b51e45784" data-snippet-saved="false" data-codota-status="done">[code]/**
* 发送普通红包
* @param request 获取IP
* @param total_amount  付款现金(单位分)
* @param total_num 红包发放总人数
* @param wishing 红包祝福语
* @param act_name 活动名称
* @param remark 备注
* @param reOpenid 用户openid
* @param partner 商户号
* @param wxappid 公众账号appid
* @param sendName 商户名称
* @param paternerKey 商户签名key
* @param certPath 证书路径
* @return
*/
public static boolean sendredpack(HttpServletRequest request,String total_amount,String total_num,String wishing,String act_name,String remark,String reOpenid,String partner,String wxappid,String sendName,String paternerKey,String certPath) {
// 商户订单号
String mchBillno = System.currentTimeMillis() + "";
String ip = IpKit.getRealIp(request);

Map<String, String> params = new HashMap<String, String>();
// 随机字符串
params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
// 商户订单号
params.put("mch_billno", mchBillno);
// 商户号
params.put("mch_id", partner);
// 公众账号ID
params.put("wxappid", wxappid);
// 商户名称
params.put("send_name", sendName);
// 用户OPENID
params.put("re_openid", reOpenid);
// 付款现金(单位分)
params.put("total_amount", total_amount);
// 红包发放总人数
params.put("total_num", total_num);
// 红包祝福语
params.put("wishing", wishing);
// 终端IP
params.put("client_ip", ip);
// 活动名称
params.put("act_name", act_name );
// 备注
params.put("remark", remark);
//创建签名
String sign = PaymentKit.createSign(params, paternerKey);
params.put("sign", sign);

String xmlResult = RedPackApi.sendRedPack(params, certPath, partner);
Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
log.warn(JsonKit.toJson(result));
//此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断
String return_code = result.get("return_code");
//业务结果
String result_code = result.get("result_code");

if (StrKit.isBlank(return_code) || !"SUCCESS".equals(return_code)) {
return false;
}
if (StrKit.notBlank(result_code) && "SUCCESS".equals(result_code)) {

return true;
}
return false;
}


2、裂变红包

params = new HashMap();
// 随机字符串
params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
// 商户订单号
params.put("mch_billno", mchBillno);
// 商户号
params.put("mch_id", partner);
// 公众账号ID
params.put("wxappid", wxappid);
// 商户名称
params.put("send_name", sendName);
// 用户OPENID
params.put("re_openid", reOpenid);
// 付款现金(单位分)
params.put("total_amount", total_amount);
// 红包发放总人数
params.put("total_num", total_num);
//红包金额设置方式
params.put("amt_type", "ALL_RAND");
// 红包祝福语
params.put("wishing", wishing);
// 活动名称
params.put("act_name", act_name );
// 备注
params.put("remark", remark);

//创建签名
String sign = PaymentKit.createSign(params, paternerKey);
params.put("sign", sign);

String xmlResult = RedPackApi.sendGroupRedPack(params, certPath, partner);
Map result = PaymentKit.xmlToMap(xmlResult);
log.warn(JsonKit.toJson(result));
//此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断
String return_code = result.get("return_code");
//业务结果
String result_code = result.get("result_code");

if (StrKit.isBlank(return_code) || !"SUCCESS".equals(return_code)) {
return false;
}
if (StrKit.notBlank(result_code) && "SUCCESS".equals(result_code)) {

return true;
}
return false;

}" data-snippet-id="ext.f41cdd5abb451f82f6c90494ad456484" data-snippet-saved="false" data-codota-status="done">[code]/**
* 发送裂变红包
* @param partner
* @param wxappid
* @param sendName
* @param reOpenid
* @param total_amount
* @param total_num
* @param wishing
* @param act_name
* @param remark
* @param paternerKey
* @param certPath
* @return
*/
public static boolean sendGroupRedPack(String partner, String wxappid, String sendName, String reOpenid, String total_amount, String total_num, String wishing, String act_name, String remark, String paternerKey, String certPath){
// 商户订单号
String mchBillno = System.currentTimeMillis() + "";

Map<String, String> params = new HashMap<String, String>();
// 随机字符串
params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
// 商户订单号
params.put("mch_billno", mchBillno);
// 商户号
params.put("mch_id", partner);
// 公众账号ID
params.put("wxappid", wxappid);
// 商户名称
params.put("send_name", sendName);
// 用户OPENID
params.put("re_openid", reOpenid);
// 付款现金(单位分)
params.put("total_amount", total_amount);
// 红包发放总人数
params.put("total_num", total_num);
//红包金额设置方式
params.put("amt_type", "ALL_RAND");
// 红包祝福语
params.put("wishing", wishing);
// 活动名称
params.put("act_name", act_name );
// 备注
params.put("remark", remark);

//创建签名
String sign = PaymentKit.createSign(params, paternerKey);
params.put("sign", sign);

String xmlResult = RedPackApi.sendGroupRedPack(params, certPath, partner);
Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
log.warn(JsonKit.toJson(result));
//此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断
String return_code = result.get("return_code");
//业务结果
String result_code = result.get("result_code");

if (StrKit.isBlank(return_code) || !"SUCCESS".equals(return_code)) {
return false;
}
if (StrKit.notBlank(result_code) && "SUCCESS".equals(result_code)) {

return true;
}
return false;

}


发送红包Demo

/**
* 微信红包demo
* @author Javen
* 2016年5月28日
*/
public class RedPackApiController extends Controller {
private static String sendName = "Javen205";
//微信证书路径
private static String certPath = "/Users/Javen/Downloads/cert/apiclient_cert.p12";
//商户相关资料
String wxappid = PropKit.get("appId");
// 微信支付分配的商户号
String partner = PropKit.get("mch_id");
//API密钥
String paternerKey = PropKit.get("paternerKey");

/**
* 发送普通红包
*/
public void sendredpack() {

boolean isSend = ReadPackUtils.sendredpack(getRequest(), "100", "1", "感谢您参加猜灯谜活动,祝您元宵节快乐!",
"猜灯谜抢红包活动", "猜越多得越多,快来抢!", "o_pncsidC-pRRfCP4zj98h6slREw",
partner, wxappid, sendName, paternerKey, certPath);

renderJson(isSend);
}
/**
* 发送裂变红包
*/
public void sendGroupRedPack() {

boolean isSend = ReadPackUtils.sendGroupRedPack(partner, wxappid, "天虹百货", "o_pncsidC-pRRfCP4zj98h6slREw",
"100", "10", "感谢您参加猜灯谜活动,祝您元宵节快乐!", "猜灯谜抢红包活动",
"猜越多得越多,快来抢", paternerKey, certPath);

renderJson(isSend);
}

public void query() {
String query = ReadPackUtils.query("10000098201411111234567890", partner, wxappid, paternerKey, certPath);
renderJson(query);
}

}


查询红包记录

【查询红包记录官方文档】

接口封装
com.javen.weixin.api.RedPackApi.java


params, String certPath, String partner) {
return HttpUtils.postSSL(getHBInfo, PaymentKit.toXml(params), certPath, partner);
}" data-snippet-id="ext.e324eb32d69613b7045c3bf31b3dee41" data-snippet-saved="false" data-codota-status="done">[code]private static String getHBInfo = "https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo ";

/**
* 根据商户订单号查询信息
* @param params 请求参数
* @param certPath 证书文件目录
* @param partner 证书密码
* @return {String}
*/
public static String getHbInfo(Map<String, String> params, String certPath, String partner) {
return HttpUtils.postSSL(getHBInfo, PaymentKit.toXml(params), certPath, partner);
}


具体实现封装
com.javen.utils.ReadPackUtils.java


params = new HashMap();
// 随机字符串
params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
// 商户订单号
params.put("mch_billno", mch_billno);
// 商户号
params.put("mch_id", partner);
// 公众账号ID
params.put("appid", wxappid);
params.put("bill_type", "MCHT");
//创建签名
String sign = PaymentKit.createSign(params, paternerKey);
params.put("sign", sign);

String xmlResult = RedPackApi.getHbInfo(params, certPath, partner);
Map result = PaymentKit.xmlToMap(xmlResult);
System.out.println(result);
return JsonKit.toJson(result);
}" data-snippet-id="ext.a19a691986827e8779b68ab6214e8835" data-snippet-saved="false" data-codota-status="done">[code]/**
* 根据商户订单号查询红包
* @param mch_billno 商户订单号
* @param partner 商户号
* @param wxappid 公众账号ID
* @param paternerKey 商户签名Key
* @param certPath 证书路径
* @return
*/
public static String  query(String mch_billno,String partner,String wxappid,String paternerKey,String certPath) {
Map<String, String> params = new HashMap<String, String>();
// 随机字符串
params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
// 商户订单号
params.put("mch_billno", mch_billno);
// 商户号
params.put("mch_id", partner);
// 公众账号ID
params.put("appid", wxappid);
params.put("bill_type", "MCHT");
//创建签名
String sign = PaymentKit.createSign(params, paternerKey);
params.put("sign", sign);

String xmlResult = RedPackApi.getHbInfo(params, certPath, partner);
Map<String, String> result = PaymentKit.xmlToMap(xmlResult);
System.out.println(result);
return JsonKit.toJson(result);
}


码字完毕,以上就是微信发送现金红包的详细介绍。

欢迎留言、转发

微信极速开发系列文章:http://www.jianshu.com/p/a172a1b69fdd

此文章项目开源地址:极速开发微信公众号-Start支持项目发展
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息