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

PHP 開發微信支付獲取用戶收貨地址完整流程

     編輯:PHP 綜合知識

功能概述

微信支付申通過後,可調用「獲取用戶共享收貨地址」接口。用戶點擊按鈕授權後,直接將微信儲存的收貨地址填入訂單頁,省去手動輸入,大幅提升轉化率。注意:必須由用戶主動點擊觸發,不可自動獲取(隱私保護)。

完整業務流程

步驟 1:引導用戶進入 OAuth2 授權頁

用戶點擊結算 → 跳轉微信 OAuth2 頁面:

https://open.weixin.qq.com/connect/oauth2/authorize?
    appid=APPID
    &redirect_uri=URL_ENCODED_訂單頁地址
    &response_type=code
    &scope=snsapi_base
    &state=任意字符串
    #wechat_redirect
  • redirect_uri 必須 URL 編碼
  • scope=snsapi_base 靜默授權(不彈窗),僅獲取 openid
  • state 可攜帶業務參數(如訂單 ID)

步驟 2:回調頁獲取 Access Token

微信重定向至 redirect_uri?code=CODE,服務端用 code 換取 access_token:

<?php
$code = $_GET['code'];
$url = "https://api.weixin.qq.com/sns/oauth2/access_token?"
    . "appid=APPID&secret=APP_SECRET&code={$code}&grant_type=authorization_code";

$response = file_get_contents($url); // 或 curl
$data = json_decode($response, true);

if (isset($data['errcode'])) {
    // 錯誤處理:code 過期、已使用、頻率限制等
    exit('授權失敗: ' . $data['errmsg']);
}

$accessToken = $data['access_token'];
$openid = $data['openid'];

// 注意:此 access_token 僅用於獲取用戶信息,非基礎接口 access_token
?>

步驟 3:生成 JS-SDK 地址簽名

<?php
// 簽名算法:SHA1(accesstoken=...&appid=...&noncestr=...×tamp=...&url=...)
// 參與簽名的 url 必須是當前頁面完整 URL(不含 # 及後內容)

$timestamp = time();
$nonceStr = md5(uniqid(mt_rand(), true)); // 32位隨機串
$url = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

$string = "accesstoken={$accessToken}"
        . "&appid=APPID"
        . "&noncestr={$nonceStr}"
        . "×tamp={$timestamp}"
        . "&url={$url}";

$addrSign = sha1($string);

// 傳遞給前端的配置
$wxConfig = [
    'appId'     => 'APPID',
    'scope'     => 'jsapi_address',
    'signType'  => 'sha1',
    'addrSign'  => $addrSign,
    'timeStamp' => "$timestamp", // JS 需字符串
    'nonceStr'  => $nonceStr
];
?>

步驟 4:前端調用 WeixinJSBridge 獲取地址

<!-- 頁面引入微信 JS-SDK -->
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>

<button id="getAddressBtn">獲取微信收貨地址</button>
<div id="address_info"></div>

<script>
document.getElementById('getAddressBtn').onclick = function() {
    // 配置參數來自 PHP 渲染
    wx.config({
        appId: '',
        timestamp: ,
        nonceStr: '',
        signature: '',
        jsApiList: ['editAddress']
    });

    wx.ready(function() {
        wx.editAddress({
            scope: 'jsapi_address',
            signType: 'sha1',
            addrSign: '',
            timeStamp: '',
            nonceStr: '',
            success: function(res) {
                // res: {userName, telNumber, proviceFirstStageName, addressCitySecondStageName, addressCountiesThirdStageName, addressDetailInfo, ...}
                const addr = `${res.proviceFirstStageName}${res.addressCitySecondStageName}${res.addressCountiesThirdStageName}${res.addressDetailInfo}`;
                document.getElementById('address_info').innerHTML = 
                    `<b>收件人:${res.userName}</b> <b>${res.telNumber}</b><br>收貨地址:${addr}`;
                
                // 可選:AJAX 保存至後端數據庫
                saveAddressToBackend(res);
            },
            fail: function(res) {
                alert('獲取失敗:' + res.errMsg);
            }
        });
    });
};

function saveAddressToBackend(addrData) {
    fetch('/api/save-wx-address', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify(addrData)
    });
}
</script>

關鍵注意事項

風險點解決方案
微信重複回調導致 code 失效用 Redis/setnx 鎖住 code,或記錄已用 code 10 分鐘內去重
簽名驗證失敗確保 url 為當前頁完整 URL(含查詢參數,不含 #hash),參數名大小寫、排序完全一致
JS-SDK 配置無效確認微信公眾平台「JS 接口安全域名」已配置,且引入 jweixin.js
用戶拒絕授權捕獲 fail 回調,友好提示引導手動填寫

優化建議

  1. 地址緩存:首次獲取後存入數據庫/Redis,下次直接讀取,減少授權跳轉
  2. 多地址管理:微信返回的是「默認收貨地址」,建議提供「修改地址」入口調用 editAddress 讓用戶選擇其他地址
  3. 降級方案:授權失敗時自動顯示手動輸入表單,保證流程不中斷

總結

微信共享地址功能通過 OAuth2 靜默授權獲取 openid,結合 JS-SDK 簽名調用 wx.editAddress 實現。核心難點在於簽名參數構造(特別是 url 計算)與微信頻控處理。正確實現可顯著減少用戶輸入成本,是電商類小程序/公眾號支付場景的標配功能。

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