提交 d1a88b76 编写于 作者: 组合缺一's avatar 组合缺一

添加新 demo 模块: IJPay-Demo-Solon

上级 50f9bd54
# IJPay-Demo-Solon
如果该库对你有帮助不妨右上角点点 Star 或者任意赞助支持,我更喜欢你 Fork PR 成为项目贡献者。
IJPay 一直以简洁至上、开箱即用为核心。提供的 IJPay-Demo 也在简化使用流程做到简单修改配置就能用,同时也鼓励用户与 IJPay 「亲密接触」。
如果项目周期短不想投入过多时间和精力在接入上面或者实在为技术感到头疼,那么请考虑一下 IJPay 提供的 VIP 服务。
[IJPay VIP 服务说明](https://javen205.gitee.io/ijpay/guide/donate)
## IJPay-Demo 使用步骤
- 默认使用 `resources/dev` 下的配置,如果没有请复制 `resources/production` 并修改为 `dev`
如果不使用对环境配置可以直接删除直接将配置文件放在 resources 根目录中,并删除 pom.xml 中的 profiles 以及 resources
- 修改 dev 下不同支付方式的属性文件。
1. 属性文件配置详细介绍请参考 [IJPay 文档](https://javen205.gitee.io/ijpay/guide/config/alipay_config.html)
2. 属性文件乱码解决方案 [IDE中显示 *.properties 为中文](https://javen.blog.csdn.net/article/details/77487645)
- 运行 `com.ijpay.demo.DemoApplication` 中的 `main` 方法启动项目
- 前端页面 `com.ijpay.demo.controller.IndexController`
>注意: 如果你有使用银联支付就需要单独添加银联支付的相关依赖。
>为什么要这么做?请参考 [引入依赖 Maven 打包报错](https://gitee.com/javen205/IJPay/issues/I12WOD)
## 全民云计算
[云主机低至2折](https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=b1hkzv2x)
[云服务首年 88](https://cloud.tencent.com/act/cps/redirect?redirect=1048&cps_key=a21676d22e4b11a883893d54e158c1d3&from=console)
## 官方文档
IJPay 更多使用技巧请参考 [IJPay 文档](https://javen205.gitee.io/ijpay)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.noear</groupId>
<artifactId>solon-parent</artifactId>
<version>1.12.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ijpay.demo</groupId>
<artifactId>IJPay-Demo-Solon</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>${project.artifactId}</name>
<description>IJPay Demo for Solon</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<ijapy.version>2.9.3</ijapy.version>
<enjoy.version>4.3</enjoy.version>
<fastjson.version>1.2.75</fastjson.version>
</properties>
<dependencies>
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.noear</groupId>
<artifactId>solon.boot.jlhttp</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- ijpay 需要 servlet 接口 -->
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon.boot.jetty</artifactId>
</dependency>
<dependency>
<groupId>org.noear</groupId>
<artifactId>logback-solon-plugin</artifactId>
</dependency>
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon.view.enjoy</artifactId>
</dependency>
<dependency>
<groupId>com.github.javen205</groupId>
<artifactId>IJPay-WxPay</artifactId>
<version>${ijapy.version}</version>
</dependency>
<dependency>
<groupId>com.github.javen205</groupId>
<artifactId>IJPay-AliPay</artifactId>
<version>${ijapy.version}</version>
</dependency>
<dependency>
<groupId>com.github.javen205</groupId>
<artifactId>IJPay-QQ</artifactId>
<version>${ijapy.version}</version>
</dependency>
<dependency>
<groupId>com.github.javen205</groupId>
<artifactId>IJPay-UnionPay</artifactId>
<version>${ijapy.version}</version>
</dependency>
<dependency>
<groupId>com.github.javen205</groupId>
<artifactId>IJPay-JDPay</artifactId>
<version>${ijapy.version}</version>
</dependency>
<dependency>
<groupId>com.github.javen205</groupId>
<artifactId>IJPay-PayPal</artifactId>
<version>${ijapy.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<compilerArgument>-parameters</compilerArgument>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.noear</groupId>
<artifactId>solon-maven-plugin</artifactId><configuration>
<!-- 如果只有一个 main 函数,则不用配置 -->
<mainClass>com.ijpay.demo.DemoApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
package com.ijpay.demo;
import org.noear.solon.Solon;
/**
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
*
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
*
* <p>IJPay 交流群: 723992875、864988890</p>
*
* <p>Node.js 版: <a href="https://gitee.com/javen205/TNWX">https://gitee.com/javen205/TNWX</a></p>
*
* @author Javen
*/
public class DemoApplication {
public static void main(String[] args) {
Solon.start(DemoApplication.class, args, app -> {
app.cfg().loadAdd("production/alipay.properties");
app.cfg().loadAdd("production/jdpay.properties");
app.cfg().loadAdd("production/paypal.properties");
app.cfg().loadAdd("production/unionpay.properties");
app.cfg().loadAdd("production/wxpay.properties");
app.cfg().loadAdd("production/wxpay_v3.properties");
});
}
}
package com.ijpay.demo.config;
import com.ijpay.demo.interceptor.AliPayInterceptor;
import com.ijpay.demo.interceptor.WxPayInterceptor;
import org.noear.solon.Solon;
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Configuration;
@Configuration
public class IJPayConfigurer {
@Bean
public void addInterceptors() {
Solon.app().before("/aliPay/**", new AliPayInterceptor());
Solon.app().before("/wxPay/**", new WxPayInterceptor());
}
}
package com.ijpay.demo.controller;
import org.noear.solon.annotation.*;
import org.noear.solon.core.handle.ModelAndView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
*
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
*
* <p>IJPay 交流群: 723992875、864988890</p>
*
* <p>Node.js 版: <a href="https://gitee.com/javen205/TNWX">https://gitee.com/javen205/TNWX</a></p>
*
* @author Javen
*/
@Controller
public class IndexController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Mapping("")
public String index() {
logger.error("欢迎使用 IJPay -By Javen 交流群:723992875、864988890");
return "index.html";
}
@Mapping("/toWxH5Pay")
public String toWxH5Pay() {
return "wxh5pay.html";
}
@Mapping("/toWxPay")
public String toWxPay() {
return "wxpay.html";
}
@Mapping("/toWxSuPay")
public String toWxSuPay() {
return "wxsubpay.html";
}
@Mapping(value = "/payInputMoney")
public ModelAndView payInputMoney() {
ModelAndView mav = new ModelAndView("pay_input_money.html");
mav.put("content", "xxx");
return mav;
}
@Mapping(value = "/payKeyBoard")
public String payKeyBoard() {
return "pay_keyboard.html";
}
@Mapping(value = "/paySelectMoney")
public String paySelectMoney() {
return "pay_select_money.html";
}
@Mapping("/success")
public String success() {
return "success.html";
}
@Get
@Mapping("/ss/{id}")
public String pa(@PathVar("id") Integer id) {
return "id>" + id;
}
@Get
@Mapping("/xx")
public String param(@Param("id") Integer xx) {
return "id>" + xx;
}
@Get
@Mapping("/xxx")
public String param2(@Param(value = "id", required = false, defaultValue = "2") Integer xx) {
return "id>" + xx;
}
}
package com.ijpay.demo.controller.alipay;
import com.alipay.api.AlipayApiException;
import com.ijpay.alipay.AliPayApiConfig;
/**
* @author Javen
*/
public abstract class AbstractAliPayApiController {
/**
* 获取支付宝配置
*
* @return {@link AliPayApiConfig} 支付宝配置
* @throws AlipayApiException 支付宝 Api 异常
*/
public abstract AliPayApiConfig getApiConfig() throws AlipayApiException;
}
/**
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
*
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
*
* <p>IJPay 交流群: 723992875、864988890</p>
*
* <p>Node.js 版: <a href="https://gitee.com/javen205/TNWX">https://gitee.com/javen205/TNWX</a></p>
*
* <p> 京东APP支付 </p>
*
* @author Javen
*/
package com.ijpay.demo.controller.jdpay;
public class AppParams {
private String orderId;
private String merchant;
private String appId;
private String signData;
private String extraInfo;
public AppParams() {
}
public AppParams(String orderId, String merchant, String appId, String signData, String extraInfo) {
this.orderId = orderId;
this.merchant = merchant;
this.appId = appId;
this.signData = signData;
this.extraInfo = extraInfo;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public String getMerchant() {
return merchant;
}
public void setMerchant(String merchant) {
this.merchant = merchant;
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getSignData() {
return signData;
}
public void setSignData(String signData) {
this.signData = signData;
}
public String getExtraInfo() {
return extraInfo;
}
public void setExtraInfo(String extraInfo) {
this.extraInfo = extraInfo;
}
}
package com.ijpay.demo.controller.jdpay;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.XmlUtil;
import com.ijpay.demo.entity.JdPayBean;
import com.ijpay.demo.vo.AjaxResult;
import com.ijpay.jdpay.JdPayApi;
import com.ijpay.jdpay.model.*;
import com.ijpay.jdpay.kit.JdPayKit;
import org.noear.solon.annotation.*;
import org.noear.solon.core.handle.ModelAndView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
import java.util.Map;
/**
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
*
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
*
* <p>IJPay 交流群: 723992875、864988890</p>
*
* <p>Node.js 版: <a href="https://gitee.com/javen205/TNWX">https://gitee.com/javen205/TNWX</a></p>
*
* <p>微信支付 Demo</p>
*
* @author Javen
*/
@Controller
@Mapping("/JDPay")
public class JdPayController {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Inject
JdPayBean jdPayBean;
@Mapping("")
public String index() {
log.info("欢迎使用 IJPay 中的京东支付 -By Javen <br/><br> 交流群:723992875、864988890");
log.info(jdPayBean.toString());
return ("欢迎使用 IJPay 中的京东支付 -By Javen <br/><br> 交流群:723992875、864988890");
}
@Get
@Mapping("/test")
public JdPayBean test() {
return jdPayBean;
}
/**
* App 支付
*
* @return
*/
@Get
@Post
@Mapping("/appPay")
public AjaxResult appPay() {
String reqXml = UniOrderModel.builder()
.version("V2.0")
.merchant(jdPayBean.getMchId())
.tradeNum(System.currentTimeMillis() + "")
.tradeName("IJPay 让支付触手可及")
.tradeDesc("https://gitee.com/javen205/IJPay")
.tradeTime(DateUtil.format(new Date(), "yyyyMMddHHmmss"))
.amount("1")
.orderType("1")
.currency("CNY")
.note("备注")
.notifyUrl("http://jdpaydemo.jd.com/asynNotify.htm")
.tradeType("GEN")
.build()
.genReqXml(jdPayBean.getRsaPrivateKey(), jdPayBean.getDesKey(), "V2.0", jdPayBean.getMchId());
// 执行请求
String resultData = JdPayApi.uniOrder(reqXml);
log.info("resultData:" + resultData);
// 解析响应的 xml 数据
Map<String, String> map = JdPayKit.parseResp(resultData);
String code = map.get("code");
String encrypt = map.get("encrypt");
if (!"000000".equals(code)) {
String desc = map.get("desc");
return new AjaxResult().addError(desc);
}
// 解密并验证签名
String decrypt = JdPayKit.decrypt(jdPayBean.getRsaPublicKey(), jdPayBean.getDesKey(), encrypt);
log.info("decrypt>" + decrypt);
// 将 xml 转化为 map
Map<String, Object> toMap = XmlUtil.xmlToMap(decrypt);
log.info("result toMap>" + toMap);
String orderId = (String) toMap.get("orderId");
StringBuilder sb = new StringBuilder();
sb.append("merchant=").append(jdPayBean.getMchId());
sb.append("&orderId=").append(orderId);
sb.append("&key=").append("test");
String sign = JdPayKit.md5LowerCase(sb.toString());
return new AjaxResult().success(new AppParams(orderId, jdPayBean.getMchId(), "123456789",
sign, "123456789"));
}
/**
* PC H5 支付
*
* @param payType
* @return
*/
@Get
@Post
@Mapping("/saveOrder")
public ModelAndView saveOrder(@Param("payType") String payType) {
ModelAndView mv = new ModelAndView();
Map<String, String> map = SaveOrderModel.builder()
.version("V2.0")
.merchant(jdPayBean.getMchId())
.tradeNum(System.currentTimeMillis() + "")
.tradeName("IJPay")
.tradeDesc("IJPay 让支付触手可及")
.tradeTime(DateUtil.format(new Date(), "yyyyMMddHHmmss"))
.amount("10000")
.orderType("0")
.currency("CNY")
.note("IJPay 了解一下")
.callbackUrl("https://jdpay.com")
.notifyUrl("https://jdpay.com")
.userId("IJPay001")
.build()
.createSign(jdPayBean.getRsaPrivateKey(), jdPayBean.getDesKey());
mv.put("map", map);
mv.put("payUrl", payType.equals("pc") ? JdPayApi.PC_SAVE_ORDER_URL : JdPayApi.H5_SAVE_ORDER_URL);
mv.view("jd_pc_h5.html");
return mv;
}
/**
* 商户二维码支付
*/
@Get
@Post
@Mapping("/customerPay")
public ModelAndView customerPay() {
ModelAndView mv = new ModelAndView();
Map<String, String> map = CustomerPayModel.builder()
.version("V2.0")
.merchant(jdPayBean.getMchId())
.tradeNum(System.currentTimeMillis() + "")
.tradeName("IJPay")
.tradeDesc("IJPay 让支付触手可及")
.tradeTime(DateUtil.format(new Date(), "yyyyMMddHHmmss"))
// .amount("1000")
.orderType("0")
.currency("CNY")
.note("IJPay 了解一下")
.notifyUrl("https://jdpay.com")
.build()
.createSign(jdPayBean.getRsaPrivateKey(), jdPayBean.getDesKey());
mv.put("map", map);
mv.put("payUrl", JdPayApi.CUSTOMER_PAY_URL);
mv.view("jd_customer_pay.html");
return mv;
}
@Get
@Post
@Mapping("/queryOrder")
public AjaxResult queryOrder(@Param("tradeType") String tradeType,
@Param("oTradeNum") String oTradeNum,
@Param("tradeNum") String tradeNum) {
String reqXml = QueryOrderModel.builder()
.version("V2.0")
.merchant(jdPayBean.getMchId())
.tradeNum(tradeNum)
.tradeType(tradeType)
.oTradeNum(oTradeNum)
.build()
.genReqXml(jdPayBean.getRsaPrivateKey(), jdPayBean.getDesKey(), "V2.0", jdPayBean.getMchId());
String queryResult = JdPayApi.queryOrder(reqXml);
log.info("queryResult:" + queryResult);
// 解析响应的 xml 数据
Map<String, String> map = JdPayKit.parseResp(queryResult);
String code = map.get("code");
String encrypt = map.get("encrypt");
if (!"000000".equals(code)) {
String desc = map.get("desc");
return new AjaxResult().addError(desc);
}
// 解密并验证签名
String decrypt = JdPayKit.decrypt(jdPayBean.getRsaPublicKey(), jdPayBean.getDesKey(), encrypt);
log.info("decrypt>" + decrypt);
return new AjaxResult().success(decrypt);
}
@Get
@Post
@Mapping("/fkmPay")
public AjaxResult fkmPay(@Param("token") String token,
@Param("amount") String amount) {
String reqXml = FkmModel.builder()
.token(token)
.version("V2.0")
.merchant(jdPayBean.getMchId())
.device("IJPay Dev")
.tradeNum(System.currentTimeMillis() + "")
.tradeName("IJPay 刷卡支付")
.tradeDesc("IJPay 了解一下")
.tradeTime(DateUtil.format(new Date(), "yyyyMMddHHmmss"))
.amount(amount)
.currency("CNY")
.note("备注")
.notifyUrl("https://gitee.com/javen205/IJPay")
.build()
.genReqXml(jdPayBean.getRsaPrivateKey(), jdPayBean.getDesKey(), "V2.0", jdPayBean.getMchId());
String queryResult = JdPayApi.fkmPay(reqXml);
log.info("queryResult:" + queryResult);
// 解析响应的 xml 数据
Map<String, String> map = JdPayKit.parseResp(queryResult);
String code = map.get("code");
String encrypt = map.get("encrypt");
if (!"000000".equals(code)) {
String desc = map.get("desc");
return new AjaxResult().addError(desc);
}
// 解密并验证签名
String decrypt = JdPayKit.decrypt(jdPayBean.getRsaPublicKey(), jdPayBean.getDesKey(), encrypt);
log.info("decrypt>" + decrypt);
return new AjaxResult().success(decrypt);
}
@Get
@Post
@Mapping("/userRelation")
public AjaxResult userRelation(@Param("userId") String userId,
@Param("type") String type) {
String reqXml = UserRelationModel.builder()
.version("V2.0")
.merchant(jdPayBean.getMchId())
.userId(userId)
.build()
.genReqXml(jdPayBean.getRsaPrivateKey(), jdPayBean.getDesKey(), "V2.0", jdPayBean.getMchId());
String result = null;
if ("get".equals(type)) {
result = JdPayApi.getUserRelation(reqXml);
} else {
result = JdPayApi.cancelUserRelation(reqXml);
}
log.info(result);
// 解析响应的 xml 数据
Map<String, String> map = JdPayKit.parseResp(result);
String code = map.get("code");
String encrypt = map.get("encrypt");
if (!"000000".equals(code)) {
String desc = map.get("desc");
return new AjaxResult().addError(desc);
}
// 解密并验证签名
String decrypt = JdPayKit.decrypt(jdPayBean.getRsaPublicKey(), jdPayBean.getDesKey(), encrypt);
log.info("decrypt>" + decrypt);
Map<String, Object> toMap = XmlUtil.xmlToMap(decrypt);
System.out.println(toMap);
return new AjaxResult().success(decrypt);
}
@Get
@Post
@Mapping("/refund")
public AjaxResult refund(@Param("amount") String amount,
@Param("oTradeNum") String oTradeNum,
@Param("tradeNum") String tradeNum) {
System.out.println(Base64.encode(FileUtil.readBytes(jdPayBean.getCertPath())));
String reqXml = RefundModel.builder()
.version("V2.0")
.merchant(jdPayBean.getMchId())
.tradeNum(tradeNum)
.oTradeNum(oTradeNum)
.amount(amount)
.currency("CNY")
.build()
.genReqXml(jdPayBean.getRsaPrivateKey(), jdPayBean.getDesKey(), "V2.0", jdPayBean.getMchId());
String queryResult = JdPayApi.refund(reqXml);
log.info("queryResult:" + queryResult);
// 解析响应的 xml 数据
Map<String, String> map = JdPayKit.parseResp(queryResult);
String code = map.get("code");
String encrypt = map.get("encrypt");
if (!"000000".equals(code)) {
String desc = map.get("desc");
return new AjaxResult().addError(desc);
}
// 解密并验证签名
String decrypt = JdPayKit.decrypt(jdPayBean.getRsaPublicKey(), jdPayBean.getDesKey(), encrypt);
log.info("decrypt>" + decrypt);
return new AjaxResult().success(decrypt);
}
@Get
@Post
@Mapping("/queryBaiTiaoFq")
public AjaxResult queryBaiTiaoFq(@Param("amount") String amount) {
String reqXml = QueryBaiTiaoFqModel.builder()
.version("V2.0")
.merchant(jdPayBean.getMchId())
.tradeNum(System.currentTimeMillis() + "")
.amount(amount)
.build()
.genReqXml(jdPayBean.getRsaPrivateKey(), jdPayBean.getDesKey(), "V2.0", jdPayBean.getMchId());
String baiTiaoResult = JdPayApi.queryBaiTiaoFq(reqXml);
log.info(baiTiaoResult);
// 解析响应的 xml 数据
Map<String, String> map = JdPayKit.parseResp(baiTiaoResult);
String code = map.get("code");
String encrypt = map.get("encrypt");
if (!"000000".equals(code)) {
String desc = map.get("desc");
return new AjaxResult().addError(desc);
}
// 解密并验证签名
String decrypt = JdPayKit.decrypt(jdPayBean.getRsaPublicKey(), jdPayBean.getDesKey(), encrypt);
log.info("decrypt>" + decrypt);
Map<String, Object> toMap = XmlUtil.xmlToMap(decrypt);
System.out.println(toMap);
return new AjaxResult().success(decrypt);
}
}
/**
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
*
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
*
* <p>IJPay 交流群: 723992875、864988890</p>
*
* <p>Node.js 版: <a href="https://gitee.com/javen205/TNWX">https://gitee.com/javen205/TNWX</a></p>
*
* <p>PayPal 支付示例</p>
*
* @author Javen
*/
package com.ijpay.demo.controller.paypal;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ijpay.core.IJPayHttpResponse;
import com.ijpay.core.kit.HttpKit;
import com.ijpay.core.kit.PayKit;
import com.ijpay.demo.entity.PayPalBean;
import com.ijpay.paypal.PayPalApi;
import com.ijpay.paypal.PayPalApiConfig;
import com.ijpay.paypal.PayPalApiConfigKit;
import com.ijpay.paypal.accesstoken.AccessToken;
import com.ijpay.paypal.accesstoken.AccessTokenKit;
import org.noear.solon.annotation.Controller;
import org.noear.solon.annotation.Inject;
import org.noear.solon.annotation.Mapping;
import org.noear.solon.annotation.Param;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@Controller
@Mapping("/payPal")
public class PayPalController {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Inject
PayPalBean payPalBean;
private final static String RETURN_URL = "/payPal/return";
private final static String CANCEL_URL = "/payPal/cancel";
@Mapping("")
public String index() {
log.info("欢迎使用 IJPay 中的 PayPal 支付 -By Javen <br/><br> 交流群:723992875、864988890");
log.info(payPalBean.toString());
return ("欢迎使用 IJPay 中的 PayPal 支付 -By Javen <br/><br> 交流群:723992875、864988890");
}
@Mapping("test")
public PayPalBean test() {
return payPalBean;
}
public PayPalApiConfig getConfig() {
PayPalApiConfig config = new PayPalApiConfig();
config.setClientId(payPalBean.getClientId());
config.setSecret(payPalBean.getSecret());
config.setSandBox(payPalBean.getSandBox());
config.setDomain(payPalBean.getDomain());
PayPalApiConfigKit.setThreadLocalApiConfig(config);
return config;
}
@Mapping("/getAccessToken")
public AccessToken getAccessToken() {
try {
getConfig();
return AccessTokenKit.get();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Mapping("/createOrder")
public void createOrder(HttpServletResponse response) {
try {
PayPalApiConfig config = getConfig();
//参数请求参数文档 https://developer.paypal.com/docs/api/orders/v2/#orders_create
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("intent", "CAPTURE");
ArrayList<Map<String, Object>> list = new ArrayList<>();
Map<String, Object> amount = new HashMap<>();
amount.put("currency_code", "USD");
amount.put("value", "100.00");
Map<String, Object> itemMap = new HashMap<>();
itemMap.put("amount", amount);
list.add(itemMap);
dataMap.put("purchase_units", list);
Map<String, String> applicationContext = new HashMap<>();
applicationContext.put("cancel_url", config.getDomain().concat(CANCEL_URL));
applicationContext.put("return_url", config.getDomain().concat(RETURN_URL));
dataMap.put("application_context", applicationContext);
String data = JSONUtil.toJsonStr(dataMap);
log.info(data);
IJPayHttpResponse resData = PayPalApi.createOrder(config, data);
log.info(resData.toString());
if (resData.getStatus() == 201) {
String resultStr = resData.getBody();
JSONObject jsonObject = JSONUtil.parseObj(resultStr);
JSONArray links = jsonObject.getJSONArray("links");
for (int i = 0; i < links.size(); i++) {
JSONObject item = links.getJSONObject(i);
String rel = item.getStr("rel");
String href = item.getStr("href");
if ("approve".equalsIgnoreCase(rel)) {
response.sendRedirect(href);
break;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Mapping("/updateOrder")
public String updateOrder(@Param("id") String id) {
try {
PayPalApiConfig config = getConfig();
// https://developer.paypal.com/docs/api/orders/v2/#orders_patch
ArrayList<Map<String, Object>> updateData = new ArrayList<>();
Map<String, Object> itemMap = new HashMap<>();
itemMap.put("op", "replace");
itemMap.put("path", "/purchase_units/@reference_id=='default'/amount");
Map<String, Object> amount = new HashMap<>();
amount.put("currency_code", "USD");
amount.put("value", "199.00");
itemMap.put("value", amount);
updateData.add(itemMap);
String data = JSONUtil.toJsonStr(updateData);
log.info(data);
IJPayHttpResponse resData = PayPalApi.updateOrder(config, id, data);
log.info(resData.toString());
if (resData.getStatus() == 204) {
return "success";
}
return "接口请求错误码为:" + resData.getStatus();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Mapping("/queryOrder")
public String queryOrder(@Param("id") String id) {
try {
PayPalApiConfig config = getConfig();
IJPayHttpResponse response = PayPalApi.queryOrder(config, id);
log.info(response.toString());
if (response.getStatus() == 200) {
return response.getBody();
} else {
return "接口请求错误码为:" + response.getStatus();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Mapping("/captureOrder")
public String captureOrder(@Param("id") String id) {
try {
PayPalApiConfig config = getConfig();
IJPayHttpResponse response = PayPalApi.captureOrder(config, id, "");
log.info(response.toString());
if (response.getStatus() == 200 || response.getStatus() == 201) {
return response.getBody();
} else {
return "接口请求错误码为:" + response.getStatus();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Mapping("/captureQuery")
public String captureQuery(@Param("captureId") String captureId) {
try {
PayPalApiConfig config = getConfig();
IJPayHttpResponse response = PayPalApi.captureQuery(config, captureId);
log.info(response.toString());
if (response.getStatus() == 200) {
return response.getBody();
} else {
return "接口请求错误码为:" + response.getStatus();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Mapping("/refund")
public String refund(@Param("id") String id) {
try {
PayPalApiConfig config = getConfig();
System.out.println("id>" + id);
Map<String, Object> map = new HashMap<>();
map.put("invoice_id", PayKit.generateStr());
map.put("note_to_payer", "test product");
Map<String, String> amount = new HashMap<>();
amount.put("value", "1.00");
amount.put("currency_code", "USD");
map.put("amount", amount);
String data = JSONUtil.toJsonStr(map);
log.info("refund data:" + data);
IJPayHttpResponse response = PayPalApi.refund(config, id, data);
log.info(response.toString());
if (response.getStatus() == 201) {
return response.getBody();
} else {
return "接口请求错误码为:" + response.getStatus();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Mapping("/refundQuery")
public String refundQuery(@Param("id") String id) {
try {
PayPalApiConfig config = getConfig();
IJPayHttpResponse response = PayPalApi.refundQuery(config, id);
log.info(response.toString());
if (response.getStatus() == 200) {
return response.getBody();
} else {
return "接口请求错误码为:" + response.getStatus();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Mapping("/return")
public String returnUrl(HttpServletRequest request) {
try {
String token = request.getParameter("token");
String payerId = request.getParameter("PayerID");
log.info("token:" + token);
log.info("payerId:" + payerId);
return token;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Mapping("/cancel")
public String cancelUrl(HttpServletRequest request, HttpServletResponse response) {
String readData = HttpKit.readData(request);
System.out.println(readData);
return readData;
}
}
package com.ijpay.demo.controller.unionpay;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.kit.HttpKit;
import com.ijpay.core.kit.IpKit;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.demo.entity.UnionPayBean;
import com.ijpay.demo.vo.AjaxResult;
import com.ijpay.unionpay.UnionPayApi;
import com.ijpay.unionpay.enums.ServiceEnum;
import com.ijpay.unionpay.model.*;
import com.jfinal.kit.StrKit;
import org.noear.solon.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@Controller
@Mapping("/unionPay")
public class UnionPayController {
private static final Logger logger = LoggerFactory.getLogger(UnionPayController.class);
@Inject
UnionPayBean unionPayBean;
@Mapping("")
public String index() {
logger.info("欢迎使用 IJPay 中的云闪付 - by Javen");
return "欢迎使用 IJPay 中的云闪付 - by Javen";
}
@Mapping("test")
public UnionPayBean test() {
return unionPayBean;
}
/**
* 刷卡支付
*/
@Get
@Post
@Mapping("/microPay")
public AjaxResult microPay(HttpServletRequest request, HttpServletResponse response) {
try {
String authCode = request.getParameter("authCode");
String totalFee = request.getParameter("totalFee");
String ip = IpKit.getRealIp(request);
if (StrKit.isBlank(ip)) {
ip = "127.0.0.1";
}
Map<String, String> params = MicroPayModel.builder()
.service(ServiceEnum.MICRO_PAY.toString())
.mch_id(unionPayBean.getMachId())
.out_trade_no(WxPayKit.generateStr())
.body("IJPay 云闪付测试")
.attach("聚合支付 SDK")
.total_fee(totalFee)
.mch_create_ip(ip)
.auth_code(authCode)
.nonce_str(WxPayKit.generateStr())
.build()
.createSign(unionPayBean.getKey(), SignType.MD5);
logger.info("请求参数:" + JSONUtil.toJsonStr(params));
String xmlResult = UnionPayApi.execution(unionPayBean.getServerUrl(), params);
logger.info("xmlResult:" + xmlResult);
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
String returnCode = result.get("status");
String resultCode = result.get("result_code");
String errMsg = result.get("err_msg");
String errCode = result.get("err_code");
if (!"0".equals(returnCode) || !"0".equals(resultCode)) {
return new AjaxResult().addError("errCode:" + errCode + " errMsg:" + errMsg);
}
return new AjaxResult().success(result);
} catch (Exception e) {
e.printStackTrace();
return new AjaxResult().addError(e.getMessage());
}
}
@Get
@Post
@Mapping("/queryOrder")
public AjaxResult query(@Param(value = "transactionId", required = false) String transactionId,
@Param(value = "outTradeNo", required = false) String outTradeNo) {
try {
if (StrUtil.isEmpty(transactionId) && StrUtil.isEmpty(outTradeNo)) {
return new AjaxResult().addError("out_trade_no transaction_id 不能同时为空");
}
Map<String, String> params = OrderQueryModel.builder()
.service(ServiceEnum.QUERY.toString())
.mch_id(unionPayBean.getMachId())
.out_trade_no(outTradeNo)
.transaction_id(transactionId)
.nonce_str(WxPayKit.generateStr())
.build()
.createSign(unionPayBean.getKey(), SignType.MD5);
String xmlResult = UnionPayApi.execution(unionPayBean.getServerUrl(), params);
logger.info("xmlResult:" + xmlResult);
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
if (!WxPayKit.verifyNotify(result, unionPayBean.getKey(), SignType.MD5)) {
return new AjaxResult().addError("签名异常");
}
return new AjaxResult().success(result);
} catch (Exception e) {
e.printStackTrace();
return new AjaxResult().addError(e.getMessage());
}
}
@Get
@Post
@Mapping("/microPayReverse")
public AjaxResult microPayReverse(@Param("outTradeNo") String outTradeNo) {
try {
Map<String, String> params = OrderQueryModel.builder()
.service(ServiceEnum.MICRO_PAY_REVERSE.toString())
.mch_id(unionPayBean.getMachId())
.out_trade_no(outTradeNo)
.nonce_str(WxPayKit.generateStr())
.build()
.createSign(unionPayBean.getKey(), SignType.MD5);
String xmlResult = UnionPayApi.execution(unionPayBean.getServerUrl(), params);
logger.info("xmlResult:" + xmlResult);
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
return new AjaxResult().success(result);
} catch (Exception e) {
e.printStackTrace();
return new AjaxResult().addError(e.getMessage());
}
}
@Get
@Post
@Mapping("/refund")
public AjaxResult refund(@Param(value = "transactionId", required = false) String transactionId,
@Param(value = "outTradeNo", required = false) String outTradeNo,
@Param(value = "totalFee") String totalFee,
@Param(value = "refundFee") String refundFee) {
try {
if (StrUtil.isEmpty(transactionId) && StrUtil.isEmpty(outTradeNo)) {
return new AjaxResult().addError("out_trade_no transaction_id 不能同时为空");
}
Map<String, String> params = RefundModel.builder()
.service(ServiceEnum.REFUND.toString())
.mch_id(unionPayBean.getMachId())
.out_trade_no(outTradeNo)
.transaction_id(transactionId)
.out_refund_no(transactionId)
.total_fee(totalFee)
.refund_fee(refundFee)
.op_user_id(unionPayBean.getMachId())
.nonce_str(WxPayKit.generateStr())
.build()
.createSign(unionPayBean.getKey(), SignType.MD5);
String xmlResult = UnionPayApi.execution(unionPayBean.getServerUrl(), params);
logger.info("xmlResult:" + xmlResult);
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
return new AjaxResult().success(result);
} catch (Exception e) {
e.printStackTrace();
return new AjaxResult().addError(e.getMessage());
}
}
@Get
@Post
@Mapping("/queryRefund")
public AjaxResult queryRefund(@Param(value = "transactionId", required = false) String transactionId,
@Param(value = "outTradeNo", required = false) String outTradeNo,
@Param(value = "outRefundNo", required = false) String outRefundNo,
@Param(value = "refundId", required = false) String refundId) {
try {
if (StrUtil.isEmpty(transactionId) && StrUtil.isEmpty(outTradeNo)) {
return new AjaxResult().addError("out_trade_no transaction_id 不能同时为空");
}
if (StrUtil.isEmpty(outRefundNo) && StrUtil.isEmpty(refundId)) {
return new AjaxResult().addError("out_refund_no refund_id 不能同时为空");
}
Map<String, String> params = RefundQueryModel.builder()
.service(ServiceEnum.REFUND_QUERY.toString())
.mch_id(unionPayBean.getMachId())
.out_trade_no(outTradeNo)
.transaction_id(transactionId)
.out_refund_no(outRefundNo)
.refund_id(refundId)
.nonce_str(WxPayKit.generateStr())
.build()
.createSign(unionPayBean.getKey(), SignType.MD5);
String xmlResult = UnionPayApi.execution(unionPayBean.getServerUrl(), params);
logger.info("xmlResult:" + xmlResult);
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
return new AjaxResult().success(result);
} catch (Exception e) {
e.printStackTrace();
return new AjaxResult().addError(e.getMessage());
}
}
@Get
@Post
@Mapping("/authCodeToOpenId")
public AjaxResult authCodeToOpenId(@Param(value = "code") String code) {
try {
Map<String, String> params = AuthCodeToOpenIdModel.builder()
.service(ServiceEnum.AUTH_CODE_TO_OPENID.toString())
.mch_id(unionPayBean.getMachId())
.auth_code(code)
.nonce_str(WxPayKit.generateStr())
.build()
.createSign(unionPayBean.getKey(), SignType.MD5);
String xmlResult = UnionPayApi.execution(unionPayBean.getServerUrl(), params);
logger.info("xmlResult:" + xmlResult);
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
return new AjaxResult().success(result);
} catch (Exception e) {
e.printStackTrace();
return new AjaxResult().addError(e.getMessage());
}
}
@Get
@Post
@Mapping("/native")
public AjaxResult nativePay(HttpServletRequest request,
@Param(value = "totalFee", defaultValue = "1") String totalFee) {
try {
String notifyUrl = unionPayBean.getDomain().concat("/unionPay/payNotify");
String ip = IpKit.getRealIp(request);
if (StrKit.isBlank(ip)) {
ip = "127.0.0.1";
}
Map<String, String> params = UnifiedOrderModel.builder()
.service(ServiceEnum.NATIVE.toString())
.mch_id(unionPayBean.getMachId())
.out_trade_no(WxPayKit.generateStr())
.body("IJPay 云闪付-扫码支付")
.attach("聚合支付 SDK")
.total_fee(totalFee)
.mch_create_ip(ip)
.notify_url(notifyUrl)
.nonce_str(WxPayKit.generateStr())
.build()
.createSign(unionPayBean.getKey(), SignType.MD5);
String xmlResult = UnionPayApi.execution(unionPayBean.getServerUrl(), params);
logger.info("xmlResult:" + xmlResult);
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
return new AjaxResult().success(result);
} catch (Exception e) {
e.printStackTrace();
return new AjaxResult().addError(e.getMessage());
}
}
@Get
@Post
@Mapping("/wxJsPay")
public AjaxResult wxJsPay(HttpServletRequest request,
@Param(value = "totalFee", defaultValue = "1") String totalFee,
@Param(value = "openId") String openId) {
try {
String notifyUrl = unionPayBean.getDomain().concat("/unionPay/payNotify");
String ip = IpKit.getRealIp(request);
if (ip.contains(",")) {
ip = ip.split(",")[0];
}
if (StrKit.isBlank(ip)) {
ip = "127.0.0.1";
}
Map<String, String> params = UnifiedOrderModel.builder()
.service(ServiceEnum.WEI_XIN_JS_PAY.toString())
.mch_id(unionPayBean.getMachId())
.is_raw("1")
.out_trade_no(WxPayKit.generateStr())
.body("IJPay 云闪付-微信公众号/小程序支付")
.sub_openid(openId)
// .sub_appid("appId")
.attach("聚合支付 SDK")
.total_fee(totalFee)
.mch_create_ip(ip)
.notify_url(notifyUrl)
.nonce_str(WxPayKit.generateStr())
.build()
.createSign(unionPayBean.getKey(), SignType.MD5);
System.out.println(params);
String xmlResult = UnionPayApi.execution(unionPayBean.getServerUrl(), params);
logger.info("xmlResult:" + xmlResult);
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
return new AjaxResult().success(result);
} catch (Exception e) {
e.printStackTrace();
return new AjaxResult().addError(e.getMessage());
}
}
@Get
@Post
@Mapping("/wxApp")
public AjaxResult wxApp(HttpServletRequest request,
@Param(value = "totalFee", defaultValue = "1") String totalFee,
@Param(value = "appId") String appId) {
try {
String notifyUrl = unionPayBean.getDomain().concat("/unionPay/payNotify");
String ip = IpKit.getRealIp(request);
if (ip.contains(",")) {
ip = ip.split(",")[0];
}
if (StrKit.isBlank(ip)) {
ip = "127.0.0.1";
}
Map<String, String> params = UnifiedOrderModel.builder()
.service(ServiceEnum.WEI_XIN_APP_PAY.toString())
.mch_id(unionPayBean.getMachId())
.appid(appId)
.out_trade_no(WxPayKit.generateStr())
.body("IJPay 云闪付-微信 App 支付")
.attach("聚合支付 SDK")
.total_fee(totalFee)
.mch_create_ip(ip)
.notify_url(notifyUrl)
.nonce_str(WxPayKit.generateStr())
.build()
.createSign(unionPayBean.getKey(), SignType.MD5);
System.out.println(params);
String xmlResult = UnionPayApi.execution(unionPayBean.getServerUrl(), params);
logger.info("xmlResult:" + xmlResult);
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
if (!WxPayKit.verifyNotify(result, unionPayBean.getKey(), SignType.MD5)) {
return new AjaxResult().addError("签名异常");
}
String status = result.get("status");
String resultCode = result.get("result_code");
if (!"0".equals(status) && !"0".equals(resultCode)) {
return new AjaxResult().addError(result.get("err_msg"));
}
return new AjaxResult().success(result.get("pay_info"));
} catch (Exception e) {
e.printStackTrace();
return new AjaxResult().addError(e.getMessage());
}
}
@Get
@Post
@Mapping("/aliJsPay")
public AjaxResult aliJsPay(HttpServletRequest request,
@Param(value = "totalFee", defaultValue = "1") String totalFee,
@Param(value = "buyerLogonId", required = false) String buyerLogonId,
@Param(value = "buyerId", required = false) String buyerId) {
try {
if (StrUtil.isEmpty(buyerLogonId) && StrUtil.isEmpty(buyerId)) {
return new AjaxResult().addError("buyer_logon_id buyer_id 不能同时为空");
}
String notifyUrl = unionPayBean.getDomain().concat("/unionPay/payNotify");
String ip = IpKit.getRealIp(request);
if (ip.contains(",")) {
ip = ip.split(",")[0];
}
if (StrKit.isBlank(ip)) {
ip = "127.0.0.1";
}
Map<String, String> params = UnifiedOrderModel.builder()
.service(ServiceEnum.ALI_PAY_JS_PAY.toString())
.mch_id(unionPayBean.getMachId())
.out_trade_no(WxPayKit.generateStr())
.body("IJPay 云闪付-支付宝服务窗口")
.attach("聚合支付 SDK")
.total_fee(totalFee)
.mch_create_ip(ip)
.notify_url(notifyUrl)
.nonce_str(WxPayKit.generateStr())
.buyer_id(buyerId)
.buyer_logon_id(buyerLogonId)
.build()
.createSign(unionPayBean.getKey(), SignType.MD5);
System.out.println(params);
String xmlResult = UnionPayApi.execution(unionPayBean.getServerUrl(), params);
logger.info("xmlResult:" + xmlResult);
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
return new AjaxResult().success(result);
} catch (Exception e) {
e.printStackTrace();
return new AjaxResult().addError(e.getMessage());
}
}
@Get
@Post
@Mapping("/unionPayUserAuth")
public void unionPayUserAuth(HttpServletResponse response) throws IOException {
String notifyUrl = unionPayBean.getDomain().concat("/unionPay/callBack");
String authUrl = UnionPayApi.buildAuthUrl(notifyUrl);
logger.info("authUrl:" + authUrl);
response.sendRedirect(authUrl);
}
@Get
@Post
@Mapping("/callBack")
public Map<String, String> unionPayCall(HttpServletRequest request) {
Map<String, String> params = new HashMap<>();
Map<String, String[]> requestParams = request.getParameterMap();
for (String name : requestParams.keySet()) {
String[] values = requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
}
params.put(name, valueStr);
}
return params;
}
@Get
@Post
@Mapping("/unionJsPay")
public AjaxResult unionJsPay(HttpServletRequest request,
@Param(value = "totalFee", defaultValue = "1") String totalFee,
@Param(value = "userId", required = false) String userId) {
try {
String notifyUrl = unionPayBean.getDomain().concat("/unionPay/payNotify");
String ip = IpKit.getRealIp(request);
if (ip.contains(",")) {
ip = ip.split(",")[0];
}
if (StrKit.isBlank(ip)) {
ip = "127.0.0.1";
}
Map<String, String> params = UnifiedOrderModel.builder()
.service(ServiceEnum.UNION_JS_PAY.toString())
.mch_id(unionPayBean.getMachId())
.out_trade_no(WxPayKit.generateStr())
.body("IJPay 云闪付-银联JS支付")
.user_id(userId)
.customer_ip(ip)
.attach("聚合支付 SDK")
.total_fee(totalFee)
.mch_create_ip(ip)
.notify_url(notifyUrl)
.nonce_str(WxPayKit.generateStr())
.build()
.createSign(unionPayBean.getKey(), SignType.MD5);
System.out.println(params);
String xmlResult = UnionPayApi.execution(unionPayBean.getServerUrl(), params);
logger.info("xmlResult:" + xmlResult);
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
return new AjaxResult().success(result);
} catch (Exception e) {
e.printStackTrace();
return new AjaxResult().addError(e.getMessage());
}
}
@Get
@Post
@Mapping("/billDownload")
public AjaxResult billDownload(@Param(value = "billDate", defaultValue = "20200325") String billDate,
@Param(value = "billType", defaultValue = "ALL") String billType) {
try {
Map<String, String> params = BillDownloadModel.builder()
.service(ServiceEnum.BILL_MERCHANT.toString())
.bill_date(billDate)
.bill_type(billType)
.mch_id(unionPayBean.getMachId())
.nonce_str(WxPayKit.generateStr())
.build()
.createSign(unionPayBean.getKey(), SignType.MD5);
System.out.println(params);
String result = UnionPayApi.execution(unionPayBean.getServerUrl(), params);
logger.info("result:" + result);
return new AjaxResult().success(result);
} catch (Exception e) {
e.printStackTrace();
return new AjaxResult().addError(e.getMessage());
}
}
/**
* 异步通知
*/
@Get
@Post
@Mapping("/payNotify")
public String payNotify(HttpServletRequest request) {
String xmlMsg = HttpKit.readData(request);
logger.info("支付通知=" + xmlMsg);
Map<String, String> params = WxPayKit.xmlToMap(xmlMsg);
String status = params.get("status");
String returnCode = params.get("result_code");
logger.info(status + " " + returnCode);
if ("0".equals(status) && "0".equals(returnCode)) {
// 注意重复通知的情况,同一订单号可能收到多次通知,请注意一定先判断订单状态
// 注意此处签名方式需与统一下单的签名类型一致
if (WxPayKit.verifyNotify(params, unionPayBean.getKey(), SignType.MD5)) {
logger.info("支付成功....");
// 更新订单信息
// 发送通知等
return "success";
}
}
return "fail";
}
}
package com.ijpay.demo.controller.wxpay;
import com.ijpay.wxpay.WxPayApiConfig;
/**
* @author Javen
*/
public abstract class AbstractWxPayApiController {
/**
* 获取微信支付配置
*
* @return {@link WxPayApiConfig} 微信支付配置
*/
public abstract WxPayApiConfig getApiConfig();
}
/**
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
*
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
*
* <p>IJPay 交流群: 723992875、864988890</p>
*
* <p>Node.js 版: <a href="https://gitee.com/javen205/TNWX">https://gitee.com/javen205/TNWX</a></p>
*
* <p>自定义 Http 客户端</p>
*
* @author Javen
*/
package com.ijpay.demo.custom;
import com.ijpay.core.http.AbstractHttpDelegate;
import java.io.InputStream;
import java.util.Map;
public class OkHttpKit extends AbstractHttpDelegate {
@Override
public String get(String url) {
// 替换具体实现
return super.get(url);
}
@Override
public String post(String url, String data) {
// 替换具体实现
return super.post(url, data);
}
@Override
public String post(String url, String data, String certPath, String certPass) {
// 替换具体实现
return super.post(url, data, certPath, certPass);
}
@Override
public String post(String url, Map<String, Object> paramMap) {
// 替换具体实现
return super.post(url, paramMap);
}
@Override
public String post(String url, String data, InputStream certFile, String certPass) {
// 替换具体实现
return super.post(url, data, certFile, certPass);
}
}
package com.ijpay.demo.entity;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
/**
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
*
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
*
* <p>IJPay 交流群: 723992875、864988890</p>
*
* <p>Node.js 版: <a href="https://gitee.com/javen205/TNWX">https://gitee.com/javen205/TNWX</a></p>
*
* <p>支付宝配置 Bean</p>
*
* @author Javen
*/
@Inject("${alipay}")
@Configuration
public class AliPayBean {
private String appId;
private String privateKey;
private String publicKey;
private String appCertPath;
private String aliPayCertPath;
private String aliPayRootCertPath;
private String serverUrl;
private String domain;
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getPrivateKey() {
return privateKey;
}
public void setPrivateKey(String privateKey) {
this.privateKey = privateKey;
}
public String getPublicKey() {
return publicKey;
}
public void setPublicKey(String publicKey) {
this.publicKey = publicKey;
}
public String getAppCertPath() {
return appCertPath;
}
public void setAppCertPath(String appCertPath) {
this.appCertPath = appCertPath;
}
public String getAliPayCertPath() {
return aliPayCertPath;
}
public void setAliPayCertPath(String aliPayCertPath) {
this.aliPayCertPath = aliPayCertPath;
}
public String getAliPayRootCertPath() {
return aliPayRootCertPath;
}
public void setAliPayRootCertPath(String aliPayRootCertPath) {
this.aliPayRootCertPath = aliPayRootCertPath;
}
public String getServerUrl() {
return serverUrl;
}
public void setServerUrl(String serverUrl) {
this.serverUrl = serverUrl;
}
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
@Override
public String toString() {
return "AliPayBean{" +
"appId='" + appId + '\'' +
", privateKey='" + privateKey + '\'' +
", publicKey='" + publicKey + '\'' +
", appCertPath='" + appCertPath + '\'' +
", aliPayCertPath='" + aliPayCertPath + '\'' +
", aliPayRootCertPath='" + aliPayRootCertPath + '\'' +
", serverUrl='" + serverUrl + '\'' +
", domain='" + domain + '\'' +
'}';
}
}
package com.ijpay.demo.entity;
import com.alibaba.fastjson.JSON;
/**
* @author Javen
*/
public class H5SceneInfo {
private H5 h5_info;
public H5 getH5Info() {
return h5_info;
}
public void setH5Info(H5 h5_info) {
this.h5_info = h5_info;
}
@Override
public String toString() {
return JSON.toJSONString(this);
}
public static class H5 {
private String type;
private String app_name;
private String bundle_id;
private String package_name;
private String wap_url;
private String wap_name;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getApp_name() {
return app_name;
}
public void setApp_name(String app_name) {
this.app_name = app_name;
}
public String getBundle_id() {
return bundle_id;
}
public void setBundle_id(String bundle_id) {
this.bundle_id = bundle_id;
}
public String getPackage_name() {
return package_name;
}
public void setPackage_name(String package_name) {
this.package_name = package_name;
}
public String getWap_url() {
return wap_url;
}
public void setWap_url(String wap_url) {
this.wap_url = wap_url;
}
public String getWap_name() {
return wap_name;
}
public void setWap_name(String wap_name) {
this.wap_name = wap_name;
}
}
}
package com.ijpay.demo.entity;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
/**
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
*
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
*
* <p>IJPay 交流群: 723992875、864988890</p>
*
* <p>Node.js 版: <a href="https://gitee.com/javen205/TNWX">https://gitee.com/javen205/TNWX</a></p>
*
* <p>JD配置 Bean</p>
*
* @author Javen
*/
@Inject("${jdpay}")
@Configuration
public class JdPayBean {
private String mchId;
private String rsaPrivateKey;
private String desKey;
private String rsaPublicKey;
private String certPath;
public String getMchId() {
return mchId;
}
public void setMchId(String mchId) {
this.mchId = mchId;
}
public String getRsaPrivateKey() {
return rsaPrivateKey;
}
public void setRsaPrivateKey(String rsaPrivateKey) {
this.rsaPrivateKey = rsaPrivateKey;
}
public String getDesKey() {
return desKey;
}
public void setDesKey(String desKey) {
this.desKey = desKey;
}
public String getRsaPublicKey() {
return rsaPublicKey;
}
public void setRsaPublicKey(String rsaPublicKey) {
this.rsaPublicKey = rsaPublicKey;
}
public String getCertPath() {
return certPath;
}
public void setCertPath(String certPath) {
this.certPath = certPath;
}
@Override
public String toString() {
return "JdPayBean{" +
"mchId='" + mchId + '\'' +
", rsaPrivateKey='" + rsaPrivateKey + '\'' +
", desKey='" + desKey + '\'' +
", rsaPublicKey='" + rsaPublicKey + '\'' +
", certPath='" + certPath + '\'' +
'}';
}
}
package com.ijpay.demo.entity;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
/**
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
*
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
*
* <p>IJPay 交流群: 723992875、864988890</p>
*
* <p>Node.js 版: <a href="https://gitee.com/javen205/TNWX">https://gitee.com/javen205/TNWX</a></p>
*
* <p>PayPal配置 Bean</p>
*
* @author Javen
*/
@Inject("${paypal}") //"classpath:/paypal.properties",启动时进行加载
@Configuration
public class PayPalBean {
private String clientId;
private String secret;
private Boolean sandBox;
private String domain;
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
public Boolean getSandBox() {
return sandBox;
}
public void setSandBox(Boolean sandBox) {
this.sandBox = sandBox;
}
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
@Override
public String toString() {
return "PayPalBean{" +
"clientId='" + clientId + '\'' +
", secret='" + secret + '\'' +
", sandBox=" + sandBox +
", domain='" + domain + '\'' +
'}';
}
}
package com.ijpay.demo.entity;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
/**
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
*
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
*
* <p>IJPay 交流群: 723992875、864988890</p>
*
* <p>Node.js 版: <a href="https://gitee.com/javen205/TNWX">https://gitee.com/javen205/TNWX</a></p>
*
* <p>云闪付配置 Bean</p>
*
* @author Javen
*/
@Inject("${union}")
@Configuration
public class UnionPayBean {
private String machId;
private String key;
private String serverUrl;
private String domain;
public String getMachId() {
return machId;
}
public void setMachId(String machId) {
this.machId = machId;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getServerUrl() {
return serverUrl;
}
public void setServerUrl(String serverUrl) {
this.serverUrl = serverUrl;
}
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
@Override
public String toString() {
return "UnionPayBean{" +
"machId='" + machId + '\'' +
", key='" + key + '\'' +
", serverUrl='" + serverUrl + '\'' +
", domain='" + domain + '\'' +
'}';
}
}
package com.ijpay.demo.entity;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
/**
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
*
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
*
* <p>IJPay 交流群: 723992875、864988890</p>
*
* <p>Node.js 版: <a href="https://gitee.com/javen205/TNWX">https://gitee.com/javen205/TNWX</a></p>
*
* <p>微信配置 Bean</p>
*
* @author Javen
*/
@Inject("${wxpay}")
@Configuration
public class WxPayBean {
private String appId;
private String appSecret;
private String mchId;
private String partnerKey;
private String certPath;
private String domain;
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getAppSecret() {
return appSecret;
}
public void setAppSecret(String appSecret) {
this.appSecret = appSecret;
}
public String getMchId() {
return mchId;
}
public void setMchId(String mchId) {
this.mchId = mchId;
}
public String getPartnerKey() {
return partnerKey;
}
public void setPartnerKey(String partnerKey) {
this.partnerKey = partnerKey;
}
public String getCertPath() {
return certPath;
}
public void setCertPath(String certPath) {
this.certPath = certPath;
}
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
@Override
public String toString() {
return "WxPayBean [appId=" + appId + ", appSecret=" + appSecret + ", mchId=" + mchId + ", partnerKey="
+ partnerKey + ", certPath=" + certPath + ", domain=" + domain + "]";
}
}
package com.ijpay.demo.entity;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
/**
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
*
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
*
* <p>IJPay 交流群: 723992875、864988890</p>
*
* <p>Node.js 版: <a href="https://gitee.com/javen205/TNWX">https://gitee.com/javen205/TNWX</a></p>
*
* <p>微信配置 Bean</p>
*
* @author Javen
*/
@Inject("${v3}")
@Configuration
public class WxPayV3Bean {
private String appId;
private String keyPath;
private String certPath;
private String certP12Path;
private String platformCertPath;
private String mchId;
private String apiKey;
private String apiKey3;
private String domain;
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getKeyPath() {
return keyPath;
}
public void setKeyPath(String keyPath) {
this.keyPath = keyPath;
}
public String getCertPath() {
return certPath;
}
public void setCertPath(String certPath) {
this.certPath = certPath;
}
public String getCertP12Path() {
return certP12Path;
}
public void setCertP12Path(String certP12Path) {
this.certP12Path = certP12Path;
}
public String getPlatformCertPath() {
return platformCertPath;
}
public void setPlatformCertPath(String platformCertPath) {
this.platformCertPath = platformCertPath;
}
public String getMchId() {
return mchId;
}
public void setMchId(String mchId) {
this.mchId = mchId;
}
public String getApiKey() {
return apiKey;
}
public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}
public String getApiKey3() {
return apiKey3;
}
public void setApiKey3(String apiKey3) {
this.apiKey3 = apiKey3;
}
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
@Override
public String toString() {
return "WxPayV3Bean{" +
"keyPath='" + keyPath + '\'' +
", certPath='" + certPath + '\'' +
", certP12Path='" + certP12Path + '\'' +
", platformCertPath='" + platformCertPath + '\'' +
", mchId='" + mchId + '\'' +
", apiKey='" + apiKey + '\'' +
", apiKey3='" + apiKey3 + '\'' +
", domain='" + domain + '\'' +
'}';
}
}
package com.ijpay.demo.interceptor;
import com.alipay.api.AlipayApiException;
import com.ijpay.alipay.AliPayApiConfigKit;
import com.ijpay.demo.controller.alipay.AbstractAliPayApiController;
import org.noear.solon.core.handle.Action;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Handler;
/**
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
*
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
*
* <p>IJPay 交流群: 723992875、864988890</p>
*
* <p>Node.js 版: <a href="https://gitee.com/javen205/TNWX">https://gitee.com/javen205/TNWX</a></p>
*
* <p>支付宝支付拦截器</p>
*
* @author Javen
*/
public class AliPayInterceptor implements Handler {
@Override
public void handle(Context ctx) throws Throwable {
Object controller = ctx.controller();
if (controller != null) {
if (!(controller instanceof AbstractAliPayApiController)) {
throw new RuntimeException("控制器需要继承 AbstractAliPayApiController");
}
AliPayApiConfigKit.setThreadLocalAliPayApiConfig(((AbstractAliPayApiController) controller).getApiConfig());
//ctx.setHandled(true);
}
}
}
package com.ijpay.demo.interceptor;
import com.ijpay.demo.controller.wxpay.AbstractWxPayApiController;
import com.ijpay.wxpay.WxPayApiConfigKit;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Handler;
/**
* <p>IJPay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
*
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
*
* <p>IJPay 交流群: 723992875、864988890</p>
*
* <p>Node.js 版: <a href="https://gitee.com/javen205/TNWX">https://gitee.com/javen205/TNWX</a></p>
*
* <p>微信支付拦截器</p>
*
* @author Javen
*/
public class WxPayInterceptor implements Handler {
@Override
public void handle(Context ctx) throws Throwable {
Object controller = ctx.controller();
if(controller != null){
if (!(controller instanceof AbstractWxPayApiController)) {
throw new RuntimeException("控制器需要继承 AbstractWxPayApiController");
}
WxPayApiConfigKit.setThreadLocalWxPayApiConfig(((AbstractWxPayApiController) controller).getApiConfig());
//ctx.setHandled(true);
}
}
}
package com.ijpay.demo.kit;
import org.noear.solon.core.handle.Context;
/**
* @author Javen
*/
public class IpKit {
private final static String UNKNOWN = "unknown";
public static String getRealIp(Context ctx) {
return ctx.realIp();
}
public static String getRealIpV2(Context ctx) {
String accessIp = ctx.header("x-forwarded-for");
if (null == accessIp) {
return ctx.ip();
}
return accessIp;
}
}
package com.ijpay.demo.vo;
import java.io.Serializable;
/**
* @author Javen
*/
public class AjaxResult implements Serializable {
private static final long serialVersionUID = 6439646269084700779L;
private int code = 0;
/**
* 返回的中文消息
*/
private String message;
/**
* 成功时携带的数据
*/
private Object data;
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
/**
* 校验错误
*
* @return
*/
public boolean hasError() {
return this.code != 0;
}
/**
* 添加错误,用于alertError
*
* @param message
* @return
*/
public AjaxResult addError(String message) {
this.message = message;
this.code = 1;
return this;
}
/**
* 用于Confirm的错误信息
*
* @param message 描述消息
* @return {AjaxResult}
*/
public AjaxResult addConfirmError(String message) {
this.message = message;
this.code = 2;
return this;
}
/**
* 封装成功时的数据
*
* @param data Object
* @return {AjaxResult}
*/
public AjaxResult success(Object data) {
this.data = data;
this.code = 0;
return this;
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>401</title>
</head>
<body>
<div>错误代码:401</div>
<div>错误描述:未授权</div>
<h3>开源推荐</h3>
<ul>
<li><code>TNWX</code> 微信系开发脚手架:<a href="https://gitee.com/javen205/TNWX">https://gitee.com/javen205/TNWX</a>
</li>
<li><code>IJPay</code> 让支付触手可及:<a href="https://gitee.com/javen205/IJPay">https://gitee.com/javen205/IJPay</a>
</li>
<li>SpringBoot 微服务高效开发 <code>mica</code> 工具集:<a href="https://gitee.com/596392912/mica">https://gitee.com/596392912/mica</a>
</li>
<li><code>Avue</code> 一款基于 vue 可配置化的神奇框架:<a href="https://gitee.com/smallweigit/avue">https://gitee.com/smallweigit/avue</a>
</li>
<li><code>pig</code> 宇宙最强微服务(架构师必备):<a href="https://gitee.com/log4j/pig">https://gitee.com/log4j/pig</a>
</li>
<li><code>SpringBlade</code> 完整的线上解决方案(企业开发必备):<a href="https://gitee.com/smallc/SpringBlade">https://gitee.com/smallc/SpringBlade</a>
</li>
</ul>
</body>
</html>
Unexpected error. File contents could not be restored from local history during undo/redo.
\ No newline at end of file
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册