| @@ -0,0 +1,46 @@ | |||||
| package com.github.binarywang.wxpay.bean.request; | |||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
| /** | |||||
| * <pre> | |||||
| * 转换短链接请求对象类 | |||||
| * Created by Binary Wang on 2017-3-27. | |||||
| * @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a> | |||||
| * </pre> | |||||
| */ | |||||
| @XStreamAlias("xml") | |||||
| public class WxPayShorturlRequest extends WxPayBaseRequest { | |||||
| /** | |||||
| * <pre> | |||||
| * URL链接 | |||||
| * long_url | |||||
| * 是 | |||||
| * String(512) | |||||
| * weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXXX&time_stamp=XXXXXX&nonce_str=XXXXX | |||||
| * 需要转换的URL,签名用原串,传输需URLencode | |||||
| * </pre> | |||||
| */ | |||||
| @XStreamAlias("long_url") | |||||
| private String longUrl; | |||||
| public String getLongUrl() { | |||||
| return this.longUrl; | |||||
| } | |||||
| public void setLongUrl(String longUrl) { | |||||
| this.longUrl = longUrl; | |||||
| } | |||||
| public WxPayShorturlRequest() { | |||||
| } | |||||
| public WxPayShorturlRequest(String longUrl) { | |||||
| this.longUrl = longUrl; | |||||
| } | |||||
| @Override | |||||
| protected void checkConstraints() { | |||||
| //do nothing | |||||
| } | |||||
| } | |||||
| @@ -9,6 +9,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
| * @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a> | * @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a> | ||||
| * </pre> | * </pre> | ||||
| */ | */ | ||||
| @XStreamAlias("xml") | |||||
| public class WxPayOrderReverseResult extends WxPayBaseResult { | public class WxPayOrderReverseResult extends WxPayBaseResult { | ||||
| /** | /** | ||||
| @@ -0,0 +1,34 @@ | |||||
| package com.github.binarywang.wxpay.bean.result; | |||||
| import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
| /** | |||||
| * <pre> | |||||
| * 转换短链接结果对象类 | |||||
| * Created by Binary Wang on 2017-3-27. | |||||
| * @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a> | |||||
| * </pre> | |||||
| */ | |||||
| @XStreamAlias("xml") | |||||
| public class WxPayShorturlResult extends WxPayBaseResult { | |||||
| /** | |||||
| * <pre> | |||||
| * URL链接 | |||||
| * short_url | |||||
| * 是 | |||||
| * String(64) | |||||
| * weixin://wxpay/s/XXXXXX | |||||
| * 转换后的URL | |||||
| * </pre> | |||||
| */ | |||||
| @XStreamAlias("short_url") | |||||
| private String shortUrl; | |||||
| public String getShortUrl() { | |||||
| return this.shortUrl; | |||||
| } | |||||
| public void setShortUrl(String shortUrl) { | |||||
| this.shortUrl = shortUrl; | |||||
| } | |||||
| } | |||||
| @@ -267,12 +267,39 @@ public interface WxPayService { | |||||
| * 撤销订单API | * 撤销订单API | ||||
| * 文档地址:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_11&index=3 | * 文档地址:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_11&index=3 | ||||
| * 应用场景: | * 应用场景: | ||||
| * 支付交易返回失败或支付系统超时,调用该接口撤销交易。如果此订单用户支付失败,微信支付系统会将此订单关闭;如果用户支付成功,微信支付系统会将此订单资金退还给用户。 | |||||
| * 注意:7天以内的交易单可调用撤销,其他正常支付的单如需实现相同功能请调用申请退款API。提交支付交易后调用【查询订单API】,没有明确的支付结果再调用【撤销订单API】。 | |||||
| * 支付交易返回失败或支付系统超时,调用该接口撤销交易。如果此订单用户支付失败,微信支付系统会将此订单关闭; | |||||
| * 如果用户支付成功,微信支付系统会将此订单资金退还给用户。 | |||||
| * 注意:7天以内的交易单可调用撤销,其他正常支付的单如需实现相同功能请调用申请退款API。 | |||||
| * 提交支付交易后调用【查询订单API】,没有明确的支付结果再调用【撤销订单API】。 | |||||
| * 调用支付接口后请勿立即调用撤销订单API,建议支付后至少15s后再调用撤销订单接口。 | * 调用支付接口后请勿立即调用撤销订单API,建议支付后至少15s后再调用撤销订单接口。 | ||||
| * 接口链接 :https://api.mch.weixin.qq.com/secapi/pay/reverse | * 接口链接 :https://api.mch.weixin.qq.com/secapi/pay/reverse | ||||
| * 是否需要证书:请求需要双向证书。 | * 是否需要证书:请求需要双向证书。 | ||||
| *</pre> | |||||
| * </pre> | |||||
| */ | */ | ||||
| WxPayOrderReverseResult reverseOrder(WxPayOrderReverseRequest request) throws WxErrorException; | WxPayOrderReverseResult reverseOrder(WxPayOrderReverseRequest request) throws WxErrorException; | ||||
| /** | |||||
| * <pre> | |||||
| * 转换短链接 | |||||
| * 应用场景: | |||||
| * 该接口主要用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),减小二维码数据量,提升扫描速度和精确度。 | |||||
| * 接口地址:https://api.mch.weixin.qq.com/tools/shorturl | |||||
| * 是否需要证书:否 | |||||
| * </pre> | |||||
| * @param request 请求对象 | |||||
| */ | |||||
| String shorturl(WxPayShorturlRequest request) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 转换短链接 | |||||
| * 应用场景: | |||||
| * 该接口主要用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),减小二维码数据量,提升扫描速度和精确度。 | |||||
| * 接口地址:https://api.mch.weixin.qq.com/tools/shorturl | |||||
| * 是否需要证书:否 | |||||
| * </pre> | |||||
| * @param longUrl 需要被压缩的网址 | |||||
| */ | |||||
| String shorturl(String longUrl) throws WxErrorException; | |||||
| } | } | ||||
| @@ -328,6 +328,22 @@ public class WxPayServiceImpl implements WxPayService { | |||||
| return result; | return result; | ||||
| } | } | ||||
| @Override | |||||
| public String shorturl(WxPayShorturlRequest request) throws WxErrorException { | |||||
| request.checkAndSign(this.getConfig()); | |||||
| String url = this.getPayBaseUrl() + "/tools/shorturl"; | |||||
| String responseContent = this.post(url, request.toXML()); | |||||
| WxPayShorturlResult result = WxPayBaseResult.fromXML(responseContent, WxPayShorturlResult.class); | |||||
| result.checkResult(this); | |||||
| return result.getShortUrl(); | |||||
| } | |||||
| @Override | |||||
| public String shorturl(String longUrl) throws WxErrorException { | |||||
| return this.shorturl(new WxPayShorturlRequest(longUrl)); | |||||
| } | |||||
| private String post(String url, String xmlParam) { | private String post(String url, String xmlParam) { | ||||
| String requestString = xmlParam; | String requestString = xmlParam; | ||||
| try { | try { | ||||
| @@ -28,10 +28,11 @@ import static org.testng.Assert.*; | |||||
| @Test | @Test | ||||
| @Guice(modules = ApiTestModule.class) | @Guice(modules = ApiTestModule.class) | ||||
| public class WxPayServiceImplTest { | public class WxPayServiceImplTest { | ||||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | private final Logger logger = LoggerFactory.getLogger(this.getClass()); | ||||
| @Inject | @Inject | ||||
| protected WxPayService payService; | |||||
| private WxPayService payService; | |||||
| @Test | @Test | ||||
| public void testGetPayInfo() throws Exception { | public void testGetPayInfo() throws Exception { | ||||
| @@ -221,10 +222,12 @@ public class WxPayServiceImplTest { | |||||
| @Test | @Test | ||||
| public void testGetConfig() throws Exception { | public void testGetConfig() throws Exception { | ||||
| // no need to test | |||||
| } | } | ||||
| @Test | @Test | ||||
| public void testSetConfig() throws Exception { | public void testSetConfig() throws Exception { | ||||
| // no need to test | |||||
| } | } | ||||
| @Test | @Test | ||||
| @@ -236,4 +239,16 @@ public class WxPayServiceImplTest { | |||||
| this.logger.info(result.toString()); | this.logger.info(result.toString()); | ||||
| } | } | ||||
| @Test | |||||
| public void testShorturl() throws Exception { | |||||
| String longUrl = "weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXXX&time_stamp=XXXXXX&nonce_str=XXXXX"; | |||||
| String result = this.payService.shorturl(new WxPayShorturlRequest(longUrl)); | |||||
| assertNotNull(result); | |||||
| this.logger.info(result.toString()); | |||||
| result = this.payService.shorturl(longUrl); | |||||
| assertNotNull(result); | |||||
| this.logger.info(result.toString()); | |||||
| } | |||||
| } | } | ||||