最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實(shí)現(xiàn)統(tǒng)一支付入口集成六種支付方式

 更新時(shí)間:2025年11月12日 10:12:15   作者:馮仙笙  
本文介紹了Java實(shí)現(xiàn)統(tǒng)一支付入口集成六種支付方式,包括PC端、H5端、微信小程序端和自研會(huì)員卡支付的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一、需求背景

我們正在為公司自研平臺(tái)(以下簡(jiǎn)稱“平臺(tái)”)構(gòu)建統(tǒng)一支付能力。平臺(tái)覆蓋多端場(chǎng)景,具體需求如下:

  • PC 端:支持掃碼支付(展示二維碼,用戶掃碼完成付款)
  • H5 端:支持調(diào)起支付寶/微信支付,并支持會(huì)員卡支付
  • 微信小程序端:支持一鍵喚起微信支付,同時(shí)支持會(huì)員卡支付

?? 會(huì)員卡支付為平臺(tái)自研支付方式,基于用戶儲(chǔ)值賬戶體系實(shí)現(xiàn)。本文重點(diǎn)聚焦于第三方支付的統(tǒng)一接入設(shè)計(jì),故該部分僅作簡(jiǎn)要提及。

二、可行性分析:支持的支付方式

根據(jù)業(yè)務(wù)需求,需集成以下主流支付方式:

支付渠道支付類型官方文檔
支付寶H5 支付支付寶 H5 支付文檔
支付寶訂單碼支付(掃碼)支付寶訂單碼支付文檔
微信支付H5 支付微信 H5 支付文檔
微信支付二維碼支付(掃碼)微信掃碼支付文檔
微信支付小程序支付微信小程序支付文檔
自研會(huì)員卡支付——

三、架構(gòu)設(shè)計(jì)與實(shí)現(xiàn)

為避免大量 if-else 或 switch-case 判斷帶來的代碼膨脹與維護(hù)困難,我們采用 工廠模式 + Spring 容器管理 的策略,實(shí)現(xiàn)支付方式的動(dòng)態(tài)分發(fā)與解耦。

1. 統(tǒng)一支付入口:Controller 層

定義統(tǒng)一的 /pay 接口作為所有支付請(qǐng)求的入口,屏蔽客戶端差異。

@RestController
@RequestMapping("/api/pay")
@Tag(name = "支付中心", description = "統(tǒng)一支付接口")
public class PayController {

    private final PayService payService;
    private final RedissonPropertiesConfig redissonPropertiesConfig;
    private final Redisson redisson;

    @Autowired
    public PayController(RedissonPropertiesConfig redissonPropertiesConfig,
                         Redisson redisson,
                         PayService payService) {
        this.redissonPropertiesConfig = redissonPropertiesConfig;
        this.redisson = redisson;
        this.payService = payService;
    }

    @PostMapping("/pay")
    @Operation(summary = "統(tǒng)一支付入口")
    @PermitAll
    public CommonResult<PaymentVO> corePay(@RequestBody @Valid PayVO payParam) throws Exception {
        log.info("【訂單 {}】發(fā)起支付請(qǐng)求,參數(shù):{}", payParam.getOrderId(), JSON.toJSONString(payParam));

        String lockKey = RedisConstant.PAYMENT_LOCK.concat(payParam.getOrderId().toString());
        RLock lock = redisson.getLock(lockKey);
        PaymentVO r = null;
        try {
            lock.lock(redissonPropertiesConfig.getAutomaticReleaseTimeValue(), TimeUnit.SECONDS);

            // 執(zhí)行支付
            r = payService.corePay(payParam);

        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }

        return CommonResult.success(result);
    }
}

?? 說明:使用 Redisson 分布式鎖防止訂單重復(fù)支付,鎖的持有時(shí)間與等待時(shí)間可配置,提升系統(tǒng)健壯性。

2. 支付服務(wù)層:PayService

PayService 是支付流程的調(diào)度中心,負(fù)責(zé)執(zhí)行公共邏輯,如:

  • 查詢支付方式配置
  • 支付金額校驗(yàn)
  • 訂單狀態(tài)檢查(是否已支付、是否可支付)
  • 調(diào)用對(duì)應(yīng)支付工廠執(zhí)行支付
@Service
public class PayServiceImpl implements PayService {

    @Resource
    private ApplicationContext applicationContext;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public PaymentVO corePay(PayVO payParam) throws Exception {
        // todo 1. 查詢支付方式配置
        PayTypeDO payType = ...
        // todo 2. 金額預(yù)檢
        validateAmount(payParam.getAmount());

        // todo 3. 檢查訂單狀態(tài)(是否已支付、是否存在)

        // 4. 動(dòng)態(tài)獲取支付實(shí)現(xiàn)類
        CorePayService corePayService = applicationContext.getBean(payType.getServiceName(), CorePayService.class);
        
        // 5. 執(zhí)行支付
        return corePayService.pay(payParam);
    }
}

