微信小店 API 採用 HTTPS + JSON 格式,常見失敗原因在於參數格式錯誤(如布林值未轉小寫、字串未加引號)或 Access Token 過期。本文提供可直接落地的 PHP cURL 封裝類與四大核心介面調用範例:獲取商品列表、查詢分組、按分組查商品、查單一商品。
<?php
function curl_request(string $url, ?string $data = null): string {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_SSL_VERIFYPEER => false, // 測試環境關閉驗證,生產請配置 CA 憑證
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
CURLOPT_POST => $data !== null,
CURLOPT_POSTFIELDS => $data,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
]);
$response = curl_exec($ch);
if (curl_errno($ch)) {
throw new Exception('cURL 錯誤: ' . curl_error($ch));
}
curl_close($ch);
return $response;
}
function get_access_token(string $appid, string $appsecret): string {
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$appsecret}";
$res = json_decode(curl_request($url), true);
if (empty($res['access_token'])) {
throw new Exception('獲取 access_token 失敗: ' . ($res['errmsg'] ?? '未知錯誤'));
}
return $res['access_token'];
}
function get_products_by_status(int $status, string $token): array {
$url = "https://api.weixin.qq.com/merchant/getbystatus?access_token={$token}";
$data = json_encode(['status' => $status]); // 必須用 json_encode 確保格式正確
return json_decode(curl_request($url, $data), true);
}
function get_all_categories(int $status, string $token): array {
$url = "https://api.weixin.qq.com/merchant/group/getall?access_token={$token}";
$data = json_encode(['status' => $status]);
return json_decode(curl_request($url, $data), true);
}
function get_products_by_group_id(int $group_id, string $token): array {
$url = "https://api.weixin.qq.com/merchant/group/getbyid?access_token={$token}";
$data = json_encode(['group_id' => $group_id]);
return json_decode(curl_request($url, $data), true);
}
function get_product_by_id(string $product_id, string $token): array {
$url = "https://api.weixin.qq.com/merchant/get?access_token={$token}";
$data = json_encode(['product_id' => $product_id]);
return json_decode(curl_request($url, $data), true);
}
<?php
$APPID = 'your_appid';
$APPSECRET = 'your_appsecret';
try {
$token = get_access_token($APPID, $APPSECRET);
// 範例:獲取上架商品
$products = get_products_by_status(1, $token);
echo "上架商品數: " . count($products['products_info'] ?? []) . "\n";
// 範例:獲取所有分組
$groups = get_all_categories(1, $token);
print_r($groups);
// 範例:查詢特定商品
$product = get_product_by_id('pf82VwN45zr8eOlur5mAiSTjg8WU', $token);
print_r($product);
} catch (Exception $e) {
error_log('[微信小店] ' . $e->getMessage());
echo "錯誤: " . $e->getMessage();
}
| 問題 | 原因 | 解決 |
|---|---|---|
| system error / 參數錯誤 | JSON 格式不標準(如 {status: 1} 缺引號) | 統一用 json_encode() 生成請求體 |
| 40001 invalid credential | Access Token 過期或錯誤 | Token 有效期 2 周,建議快取並定時刷新 |
| HTTPS 憑證驗證失敗 | 伺服器缺少 CA 憑證 | 生產環境設定 CURLOPT_CAINFO 指向 cacert.pem |
| IP 白名單限制 | 微信後台未加入伺服器 IP | 在公眾平台「開發配置」添加伺服器公網 IP |
class WechatShopService {
private $appid, $secret, $token_cache_key = 'wechat_shop_token';
public function __construct($appid, $secret) { $this->appid=$appid; $this->secret=$secret; }
private function getToken() { /* 從 Redis/檔案快取讀取,過期則重新獲取 */ }
public function getProducts($status) { /* 呼叫 get_products_by_status */ }
public function getCategories() { /* ... */ }
// ...
}
將 cURL 細節、Token 管理、錯誤重試封裝進 Service 類,控制器僅需注入服務呼叫業務方法,符合單一職責原則,便於單元測試與維護。