mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2025-05-05 13:17:46 +08:00
重构微信支付申请退款接口 for issue #25
This commit is contained in:
parent
10ce6a8920
commit
5fe1c061f2
@ -1,19 +1,11 @@
|
||||
package me.chanjar.weixin.mp.api;
|
||||
|
||||
import me.chanjar.weixin.common.exception.WxErrorException;
|
||||
import me.chanjar.weixin.mp.bean.pay.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
import me.chanjar.weixin.common.exception.WxErrorException;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxEntPayRequest;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxEntPayResult;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxMpPayCallback;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxMpPayRefundResult;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxMpPayResult;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxRedpackResult;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxSendRedpackRequest;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxUnifiedOrderRequest;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxUnifiedOrderResult;
|
||||
|
||||
/**
|
||||
* 微信支付相关接口
|
||||
* Created by Binary Wang on 2016/7/28.
|
||||
@ -25,7 +17,7 @@ public interface WxMpPayService {
|
||||
* 统一下单(详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1)
|
||||
* 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识"
|
||||
* 接口地址:https://api.mch.weixin.qq.com/pay/unifiedorder
|
||||
* @throws WxErrorException
|
||||
* @throws WxErrorException
|
||||
*
|
||||
*/
|
||||
WxUnifiedOrderResult unifiedOrder(WxUnifiedOrderRequest request)
|
||||
@ -42,7 +34,7 @@ public interface WxMpPayService {
|
||||
/**
|
||||
* 该接口提供所有微信支付订单的查询,当支付通知处理异常戒丢失的情冴,商户可以通过该接口查询订单支付状态。
|
||||
* 详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2
|
||||
* @throws WxErrorException
|
||||
* @throws WxErrorException
|
||||
*
|
||||
*/
|
||||
WxMpPayResult getJSSDKPayResult(String transactionId, String outTradeNo)
|
||||
@ -56,18 +48,15 @@ public interface WxMpPayService {
|
||||
WxMpPayCallback getJSSDKCallbackData(String xmlData);
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 微信支付-申请退款
|
||||
* 详见 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
|
||||
*
|
||||
* @param parameters 需要传入的退款参数的Map。以下几项为参数的必须项:<br/>
|
||||
* <li/> transaction_id
|
||||
* <li/> out_trade_no (仅在上述transaction_id为空时是必须项)
|
||||
* <li/> out_refund_no
|
||||
* <li/> total_fee
|
||||
* <li/> refund_fee
|
||||
* 接口链接:https://api.mch.weixin.qq.com/secapi/pay/refund
|
||||
* </pre>
|
||||
* @param keyFile 证书文件对象
|
||||
* @return 退款操作结果
|
||||
*/
|
||||
WxMpPayRefundResult refundPay(Map<String, String> parameters) throws WxErrorException;
|
||||
WxMpPayRefundResult refund(WxMpPayRefundRequest request, File keyFile) throws WxErrorException;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
@ -80,7 +69,7 @@ public interface WxMpPayService {
|
||||
|
||||
/**
|
||||
* 发送微信红包给个人用户
|
||||
* <pre>
|
||||
* <pre>
|
||||
* 文档详见:
|
||||
* 发送普通红包 https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_4&index=3
|
||||
* 发送裂变红包 https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_5&index=4
|
||||
@ -89,7 +78,7 @@ public interface WxMpPayService {
|
||||
WxRedpackResult sendRedpack(WxSendRedpackRequest request) throws WxErrorException;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* <pre>
|
||||
* 企业付款业务是基于微信支付商户平台的资金管理能力,为了协助商户方便地实现企业向个人付款,针对部分有开发能力的商户,提供通过API完成企业付款的功能。
|
||||
* 比如目前的保险行业向客户退保、给付、理赔。
|
||||
* 企业付款将使用商户的可用余额,需确保可用余额充足。查看可用余额、充值、提现请登录商户平台“资金管理”https://pay.weixin.qq.com/进行操作。
|
||||
|
@ -1,19 +1,18 @@
|
||||
package me.chanjar.weixin.mp.api.impl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.security.KeyStore;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
import me.chanjar.weixin.common.annotation.Required;
|
||||
import me.chanjar.weixin.common.bean.result.WxError;
|
||||
import me.chanjar.weixin.common.exception.WxErrorException;
|
||||
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
|
||||
import me.chanjar.weixin.mp.api.WxMpPayService;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.pay.*;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
@ -26,26 +25,13 @@ import org.apache.http.ssl.SSLContexts;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.joor.Reflect;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
|
||||
import me.chanjar.weixin.common.annotation.Required;
|
||||
import me.chanjar.weixin.common.bean.result.WxError;
|
||||
import me.chanjar.weixin.common.exception.WxErrorException;
|
||||
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
|
||||
import me.chanjar.weixin.mp.api.WxMpPayService;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxEntPayRequest;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxEntPayResult;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxMpPayCallback;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxMpPayRefundResult;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxMpPayResult;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxRedpackResult;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxSendRedpackRequest;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxUnifiedOrderRequest;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxUnifiedOrderResult;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.security.KeyStore;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* Created by Binary Wang on 2016/7/28.
|
||||
@ -55,8 +41,10 @@ import me.chanjar.weixin.mp.bean.pay.WxUnifiedOrderResult;
|
||||
public class WxMpPayServiceImpl implements WxMpPayService {
|
||||
|
||||
private static final String PAY_BASE_URL = "https://api.mch.weixin.qq.com";
|
||||
private static final List<String> TRADE_TYPES = Lists.newArrayList("JSAPI",
|
||||
"NATIVE", "APP");
|
||||
private static final String[] TRADE_TYPES = new String[]{"JSAPI","NATIVE", "APP"};
|
||||
private static final String[] REFUND_ACCOUNT = new String[]{"REFUND_SOURCE_RECHARGE_FUNDS",
|
||||
"REFUND_SOURCE_UNSETTLED_FUNDS"};
|
||||
|
||||
private WxMpService wxMpService;
|
||||
|
||||
public WxMpPayServiceImpl(WxMpService wxMpService) {
|
||||
@ -115,33 +103,25 @@ public class WxMpPayServiceImpl implements WxMpPayService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public WxMpPayRefundResult refundPay(Map<String, String> parameters)
|
||||
public WxMpPayRefundResult refund(WxMpPayRefundRequest request, File keyFile)
|
||||
throws WxErrorException {
|
||||
SortedMap<String, String> refundParams = new TreeMap<>(parameters);
|
||||
refundParams.put("appid",
|
||||
this.wxMpService.getWxMpConfigStorage().getAppId());
|
||||
refundParams.put("mch_id",
|
||||
this.wxMpService.getWxMpConfigStorage().getPartnerId());
|
||||
refundParams.put("nonce_str", System.currentTimeMillis() + "");
|
||||
refundParams.put("op_user_id",
|
||||
this.wxMpService.getWxMpConfigStorage().getPartnerId());
|
||||
String sign = this.createSign(refundParams,
|
||||
this.wxMpService.getWxMpConfigStorage().getPartnerKey());
|
||||
refundParams.put("sign", sign);
|
||||
checkParameters(request);
|
||||
|
||||
StringBuilder request = new StringBuilder("<xml>");
|
||||
for (Map.Entry<String, String> para : refundParams.entrySet()) {
|
||||
request.append(String.format("<%s>%s</%s>", para.getKey(),
|
||||
para.getValue(), para.getKey()));
|
||||
}
|
||||
request.append("</xml>");
|
||||
|
||||
String url = PAY_BASE_URL + "/secapi/pay/refund";
|
||||
String responseContent = this.wxMpService.post(url, request.toString());
|
||||
XStream xstream = XStreamInitializer.getInstance();
|
||||
xstream.processAnnotations(WxMpPayRefundResult.class);
|
||||
WxMpPayRefundResult wxMpPayRefundResult = (WxMpPayRefundResult) xstream
|
||||
.fromXML(responseContent);
|
||||
xstream.processAnnotations(WxMpPayRefundRequest.class);
|
||||
|
||||
request.setAppid(this.wxMpService.getWxMpConfigStorage().getAppId());
|
||||
String partnerId = this.wxMpService.getWxMpConfigStorage().getPartnerId();
|
||||
request.setMchId(partnerId);
|
||||
request.setNonceStr( System.currentTimeMillis() + "");
|
||||
request.setOpUserId(partnerId);
|
||||
String sign = this.createSign(this.xmlBean2Map(request), this.wxMpService.getWxMpConfigStorage().getPartnerKey());
|
||||
request.setSign(sign);
|
||||
|
||||
String url = PAY_BASE_URL + "/secapi/pay/refund";
|
||||
String responseContent = this.executeRequestWithKeyFile(url, xstream.toXML(request), keyFile, partnerId);
|
||||
WxMpPayRefundResult wxMpPayRefundResult = (WxMpPayRefundResult) xstream.fromXML(responseContent);
|
||||
|
||||
if (!"SUCCESS".equalsIgnoreCase(wxMpPayRefundResult.getResultCode())
|
||||
|| !"SUCCESS".equalsIgnoreCase(wxMpPayRefundResult.getReturnCode())) {
|
||||
@ -158,6 +138,20 @@ public class WxMpPayServiceImpl implements WxMpPayService {
|
||||
return wxMpPayRefundResult;
|
||||
}
|
||||
|
||||
private void checkParameters(WxMpPayRefundRequest request) {
|
||||
checkNotNullParams(request);
|
||||
|
||||
if (StringUtils.isNotBlank(request.getRefundAccount())) {
|
||||
if(!ArrayUtils.contains(REFUND_ACCOUNT, request.getRefundAccount())){
|
||||
throw new IllegalArgumentException("refund_account目前必须为" + Arrays.toString(REFUND_ACCOUNT) + "其中之一");
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(request.getOutTradeNo()) && StringUtils.isBlank(request.getTransactionId())) {
|
||||
throw new IllegalArgumentException("transaction_id 和 out_trade_no 不能同时为空,必须提供一个");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkJSSDKCallbackDataSignature(Map<String, String> kvm,
|
||||
String signature) {
|
||||
@ -176,7 +170,7 @@ public class WxMpPayServiceImpl implements WxMpPayService {
|
||||
request.setMchId(this.wxMpService.getWxMpConfigStorage().getPartnerId());
|
||||
request.setNonceStr(System.currentTimeMillis() + "");
|
||||
|
||||
String sign = this.createSign(xmlBean2Map(request),
|
||||
String sign = this.createSign(this.xmlBean2Map(request),
|
||||
this.wxMpService.getWxMpConfigStorage().getPartnerKey());
|
||||
request.setSign(sign);
|
||||
|
||||
@ -258,7 +252,7 @@ public class WxMpPayServiceImpl implements WxMpPayService {
|
||||
request.setMchId(this.wxMpService.getWxMpConfigStorage().getPartnerId());
|
||||
request.setNonceStr(System.currentTimeMillis() + "");
|
||||
|
||||
String sign = this.createSign(xmlBean2Map(request),
|
||||
String sign = this.createSign(this.xmlBean2Map(request),
|
||||
this.wxMpService.getWxMpConfigStorage().getPartnerKey());
|
||||
request.setSign(sign);
|
||||
|
||||
@ -274,16 +268,13 @@ public class WxMpPayServiceImpl implements WxMpPayService {
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
private void checkParameters(WxUnifiedOrderRequest request) {
|
||||
|
||||
checkNotNullParams(request);
|
||||
|
||||
if (!TRADE_TYPES.contains(request.getTradeType())) {
|
||||
throw new IllegalArgumentException("trade_type目前必须为" + TRADE_TYPES + "其中之一");
|
||||
|
||||
if (! ArrayUtils.contains(TRADE_TYPES, request.getTradeType())) {
|
||||
throw new IllegalArgumentException("trade_type目前必须为" + Arrays.toString(TRADE_TYPES) + "其中之一");
|
||||
}
|
||||
|
||||
if ("JSAPI".equals(request.getTradeType()) && request.getOpenid() == null) {
|
||||
@ -368,10 +359,19 @@ public class WxMpPayServiceImpl implements WxMpPayService {
|
||||
|
||||
String url = PAY_BASE_URL + "/mmpaymkttransfers/promotion/transfers";
|
||||
|
||||
try (FileInputStream instream = new FileInputStream(keyFile)) {
|
||||
String mchId = request.getMchId();
|
||||
String responseContent = this.executeRequestWithKeyFile(xstream.toXML(request), url, keyFile, request.getMchId());
|
||||
WxEntPayResult result = (WxEntPayResult) xstream.fromXML(responseContent);
|
||||
if ("FAIL".equals(result.getResultCode())) {
|
||||
throw new WxErrorException(
|
||||
WxError.newBuilder().setErrorMsg(result.getErrCode() + ":" + result.getErrCodeDes()).build());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private String executeRequestWithKeyFile( String requestStr, String url, File keyFile, String mchId) throws WxErrorException {
|
||||
try (FileInputStream inputStream = new FileInputStream(keyFile)) {
|
||||
KeyStore keyStore = KeyStore.getInstance("PKCS12");
|
||||
keyStore.load(instream, mchId.toCharArray());
|
||||
keyStore.load(inputStream, mchId.toCharArray());
|
||||
|
||||
SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, mchId.toCharArray()).build();
|
||||
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null,
|
||||
@ -379,17 +379,10 @@ public class WxMpPayServiceImpl implements WxMpPayService {
|
||||
|
||||
try (CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build()) {
|
||||
HttpPost httpPost = new HttpPost(url);
|
||||
httpPost.setEntity(new StringEntity(new String(xstream.toXML(request).getBytes("UTF-8"), "ISO-8859-1")));
|
||||
httpPost.setEntity(new StringEntity(new String(requestStr.getBytes("UTF-8"), "ISO-8859-1")));
|
||||
|
||||
try (CloseableHttpResponse response = httpclient.execute(httpPost)) {
|
||||
String responseContent = EntityUtils.toString(response.getEntity());
|
||||
WxEntPayResult result = (WxEntPayResult) xstream.fromXML(responseContent);
|
||||
if ("FAIL".equals(result.getResultCode())) {
|
||||
throw new WxErrorException(
|
||||
WxError.newBuilder().setErrorMsg(result.getErrCode() + ":" + result.getErrCodeDes()).build());
|
||||
}
|
||||
|
||||
return result;
|
||||
return EntityUtils.toString(response.getEntity());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -1,7 +1,21 @@
|
||||
package me.chanjar.weixin.mp.api.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import me.chanjar.weixin.common.bean.WxAccessToken;
|
||||
import me.chanjar.weixin.common.bean.WxJsapiSignature;
|
||||
import me.chanjar.weixin.common.bean.result.WxError;
|
||||
import me.chanjar.weixin.common.exception.WxErrorException;
|
||||
import me.chanjar.weixin.common.session.StandardSessionManager;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.common.util.RandomUtils;
|
||||
import me.chanjar.weixin.common.util.crypto.SHA1;
|
||||
import me.chanjar.weixin.common.util.http.*;
|
||||
import me.chanjar.weixin.mp.api.*;
|
||||
import me.chanjar.weixin.mp.bean.*;
|
||||
import me.chanjar.weixin.mp.bean.result.*;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
@ -13,51 +27,7 @@ import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import me.chanjar.weixin.common.bean.WxAccessToken;
|
||||
import me.chanjar.weixin.common.bean.WxJsapiSignature;
|
||||
import me.chanjar.weixin.common.bean.result.WxError;
|
||||
import me.chanjar.weixin.common.exception.WxErrorException;
|
||||
import me.chanjar.weixin.common.session.StandardSessionManager;
|
||||
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||
import me.chanjar.weixin.common.util.RandomUtils;
|
||||
import me.chanjar.weixin.common.util.crypto.SHA1;
|
||||
import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder;
|
||||
import me.chanjar.weixin.common.util.http.DefaultApacheHttpClientBuilder;
|
||||
import me.chanjar.weixin.common.util.http.RequestExecutor;
|
||||
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
|
||||
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
|
||||
import me.chanjar.weixin.common.util.http.URIUtil;
|
||||
import me.chanjar.weixin.mp.api.WxMpCardService;
|
||||
import me.chanjar.weixin.mp.api.WxMpConfigStorage;
|
||||
import me.chanjar.weixin.mp.api.WxMpDataCubeService;
|
||||
import me.chanjar.weixin.mp.api.WxMpKefuService;
|
||||
import me.chanjar.weixin.mp.api.WxMpMaterialService;
|
||||
import me.chanjar.weixin.mp.api.WxMpMenuService;
|
||||
import me.chanjar.weixin.mp.api.WxMpPayService;
|
||||
import me.chanjar.weixin.mp.api.WxMpQrcodeService;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.api.WxMpStoreService;
|
||||
import me.chanjar.weixin.mp.api.WxMpUserBlacklistService;
|
||||
import me.chanjar.weixin.mp.api.WxMpUserService;
|
||||
import me.chanjar.weixin.mp.api.WxMpUserTagService;
|
||||
import me.chanjar.weixin.mp.bean.WxMpIndustry;
|
||||
import me.chanjar.weixin.mp.bean.WxMpMassNews;
|
||||
import me.chanjar.weixin.mp.bean.WxMpMassOpenIdsMessage;
|
||||
import me.chanjar.weixin.mp.bean.WxMpMassPreviewMessage;
|
||||
import me.chanjar.weixin.mp.bean.WxMpMassTagMessage;
|
||||
import me.chanjar.weixin.mp.bean.WxMpMassVideo;
|
||||
import me.chanjar.weixin.mp.bean.WxMpSemanticQuery;
|
||||
import me.chanjar.weixin.mp.bean.WxMpTemplateMessage;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpMassUploadResult;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpUser;
|
||||
import java.io.IOException;
|
||||
|
||||
public class WxMpServiceImpl implements WxMpService {
|
||||
|
||||
@ -477,6 +447,7 @@ public class WxMpServiceImpl implements WxMpService {
|
||||
}
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
this.log.error("\n[URL]: {}\n[PARAMS]: {}\n[EXECEPTION]: {}", uri, data, e.getMessage());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,301 @@
|
||||
package me.chanjar.weixin.mp.bean.pay;
|
||||
|
||||
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||
import me.chanjar.weixin.common.annotation.Required;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 微信支付-申请退款请求参数
|
||||
* 注释中各行每个字段描述对应如下:
|
||||
* <li>字段名
|
||||
* <li>变量名
|
||||
* <li>是否必填
|
||||
* <li>类型
|
||||
* <li>示例值
|
||||
* <li>描述
|
||||
* </pre>
|
||||
*
|
||||
* @author binarywang(https://github.com/binarywang)
|
||||
* Created by Binary Wang on 2016-10-08.
|
||||
*/
|
||||
@XStreamAlias("xml")
|
||||
public class WxMpPayRefundRequest {
|
||||
/**
|
||||
* <pre>
|
||||
* 公众账号ID
|
||||
* appid
|
||||
* 是
|
||||
* String(32)
|
||||
* wx8888888888888888
|
||||
* 微信分配的公众账号ID(企业号corpid即为此appId)
|
||||
* </pre>
|
||||
*/
|
||||
@XStreamAlias("appid")
|
||||
private String appid;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 商户号
|
||||
* mch_id
|
||||
* 是
|
||||
* String(32)
|
||||
* 1900000109
|
||||
* 微信支付分配的商户号
|
||||
* </pre>
|
||||
*/
|
||||
@XStreamAlias("mch_id")
|
||||
private String mchId;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 设备号
|
||||
* device_info
|
||||
* 否
|
||||
* String(32)
|
||||
* 13467007045764
|
||||
* 终端设备号
|
||||
* </pre>
|
||||
*/
|
||||
@XStreamAlias("device_info")
|
||||
private String deviceInfo;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 随机字符串
|
||||
* nonce_str
|
||||
* 是
|
||||
* String(32)
|
||||
* 5K8264ILTKCH16CQ2502SI8ZNMTM67VS
|
||||
* 随机字符串,不长于32位。推荐随机数生成算法
|
||||
* </pre>
|
||||
*/
|
||||
@XStreamAlias("nonce_str")
|
||||
private String nonceStr;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 签名
|
||||
* sign
|
||||
* 是
|
||||
* String(32)
|
||||
* C380BEC2BFD727A4B6845133519F3AD6
|
||||
* 签名,详见签名生成算法
|
||||
* </pre>
|
||||
*/
|
||||
@XStreamAlias("sign")
|
||||
private String sign;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 微信订单号
|
||||
* transaction_id
|
||||
* 跟out_trade_no二选一
|
||||
* String(28)
|
||||
* 1217752501201400000000000000
|
||||
* 微信生成的订单号,在支付通知中有返回
|
||||
* </pre>
|
||||
*/
|
||||
@XStreamAlias("transaction_id")
|
||||
private String transactionId;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 商户订单号
|
||||
* out_trade_no
|
||||
* 跟transaction_id二选一
|
||||
* String(32)
|
||||
* 1217752501201400000000000000
|
||||
* 商户侧传给微信的订单号
|
||||
* </pre>
|
||||
*/
|
||||
@XStreamAlias("out_trade_no")
|
||||
private String outTradeNo;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 商户退款单号
|
||||
* out_refund_no
|
||||
* 是
|
||||
* String(32)
|
||||
* 1217752501201400000000000000
|
||||
* 商户系统内部的退款单号,商户系统内部唯一,同一退款单号多次请求只退一笔
|
||||
* </pre>
|
||||
*/
|
||||
@Required
|
||||
@XStreamAlias("out_refund_no")
|
||||
private String outRefundNo;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 订单金额
|
||||
* total_fee
|
||||
* 是
|
||||
* Int
|
||||
* 100
|
||||
* 订单总金额,单位为分,只能为整数,详见支付金额
|
||||
* </pre>
|
||||
*/
|
||||
@Required
|
||||
@XStreamAlias("total_fee")
|
||||
private Integer totalFee;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 退款金额
|
||||
* refund_fee
|
||||
* 是
|
||||
* Int
|
||||
* 100
|
||||
* 退款总金额,订单总金额,单位为分,只能为整数,详见支付金额
|
||||
* </pre>
|
||||
*/
|
||||
@Required
|
||||
@XStreamAlias("refund_fee")
|
||||
private Integer refundFee;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 货币种类
|
||||
* refund_fee_type
|
||||
* 否
|
||||
* String(8)
|
||||
* CNY
|
||||
* 货币类型,符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
|
||||
* </pre>
|
||||
*/
|
||||
@XStreamAlias("refund_fee_type")
|
||||
private String refundFeeType;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 操作员
|
||||
* op_user_id
|
||||
* 是
|
||||
* String(32)
|
||||
* 1900000109
|
||||
* 操作员帐号, 默认为商户号
|
||||
* </pre>
|
||||
*/
|
||||
//@Required
|
||||
@XStreamAlias("op_user_id")
|
||||
private String opUserId;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 退款资金来源
|
||||
* refund_account
|
||||
* 否
|
||||
* String(30)
|
||||
* REFUND_SOURCE_RECHARGE_FUNDS
|
||||
* 仅针对老资金流商户使用,
|
||||
* <li>REFUND_SOURCE_UNSETTLED_FUNDS---未结算资金退款(默认使用未结算资金退款),
|
||||
* <li>REFUND_SOURCE_RECHARGE_FUNDS---可用余额退款
|
||||
* </pre>
|
||||
*/
|
||||
@XStreamAlias("refund_account")
|
||||
private String refundAccount;
|
||||
|
||||
public String getAppid() {
|
||||
return appid;
|
||||
}
|
||||
|
||||
public void setAppid(String appid) {
|
||||
this.appid = appid;
|
||||
}
|
||||
|
||||
public String getMchId() {
|
||||
return mchId;
|
||||
}
|
||||
|
||||
public void setMchId(String mchId) {
|
||||
this.mchId = mchId;
|
||||
}
|
||||
|
||||
public String getDeviceInfo() {
|
||||
return deviceInfo;
|
||||
}
|
||||
|
||||
public void setDeviceInfo(String deviceInfo) {
|
||||
this.deviceInfo = deviceInfo;
|
||||
}
|
||||
|
||||
public String getNonceStr() {
|
||||
return nonceStr;
|
||||
}
|
||||
|
||||
public void setNonceStr(String nonceStr) {
|
||||
this.nonceStr = nonceStr;
|
||||
}
|
||||
|
||||
public String getSign() {
|
||||
return sign;
|
||||
}
|
||||
|
||||
public void setSign(String sign) {
|
||||
this.sign = sign;
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public void setTransactionId(String transactionId) {
|
||||
this.transactionId = transactionId;
|
||||
}
|
||||
|
||||
public String getOutTradeNo() {
|
||||
return outTradeNo;
|
||||
}
|
||||
|
||||
public void setOutTradeNo(String outTradeNo) {
|
||||
this.outTradeNo = outTradeNo;
|
||||
}
|
||||
|
||||
public String getOutRefundNo() {
|
||||
return outRefundNo;
|
||||
}
|
||||
|
||||
public void setOutRefundNo(String outRefundNo) {
|
||||
this.outRefundNo = outRefundNo;
|
||||
}
|
||||
|
||||
public Integer getTotalFee() {
|
||||
return totalFee;
|
||||
}
|
||||
|
||||
public void setTotalFee(Integer totalFee) {
|
||||
this.totalFee = totalFee;
|
||||
}
|
||||
|
||||
public Integer getRefundFee() {
|
||||
return refundFee;
|
||||
}
|
||||
|
||||
public void setRefundFee(Integer refundFee) {
|
||||
this.refundFee = refundFee;
|
||||
}
|
||||
|
||||
public String getRefundFeeType() {
|
||||
return refundFeeType;
|
||||
}
|
||||
|
||||
public void setRefundFeeType(String refundFeeType) {
|
||||
this.refundFeeType = refundFeeType;
|
||||
}
|
||||
|
||||
public String getOpUserId() {
|
||||
return opUserId;
|
||||
}
|
||||
|
||||
public void setOpUserId(String opUserId) {
|
||||
this.opUserId = opUserId;
|
||||
}
|
||||
|
||||
public String getRefundAccount() {
|
||||
return refundAccount;
|
||||
}
|
||||
|
||||
public void setRefundAccount(String refundAccount) {
|
||||
this.refundAccount = refundAccount;
|
||||
}
|
||||
}
|
@ -1,20 +1,14 @@
|
||||
package me.chanjar.weixin.mp.api.impl;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.testng.annotations.Guice;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import me.chanjar.weixin.common.exception.WxErrorException;
|
||||
import me.chanjar.weixin.mp.api.ApiTestModule;
|
||||
import me.chanjar.weixin.mp.api.WxXmlMpInMemoryConfigStorage;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxEntPayRequest;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxRedpackResult;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxSendRedpackRequest;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxUnifiedOrderRequest;
|
||||
import me.chanjar.weixin.mp.bean.pay.WxUnifiedOrderResult;
|
||||
import me.chanjar.weixin.mp.bean.pay.*;
|
||||
import org.testng.annotations.Guice;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* 测试支付相关接口
|
||||
@ -44,8 +38,14 @@ public class WxMpPayServiceImplTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefundPay() throws Exception {
|
||||
|
||||
public void testRefund() throws Exception {
|
||||
WxMpPayRefundRequest request = new WxMpPayRefundRequest();
|
||||
request.setOutRefundNo("aaa");
|
||||
request.setOutTradeNo("1111");
|
||||
request.setTotalFee(1222);
|
||||
request.setRefundFee(111);
|
||||
WxMpPayRefundResult result = this.wxService.getPayService().refund(request);
|
||||
System.err.println(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Loading…
Reference in New Issue
Block a user