微信支付之现金红包 - Java 开发
本文章是首次接触微信支付所写下,如果对您有帮助希望点个赞。若有疑问或不对的地方欢迎各位留言或私信指正交流
基本原理就是调用微信现金红包接口(ssh带证书和签名),传入参数,获取响应
- 接口url:https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack
- 入参:WxRedpackSdkVo
- 出参:WxRedpackSdkRes
- 入参和出参均为 xml格式
另外 binarywang的WxJava开源项目已经把这些都封装好了,可以直接食用https://gitee.com/binary/weixin-java-tools
产品简介
现金红包,是营销工具之一,受广大商户与用户的喜爱
商户可以通过公众号或者服务通知向用户发放现金红包
用户领取红包后,资金到达用户零钱
若用户未领取,资金将会在24小时后退回商户的微信支付账户中
必备要素 【对照官网进行准备】
- 一个正常的微信商户号
- 开通现金红包权限
- 一个公众号(服务号)并且绑定到该商户号
- 在商户平台下载 API证书
- 给你的商户充上两块钱
- 在微信平台设置一些必要参数
支付接口核心代码
SSL 请求调用 微信的现金红包接口
// xian'j Url 地址
private static final SENDREDPACK_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";
// 证书存放地址
private static final PKCS12_FILE_PATH = "../../apiclient_cert.p12";
/**
* ssl 请求
*
* @param url
* @param reqXmlData xml 格式请求参数
* @param mchId 商户 ID
* @return
*/
private static String ssl(String url, String reqXmlData, String mchId) {
// 证书准备
char[] password = mchId.toCharArray();
KeyStore ks = KeyStore.getInstance("PKCS12");
FileInputStream instream = new FileInputStream(WXPayConstants.CERT_PATH_SERVER);
ks.load(instream, password);
log.info("Load keyStore success");
// 实例化密钥库 & 初始化密钥工厂 && 创建 SSL 连接
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, password);
BasicHttpClientConnectionManager connManager = getBasicHttpClientConnectionManager(kmf);
log.info("nit keyManagerFactory success。Create SSLContext & connManager init success");
// 准备 POST 请求
HttpPost httpPost = new HttpPost(url);
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(8 * 1000).setConnectTimeout(6 * 1000).build();
httpPost.setConfig(requestConfig);
httpPost.addHeader("Content-Type", "text/xml");
httpPost.addHeader("User-Agent", USER_AGENT + " " + mchId);
httpPost.setEntity(new StringEntity(reqXmlData, "UTF-8"));
log.info("Create httpClient & httpPost success");
// 通过 HttpClient 发起 POST 请求,HttpResponse 接收请求结果
HttpClient httpClient = HttpClientBuilder.create().setConnectionManager(connManager).build();
HttpResponse httpResponse = httpClient.execute(httpPost);
// 返回响应体内容 xml(String)
return EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
}
请求 xml 示列
<xml>
<mch_id>8888888888</mch_id>
<wxappid>wxappid88888888888</wxappid>
<re_openid>oPPyl1cjU8fcOps-qKwIOY9XuyI8</re_openid>
<total_num>1</total_num>
<total_amount>1000</total_amount>
<wishing>恭喜发财,大吉大利</wishing>
<send_name>白嫖不对哦</send_name>
<sign>00OSD69724074UI982867A1607A87UF2V</sign>
<nonce_str>DmTGX1VZ9KoJirLKwo86HnnKhFo0BtLH</nonce_str>
<mch_billno>8888888888202212128888888888</mch_billno>
<act_name>快快要请好友一起领取现金红包吧</act_name>
<scene_id>PRODUCT_3</scene_id>
<client_ip>118.122.18.168</client_ip>
<remark>感谢支持现金红包</remark>
<risk_info/>
</xml>
响应 xml 示列
<xml>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[发放成功]]></return_msg>
<result_code><![CDATA[SUCCESS]]></result_code>
<err_code><![CDATA[SUCCESS]]></err_code>
<err_code_des><![CDATA[发放成功]]></err_code_des>
<mch_billno><![CDATA[8888888888202212128888888888]]></mch_billno>
<mch_id><![CDATA[8888888888]]></mch_id>
<wxappid><![CDATA[wxappid88888888888]]></wxappid>
<re_openid><![CDATA[oPPyl1cjU8fcOps-qKwIOY9XuyI8]]></re_openid>
<total_amount>1000</total_amount>
<send_listid><![CDATA[1000041701202212053666666888888]]></send_listid>
</xml>
接口请求入参类
WxRedpackSdkVo.class
package com.lcl.redpacket.config.wx;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.io.Serializable;
/**
* 微信发放红包接口 sdkVo
*
* @author lichenglong
* @date 2022-11-24 10:24
*/
@Data
@Component
@ConfigurationProperties(prefix = "wx.redpack")
public class WxRedpackSdkVo implements Serializable {
private String nonce_str;
private String sign;
private String mch_billno;
private String mch_id;
private String wxappid;
private String send_name;
private String re_openid;
private int total_amount;
private int total_num;
private String wishing;
private String client_ip;
private String act_name;
private String remark;
private String scene_id;
private String risk_info;
}
接口响应结果类
WxRedpackSdkRes.class
package com.lcl.redpacket.config.wx;
import java.io.Serializable;
/**
* 微信现金红包接口 sdkRes
*
* @author lichenglong
* @date 2022-11-24 10:24
*/
@Data
public class WxRedpackSdkRes implements Serializable {
/**
* 返回状态码 SUCCESS/FAIL
*/
private String return_code;
/**
* 返回信息
*/
private String return_msg;
// ===== 以下字段在return_code为SUCCESS的时候有返回 =====
/**
* 业务结果 SUCCESS/FAIL
* 注意:当状态为FAIL时,存在业务结果未明确的情况。所以如果状态是FAIL,请务必再请求一次查询接口[请务必关注错误代码(err_code字段),通过查询得到的红包状态确认此次发放的结果。],以确认此次发放的结果。
*/
private String result_code;
/**
* 错误码信息
* 注意:出现未明确的错误码(SYSTEMERROR等)时,请务必用原商户订单号重试,或者再请求一次查询接口以确认此次发放的结果。
*/
private String err_code;
/**
* 错误代码描述
*/
private String err_code_des;
// ===== 以下字段在return_code和result_code都为SUCCESS的时候有返回 =====
/**
* 商户订单号:必须唯一
* 组成:mch_id+yyyymmdd+10位一天内不能重复的数字
*/
private String mch_billno;
/**
* 商户号
*/
private String mch_id;
/**
* 公众账号 appid
*/
private String wxappid;
/**
* 接受收红包的用户
*/
private String re_openid;
/**
* 付款金额,单位分
*/
private int total_amount;
/**
* 红包订单的微信单号
*/
private String send_listid;
}