在微信瀏覽器中呼叫 JSAPI 支付,需完成:網頁授權獲取 openid → 統一下單獲取 prepay_id → 前端喚起支付 → 異步通知驗證。本文提供 OneThink 鉤子機制下的完整實作代碼。
public function Wxpay($param) {
require './Addons/Wxpay/WxPayPubHelper/WxPayPubHelper.php';
$jsApi = new \JsApi_pub();
// 步驟1:網頁授權獲取 openid
if (!isset($_GET['code'])) {
$url = $jsApi->createOauthUrlForCode(\WxPayConf_pub::JS_API_CALL_URL . '/order_id/' . $param['order_id']);
header("Location: $url");
exit;
}
$order_id = $param['order_id'];
$info = M('Order')->where('id='.$order_id)->find();
if (empty($info) || $info['is_pay'] == 1) {
dump('訂單不存在或已支付'.$order_id); exit();
}
$this->assign('info', $info);
// 金額轉分
$total_fee = $info['money'] * 100;
// 步驟2:統一下單
$unifiedOrder = new \UnifiedOrder_pub();
$unifiedOrder->setParameter("openid", $jsApi->getOpenId());
$unifiedOrder->setParameter("body", "線上預訂");
$unifiedOrder->setParameter("out_trade_no", $info['ordersn']);
$unifiedOrder->setParameter("total_fee", $total_fee);
$unifiedOrder->setParameter("notify_url", \WxPayConf_pub::NOTIFY_URL . '/order_id/' . $param['order_id']);
$unifiedOrder->setParameter("trade_type", "JSAPI");
$prepay_id = $unifiedOrder->getPrepayId();
// 步驟3:前端喚起支付參數
$jsApi->setPrepayId($prepay_id);
$jsApiParameters = $jsApi->getParameters();
$this->assign('jsApiParameters', $jsApiParameters);
$this->display('pay');
}
<script type="text/javascript">
function jsApiCall() {
WeixinJSBridge.invoke('getBrandWCPayRequest', {$jsApiParameters}, function(res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
alert('支付成功');
location.href = '/order/detail/id/{$info.id}';
} else {
alert('支付失敗: ' + res.err_msg);
}
});
}
if (typeof WeixinJSBridge == "undefined") {
if (document.addEventListener) document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
else if (document.attachEvent) document.attachEvent('WeixinJSBridgeReady', jsApiCall);
else document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
} else { jsApiCall(); }
</script>
APPID、MCHID、KEY、APPSECRET:微信商戶平台申請。JS_API_CALL_URL:支付回調頁面完整 URL (需在微信支付後台配置授權目錄)。NOTIFY_URL:異步通知 URL,需驗證簽名、更新訂單狀態、防重複處理。result_code 與 return_code 皆為 SUCCESS。out_trade_no 必須全域唯一,建議 訂單前綴 + 時間戳 + 隨機數。