?? 關(guān)鍵設(shè)計(jì):通過 PayTypeDO 表中的 serviceName 字段動(dòng)態(tài)映射到 Spring 容器中的 Bean,實(shí)現(xiàn)運(yùn)行時(shí)動(dòng)態(tài)調(diào)用。

3. 支付方式配置表:PayTypeDO

字段描述
id主鍵
pay_code支付方式編碼(如:ALI_H5、WX_NATIVE、MEMBER_CARD)
service_name對(duì)應(yīng) Spring Bean 名稱(如:aliH5PayService、wxNativePayService)
config_json支付參數(shù)(JSON,如 appId、商戶號(hào)、密鑰等)

? 這種設(shè)計(jì)使得新增支付方式只需:

  1. 新增配置記錄
  2. 實(shí)現(xiàn) CorePayService 接口
  3. 注冊(cè)為 Spring Bean

無需修改任何已有代碼,完美符合 開閉原則。

4. 支付工廠:CorePayService 接口與實(shí)現(xiàn)

接口定義

public interface CorePayService {
    /**
     * 執(zhí)行支付
     * @param payParam 支付參數(shù)
     * @return 支付結(jié)果(如:二維碼鏈接、跳轉(zhuǎn) URL 等)
     */
    PaymentVO pay(PayVO payParam) throws Exception;
}

實(shí)現(xiàn)示例:支付寶掃碼支付(訂單碼)

@Service("AliPayQRCodeServiceImpl")
@Slf4j
public class AliPayQRCodeServiceImpl implements CorePayService {
    @Resource
    private AlipayConfig alipayConfig;
    @Resource
    private AliPayPropertiesConfig aliPayPropertiesConfig;
    @Resource
    private PayLogMapper logMapper;
    @Resource
    private OrderRefundApi orderRefundApi;
    @Resource
    private PayLogMapper payLogMapper;
    @Resource
    private OrderPayLogApi orderPayLogApi;
    @Resource
    private StringRedisTemplate stringRedisTemplate;


    @Override
    public PaymentVO pay(PayVO payParam) throws Exception {
        // 支付日志
        log.info("【{}】訂單支付場(chǎng)景信息 => {}", payLog.getOrderId(), JSONUtil.toJsonStr(build));

        // 支付場(chǎng)景信息保存到redis中,避免傳入的數(shù)據(jù)字節(jié)數(shù)太大導(dǎo)致接口調(diào)用失敗
        stringRedisTemplate.opsForValue().set(PAYMENT_INFO.concat(payLog.getPayPaylog()), JSONUtil.toJsonStr(build), 12, TimeUnit.HOURS);

        // 初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);

        // 構(gòu)造請(qǐng)求參數(shù)以調(diào)用接口
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();

        // 設(shè)置商戶訂單號(hào)
        model.setOutTradeNo(...);

        // 設(shè)置訂單總金額(小數(shù)點(diǎn)后兩位)
        model.setTotalAmount(...);

        // 設(shè)置訂單標(biāo)題
        model.setSubject(...);

        // 設(shè)置產(chǎn)品碼
        model.setProductCode("QR_CODE_OFFLINE");

        // 設(shè)置訂單附加信息
        model.setBody(JSON.toJSONString(payParam.getScenarios()));

        log.info("訂單【{}】申請(qǐng)支付寶QR付款(v3)參數(shù) => {}", payParam.getOrderId(), JSONUtil.toJsonStr(model));

        request.setBizModel(model);

        request.setNotifyUrl(...);

        AlipayTradePrecreateResponse response = alipayClient.execute(request);

        JSONObject entries = JSONUtil.parseObj(response.getBody());

        if (!response.isSuccess()) {
            log.error("訂單【{}】申請(qǐng)支付寶QR付款(v3)失敗響應(yīng) => {}", payParam.getOrderId(), entries);
            throw exception(PayErrorCode.ZFB_QR_PAY_ERR);
        }

        log.info("訂單【{}】申請(qǐng)支付寶QR付款(v3)成功響應(yīng) => {}", payParam.getOrderId(), entries);

        JSONObject resp = entries.getJSONObject("alipay_trade_precreate_response");
        String qrCode = resp.getStr("qr_code");

        return PaymentVO.builder()
                .payType(Integer.valueOf(payParam.getPayTypeNo()))
                .inTradeNo(payParam.getPayLog())
                .param(qrCode)
                .build();
    }

?? 同理可實(shí)現(xiàn) AliH5PayService、WxAppletPayService 等,各自獨(dú)立,互不影響。

5. 組件圖:統(tǒng)一支付系統(tǒng)架構(gòu)

6. 序列圖:用戶發(fā)起支付流程

四、總結(jié)與思考

通過本次統(tǒng)一支付系統(tǒng)的構(gòu)建,我們實(shí)現(xiàn)了以下目標(biāo):

? 成果亮點(diǎn)

