首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

ThinkPHP 整合微信掃碼支付 (Native 模式) 完整實現代碼與流程解析

     編輯:PHP 相關知識

ThinkPHP 整合微信掃碼支付 (Native 模式) 完整實現

微信掃碼支付 (Native 模式) 適用於 PC 網站、實體店面等場景,用戶掃描二維碼發起支付。本文基於 ThinkPHP 3.2 框架,梳理從官方 SDK 整理、統一下單、二維碼生成、異步通知驗證到前端展示的完整閉環代碼,並針對常見坑點給出解決方案。

一、 SDK 文件佈局 (放入 Vendor 目錄)

Vendor/
└── Wxpay/
    ├── WxPay.Api.php          # 核心接口調用
    ├── WxPay.Config.php       # 配置項 (APPID, MCHID, KEY...)
    ├── WxPay.Data.php         # 請求/響應數據對象
    ├── WxPay.NativePay.php    # Native 支付業務邏輯
    ├── WxPay.Notify.php       # 異步通知基類
    ├── log.php                # 日誌處理
    └── phpqrcode/             # PHP QR Code 生成庫
        └── phpqrcode.php

二、 控制器核心代碼 (WechatController.class.php)

1. 統一下單生成預支付鏈接

public function native($v_oid='', $v_amount='') {
    ini_set('date.timezone','Asia/Shanghai');
    error_reporting(E_ERROR);

    // 載入 SDK
    vendor('Wxpay.WxPayApi');
    vendor('Wxpay.log');
    vendor('Wxpay.NativePay');

    // 日誌初始化
    $logHandler = new \CLogFileHandler("../logs/".date('Y-m-d').'.log');
    \Log::Init($logHandler, 15);

    // 參數校驗
    if (empty(trim($v_oid))) {
        $this->error('訂單號為空', U('User/index'));
        exit;
    }
    $v_oid = trim($v_oid);
    $v_amount = intval($v_amount * 100); // 轉分

    // 調用統一下單
    $notify = new \NativePay();
    $input = new \WxPayUnifiedOrder();
    $input->SetBody("商品描述");           // 必填
    $input->SetAttach("附加數據");         // 選填,原樣返回
    $input->SetOut_trade_no($v_oid);       // 商戶訂單號
    $input->SetTotal_fee($v_amount);       // 總金額(分)
    $input->SetTime_start(date("YmdHis")); // 開始時間
    $input->SetTime_expire(date("YmdHis", time()+600)); // 10分鐘過期
    $input->SetGoods_tag("標記");          // 訂單優惠標記
    $input->SetNotify_url(U('NotifyProcess', '', '', true)); // 異步通知地址(全域名)
    $input->SetTrade_type("NATIVE");       // 掃碼支付
    $input->SetProduct_id("123456789");    // 商品ID

    $result = $notify->GetPayUrl($input);
    $url2 = $result["code_url"];           // 獲取二維碼鏈接

    $this->assign('data', urlencode($url2));
    $this->assign('v_oid', $v_oid);
    $this->assign('v_amount', $v_amount/100);
    $this->display(); // 渲染支付頁面
}

2. 二維碼生成接口

public function qrcode() {
    error_reporting(E_ERROR);
    vendor('Wxpay.phpqrcode.phpqrcode');
    $url = $_GET["data"];
    \QRcode::png($url); // 直接輸出 PNG 圖片流
}

3. 異步通知處理 (NotifyProcess)

public function NotifyProcess() {
    vendor('Wxpay.WxPayApi');
    vendor('Wxpay.log');
    $notify = new \NativePay(); // 復用或自定義 Notify 類
    $notify->Handle(false);     // false: 不在頁面輸出
    // 內部會調用 WxPayApi::notify() 驗證簽名、寫日誌
    // 業務邏輯:查詢訂單狀態 → 更新本地訂單 → 返回 SUCCESS
}

4. 主動查單邏輯 (防漏單)

public function Queryorder($transaction_id) {
    $input = new \WxPayOrderQuery();
    $input->SetTransaction_id($transaction_id);
    $result = \WxPayApi::orderQuery($input);
    \Log::DEBUG("query: ".json_encode($result));
    return isset($result["return_code"]) && $result["return_code"]=="SUCCESS"
        && isset($result["result_code"]) && $result["result_code"]=="SUCCESS";
}

三、 前端支付頁面模板 (支付頁面.html)

<form action="" method="post" id="myForm-table">
  <h2>訂單信息</h2>
  <div class="orderNumber">
    <p class="a">訂單號:"{$v_oid}"</p>
    <p class="b">
      <span class="left">應付金額:<strong><em>{$v_amount}</em>元</strong></span>
      <span class="right">付款後客服會聯系您,熱線 400-700-2016</span>
    </p>
  </div>
  <h2>微信支付</h2>
  <img src="{:U('qrcode')}?data={$data}" alt="微信掃碼">
  <div class="order-submit">
    <a href="javascript:history.go(-1);" class="submitOrder Order">返回其他支付方式</a>
  </div>
</form>

四、 關鍵配置與坑點提醒

  1. WxPay.Config.php 必須正確填寫:APPID、MCHID、KEY (商戶平台設置)、APPSECRET、SSLCERT_PATH/SSLKEY_PATH (退款/紅包需雙向證書)。
  2. 異步通知 URL 必須為外網可訪問的完整域名,不能帶參數,不能用 localhost/IP,端口必須 80/443。
  3. 總金額單位為分,傳入前 intval($yuan * 100),避免浮點數誤差。
  4. code_url 有效期 2 小時,超時需重新下單;前端可設置定時輪詢訂單狀態。
  5. 簽名驗證失敗:檢查 KEY 是否一致、參數是否參與簽名、字符集是否 UTF-8、是否過濾了空值。
  6. 測試環境:使用微信支付沙箱環境 (https://sandboxnew.weixin.qq.com/),需單獨配置沙箱 KEY。

五、 完善建議

  • 將 SDK 封裝為 Composer 包 (composer require wechatpay/wechatpay) 統一版本管理。
  • 異步通知採用「冪等性」設計:以 transaction_id 為唯一鍵防重複處理。
  • 引入消息隊列 (Redis/RabbitMQ) 異步處理通知,快速返回 SUCCESS 避免微信重試。
  • 增加支付狀態輪詢定時任務,補償異步通知丟失導致的漏單。
  • 前端接入微信 JSAPI 唤起支付 (公眾號/H5 場景) 復用統一下單接口。

掌握這套流程,即可在 ThinkPHP 專案中快速接入微信掃碼支付,滿足 PC 端、展會現場、桌面應用等多樣化收款需求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved