Commit 8e1be014515efa3becb130728fa9c5ce6e72ce16
1 parent
379aeeae
pay: 增加支付宝的条形码支付的配置
Showing
8 changed files
with
105 additions
and
10 deletions
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java
| @@ -4,10 +4,7 @@ import cn.hutool.core.lang.Assert; | @@ -4,10 +4,7 @@ import cn.hutool.core.lang.Assert; | ||
| 4 | import cn.iocoder.yudao.framework.pay.core.client.PayClient; | 4 | import cn.iocoder.yudao.framework.pay.core.client.PayClient; |
| 5 | import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; | 5 | import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; |
| 6 | import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; | 6 | import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory; |
| 7 | -import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig; | ||
| 8 | -import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPcPayClient; | ||
| 9 | -import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayQrPayClient; | ||
| 10 | -import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayWapPayClient; | 7 | +import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.*; |
| 11 | import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXLitePayClient; | 8 | import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXLitePayClient; |
| 12 | import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXNativePayClient; | 9 | import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXNativePayClient; |
| 13 | import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig; | 10 | import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig; |
| @@ -71,6 +68,7 @@ public class PayClientFactoryImpl implements PayClientFactory { | @@ -71,6 +68,7 @@ public class PayClientFactoryImpl implements PayClientFactory { | ||
| 71 | case ALIPAY_QR: return (AbstractPayClient<Config>) new AlipayQrPayClient(channelId, (AlipayPayClientConfig) config); | 68 | case ALIPAY_QR: return (AbstractPayClient<Config>) new AlipayQrPayClient(channelId, (AlipayPayClientConfig) config); |
| 72 | case ALIPAY_APP: return (AbstractPayClient<Config>) new AlipayQrPayClient(channelId, (AlipayPayClientConfig) config); | 69 | case ALIPAY_APP: return (AbstractPayClient<Config>) new AlipayQrPayClient(channelId, (AlipayPayClientConfig) config); |
| 73 | case ALIPAY_PC: return (AbstractPayClient<Config>) new AlipayPcPayClient(channelId, (AlipayPayClientConfig) config); | 70 | case ALIPAY_PC: return (AbstractPayClient<Config>) new AlipayPcPayClient(channelId, (AlipayPayClientConfig) config); |
| 71 | + case ALIPAY_BAR: return (AbstractPayClient<Config>) new AlipayBarPayClient(channelId, (AlipayPayClientConfig) config); | ||
| 74 | } | 72 | } |
| 75 | // 创建失败,错误日志 + 抛出异常 | 73 | // 创建失败,错误日志 + 抛出异常 |
| 76 | log.error("[createPayClient][配置({}) 找不到合适的客户端实现]", config); | 74 | log.error("[createPayClient][配置({}) 找不到合适的客户端实现]", config); |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayBarPayClient.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.pay.core.client.impl.alipay; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.util.StrUtil; | ||
| 4 | +import cn.iocoder.yudao.framework.pay.core.client.PayCommonResult; | ||
| 5 | +import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO; | ||
| 6 | +import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedRespDTO; | ||
| 7 | +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum; | ||
| 8 | +import cn.iocoder.yudao.framework.pay.core.enums.PayDisplayModeEnum; | ||
| 9 | +import com.alipay.api.AlipayApiException; | ||
| 10 | +import com.alipay.api.domain.AlipayTradePayModel; | ||
| 11 | +import com.alipay.api.request.AlipayTradePayRequest; | ||
| 12 | +import com.alipay.api.response.AlipayTradePayResponse; | ||
| 13 | +import lombok.extern.slf4j.Slf4j; | ||
| 14 | + | ||
| 15 | +import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; | ||
| 16 | + | ||
| 17 | +/** | ||
| 18 | + * 支付宝【条码支付】的 PayClient 实现类 | ||
| 19 | + * | ||
| 20 | + * 文档:https://opendocs.alipay.com/open/194/105072 | ||
| 21 | + * | ||
| 22 | + * @author 芋道源码 | ||
| 23 | + */ | ||
| 24 | +@Slf4j | ||
| 25 | +public class AlipayBarPayClient extends AbstractAlipayClient { | ||
| 26 | + | ||
| 27 | + public AlipayBarPayClient(Long channelId, AlipayPayClientConfig config) { | ||
| 28 | + super(channelId, PayChannelEnum.ALIPAY_BAR.getCode(), config, | ||
| 29 | + new AlipayPayCodeMapping()); | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + @Override | ||
| 33 | + public PayCommonResult<PayOrderUnifiedRespDTO> doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) { | ||
| 34 | + // 1.1 构建 AlipayTradePayModel 请求 | ||
| 35 | + AlipayTradePayModel model = new AlipayTradePayModel(); | ||
| 36 | + // ① 通用的参数 | ||
| 37 | + model.setOutTradeNo(reqDTO.getMerchantOrderId()); | ||
| 38 | + model.setSubject(reqDTO.getSubject()); | ||
| 39 | + model.setBody(reqDTO.getBody()); | ||
| 40 | + model.setTotalAmount(formatAmount(reqDTO.getAmount())); | ||
| 41 | + model.setScene("bar_code"); // 当面付条码支付场景 | ||
| 42 | + // ② 个性化的参数【无】 | ||
| 43 | + // ③ 支付宝条码支付只有一种展示 | ||
| 44 | + String displayMode = PayDisplayModeEnum.BAR_CODE.getMode(); | ||
| 45 | + | ||
| 46 | + // 1.2 构建 AlipayTradePayRequest 请求 | ||
| 47 | + AlipayTradePayRequest request = new AlipayTradePayRequest(); | ||
| 48 | + request.setBizModel(model); | ||
| 49 | + request.setNotifyUrl(reqDTO.getNotifyUrl()); | ||
| 50 | + request.setReturnUrl(reqDTO.getReturnUrl()); // TODO 芋艿,待搞 | ||
| 51 | + | ||
| 52 | + // 2.1 执行请求 | ||
| 53 | + AlipayTradePayResponse response; | ||
| 54 | + try { | ||
| 55 | + response = client.execute(request); | ||
| 56 | + } catch (AlipayApiException e) { | ||
| 57 | + log.error("[unifiedOrder][request({}) 发起支付失败]", toJsonString(reqDTO), e); | ||
| 58 | + return PayCommonResult.build(e.getErrCode(), e.getErrMsg(), null, codeMapping); | ||
| 59 | + } | ||
| 60 | + // 2.2 处理结果 | ||
| 61 | + PayOrderUnifiedRespDTO respDTO = new PayOrderUnifiedRespDTO() | ||
| 62 | + .setDisplayMode(displayMode).setDisplayContent(response.getCode()); | ||
| 63 | + return PayCommonResult.build(StrUtil.blankToDefault(response.getCode(),"10000"), | ||
| 64 | + response.getMsg(), respDTO, codeMapping); | ||
| 65 | + } | ||
| 66 | +} |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/PayChannelEnum.java
| @@ -25,7 +25,8 @@ public enum PayChannelEnum { | @@ -25,7 +25,8 @@ public enum PayChannelEnum { | ||
| 25 | ALIPAY_PC("alipay_pc", "支付宝 PC 网站支付", AlipayPayClientConfig.class), | 25 | ALIPAY_PC("alipay_pc", "支付宝 PC 网站支付", AlipayPayClientConfig.class), |
| 26 | ALIPAY_WAP("alipay_wap", "支付宝 Wap 网站支付", AlipayPayClientConfig.class), | 26 | ALIPAY_WAP("alipay_wap", "支付宝 Wap 网站支付", AlipayPayClientConfig.class), |
| 27 | ALIPAY_APP("alipay_app", "支付宝App 支付", AlipayPayClientConfig.class), | 27 | ALIPAY_APP("alipay_app", "支付宝App 支付", AlipayPayClientConfig.class), |
| 28 | - ALIPAY_QR("alipay_qr", "支付宝扫码支付", AlipayPayClientConfig.class); | 28 | + ALIPAY_QR("alipay_qr", "支付宝扫码支付", AlipayPayClientConfig.class), |
| 29 | + ALIPAY_BAR("alipay_bar", "支付宝条码支付", AlipayPayClientConfig.class); | ||
| 29 | 30 | ||
| 30 | /** | 31 | /** |
| 31 | * 编码 | 32 | * 编码 |
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/PayDisplayModeEnum.java
| @@ -17,6 +17,7 @@ public enum PayDisplayModeEnum { | @@ -17,6 +17,7 @@ public enum PayDisplayModeEnum { | ||
| 17 | FORM("form"), // HTML 表单提交 | 17 | FORM("form"), // HTML 表单提交 |
| 18 | QR_CODE("qr_code"), // 二维码的文字内容 | 18 | QR_CODE("qr_code"), // 二维码的文字内容 |
| 19 | QR_CODE_URL("qr_code_url"), // 二维码的图片链接 | 19 | QR_CODE_URL("qr_code_url"), // 二维码的图片链接 |
| 20 | + BAR_CODE("bar_code"), // 条形码 | ||
| 20 | ; | 21 | ; |
| 21 | 22 | ||
| 22 | /** | 23 | /** |
yudao-ui-admin/src/assets/images/pay/icon/alipay_bar.svg
0 → 100644
| 1 | +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1627279586085" class="icon" viewBox="0 0 1036 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6737" xmlns:xlink="http://www.w3.org/1999/xlink" width="40.46875" height="40"><defs><style type="text/css">@font-face { font-family: feedback-iconfont; src: url("//at.alicdn.com/t/font_1031158_1uhr8ri0pk5.eot?#iefix") format("embedded-opentype"), url("//at.alicdn.com/t/font_1031158_1uhr8ri0pk5.woff2") format("woff2"), url("//at.alicdn.com/t/font_1031158_1uhr8ri0pk5.woff") format("woff"), url("//at.alicdn.com/t/font_1031158_1uhr8ri0pk5.ttf") format("truetype"), url("//at.alicdn.com/t/font_1031158_1uhr8ri0pk5.svg#iconfont") format("svg"); } | ||
| 2 | +</style></defs><path d="M27.587124 336.619083h69.148134a13.978733 13.978733 0 0 0 13.79235-13.978733V13.989916A13.978733 13.978733 0 0 0 96.735258 0.011183H27.587124a13.978733 13.978733 0 0 0-13.792351 13.978733v308.650434a13.978733 13.978733 0 0 0 13.792351 13.978733z m165.880969 0h27.584701a13.978733 13.978733 0 0 0 13.79235-13.978733V13.989916a13.978733 13.978733 0 0 0-13.79235-13.978733h-27.584701a13.978733 13.978733 0 0 0-13.79235 13.978733v308.650434a13.978733 13.978733 0 0 0 13.79235 13.978733z m138.109886 322.629167h-110.525185a27.771084 27.771084 0 0 0-27.584701 28.14385v111.829867a27.771084 27.771084 0 0 0 27.584701 28.14385h110.525185a27.957467 27.957467 0 0 0 27.584701-28.14385v-111.829867a27.957467 27.957467 0 0 0-27.584701-28.14385z m484.596091-322.629167h27.584701a13.978733 13.978733 0 0 0 13.79235-13.978733V13.989916a13.978733 13.978733 0 0 0-14.537883-13.978733h-27.5847a13.978733 13.978733 0 0 0-13.978734 13.978733v308.650434a13.978733 13.978733 0 0 0 13.978734 13.978733z m-469.871825 0H428.68358a13.978733 13.978733 0 0 0 13.792351-13.978733V13.989916A13.978733 13.978733 0 0 0 428.68358 0.011183h-83.126867a13.978733 13.978733 0 0 0-13.792351 13.978733v308.650434a13.978733 13.978733 0 0 0 13.792351 13.978733z m594.189361 0h69.148134a13.978733 13.978733 0 0 0 13.792351-13.978733V13.989916a13.978733 13.978733 0 0 0-14.537883-13.978733h-69.148135a13.978733 13.978733 0 0 0-13.79235 13.978733v308.650434a13.978733 13.978733 0 0 0 13.79235 13.978733z m-412.279444 126.181367H66.91396A67.470687 67.470687 0 0 0 0.002423 530.830286v425.139878a67.470687 67.470687 0 0 0 66.911537 68.029836h418.802853a67.470687 67.470687 0 0 0 66.911537-68.029836V487.775787a24.788954 24.788954 0 0 0-24.416188-24.975337z m-58.337914 433.899885a42.681733 42.681733 0 0 1-42.495349 43.054498H125.438257a42.681733 42.681733 0 0 1-42.495349-43.054498V590.100115a42.681733 42.681733 0 0 1 42.495349-43.054498h301.940642a42.681733 42.681733 0 0 1 42.495349 43.054498z m525.22761-433.899885a41.749817 41.749817 0 0 0-41.377051 42.122583v55.914934a41.377051 41.377051 0 1 0 82.940485 0v-55.914934a41.749817 41.749817 0 0 0-41.563434-42.122583z m0 223.659734a41.749817 41.749817 0 0 0-41.377051 42.122584V894.65012a45.477479 45.477479 0 0 1-45.291096 45.850246h-159.730327a43.240882 43.240882 0 0 0-43.613649 37.276622A41.9362 41.9362 0 0 0 745.534871 1024h233.538039a57.778765 57.778765 0 0 0 57.405999-58.337914V729.3283a41.749817 41.749817 0 0 0-41.377051-41.9362zM732.488053 322.64035V13.989916a13.978733 13.978733 0 0 0-13.79235-13.978733h-82.940485a13.978733 13.978733 0 0 0-13.79235 13.978733v308.650434a13.978733 13.978733 0 0 0 13.79235 13.978733h82.940485a13.978733 13.978733 0 0 0 13.79235-13.978733zM532.126208 0.011183c-11.36937 0-20.688525 6.337026-20.688526 13.978733v308.650434c0 7.828091 9.319156 13.978733 20.688526 13.978733s20.688525-6.337026 20.688525-13.978733V13.989916c0-7.641708-9.319156-13.978733-20.688525-13.978733z" p-id="6738" fill="#1977FD"></path><path d="M745.534871 462.80045a41.749817 41.749817 0 0 0-41.377051 42.122583v252.549117a41.377051 41.377051 0 1 0 82.940485 0V504.923033A41.749817 41.749817 0 0 0 745.534871 462.80045" p-id="6739" fill="#1977FD"></path></svg> |
yudao-ui-admin/src/utils/constants.js
| @@ -148,6 +148,10 @@ export const PayChannelEnum = { | @@ -148,6 +148,10 @@ export const PayChannelEnum = { | ||
| 148 | "code": "alipay_qr", | 148 | "code": "alipay_qr", |
| 149 | "name": "支付宝扫码支付" | 149 | "name": "支付宝扫码支付" |
| 150 | }, | 150 | }, |
| 151 | + ALIPAY_BAR: { | ||
| 152 | + "code": "alipay_bar", | ||
| 153 | + "name": "支付宝条码支付" | ||
| 154 | + }, | ||
| 151 | } | 155 | } |
| 152 | 156 | ||
| 153 | /** | 157 | /** |
yudao-ui-admin/src/views/pay/app/index.vue
| @@ -53,11 +53,6 @@ | @@ -53,11 +53,6 @@ | ||
| 53 | </template> | 53 | </template> |
| 54 | </el-table-column> | 54 | </el-table-column> |
| 55 | <el-table-column label="商户名称" align="center" prop="payMerchant.name"/> | 55 | <el-table-column label="商户名称" align="center" prop="payMerchant.name"/> |
| 56 | - <el-table-column label="创建时间" align="center" prop="createTime" width="180"> | ||
| 57 | - <template v-slot="scope"> | ||
| 58 | - <span>{{ parseTime(scope.row.createTime) }}</span> | ||
| 59 | - </template> | ||
| 60 | - </el-table-column> | ||
| 61 | <el-table-column label="支付宝配置" align="center"> | 56 | <el-table-column label="支付宝配置" align="center"> |
| 62 | <el-table-column :label="payChannelEnum.ALIPAY_APP.name" align="center"> | 57 | <el-table-column :label="payChannelEnum.ALIPAY_APP.name" align="center"> |
| 63 | <template v-slot="scope"> | 58 | <template v-slot="scope"> |
| @@ -107,6 +102,18 @@ | @@ -107,6 +102,18 @@ | ||
| 107 | </el-button> | 102 | </el-button> |
| 108 | </template> | 103 | </template> |
| 109 | </el-table-column> | 104 | </el-table-column> |
| 105 | + <el-table-column :label="payChannelEnum.ALIPAY_BAR.name" align="center"> | ||
| 106 | + <template v-slot="scope"> | ||
| 107 | + <el-button type="success" icon="el-icon-check" circle | ||
| 108 | + v-if="judgeChannelExist(scope.row.channelCodes,payChannelEnum.ALIPAY_BAR.code)" | ||
| 109 | + @click="handleUpdateChannel(scope.row,payChannelEnum.ALIPAY_BAR.code,payType.ALIPAY)"> | ||
| 110 | + </el-button> | ||
| 111 | + <el-button v-else | ||
| 112 | + type="danger" icon="el-icon-close" circle | ||
| 113 | + @click="handleCreateChannel(scope.row,payChannelEnum.ALIPAY_BAR.code,payType.ALIPAY)"> | ||
| 114 | + </el-button> | ||
| 115 | + </template> | ||
| 116 | + </el-table-column> | ||
| 110 | </el-table-column> | 117 | </el-table-column> |
| 111 | <el-table-column label="微信配置" align="center"> | 118 | <el-table-column label="微信配置" align="center"> |
| 112 | <el-table-column :label="payChannelEnum.WX_LITE.name" align="center"> | 119 | <el-table-column :label="payChannelEnum.WX_LITE.name" align="center"> |
yudao-ui-admin/src/views/pay/order/submit.vue
| @@ -82,6 +82,7 @@ export default { | @@ -82,6 +82,7 @@ export default { | ||
| 82 | alipay_app: require("@/assets/images/pay/icon/alipay_app.svg"), | 82 | alipay_app: require("@/assets/images/pay/icon/alipay_app.svg"), |
| 83 | alipay_wap: require("@/assets/images/pay/icon/alipay_wap.svg"), | 83 | alipay_wap: require("@/assets/images/pay/icon/alipay_wap.svg"), |
| 84 | alipay_pc: require("@/assets/images/pay/icon/alipay_pc.svg"), | 84 | alipay_pc: require("@/assets/images/pay/icon/alipay_pc.svg"), |
| 85 | + alipay_bar: require("@/assets/images/pay/icon/alipay_bar.svg"), | ||
| 85 | wx_app: require("@/assets/images/pay/icon/wx_app.svg"), | 86 | wx_app: require("@/assets/images/pay/icon/wx_app.svg"), |
| 86 | wx_lite: require("@/assets/images/pay/icon/wx_lite.svg"), | 87 | wx_lite: require("@/assets/images/pay/icon/wx_lite.svg"), |
| 87 | wx_pub: require("@/assets/images/pay/icon/wx_pub.svg"), | 88 | wx_pub: require("@/assets/images/pay/icon/wx_pub.svg"), |
| @@ -102,6 +103,11 @@ export default { | @@ -102,6 +103,11 @@ export default { | ||
| 102 | form: { // 展示形式:form | 103 | form: { // 展示形式:form |
| 103 | html: '', | 104 | html: '', |
| 104 | }, | 105 | }, |
| 106 | + barCode: { // 展示形式:条形码 | ||
| 107 | + value: '', | ||
| 108 | + title: '', | ||
| 109 | + visible: false, | ||
| 110 | + }, | ||
| 105 | }; | 111 | }; |
| 106 | }, | 112 | }, |
| 107 | created() { | 113 | created() { |
| @@ -155,6 +161,16 @@ export default { | @@ -155,6 +161,16 @@ export default { | ||
| 155 | }, | 161 | }, |
| 156 | /** 提交支付 */ | 162 | /** 提交支付 */ |
| 157 | submit(channelCode) { | 163 | submit(channelCode) { |
| 164 | + // 条形码支付,需要特殊处理 | ||
| 165 | + if (channelCode === PayChannelEnum.ALIPAY_BAR.code) { | ||
| 166 | + | ||
| 167 | + return; | ||
| 168 | + } | ||
| 169 | + | ||
| 170 | + // 默认的提交处理 | ||
| 171 | + this.submit0(channelCode) | ||
| 172 | + }, | ||
| 173 | + submit0(channelCode) { | ||
| 158 | this.submitLoading = true | 174 | this.submitLoading = true |
| 159 | submitOrder({ | 175 | submitOrder({ |
| 160 | id: this.id, | 176 | id: this.id, |