com.foxinmy.weixin4j.mp.WeixinPayProxy Maven / Gradle / Ivy
package com.foxinmy.weixin4j.mp;
import java.io.File;
import java.util.Date;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.JsonResult;
import com.foxinmy.weixin4j.http.XmlResult;
import com.foxinmy.weixin4j.model.WeixinMpAccount;
import com.foxinmy.weixin4j.mp.api.CashApi;
import com.foxinmy.weixin4j.mp.api.CouponApi;
import com.foxinmy.weixin4j.mp.api.Pay2Api;
import com.foxinmy.weixin4j.mp.api.Pay3Api;
import com.foxinmy.weixin4j.mp.api.PayApi;
import com.foxinmy.weixin4j.mp.payment.coupon.CouponDetail;
import com.foxinmy.weixin4j.mp.payment.coupon.CouponResult;
import com.foxinmy.weixin4j.mp.payment.coupon.CouponStock;
import com.foxinmy.weixin4j.mp.payment.v3.ApiResult;
import com.foxinmy.weixin4j.mp.payment.v3.MPPayment;
import com.foxinmy.weixin4j.mp.payment.v3.MPPaymentResult;
import com.foxinmy.weixin4j.mp.payment.v3.Redpacket;
import com.foxinmy.weixin4j.mp.payment.v3.RedpacketSendResult;
import com.foxinmy.weixin4j.mp.type.BillType;
import com.foxinmy.weixin4j.mp.type.CurrencyType;
import com.foxinmy.weixin4j.mp.type.IdQuery;
import com.foxinmy.weixin4j.mp.type.IdType;
import com.foxinmy.weixin4j.mp.type.RefundType;
import com.foxinmy.weixin4j.token.FileTokenHolder;
import com.foxinmy.weixin4j.token.TokenHolder;
import com.foxinmy.weixin4j.token.WeixinTokenCreator;
import com.foxinmy.weixin4j.type.AccountType;
import com.foxinmy.weixin4j.util.ConfigUtil;
/**
* 微信支付接口实现
*
* @className WeixinPayProxy
* @author jy
* @date 2015年1月3日
* @since JDK 1.7
* @see com.foxinmy.weixin4j.mp.api.Pay2Api
* @see com.foxinmy.weixin4j.mp.api.Pay3Api
* @see 商户平台支付API
*/
public class WeixinPayProxy {
private final PayApi payApi;
private final Pay2Api pay2Api;
private final Pay3Api pay3Api;
private final CouponApi couponApi;
private final CashApi cashApi;
public WeixinPayProxy() {
this(ConfigUtil.getWeixinMpAccount(), new FileTokenHolder(
new WeixinTokenCreator(AccountType.MP)));
}
/**
* WeixinAccount对象
*
* @param weixinAccount
* 微信账户
*/
public WeixinPayProxy(WeixinMpAccount weixinAccount, TokenHolder tokenHolder) {
this.pay2Api = new Pay2Api(weixinAccount, tokenHolder);
this.pay3Api = new Pay3Api(weixinAccount, tokenHolder);
int version = weixinAccount.getVersion();
if (version == 2) {
this.payApi = this.pay2Api;
} else if (version == 3) {
this.payApi = this.pay3Api;
} else {
this.payApi = this.pay3Api;
}
this.couponApi = new CouponApi(weixinAccount);
this.cashApi = new CashApi(weixinAccount);
}
/**
* 发货通知
*
* @param openId
* 用户ID
* @param transid
* 交易单号
* @param outTradeNo
* 订单号
* @param status
* 成功|失败
* @param statusMsg
* status为失败时携带的信息
* @return 发货处理结果
* @since V2 & V3
* @see com.foxinmy.weixin4j.mp.api.PayApi
* @throws WeixinException
*/
public JsonResult deliverNotify(String openId, String transid,
String outTradeNo, boolean status, String statusMsg)
throws WeixinException {
return payApi.deliverNotify(openId, transid, outTradeNo, status,
statusMsg);
}
/**
* 维权处理
*
* @param openId
* 用户ID
* @param feedbackId
* 维权单号
* @return 调用结果
* @see com.foxinmy.weixin4j.mp.api.PayApi
* @since V2 & V3
* @throws WeixinException
*/
public JsonResult updateFeedback(String openId, String feedbackId)
throws WeixinException {
return payApi.updateFeedback(openId, feedbackId);
}
/**
* V2订单查询
*
* @param idQuery
* 商户系统内部的订单号, transaction_id、out_trade_no 二 选一,如果同时存在优先级:
* transaction_id> out_trade_no
* @since V2
* @see com.foxinmy.weixin4j.mp.payment.v2.Order
* @see com.foxinmy.weixin4j.mp.api.PayApi
* @see com.foxinmy.weixin4j.mp.api.Pay2Api
* @return 订单详情
* @throws WeixinException
*/
public com.foxinmy.weixin4j.mp.payment.v2.Order orderQueryV2(
String outTradeNo) throws WeixinException {
return pay2Api.orderQuery(new IdQuery(outTradeNo, IdType.TRADENO));
}
/**
* V3订单查询
*
* 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知; 调用支付接口后,返回系统错误或未知交易状态情况;
* 调用被扫支付API,返回USERPAYING的状态; 调用关单或撤销接口API之前,需确认支付状态;
*
*
* @param idQuery
* 商户系统内部的订单号, transaction_id、out_trade_no 二 选一,如果同时存在优先级:
* transaction_id> out_trade_no
* @since V3
* @see com.foxinmy.weixin4j.mp.payment.v3.Order
* @see com.foxinmy.weixin4j.mp.api.PayApi
* @see com.foxinmy.weixin4j.mp.api.Pay3Api
* @see 订单查询API
* @return 订单详情
* @throws WeixinException
*/
public com.foxinmy.weixin4j.mp.payment.v3.Order orderQueryV3(IdQuery idQuery)
throws WeixinException {
return pay3Api.orderQuery(idQuery);
}
/**
* V2申请退款(请求需要双向证书)
*
* 交易时间超过 1 年的订单无法提交退款; 支持部分退款,部分退需要设置相同的订单号和不同的 out_refund_no。一笔退款失
* 败后重新提交,要采用原来的 out_refund_no。总退款金额不能超过用户实际支付金额。
*
*
* @param caFile
* 证书文件(后缀为*.pfx)
* @param idQuery
* ) 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
* transaction_id> out_trade_no
* @param outRefundNo
* 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔
* @param totalFee
* 订单总金额,单位为元
* @param refundFee
* 退款总金额,单位为元,可以做部分退款
* @param opUserId
* 操作员帐号, 默认为商户号
* @param opUserPasswd
* 操作员密码
*
* @return 退款申请结果
* @see com.foxinmy.weixin4j.mp.api.PayApi
* @see com.foxinmy.weixin4j.mp.api.Pay2Api
* @see com.foxinmy.weixin4j.mp.payment.v2.RefundResult
* @since V2
* @throws WeixinException
*/
public com.foxinmy.weixin4j.mp.payment.v2.RefundResult refundV2(
File caFile, IdQuery idQuery, String outRefundNo, double totalFee,
double refundFee, String opUserId, String opUserPasswd)
throws WeixinException {
return pay2Api.refund(caFile, idQuery, outRefundNo, totalFee,
refundFee, opUserId, opUserPasswd);
}
/**
* V2退款申请采用properties中配置的ca文件
*
* @see {@link com.foxinmy.weixin4j.mp.WeixinPayProxy#refundV2(File, IdQuery, String, double, double, String,String)}
*/
public com.foxinmy.weixin4j.mp.payment.v2.RefundResult refundV2(
IdQuery idQuery, String outRefundNo, double totalFee,
double refundFee, String opUserId, String opUserPasswd)
throws WeixinException {
File caFile = new File(ConfigUtil.getClassPathValue("ca_file"));
return refundV2(caFile, idQuery, outRefundNo, totalFee, refundFee,
opUserId, opUserPasswd);
}
/**
* V2退款申请
*
* @param caFile
* 证书文件(V2版本后缀为*.pfx)
* @param idQuery
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
* transaction_id> out_trade_no
* @param outRefundNo
* 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔
* @param totalFee
* 订单总金额,单位为元
* @param refundFee
* 退款总金额,单位为元,可以做部分退款
* @param opUserId
* 操作员帐号, 默认为商户号
* @param opUserPasswd
* 操作员密码,默认为商户后台登录密码
* @param recvUserId
* 转账退款接收退款的财付通帐号。 一般无需填写,只有退银行失败,资金转入商 户号现金账号时(即状态为转入代发,查询返 回的
* refund_status 是 7 或 11),填写原退款 单号并填写此字段,资金才会退到指定财付通
* 账号。其他情况此字段忽略
* @param reccvUserName
* 转账退款接收退款的姓名(需与接收退款的财 付通帐号绑定的姓名一致)
* @param refundType
* 为空或者填 1:商户号余额退款;2:现金帐号 退款;3:优先商户号退款,若商户号余额不足, 再做现金帐号退款。使用 2 或
* 3 时,需联系财 付通开通此功能
* @see com.foxinmy.weixin4j.mp.api.PayApi
* @see com.foxinmy.weixin4j.mp.api.Pay2Api
* @see com.foxinmy.weixin4j.mp.payment.v2.RefundResult
* @return 退款结果
*/
public com.foxinmy.weixin4j.mp.payment.v2.RefundResult refundV2(
File caFile, IdQuery idQuery, String outRefundNo, double totalFee,
double refundFee, String opUserId, String opUserPasswd,
String recvUserId, String reccvUserName, RefundType refundType)
throws WeixinException {
return pay2Api.refund(caFile, idQuery, outRefundNo, totalFee,
refundFee, opUserId, opUserPasswd, recvUserId, reccvUserName,
refundType);
}
/**
* V2退款查询 退款有一定延时,用零钱支付的退款20分钟内到账,银行卡支付的退款 3 个工作日后重新查询退款状态
*
* @param idQuery
* 单号 refund_id、out_refund_no、 out_trade_no 、 transaction_id
* 四个参数必填一个,优先级为:
* refund_id>out_refund_no>transaction_id>out_trade_no
* @return 退款记录
* @see com.foxinmy.weixin4j.mp.payment.v2.RefundRecord
* @see com.foxinmy.weixin4j.mp.api.PayApi
* @see com.foxinmy.weixin4j.mp.api.Pay2Api
* @since V2
* @throws WeixinException
*/
public com.foxinmy.weixin4j.mp.payment.v2.RefundRecord refundQueryV2(
IdQuery idQuery) throws WeixinException {
return pay2Api.refundQuery(idQuery);
}
/**
* V3申请退款(请求需要双向证书)
*
* 当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家,微信支付将在收到退款请求并且验证成功之后,
* 按照退款规则将支付款按原路退到买家帐号上。
*
*
* 1.交易时间超过半年的订单无法提交退款;
* 2.微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。一笔退款失败后重新提交
* ,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。
*
*
* @param caFile
* 证书文件(后缀为*.p12)
* @param idQuery
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
* transaction_id> out_trade_no
* @param outRefundNo
* 商户系统内部的退款单号,商 户系统内部唯一,同一退款单号多次请求只退一笔
* @param totalFee
* 订单总金额,单位为元
* @param refundFee
* 退款总金额,单位为元,可以做部分退款
* @param refundFeeType
* 货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY
* @param opUserId
* 操作员帐号, 默认为商户号
*
* @return 退款申请结果
* @see com.foxinmy.weixin4j.mp.payment.v3.RefundResult
* @see com.foxinmy.weixin4j.mp.api.PayApi
* @see com.foxinmy.weixin4j.mp.api.Pay3Api
* @see 申请退款API
* @since V3
* @throws WeixinException
*/
public com.foxinmy.weixin4j.mp.payment.v3.RefundResult refundV3(
File caFile, IdQuery idQuery, String outRefundNo, double totalFee,
double refundFee, CurrencyType refundFeeType, String opUserId)
throws WeixinException {
return pay3Api.refund(caFile, idQuery, outRefundNo, totalFee,
refundFee, refundFeeType, opUserId);
}
/**
* V3退款申请采用properties中配置的ca文件
*
* @see {@link com.foxinmy.weixin4j.mp.WeixinPayProxy#refundV3(File, IdQuery, String, double, double,CurrencyType, String)}
*/
public com.foxinmy.weixin4j.mp.payment.v3.RefundResult refundV3(
IdQuery idQuery, String outRefundNo, double totalFee,
double refundFee, String opUserId) throws WeixinException {
File caFile = new File(ConfigUtil.getClassPathValue("ca_file"));
return pay3Api.refund(caFile, idQuery, outRefundNo, totalFee,
refundFee, CurrencyType.CNY, opUserId);
}
/**
* V3退款查询
*
* 提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,用零钱支付的退款20分钟内到账,银行卡支付的退款3个工作日后重新查询退款状态。
*
*
* @param idQuery
* 单号 refund_id、out_refund_no、 out_trade_no 、 transaction_id
* 四个参数必填一个,优先级为:
* refund_id>out_refund_no>transaction_id>out_trade_no
* @return 退款记录
* @see com.foxinmy.weixin4j.mp.api.PayApi
* @see com.foxinmy.weixin4j.mp.api.Pay3Api
* @see com.foxinmy.weixin4j.mp.payment.v3.RefundRecord
* @see 退款查询API
* @since V3
* @throws WeixinException
*/
public com.foxinmy.weixin4j.mp.payment.v3.RefundRecord refundQueryV3(
IdQuery idQuery) throws WeixinException {
return pay3Api.refundQuery(idQuery);
}
/**
* 下载对账单
* 1.微信侧未成功下单的交易不会出现在对账单中。支付成功后撤销的交易会出现在对账 单中,跟原支付单订单号一致,bill_type 为
* REVOKED;
* 2.微信在次日 9 点启动生成前一天的对账单,建议商户 9 点半后再获取;
* 3.对账单中涉及金额的字段单位为“元”。
*
* @param billDate
* 下载对账单的日期
* @param billType
* 下载对账单的类型 ALL,返回当日所有订单信息, 默认值 SUCCESS,返回当日成功支付的订单
* REFUND,返回当日退款订单
* @return excel表格
* @since V2 & V3
* @see com.foxinmy.weixin4j.mp.api.PayApi
* @see 下载对账单API
* @throws WeixinException
*/
public File downloadbill(Date billDate, BillType billType)
throws WeixinException {
return payApi.downloadbill(billDate, billType);
}
/**
* 冲正订单(需要证书) 当支付返回失败,或收银系统超时需要取消交易,可以调用该接口 接口逻辑:支
* 付失败的关单,支付成功的撤销支付 7天以内的单可撤销,其他正常支付的单
* 如需实现相同功能请调用退款接口 调用扣款接口后请勿立即调用撤销,需要等待5秒以上。先调用查单接口,如果没有确切的返回,再调用撤销
*
* @param ca
* 证书文件(V2版本后缀为*.pfx,V3版本后缀为*.p12)
* @param idQuery
* 商户系统内部的订单号, transaction_id 、 out_trade_no 二选一,如果同时存在优先级:
* transaction_id> out_trade_no
* @return 撤销结果
* @see com.foxinmy.weixin4j.mp.api.PayApi
* @see com.foxinmy.weixin4j.mp.api.Pay2Api
* @see com.foxinmy.weixin4j.mp.api.Pay3Api
* @since V3
* @throws WeixinException
*/
public ApiResult reverse(File caFile, IdQuery idQuery)
throws WeixinException {
return payApi.reverse(caFile, idQuery);
}
/**
* 冲正撤销:默认采用properties中配置的ca文件
*
* @param idQuery
* transaction_id、out_trade_no 二选一
* @return 撤销结果
* @see {@link com.foxinmy.weixin4j.mp.WeixinProxy#reverse(File, IdQuery)}
* @throws WeixinException
*/
public ApiResult reverse(IdQuery idQuery) throws WeixinException {
File caFile = new File(ConfigUtil.getClassPathValue("ca_file"));
return payApi.reverse(caFile, idQuery);
}
/**
* 关闭订单
*
* 商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付;系统下单后,用户支付超时,系统退出不再受理,避免用户继续
* ,请调用关单接口,如果关单失败,返回已完 成支付请按正常支付处理。如果出现银行掉单,调用关单成功后,微信后台会主动发起退款。
*
*
* @param outTradeNo
* 商户系统内部的订单号
* @return 执行结果
* @see com.foxinmy.weixin4j.mp.api.PayApi
* @see com.foxinmy.weixin4j.mp.api.Pay3Api
* @since V3
* @throws WeixinException
* @see 关闭订单API
*/
public ApiResult closeOrder(String outTradeNo) throws WeixinException {
return payApi.closeOrder(outTradeNo);
}
/**
* native支付URL转短链接:用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),减小二维码数据量
* ,提升扫描速度和精确度。
*
* @param url
* 具有native标识的支付URL
* @return 转换后的短链接
* @see com.foxinmy.weixin4j.mp.api.PayApi
* @see com.foxinmy.weixin4j.mp.api.Pay2Api
* @see com.foxinmy.weixin4j.mp.api.Pay3Api
* @see 转换短链接API
* @since V2 & V3
* @throws WeixinException
*/
public String getPayShorturl(String url) throws WeixinException {
return payApi.getShorturl(url);
}
/**
* 接口上报
*
* @param interfaceUrl
* 上报对应的接口的完整 URL, 类似: https://api.mch.weixin.q
* q.com/pay/unifiedorder
* @param executeTime
* 接口耗时情况,单位为毫秒
* @param outTradeNo
* 商户系统内部的订单号,商 户可以在上报时提供相关商户订单号方便微信支付更好 的提高服务质量。
* @param ip
* 发起接口调用时的机器 IP
* @param time
* 商户调用该接口时商户自己 系统的时间
* @param returnXml
* 调用接口返回的基本数据
* @return 处理结果
* @see com.foxinmy.weixin4j.mp.api.PayApi
* @see com.foxinmy.weixin4j.mp.api.Pay3Api
* @see 接口测试上报API
* @throws WeixinException
*/
public XmlResult interfaceReport(String interfaceUrl, int executeTime,
String outTradeNo, String ip, Date time, XmlResult returnXml)
throws WeixinException {
return pay3Api.interfaceReport(interfaceUrl, executeTime, outTradeNo,
ip, time, returnXml);
}
/**
* 发放代金券(需要证书)
*
* @param caFile
* 证书文件(后缀为*.p12)
* @param couponStockId
* 代金券批次id
* @param partnerTradeNo
* 商户发放凭据号(格式:商户id+日期+流水号),商户侧需保持唯一性
* @param openId
* 用户的openid
* @param opUserId
* 操作员帐号, 默认为商户号 可在商户平台配置操作员对应的api权限 可为空
* @return 发放结果
* @see com.foxinmy.weixin4j.mp.api.CouponApi
* @see com.foxinmy.weixin4j.mp.payment.coupon.CouponResult
* @see 发放代金券接口
* @throws WeixinException
*/
public CouponResult sendCoupon(File caFile, String couponStockId,
String partnerTradeNo, String openId, String opUserId)
throws WeixinException {
return couponApi.sendCoupon(caFile, couponStockId, partnerTradeNo,
openId, opUserId);
}
/**
* 发放代金券采用properties中配置的ca文件
*
* @see {@link com.foxinmy.weixin4j.mp.WeixinPayProxy#sendCoupon(File, String, String, String, String)}
*/
public CouponResult sendCoupon(String couponStockId, String partnerTradeNo,
String openId) throws WeixinException {
File caFile = new File(ConfigUtil.getClassPathValue("ca_file"));
return couponApi.sendCoupon(caFile, couponStockId, partnerTradeNo,
openId, null);
}
/**
* 查询代金券批次
*
* @param couponStockId
* 代金券批次ID
* @return 代金券批次信息
* @see com.foxinmy.weixin4j.mp.api.CouponApi
* @see com.foxinmy.weixin4j.mp.payment.coupon.CouponStock
* @see 查询代金券信息
* @throws WeixinException
*/
public CouponStock queryCouponStock(String couponStockId)
throws WeixinException {
return couponApi.queryCouponStock(couponStockId);
}
/**
* 查询代金券详细
*
* @param couponId
* 代金券ID
* @return 代金券详细信息
* @see com.foxinmy.weixin4j.mp.api.CouponApi
* @see com.foxinmy.weixin4j.mp.payment.coupon.CouponDetail
* @see 查询代金券详细信息
* @throws WeixinException
*/
public CouponDetail queryCouponDetail(String couponId)
throws WeixinException {
return couponApi.queryCouponDetail(couponId);
}
/**
* 发放红包 企业向微信用户个人发现金红包
*
* @param caFile
* 证书文件(V3版本后缀为*.p12)
* @param redpacket
* 红包信息
* @return 发放结果
* @see com.foxinmy.weixin4j.mp.api.CashApi
* @see com.foxinmy.weixin4j.mp.payment.v3.Redpacket
* @see com.foxinmy.weixin4j.mp.payment.v3.RedpacketSendResult
* @see 红包接口说明
* @throws WeixinException
*/
public RedpacketSendResult sendRedpack(File caFile, Redpacket redpacket)
throws WeixinException {
return cashApi.sendRedpack(caFile, redpacket);
}
/**
* 发放红包采用properties中配置的ca文件
*
* @see {@link com.foxinmy.weixin4j.mp.WeixinPayProxy#sendRedpack(File, Redpacket)}
*/
public RedpacketSendResult sendRedpack(Redpacket redpacket)
throws WeixinException {
File caFile = new File(ConfigUtil.getClassPathValue("ca_file"));
return cashApi.sendRedpack(caFile, redpacket);
}
/**
* 企业付款 实现企业向个人付款,针对部分有开发能力的商户, 提供通过API完成企业付款的功能。 比如目前的保险行业向客户退保、给付、理赔。
*
* @param caFile
* 证书文件(V3版本后缀为*.p12)
* @param mpPayment
* 付款信息
* @return 付款结果
* @see com.foxinmy.weixin4j.mp.api.CashApi
* @see com.foxinmy.weixin4j.mp.payment.v3.MPPayment
* @see com.foxinmy.weixin4j.mp.payment.v3.MPPaymentResult
* @see 企业付款
* @throws WeixinException
*/
public MPPaymentResult mpPayment(File caFile, MPPayment mpPayment)
throws WeixinException {
return cashApi.mpPayment(caFile, mpPayment);
}
/**
* 企业付款采用properties中配置的ca文件
*
* @see {@link com.foxinmy.weixin4j.mp.WeixinPayProxy#mpPayment(File, MPPayment)}
*/
public MPPaymentResult mpPayment(MPPayment mpPayment)
throws WeixinException {
File caFile = new File(ConfigUtil.getClassPathValue("ca_file"));
return cashApi.mpPayment(caFile, mpPayment);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy