IJPay:https://javen205.gitee.io/ijpay/guide/
支付宝sdk:https://opendocs.alipay.com/open/270/106291
内网穿透工具:https://natapp.cn/
沙箱以及证书生成可以参考【使用工具】中的网址,以下是默认配置好的情况
pom.xml
<properties>
<!--第三方支付依赖版本-->
<ijapy.version>2.8.0</ijapy.version>
</properties>
<dependencies>
<!--支付相关-->
<dependency>
<groupId>com.github.javen205</groupId>
<artifactId>IJPay-AliPay</artifactId>
<version>${ijapy.version}</version>
</dependency>
<!-- 核心包,必须引入! -->
<dependency>
<groupId>com.github.javen205</groupId>
<artifactId>IJPay-Core</artifactId>
<version>${ijapy.version}</version>
</dependency>
</dependencies>
PayWayInfoEntity
import lombok.*;
import lombok.experimental.Accessors;
import lombok.experimental.SuperBuilder;
import java.io.Serializable;
/**
* @author hollow
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString(callSuper = true)
@SuperBuilder
@Accessors(chain = true)
public class PayWayInfoEntity implements Serializable {
private static final long serialVersionUID = 493664191798244071L;
/**
* 应用编号
*/
private String appId;
/**
* 应用私钥
*/
private String privateKey;
/**
* 支付宝公钥,
* 通过应用公钥上传到支付宝开放平台换取支付宝公钥
* (如果是证书模式,公钥与私钥在CSR目录)。
*/
private String publicKey;
/**
* 应用公钥证书 (证书模式必须)
*/
private String appCertPath;
/**
* 支付宝公钥证书 (证书模式必须)
*/
private String aliPayCertPath;
/**
* 支付宝根证书 (证书模式必须)
*/
private String aliPayRootCertPath;
/**
* 支付宝支付网关
*/
private String serverUrl;
/**
* 外网访问项目的域名,支付通知中会使用
*/
private String domain;
/**
* 支付描述信息
*/
private String body;
}
证书模式必须代表着你用公钥模式不必须~,这里只讲公钥模式
RpcTcPayService
public interface RpcTcPayService {
/**
* app支付
* @param payParams
* @return
*/
String appPay(PayParams payParams);
}
RpcTcPayServiceImpl
@Slf4j
@Component
@Service(timeout = 10000, interfaceClass = RpcTcPayService.class, filter = {"authFilter", "requestFilter"})
public class RpcTcPayServiceImpl implements RpcTcPayService {
@Override
public String appPay(PayParams payParams) {
String price = payParams.getPayPrice();
String orderNo = payParams.getOrderNo();
String domain = payParams.getCallbackUrl();
String body = payParams.getBody();
String payWayId = payParams.getPayWayId();
//暂时制作假数据 如果是多数据源可从数据库中获取
PayWayInfoEntity payWayInfoEntity = new PayWayInfoEntity();
payWayInfoEntity.setAppId("id")
.setPrivateKey("私钥")
.setPublicKey("公钥")
.setAppCertPath("应用公钥证书")
.setAliPayCertPath("")
.setAliPayRootCertPath("")
.setServerUrl("沙箱/正式url")
.setDomain(domain)
.setBody(body);
this.setConfig(payWayInfoEntity);
try {
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setBody(payWayInfoEntity.getBody());
model.setSubject(payWayInfoEntity.getBody());
// 商户网站 唯一 订单号0
model.setOutTradeNo(orderNo);
// 该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:5m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。 该参数数值不接受小数点, 如 1.5h,可转换为 90m
model.setTimeoutExpress("30m");
// 订单总金额,单位为元,精确到小数点后两位
model.setTotalAmount(price);
String orderInfo = AliPayApi.appPayToResponse(model, payWayInfoEntity.getDomain()).getBody();
log.info("支付宝支付参数 {}", orderInfo);
return orderInfo;
} catch (AlipayApiException e) {
e.printStackTrace();
}
return "失败";
}
/**
* 设置配置
*
* @param payWayInfoEntity
*/
private void setConfig(PayWayInfoEntity payWayInfoEntity) {
AliPayApiConfig aliPayApiConfig;
try {
aliPayApiConfig = AliPayApiConfigKit.getApiConfig(payWayInfoEntity.getAppId());
} catch (Exception e) {
aliPayApiConfig = AliPayApiConfig.builder()
.setAppId(payWayInfoEntity.getAppId())
.setAliPayPublicKey(payWayInfoEntity.getPublicKey())
.setAppCertPath(payWayInfoEntity.getAppCertPath())
.setAliPayCertPath(payWayInfoEntity.getAliPayCertPath())
.setAliPayRootCertPath(payWayInfoEntity.getAliPayRootCertPath())
.setCharset(CharsetTypeEnums.UTF_8.getType())
.setPrivateKey(payWayInfoEntity.getPrivateKey())
.setServiceUrl(payWayInfoEntity.getServerUrl())
.setSignType(SignTypeEnums.RSA2.getType())
// 普通公钥方式
.build();
}
AliPayApiConfigKit.setThreadLocalAliPayApiConfig(aliPayApiConfig);
}
PayParams
这个传入参数类,可以根据传出的值自行定义,不一定要有,看代码中具体使用到的地方
这里给贴出来
PayParams
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 支付相关
*
* @author hollow
*/
@Data
@Accessors(chain = true)
public class PayParams {
/**
* order only id
*/
private String orderNo;
/**
* receive pay money
*/
private String payPrice;
/**
* use pay type
*/
private String payWayId;
/**
* 回调数据
*/
private String callbackUrl;
/**
* 主体信息
*/
private String body;
}
@Test
void appPay() {
String randomTradeNo = StringUtils.getOutTradeNo();
PayParams payParams = new PayParams();
payParams.setPayPrice("520")
.setOrderNo(randomTradeNo)
.setCallbackUrl("")
.setBody("hollow test");
String str = rpcTcPayService.appPay(payParams);
System.out.println(str);
}
这里的工具类大家可以自己写一下,就是生成随即订单号(唯一)
测试完毕后会返回一段String,将这个传给前端就完成了支付。关于之后的验签操作大家可以多参考IJPay的demo
gitee地址:https://gitee.com/javen205/IJPay/tree/master/IJPay-Demo-SpringBoot