  1. 高內(nèi)聚低耦合:各支付方式獨(dú)立實(shí)現(xiàn),職責(zé)清晰。
  2. 易擴(kuò)展:新增支付渠道只需新增實(shí)現(xiàn)類 + 配置,核心邏輯無侵入。
  3. 可維護(hù)性強(qiáng):避免 if-else 地獄,代碼結(jié)構(gòu)清晰。
  4. 安全可靠:通過分布式鎖防止重復(fù)支付,金額校驗(yàn)防篡改。
  5. 符合開閉原則:對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。

五、結(jié)語

支付系統(tǒng)是業(yè)務(wù)的核心環(huán)節(jié),安全、穩(wěn)定、可擴(kuò)展是基本要求。本文通過 工廠模式 + Spring IOC 的組合拳,實(shí)現(xiàn)了多支付方式的優(yōu)雅接入。這不僅是一次技術(shù)實(shí)踐,更是對(duì)設(shè)計(jì)模式、系統(tǒng)架構(gòu)的深入理解。

支付無小事,細(xì)節(jié)定成敗。愿我們都能在構(gòu)建高質(zhì)量系統(tǒng)的過程中不斷精進(jìn),寫出更優(yōu)雅、更可靠的代碼。

到此這篇關(guān)于Java實(shí)現(xiàn)統(tǒng)一支付入口集成六種支付方式的文章就介紹到這了,更多相關(guān)Java 統(tǒng)一支付入口集成內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java 基礎(chǔ)語法

    Java 基礎(chǔ)語法

    這篇文章主要介紹了Java 基礎(chǔ)語法,Java 是一門面向?qū)ο蟮慕忉屝途幊陶Z言,面向?qū)ο?意味著我們應(yīng)該把一個(gè) Java 程序看作一系列對(duì)象的集合,我們的工作就是構(gòu)建這些對(duì)象,并通過調(diào)用彼此的方法來讓各種對(duì)象協(xié)同工作,解決實(shí)際的問題,下面文章內(nèi)容需要的朋友可以參考下一
    2021-11-11
  • 最詳細(xì)的文件上傳下載實(shí)例詳解(推薦)

    最詳細(xì)的文件上傳下載實(shí)例詳解(推薦)

    在Web應(yīng)用系統(tǒng)開發(fā)中,文件上傳和下載功能是非常常用的功能,今天來講一下JavaWeb中的文件上傳和下載功能的實(shí)現(xiàn)。非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起看下吧
    2016-07-07
  • Mybatis實(shí)戰(zhàn)之TypeHandler高級(jí)進(jìn)階

    Mybatis實(shí)戰(zhàn)之TypeHandler高級(jí)進(jìn)階

    本文主要介紹了自定義的枚舉TypeHandler的相關(guān)知識(shí),具有很好的參考價(jià)值,下面跟著小編一起來看下吧
    2017-02-02
  • JavaWeb 文件的上傳和下載功能簡(jiǎn)單實(shí)現(xiàn)代碼

    JavaWeb 文件的上傳和下載功能簡(jiǎn)單實(shí)現(xiàn)代碼

    這篇文章主要介紹了JavaWeb 文件的上傳和下載功能簡(jiǎn)單實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2017-04-04
  • 解決httpServletRequest.getParameter獲取不到參數(shù)的問題

    解決httpServletRequest.getParameter獲取不到參數(shù)的問題

    這篇文章主要介紹了解決httpServletRequest.getParameter獲取不到參數(shù)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Java跨session實(shí)現(xiàn)token接口測(cè)試過程圖解

    Java跨session實(shí)現(xiàn)token接口測(cè)試過程圖解

    這篇文章主要介紹了Java跨session實(shí)現(xiàn)token接口測(cè)試過程圖解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • SpringSessionRedis配置及發(fā)現(xiàn)的問題講解

    SpringSessionRedis配置及發(fā)現(xiàn)的問題講解

    今天小編就為大家分享一篇關(guān)于SpringSessionRedis配置及發(fā)現(xiàn)的問題講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • Java Caledar類(日歷類)如何判斷本周周數(shù)

    Java Caledar類(日歷類)如何判斷本周周數(shù)

    這篇文章主要介紹了Java Caledar類(日歷類)如何判斷本周周數(shù)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • Java Springboot全局異常處理

    Java Springboot全局異常處理

    這篇文章主要給大家介紹了關(guān)于Springboot全局異常處理的資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用SpringBoot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-11-11
  • Java數(shù)據(jù)庫(kù)連接池之proxool_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java數(shù)據(jù)庫(kù)連接池之proxool_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Proxool是一種Java數(shù)據(jù)庫(kù)連接池技術(shù)。方便易用,便于發(fā)現(xiàn)連接泄漏的情況
    2017-08-08

最新評(píng)論

松桃| 浠水县| 迭部县| 望谟县| 石门县| 四会市| 收藏| 榆中县| 菏泽市| 苏州市| 石屏县| 灵宝市| 玉田县| 龙山县| 德格县| 临漳县| 开封市| 织金县| 元氏县| 青田县| 昭平县| 南木林县| 九江县| 始兴县| 大荔县| 南乐县| 资阳市| 隆安县| 新龙县| 万安县| 天等县| 滦南县| 茶陵县| 高安市| 祁连县| 龙井市| 临沂市| 西和县| 沽源县| 宜州市| 南江县|