diff --git a/docs/sql/init.sql b/docs/sql/init.sql index dd2a769..69710c5 100644 --- a/docs/sql/init.sql +++ b/docs/sql/init.sql @@ -710,6 +710,7 @@ INSERT INTO t_pay_way (way_code, way_name) VALUES ('ALI_WAP', '支付宝WAP'); INSERT INTO t_pay_way (way_code, way_name) VALUES ('ALI_PC', '支付宝PC网站'); INSERT INTO t_pay_way (way_code, way_name) VALUES ('ALI_QR', '支付宝二维码'); INSERT INTO t_pay_way (way_code, way_name) VALUES ('ALI_LITE', '支付宝小程序'); +INSERT INTO t_pay_way (way_code, way_name) VALUES ('ALI_OC', '支付宝订单码'); INSERT INTO t_pay_way (way_code, way_name) VALUES ('WX_BAR', '微信条码'); INSERT INTO t_pay_way (way_code, way_name) VALUES ('WX_JSAPI', '微信公众号'); @@ -731,13 +732,14 @@ INSERT INTO t_pay_way (way_code, way_name) VALUES ('UP_B2B', '银联企业网银 INSERT INTO t_pay_way (way_code, way_name) VALUES ('UP_PC', '银联网关支付'); INSERT INTO t_pay_way (way_code, way_name) VALUES ('UP_JSAPI', '银联Js支付'); + -- 初始化支付接口定义 INSERT INTO t_pay_interface_define (if_code, if_name, is_mch_mode, is_isv_mode, config_page_type, isv_params, isvsub_mch_params, normal_mch_params, way_codes, icon, bg_color, state, remark) VALUES ('alipay', '支付宝官方', 1, 1, 2, '[{"name":"sandbox","desc":"环境配置","type":"radio","verify":"","values":"1,0","titles":"沙箱环境,生产环境","verify":"required"},{"name":"pid","desc":"合作伙伴身份(PID)","type":"text","verify":"required"},{"name":"appId","desc":"应用App ID","type":"text","verify":"required"},{"name":"privateKey", "desc":"应用私钥", "type": "textarea","verify":"required","star":"1"},{"name":"alipayPublicKey", "desc":"支付宝公钥(不使用证书时必填)", "type": "textarea","star":"1"},{"name":"signType","desc":"接口签名方式(推荐使用RSA2)","type":"radio","verify":"","values":"RSA,RSA2","titles":"RSA,RSA2","verify":"required"},{"name":"useCert","desc":"公钥证书","type":"radio","verify":"","values":"1,0","titles":"使用证书(请使用RSA2私钥),不使用证书"},{"name":"appPublicCert","desc":"应用公钥证书(.crt格式)","type":"file","verify":""},{"name":"alipayPublicCert","desc":"支付宝公钥证书(.crt格式)","type":"file","verify":""},{"name":"alipayRootCert","desc":"支付宝根证书(.crt格式)","type":"file","verify":""}]', '[{"name":"appAuthToken", "desc":"子商户app_auth_token", "type": "text","readonly":"readonly"},{"name":"refreshToken", "desc":"子商户刷新token", "type": "hidden","readonly":"readonly"},{"name":"expireTimestamp", "desc":"authToken有效期(13位时间戳)", "type": "hidden","readonly":"readonly"}]', '[{"name":"sandbox","desc":"环境配置","type":"radio","verify":"","values":"1,0","titles":"沙箱环境,生产环境","verify":"required"},{"name":"appId","desc":"应用App ID","type":"text","verify":"required"},{"name":"privateKey", "desc":"应用私钥", "type": "textarea","verify":"required","star":"1"},{"name":"alipayPublicKey", "desc":"支付宝公钥(不使用证书时必填)", "type": "textarea","star":"1"},{"name":"signType","desc":"接口签名方式(推荐使用RSA2)","type":"radio","verify":"","values":"RSA,RSA2","titles":"RSA,RSA2","verify":"required"},{"name":"useCert","desc":"公钥证书","type":"radio","verify":"","values":"1,0","titles":"使用证书(请使用RSA2私钥),不使用证书"},{"name":"appPublicCert","desc":"应用公钥证书(.crt格式)","type":"file","verify":""},{"name":"alipayPublicCert","desc":"支付宝公钥证书(.crt格式)","type":"file","verify":""},{"name":"alipayRootCert","desc":"支付宝根证书(.crt格式)","type":"file","verify":""}]', - '[{"wayCode": "ALI_JSAPI"}, {"wayCode": "ALI_WAP"}, {"wayCode": "ALI_BAR"}, {"wayCode": "ALI_APP"}, {"wayCode": "ALI_PC"}, {"wayCode": "ALI_QR"}]', + '[{"wayCode": "ALI_JSAPI"}, {"wayCode": "ALI_WAP"}, {"wayCode": "ALI_BAR"}, {"wayCode": "ALI_APP"}, {"wayCode": "ALI_PC"}, {"wayCode": "ALI_QR"}, {"wayCode": "ALI_OC"}]', 'http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/alipay.png', '#1779FF', 1, '支付宝官方通道'); INSERT INTO t_pay_interface_define (if_code, if_name, is_mch_mode, is_isv_mode, config_page_type, isv_params, isvsub_mch_params, normal_mch_params, way_codes, icon, bg_color, state, remark) diff --git a/docs/sql/patch.sql b/docs/sql/patch.sql index cd53c93..1c3ccd7 100644 --- a/docs/sql/patch.sql +++ b/docs/sql/patch.sql @@ -283,3 +283,14 @@ INSERT INTO t_pay_way (way_code, way_name) VALUES ('UP_JSAPI', '银联Js支付') -- 分账状态新增: 已受理 alter table t_pay_order_division_record modify column `state` TINYINT(6) NOT NULL COMMENT '状态: 0-待分账 1-分账成功(明确成功), 2-分账失败(明确失败), 3-分账已受理(上游受理)'; +## +-- 支付方式新增支付宝订单码 +INSERT INTO t_pay_way (way_code, way_name) VALUES ('ALI_OC', '支付宝订单码'); +DELETE FROM t_pay_interface_define WHERE if_code = 'alipay'; +INSERT INTO t_pay_interface_define (if_code, if_name, is_mch_mode, is_isv_mode, config_page_type, isv_params, isvsub_mch_params, normal_mch_params, way_codes, icon, bg_color, state, remark) +VALUES ('alipay', '支付宝官方', 1, 1, 1, + '[{"name":"sandbox","desc":"环境配置","type":"radio","verify":"","values":"1,0","titles":"沙箱环境,生产环境","verify":"required"},{"name":"pid","desc":"合作伙伴身份(PID)","type":"text","verify":"required"},{"name":"appId","desc":"应用App ID","type":"text","verify":"required"},{"name":"privateKey", "desc":"应用私钥", "type": "textarea","verify":"required","star":"1"},{"name":"alipayPublicKey", "desc":"支付宝公钥(不使用证书时必填)", "type": "textarea","star":"1"},{"name":"signType","desc":"接口签名方式(推荐使用RSA2)","type":"radio","verify":"","values":"RSA,RSA2","titles":"RSA,RSA2","verify":"required"},{"name":"useCert","desc":"公钥证书","type":"radio","verify":"","values":"1,0","titles":"使用证书(请使用RSA2私钥),不使用证书"},{"name":"appPublicCert","desc":"应用公钥证书(.crt格式)","type":"file","verify":""},{"name":"alipayPublicCert","desc":"支付宝公钥证书(.crt格式)","type":"file","verify":""},{"name":"alipayRootCert","desc":"支付宝根证书(.crt格式)","type":"file","verify":""}]', + '[{"name":"appAuthToken", "desc":"子商户app_auth_token", "type": "text","readonly":"readonly"},{"name":"refreshToken", "desc":"子商户刷新token", "type": "hidden","readonly":"readonly"},{"name":"expireTimestamp", "desc":"authToken有效期(13位时间戳)", "type": "hidden","readonly":"readonly"}]', + '[{"name":"sandbox","desc":"环境配置","type":"radio","verify":"","values":"1,0","titles":"沙箱环境,生产环境","verify":"required"},{"name":"appId","desc":"应用App ID","type":"text","verify":"required"},{"name":"privateKey", "desc":"应用私钥", "type": "textarea","verify":"required","star":"1"},{"name":"alipayPublicKey", "desc":"支付宝公钥(不使用证书时必填)", "type": "textarea","star":"1"},{"name":"signType","desc":"接口签名方式(推荐使用RSA2)","type":"radio","verify":"","values":"RSA,RSA2","titles":"RSA,RSA2","verify":"required"},{"name":"useCert","desc":"公钥证书","type":"radio","verify":"","values":"1,0","titles":"使用证书(请使用RSA2私钥),不使用证书"},{"name":"appPublicCert","desc":"应用公钥证书(.crt格式)","type":"file","verify":""},{"name":"alipayPublicCert","desc":"支付宝公钥证书(.crt格式)","type":"file","verify":""},{"name":"alipayRootCert","desc":"支付宝根证书(.crt格式)","type":"file","verify":""}]', + '[{"wayCode": "ALI_JSAPI"}, {"wayCode": "ALI_WAP"}, {"wayCode": "ALI_BAR"}, {"wayCode": "ALI_APP"}, {"wayCode": "ALI_PC"}, {"wayCode": "ALI_QR"}, {"wayCode": "ALI_OC"}]', + 'http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/alipay.png', '#1779FF', 1, '支付宝官方通道'); \ No newline at end of file diff --git a/jeepay-core/src/main/java/com/jeequan/jeepay/core/constants/CS.java b/jeepay-core/src/main/java/com/jeequan/jeepay/core/constants/CS.java index 92f88c9..b5a5386 100644 --- a/jeepay-core/src/main/java/com/jeequan/jeepay/core/constants/CS.java +++ b/jeepay-core/src/main/java/com/jeequan/jeepay/core/constants/CS.java @@ -165,6 +165,7 @@ public class CS { String ALI_PC = "ALI_PC"; //支付宝 电脑网站支付 String ALI_WAP = "ALI_WAP"; //支付宝 wap支付 String ALI_QR = "ALI_QR"; //支付宝 二维码付款 + String ALI_OC = "ALI_OC"; //支付宝 订单码支付 String YSF_BAR = "YSF_BAR"; //云闪付条码支付 String YSF_JSAPI = "YSF_JSAPI"; //云闪付服务窗支付 diff --git a/jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/alipay/payway/AliOc.java b/jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/alipay/payway/AliOc.java new file mode 100644 index 0000000..fa3cadb --- /dev/null +++ b/jeepay-payment/src/main/java/com/jeequan/jeepay/pay/channel/alipay/payway/AliOc.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com). + *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *
+ * http://www.gnu.org/licenses/lgpl.html + *
+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jeequan.jeepay.pay.channel.alipay.payway; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import com.alipay.api.domain.AlipayTradePrecreateModel; +import com.alipay.api.request.AlipayTradePrecreateRequest; +import com.alipay.api.response.AlipayTradePrecreateResponse; +import com.jeequan.jeepay.core.constants.CS; +import com.jeequan.jeepay.core.entity.PayOrder; +import com.jeequan.jeepay.core.utils.AmountUtil; +import com.jeequan.jeepay.pay.channel.alipay.AlipayKit; +import com.jeequan.jeepay.pay.channel.alipay.AlipayPaymentService; +import com.jeequan.jeepay.pay.model.MchAppConfigContext; +import com.jeequan.jeepay.pay.rqrs.AbstractRS; +import com.jeequan.jeepay.pay.rqrs.msg.ChannelRetMsg; +import com.jeequan.jeepay.pay.rqrs.payorder.UnifiedOrderRQ; +import com.jeequan.jeepay.pay.rqrs.payorder.payway.AliOcOrderRQ; +import com.jeequan.jeepay.pay.rqrs.payorder.payway.AliOcOrderRS; +import com.jeequan.jeepay.pay.util.ApiResBuilder; +import org.springframework.stereotype.Service; + +/** + * 支付宝 订单码支付 + * + * @author zhangheming + * @site https://www.jeequan.com + * @date 2024/6/12 17:20 + */ +@Service("alipayPaymentByAliOcService") +public class AliOc extends AlipayPaymentService { + + @Override + public String preCheck(UnifiedOrderRQ rq, PayOrder payOrder) { + return null; + } + + @Override + public AbstractRS pay(UnifiedOrderRQ rq, PayOrder payOrder, MchAppConfigContext mchAppConfigContext) { + + AliOcOrderRQ ocOrderRQ = (AliOcOrderRQ) rq; + // 构造请求参数以调用接口 + AlipayTradePrecreateRequest req = new AlipayTradePrecreateRequest(); + AlipayTradePrecreateModel model = new AlipayTradePrecreateModel(); + //设置商户订单号 + model.setOutTradeNo(payOrder.getPayOrderId()); + //设置订单总金额 + model.setTotalAmount(AmountUtil.convertCent2Dollar(payOrder.getAmount().toString())); + // 设置订单标题 + model.setSubject(payOrder.getSubject()); + // 设置产品码 + model.setProductCode("QR_CODE_OFFLINE"); + // 设置订单附加信息 + model.setBody(payOrder.getBody()); + //设置订单超时时间 + model.setTimeExpire(DateUtil.format(payOrder.getExpiredTime(), DatePattern.NORM_DATETIME_FORMAT)); + //设置异步通知地址 + req.setNotifyUrl(getNotifyUrl()); + req.setBizModel(model); + //统一放置 isv接口必传信息 + AlipayKit.putApiIsvInfo(mchAppConfigContext, req, model); + //调起支付宝 (如果异常, 将直接跑出 ChannelException ) + AlipayTradePrecreateResponse alipayResp = configContextQueryService. + getAlipayClientWrapper(mchAppConfigContext).execute(req); + AliOcOrderRS res = ApiResBuilder.buildSuccess(AliOcOrderRS.class); + ChannelRetMsg channelRetMsg = new ChannelRetMsg(); + res.setChannelRetMsg(channelRetMsg); + channelRetMsg.setChannelAttach(alipayResp.getBody()); + if (alipayResp.isSuccess()) { //处理成功 + if (CS.PAY_DATA_TYPE.CODE_IMG_URL.equals(ocOrderRQ.getPayDataType())) { //二维码地址 + res.setCodeImgUrl(sysConfigService.getDBApplicationConfig().genScanImgUrl(alipayResp.getQrCode())); + } else { //默认都为跳转地址方式 + res.setCodeUrl(alipayResp.getQrCode()); + } + channelRetMsg.setChannelState(ChannelRetMsg.ChannelState.WAITING); + } else { //其他状态, 表示下单失败 + res.setOrderState(PayOrder.STATE_FAIL); //支付失败 + channelRetMsg.setChannelErrCode(AlipayKit.appendErrCode(alipayResp.getCode(), alipayResp.getSubCode())); + channelRetMsg.setChannelErrMsg(AlipayKit.appendErrMsg(alipayResp.getMsg(), alipayResp.getSubMsg())); + } + return res; + } + +} diff --git a/jeepay-payment/src/main/java/com/jeequan/jeepay/pay/rqrs/payorder/UnifiedOrderRQ.java b/jeepay-payment/src/main/java/com/jeequan/jeepay/pay/rqrs/payorder/UnifiedOrderRQ.java index 9d5cbc6..c15aea0 100644 --- a/jeepay-payment/src/main/java/com/jeequan/jeepay/pay/rqrs/payorder/UnifiedOrderRQ.java +++ b/jeepay-payment/src/main/java/com/jeequan/jeepay/pay/rqrs/payorder/UnifiedOrderRQ.java @@ -158,6 +158,10 @@ public class UnifiedOrderRQ extends AbstractMchAppRQ { PPPcOrderRQ bizRQ = JSONObject.parseObject(StringUtils.defaultIfEmpty(this.channelExtra, "{}"), PPPcOrderRQ.class); BeanUtils.copyProperties(this, bizRQ); return bizRQ; + } else if (CS.PAY_WAY_CODE.ALI_OC.equals((wayCode))) { + AliOcOrderRQ bizRQ = JSONObject.parseObject(StringUtils.defaultIfEmpty(this.channelExtra, "{}"), AliOcOrderRQ.class); + BeanUtils.copyProperties(this, bizRQ); + return bizRQ; } return this; diff --git a/jeepay-payment/src/main/java/com/jeequan/jeepay/pay/rqrs/payorder/payway/AliOcOrderRQ.java b/jeepay-payment/src/main/java/com/jeequan/jeepay/pay/rqrs/payorder/payway/AliOcOrderRQ.java new file mode 100644 index 0000000..6ef04cf --- /dev/null +++ b/jeepay-payment/src/main/java/com/jeequan/jeepay/pay/rqrs/payorder/payway/AliOcOrderRQ.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com). + *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *
+ * http://www.gnu.org/licenses/lgpl.html + *
+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jeequan.jeepay.pay.rqrs.payorder.payway; + +import com.jeequan.jeepay.core.constants.CS; +import com.jeequan.jeepay.pay.rqrs.payorder.CommonPayDataRQ; +import lombok.Data; + +/** + * 支付方式 订单码 + * + * @author zhangheming + * @site https://www.jeequan.com + * @date 2024/6/12 17:20 + */ +@Data +public class AliOcOrderRQ extends CommonPayDataRQ { + + public AliOcOrderRQ() { + this.setWayCode(CS.PAY_WAY_CODE.ALI_OC); + } +} diff --git a/jeepay-payment/src/main/java/com/jeequan/jeepay/pay/rqrs/payorder/payway/AliOcOrderRS.java b/jeepay-payment/src/main/java/com/jeequan/jeepay/pay/rqrs/payorder/payway/AliOcOrderRS.java new file mode 100644 index 0000000..45b3f77 --- /dev/null +++ b/jeepay-payment/src/main/java/com/jeequan/jeepay/pay/rqrs/payorder/payway/AliOcOrderRS.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021-2031, 河北计全科技有限公司 (https://www.jeequan.com & jeequan@126.com). + *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *
+ * http://www.gnu.org/licenses/lgpl.html + *
+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.jeequan.jeepay.pay.rqrs.payorder.payway; + +import com.jeequan.jeepay.pay.rqrs.payorder.CommonPayDataRS; +import lombok.Data; + +/** + * 支付方式 ALI_OC + * + * @author zhangheming + * @site https://www.jeequan.com + * @date 2024/6/12 17:20 + */ +@Data +public class AliOcOrderRS extends CommonPayDataRS { +}