thinkphp6实现微信V3服务商支付接口

本文档介绍了如何在微信支付服务商平台上实现V3版的预支付流程,包括生成prepay_id和构建H5支付参数。详细步骤包括设置必要的商户信息,调用API获取预支付ID,然后构建包含签名的H5支付参数。同时,展示了如何进行RSA签名和验签的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文档还是要看一看的,虽然看完还不能马上写,熟悉下流程和概念

微软文档中心:产品能力概览 | 微信支付服务商平台文档中心

微信提供了SDK,有JAVA和PHP,安装后可使用,然而我不喜欢那么大块的程序,只要需要的那部分。

准备好服务商mchid,子账号mchid,公众号APPID,商户密钥,商户证书号,不懂请自行百度

第一步,生产prepay_id

$post_data = [
            "sp_mchid" => $sp_mchid,//服务商MCHID
            "sub_mchid" => $sub_mchid,//子账号MCHID
            "out_trade_no" => $query['sn'],//订单号
            "sp_appid" => $sp_appid,//公众号APPID
            "sub_appid" => "",//子账号APPID
            "description" => "七算宝车辆管理",
            "notify_url" => $notify_url,//支付通知URL
            "amount" => [
                "total" => $amount * 100,//支付金额
                "currency" => "CNY"
            ],
            "payer" => [
                "sp_openid" => $wxopenid//付款人opendid,如果未登录状态可静默获取
            ],
            'attach' => '',
        ];        
        $result = $this->wx_post($url, json_encode($post_data));      
        $result = json_decode($result, true);
        if (isset($result['prepay_id'])) {
            return $result['prepay_id'];
        }
        return json_encode($result, JSON_UNESCAPED_UNICODE);

第二步:构建H5端需要的参数,跟V2版差不多,直连模式也是这样。

注意参数中的大小写,不能错,服务商版需多返回appId这个

$pay_body = 'prepay_id=' . $this->getwxpayv3_payid($query);
        $timestamp = time();
        $nonce = createNonceStr(32);
        $sslKeyPath = '../partnerwxcert/apiclient_key.pem';//服务商私钥路径
        $private_key = $this->getPrivateKey($sslKeyPath);
        $message = $sp_appid . "\n" . $timestamp . "\n" . $nonce . "\n" . $pay_body . "\n";
//获得签名
        openssl_sign($message, $signature, $private_key, 'sha256WithRSAEncryption');
        $sign = base64_encode($signature);
        $data = array(
            'appId' => $this->sp_appid,
            'timeStamp' => $timestamp,
            'nonceStr' => $nonce,
            'package' => $pay_body,
            'signType' => 'RSA',
            'paySign' => $sign,
        );
        return json_encode($data, JSON_UNESCAPED_UNICODE);

补充:V3版发送的参数需要在header加入验签和2个参数

private function wx_post($url, $param)
    {
        $authorization = $this->getV3Sign($url, "POST", $param);
        $curl = curl_init();
        $headers = [
            'Authorization:' . $authorization,
            'Accept:application/json',
            'Content-Type:application/json;charset=utf-8',
            'User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
        ];
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 500);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $param);
        curl_setopt($curl, CURLOPT_POST, true);
        $res = curl_exec($curl);
        curl_close($curl);
        return $res;
    }
    private function getV3Sign($url, $http_method, $body)
    {
        $mchid = $this->sp_mchid;
        $nonce = strtoupper(createNonceStr(32));
        $serialNo = $this->serial;
        $timestamp = time();
        $url_parts = parse_url($url);
        $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
        $sslKeyPath = '../partnerwxcert/apiclient_key.pem';
        //拼接参数
        $message = $http_method . "\n" .
            $canonical_url . "\n" .
            $timestamp . "\n" .
            $nonce . "\n" .
            $body . "\n";
        $private_key = $this->getPrivateKey($sslKeyPath);
        openssl_sign($message, $raw_sign, $private_key, 'sha256WithRSAEncryption');
        $sign   = base64_encode($raw_sign);
        $token = sprintf('WECHATPAY2-SHA256-RSA2048 mchid="%s",nonce_str="%s",timestamp="%s",serial_no="%s",signature="%s"', $this->sp_mchid, $nonce, $timestamp, $this->serial, $sign);
        return $token;
    }

32位随机数

function createNonceStr($length = 16) { //生成随机16个字符的字符串
    $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    $str = "";
    for ($i = 0; $i < $length; $i++) {
        $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
    }
    return $str;
}

获取密钥

private function getPrivateKey($filepath = '')
    {
        if (empty($filepath)) {
            $filepath = '../partnerwxcert/apiclient_key.pem';
        }
        return openssl_get_privatekey(file_get_contents($filepath));
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值