PHP 实现微信支付 JSAPI 支付流程详解

七月
七月
发布时间:2026-10-13 | 2人浏览过
原创

掌握 PHP 对接微信支付的 JSAPI 接口开发流程。文章详述了从环境配置、OpenID 获取、统一下单到前端调用的全链路代码实现,并深入剖析了开发中遇到的证书版本、目录限制及报文格式等常见错误及解决方法。

必要条件与基础配置

在开始开发前,需确保拥有以下资质与凭证,这些通常在微信公众平台和商户平台申请成功后通过邮件或后台设置获得:

  • appid:公众号唯一标识(App ID)。
  • mchid:商户号(Merchant ID)。
  • key:商户支付安全密钥,需在商户后台自行设置。
  • appsecret:公众号开发者凭证密钥。
  • 证书文件:包含 apiclient_cert.pem 和 apiclient_key.pem,用于退款或高安全级别接口调用。

配置注意事项: 1. 进入公众号后台「微信支付」→「开发配置」,添加测试目录和授权域名。

2. 在「开发者中心」→「网页授权获取用户基本信息」中,修改授权回调域名。若未正确配置,跳转时会出现 redirect_uri 参数错误。

第一步:网页授权获取用户 OpenID

JSAPI 支付必须基于用户的 OpenID,因此第一步是引导用户完成 OAuth 授权。

// 初始化 JsApi 类
$jsApi = new JsApi_pub();

// 检查是否已携带 code 参数
if (!isset($_GET['code'])) {
    // 触发微信返回 code 码
    $url = $jsApi->createOauthUrlForCode(WxPayConf_pub::JS_API_CALL_URL);
    Header("Location: $url");
} else {
    // 通过 code 换取 openid
    $code = $_GET['code'];
    $jsApi->setCode($code);
    $openid = $jsApi->getOpenid();
}

排错提示:部分服务器环境下,默认的 curl 请求可能因 SSL 证书或版本问题无法获取 OpenID。若遇到 curl 超时或失败,可尝试切换为 file_get_contents(注意开启 allow_url_fopen),或者升级服务器 libcurl 版本至 7.20.1 以上以支持 HTTPS 证书校验。

第二步:统一下单获取 PrepayId

获取 OpenID 后,需向微信服务器发起统一下单请求,获取支付所需的核心参数 prepay_id。

$unifiedOrder = new UnifiedOrder_pub();

// 设置必填参数
$unifiedOrder->setParameter("openid", "$openid");          // 商品描述对应的用户标识
$unifiedOrder->setParameter("body", "示例商品");          // 商品简单描述
$timeStamp = time();
$out_trade_no = WxPayConf_pub::APPID . "$timeStamp";
$unifiedOrder->setParameter("out_trade_no", "$out_trade_no"); // 商户订单号
$unifiedOrder->setParameter("total_fee", "1");            // 总金额,单位为分
$unifiedOrder->setParameter("notify_url", WxPayConf_pub::NOTIFY_URL); // 异步通知地址
$unifiedOrder->setParameter("trade_type", "JSAPI");       // 交易类型

// 发起统一下单请求
$prepay_id = $unifiedOrder->getPrepayId();
var_dump($prepay_id);

关键调试技巧: 由于微信返回的是 XML 格式数据,使用 var_dump 可能仅显示长度而非内容。建议封装日志函数记录原始请求与响应:

function log_d($word) {
    $log_name="./logd.log";
    $fp = fopen($log_name, "a");
    flock($fp, LOCK_EX);
    fwrite($fp, "执行日期:".strftime("%Y-%m-%d-%H:%M:%S",time())."\n".$word."\n\n");
    flock($fp, LOCK_UN);
    fclose($fp);
}

常见错误: 若返回结果为空或报错,请检查 appid 与 mchid 是否匹配(同一主体下才有效)。可在 UnifiedOrder_pub 类的 getPrepayId() 方法内部打印 $this->result 查看具体错误码。

第三步:生成前端支付参数并唤起支付

将上一步获得的 prepay_id 填入 JSAPI 对象,生成前端可调用的 JSON 字符串。

$jsApi->setPrepayId($prepay_id);
$jsApiParameters = $jsApi->getParameters();
// echo json_encode($jsApiParameters); // 输出给前端 JavaScript 调用

前端接收到该 JSON 后,调用微信 JSSDK 提供的 chooseWXPay 接口即可唤起收银台。

常见问题与排错指南

1. 网页授权与支付目录错误

Android 端常报错 System: Access_denied,iOS 端报错 access_control:not_allowed。这通常是因为发起请求的 URL 不在配置的“支付目录”内。
解决方案:微信支付仅支持一级目录下页面直接发起支付,不支持深层子目录。例如,若你的域名是 example.com,则支付脚本必须放在 /pay/ 根目录,而不能是 /pay/demo/。务必在商户平台核对并重新配置准确的访问路径。

2. 报文与签名验证

统一下单及回调通知均涉及 XML 数据交互,需注意字段名大小写敏感及转义字符处理。标准的统一下单请求 XML 结构应包含 openid, body, out_trade_no, total_fee, notify_url, trade_type 等字段,并由签名算法(MD5/HMAC-SHA256)生成的 sign 结尾。

支付成功后的异步通知同样返回 XML,包含 result_code (SUCCESS)、transaction_id 及金额等信息,商户需根据 out_trade_no 更新本地订单状态,并返回 <xml><return_code>SUCCESS</return_code></xml> 告知微信服务器接收成功。

以上就是 PHP 微信支付 JSAPI 接口开发的详细内容,更多关于 PHP 支付集成的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表