溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SpringBoot如何實現整合微信支付

發布時間:2022-03-03 14:59:30 來源:億速云 閱讀:500 作者:小新 欄目:開發技術
# SpringBoot如何實現整合微信支付

## 目錄
- [一、微信支付概述](#一微信支付概述)
  - [1.1 微信支付產品體系](#11-微信支付產品體系)
  - [1.2 開發前準備](#12-開發前準備)
- [二、SpringBoot項目基礎搭建](#二springboot項目基礎搭建)
  - [2.1 項目初始化](#21-項目初始化)
  - [2.2 核心依賴配置](#22-核心依賴配置)
- [三、微信支付V3接口對接](#三微信支付v3接口對接)
  - [3.1 證書與密鑰管理](#31-證書與密鑰管理)
  - [3.2 微信支付配置封裝](#32-微信支付配置封裝)
- [四、支付功能實現](#四支付功能實現)
  - [4.1 Native支付實現](#41-native支付實現)
  - [4.2 JSAPI支付實現](#42-jsapi支付實現)
- [五、支付結果通知處理](#五支付結果通知處理)
  - [5.1 回調通知驗簽](#51-回調通知驗簽)
  - [5.2 訂單狀態更新](#52-訂單狀態更新)
- [六、安全與最佳實踐](#六安全與最佳實踐)
  - [6.1 敏感信息加密](#61-敏感信息加密)
  - [6.2 防重復支付處理](#62-防重復支付處理)
- [七、擴展與優化](#七擴展與優化)
  - [7.1 支付日志監控](#71-支付日志監控)
  - [7.2 分布式事務處理](#72-分布式事務處理)
- [八、常見問題排查](#八常見問題排查)
- [九、總結與展望](#九總結與展望)

---

## 一、微信支付概述

### 1.1 微信支付產品體系
微信支付提供多種支付方式:
- **Native支付**:PC網站掃碼支付
- **JSAPI支付**:微信公眾號/小程序支付
- **H5支付**:手機瀏覽器支付
- **APP支付**:移動應用集成

### 1.2 開發前準備
1. 注冊微信支付商戶號
2. 獲取API證書和密鑰(apiclient_key.pem)
3. 配置商戶平臺回調域名
4. 記錄商戶ID(mchid)和APPID

---

## 二、SpringBoot項目基礎搭建

### 2.1 項目初始化
```bash
spring init -dweb,mybatis,lombok wechat-pay-demo

2.2 核心依賴配置

<dependencies>
    <!-- 微信支付官方SDK -->
    <dependency>
        <groupId>com.github.wechatpay-apiv3</groupId>
        <artifactId>wechatpay-apache-httpclient</artifactId>
        <version>0.4.7</version>
    </dependency>
    
    <!-- 其他必要依賴 -->
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.13</version>
    </dependency>
</dependencies>

三、微信支付V3接口對接

3.1 證書與密鑰管理

建議采用PKCS12格式證書存儲:

public class CertManager {
    private static final String CERT_PATH = "/path/to/apiclient_cert.p12";
    
    public Credentials createCredentials() throws Exception {
        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(
            new FileInputStream("/path/to/apiclient_key.pem"));
            
        return new Credentials(
            "商戶號",
            new PrivateKeySigner("商戶證書序列號", merchantPrivateKey));
    }
}

3.2 微信支付配置封裝

# application.yml
wechat:
  pay:
    mch-id: 1230000109
    app-id: wx8888888888888888
    api-v3-key: your-api-v3-key-32bytes
    notify-url: https://yourdomain.com/api/pay/notify

四、支付功能實現

4.1 Native支付實現

@RestController
@RequestMapping("/api/pay")
public class PayController {
    
    @Autowired
    private WechatPayService payService;
    
    @PostMapping("/native")
    public Result<String> nativePay(@RequestBody OrderDTO dto) {
        String codeUrl = payService.createNativeOrder(
            dto.getOrderId(), 
            dto.getAmount(),
            dto.getDescription());
            
        return Result.success(codeUrl);
    }
}

4.2 JSAPI支付實現

public Map<String, String> createJsapiOrder(String openId, String orderId, int amount) {
    Map<String, Object> params = new HashMap<>();
    params.put("appid", config.getAppId());
    params.put("mchid", config.getMchId());
    params.put("description", "訂單描述");
    params.put("out_trade_no", orderId);
    params.put("notify_url", config.getNotifyUrl());
    params.put("amount", Map.of(
        "total", amount,
        "currency", "CNY"
    ));
    params.put("payer", Map.of("openid", openId));
    
    // 調用微信支付API
    HttpResponse response = httpClient.execute(
        new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi")
            .setHeader("Accept", "application/json")
            .setHeader("Content-type", "application/json")
            .setEntity(new StringEntity(JSON.toJSONString(params))));
            
    // 處理返回結果
    return parseJsapiResponse(response);
}

五、支付結果通知處理

5.1 回調通知驗簽

@PostMapping("/notify")
public String payNotify(HttpServletRequest request, 
                       @RequestBody String notifyData) {
    
    // 1. 獲取微信簽名頭
    String signature = request.getHeader("Wechatpay-Signature");
    String timestamp = request.getHeader("Wechatpay-Timestamp");
    String nonce = request.getHeader("Wechatpay-Nonce");
    String serialNo = request.getHeader("Wechatpay-Serial");
    
    // 2. 驗證簽名
    if (!signatureVerifier.verify(serialNo, notifyData, 
        signature, timestamp, nonce)) {
        throw new RuntimeException("簽名驗證失敗");
    }
    
    // 3. 處理業務邏輯
    payService.handlePayResult(JSON.parseObject(notifyData));
    
    return "success";
}

5.2 訂單狀態更新

建議采用狀態機模式:

public enum OrderStatus {
    CREATED,
    PAYING,
    PD,
    REFUNDED,
    CLOSED
}

@Transactional
public void updateOrderStatus(String orderId, OrderStatus status) {
    Order order = orderMapper.selectById(orderId);
    if (order.getStatus() == status) {
        return;
    }
    
    // 狀態校驗邏輯
    if (status == OrderStatus.PD && 
        order.getStatus() != OrderStatus.PAYING) {
        throw new IllegalStateException("訂單狀態異常");
    }
    
    orderMapper.updateStatus(orderId, status);
}

六、安全與最佳實踐

6.1 敏感信息加密

推薦使用Jasypt加密配置:

wechat:
  pay:
    api-v3-key: ENC(AbCdEfGhIjKlMnOpQrStUvWxYz0123456789==)

6.2 防重復支付處理

public String createOrder(OrderDTO dto) {
    // 冪等性控制
    String lockKey = "order:create:" + dto.getOrderId();
    if (redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 5, TimeUnit.MINUTES)) {
        try {
            // 業務處理
        } finally {
            redisTemplate.delete(lockKey);
        }
    } else {
        throw new RuntimeException("訂單正在處理中");
    }
}

七、擴展與優化

7.1 支付日志監控

建議集成ELK實現日志分析:

@Aspect
@Component
@Slf4j
public class PayLogAspect {
    
    @Around("execution(* com..pay.*Service.*(..))")
    public Object logPayOperation(ProceedingJoinPoint pjp) throws Throwable {
        long start = System.currentTimeMillis();
        try {
            Object result = pjp.proceed();
            log.info("[PAY] {}.{} success - {}ms",
                pjp.getSignature().getDeclaringTypeName(),
                pjp.getSignature().getName(),
                System.currentTimeMillis() - start);
            return result;
        } catch (Exception e) {
            log.error("[PAY] {}.{} failed - {}",
                pjp.getSignature().getDeclaringTypeName(),
                pjp.getSignature().getName(),
                e.getMessage());
            throw e;
        }
    }
}

7.2 分布式事務處理

采用Seata處理分布式支付:

@GlobalTransactional
public void payWithInventory(String orderId) {
    // 1. 創建支付訂單
    payService.create(orderId);
    
    // 2. 扣減庫存
    inventoryService.deduct(orderId);
    
    // 3. 更新訂單狀態
    orderService.updateStatus(orderId, PD);
}

八、常見問題排查

  1. 證書加載失敗

    • 檢查證書路徑權限
    • 確認證書密碼正確性
  2. 簽名驗證不通過

    • 檢查時間戳是否同步
    • 驗證APIv3密鑰是否正確
  3. 支付結果未通知

    • 檢查商戶平臺回調配置
    • 驗證服務器網絡可達性

九、總結與展望

本文詳細介紹了SpringBoot整合微信支付V3接口的全流程實現,包含: - 基礎配置與SDK集成 - 多種支付方式實現 - 安全防護措施 - 分布式場景下的解決方案

未來可擴展方向: - 結合微信支付分實現信用支付 - 接入微信發票系統 - 實現跨境支付功能 “`

注:此為精簡版框架,完整2萬字文檔需要補充以下內容: 1. 每個章節的詳細實現原理說明 2. 完整的異常處理代碼示例 3. 性能優化方案對比 4. 微信支付各接口的完整參數說明 5. 安全性設計的深度分析 6. 實際項目中的踩坑案例 7. 配套的數據庫設計說明 8. 壓力測試方案與結果 需要擴展哪部分內容可以告訴我,我可以繼續補充完善。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女