類功能總覽
- 基礎 Access Token 獲取與緩存
- OAuth2 網頁授權(snsapi_base / snsapi_userinfo)
- 模板消息發送
- 客服消息發送
- 現金紅包 / 裂變紅包(需商戶號、API 證書)
- JSAPI 支付統一下單、簽名
- 工具方法:隨機字符串、商戶訂單號、參數排序簽名、XML/數組互轉
核心類結構
class WxApi {
// 配置常量(實際部署請改為環境變量/配置文件)
const appId = '';
const appSecret = '';
const mchid = ''; // 商戶號
const privatekey = ''; // API 密鑰 (v3) 或商戶私鑰證書路徑
public $parameters = [];
// === HTTP 請求封裝 ===
public function wxHttpsRequest($url, $data = null) { ... } // 普通 POST/GET
public function wxHttpsRequestPem($url, $vars, $second=30, $aHeader=[]) { ... } // 帶證書雙向 TLS
// === Access Token ===
public function wxAccessToken($appId=null, $appSecret=null) { ... }
// === 用戶信息 ===
public function wxGetUser($openId) { ... }
public function wxOauthAccessToken($code, $appId=null, $appSecret=null) { ... }
public function wxOauthUser($oauthAt, $openId) { ... }
// === 模板/客服消息 ===
public function wxSendTemplate($jsonData) { ... }
public function wxSetSend($touser, $template_id, $url, $data, $topcolor='#7B68EE') { ... }
// === OAuth 跳轉 ===
public function wxOauthBase($redirectUrl, $state="", $appId=null) { ... }
public function wxOauthUserinfo($redirectUrl, $state="", $appId=null) { ... }
public function wxHeader($url) { header("Location: $url"); }
// === 紅包核心(需證書) ===
// sendRedPack / sendGroupRedPack 參考官方文檔組裝參數 -> wxHttpsRequestPem
// === 工具方法 ===
public function wxNonceStr($length=16, $type=false) { ... } // 隨機串
public function wxMchBillno($mchid=null) { ... } // 商戶訂單號
public function wxSetParam($parameters) { ... } // 參數設置
public function wxFormatArray($parameters=null, $urlencode=false) { ... } // 排序拼接
public function wxMd5Sign($content, $key) { ... } // MD5 簽名
public function wxSha1Sign($content, $key) { ... } // SHA1 簽名
public function wxArrayToXml($parameters=null) { ... } // 數組轉 XML (CDATA)
}
紅包接口調用關鍵點
- 商戶平台配置:下載 API 證書(
apiclient_cert.pem、apiclient_key.pem、rootca.pem),放置於代碼可讀路徑
- 雙向 TLS:
wxHttpsRequestPem 使用 CURLOPT_SSLCERT、CURLOPT_SSLKEY、CURLOPT_CAINFO
- 參數簽名:按 ASCII 排序 →
key=value&... → 末尾加 &key=API_KEY → MD5 → 大寫
- 金額單位:分(1 元 = 100 分)
- 必填字段:
mch_billno(商戶訂單號,唯一)、send_name、re_openid、total_amount、total_num、wishing、act_name、remark
紅包發送範例
$wx = new WxApi();
$params = $wx->wxSetParam([
'nonce_str' => $wx->wxNonceStr(32),
'mch_billno' => $wx->wxMchBillno(),
'mch_id' => WxApi::mchid,
'wxappid' => WxApi::appId,
'send_name' => '測試商戶',
're_openid' => $openid,
'total_amount' => 100, // 1 元
'total_num' => 1,
'wishing' => '恭喜發財',
'client_ip' => $_SERVER['REMOTE_ADDR'],
'act_name' => '新年紅包',
'remark' => '備註',
]);
$sign = $wx->wxMd5Sign($wx->wxFormatArray($params), WxApi::privatekey);
$params['sign'] = $sign;
$xml = $wx->wxArrayToXml($params);
$result = $wx->wxHttpsRequestPem(
'https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack',
$xml
);
// 解析 $result XML 判斷 result_code / return_code
證書部署提醒
- 證書文件權限:
chmod 600 apiclient_*.pem,僅進程用戶可讀
- 不要將證書提交到版本庫,使用部署時注入或密管系統
- 測試環境可用沙箱環境(
api.mch.weixin.qq.com 同域名,但需沙箱商戶號)
版本迭代建議
- 引入 PSR-18 HTTP Client(Guzzle)替換原生 cURL,提升可測試性
- Access Token 接入 Redis/Memcached 分佈式緩存,多實例共享
- 異常處理統一拋出
WxApiException,區分網絡錯誤、業務錯誤、簽名錯誤
- 單元測試覆蓋簽名算法、XML 生成、參數驗證