php微信H5支付V3版

php微信H5支付V3版
    /**
     * todo 微信支付下单
     * @param Request $request
     */
    public function unifiedOrder(Request $request)
    {
        $body = [
            'appid' => config('xingji_wechatpay_v3.appid'),
            'mchid' => config('xingji_wechatpay_v3.mch_id'),
            'description' => '描述',
            'out_trade_no' => $phone . '_' . time(),
            'notify_url' => $this->notify_url,
            'amount' => [
                'total' => $money,
                'currency' => 'CNY'
            ],
            'scene_info' => [
                'payer_client_ip' => $request->ip(),
                'h5_info' => [
                    'type' => 'Wap',
                ],
            ],
        ];
        $server = $request->server();
        $headers = self::sign('POST', 'https://api.mch.weixin.qq.com/v3/pay/transactions/h5', json_encode($body));
        $http = new Client([
            'headers' => $headers
        ]);
        $response = $http->post('https://api.mch.weixin.qq.com/v3/pay/transactions/h5', [
            'json' => $body
        ]);
        $result = json_decode($response->getBody()->getContents(), true);

        $returnUrl = "支付完成跳转地址";
        $headers = [
            'REFERER' => $returnUrl,
            'USER-AGENT' => $server["HTTP_USER_AGENT"],
        ];
        $url = $result['h5_url'] . "&redirect_url=" . urlencode($returnUrl);
        $client = new Client();
        $response = $client->post($url, [
            'headers' => $headers,
            'verify' => false,
        ]);
        $body = $response->getBody()->getContents();
        echo $body;
        exit;
    }
 /**
     * 签名
     * @param string $http_method 请求方式GET|POST
     * @param string $url url
     * @param string $body 报文主体
     * @return array
     */
    public static function sign($http_method = 'POST', $url = '', $body = '')
    {
        $mch_private_key = self::getMchKey();//私钥
        $timestamp = time();//时间戳
        $nonce = self::getRandomStr(32);//随机串
        $url_parts = parse_url($url);
        $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
        //构造签名串
        $message = $http_method . "\n" .
            $canonical_url . "\n" .
            $timestamp . "\n" .
            $nonce . "\n" .
            $body . "\n";//报文主体
        //计算签名值
        openssl_sign($message, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption');
        $sign = base64_encode($raw_sign);
        //设置HTTP头
        $token = sprintf('WECHATPAY2-SHA256-RSA2048 mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',
            config('xingji_wechatpay_v3.mch_id'), $nonce, $timestamp, config('xingji_wechatpay_v3.serial_no'), $sign);
        return [
            'Accept' => 'application/json',
            'User-Agent' => '*/*',
            'Content-Type' => 'application/json; charset=utf-8',
            'Authorization' => $token
        ];
    }

    //读取私钥
    public static function getMchKey()
    {
        return openssl_get_privatekey(file_get_contents('apiclient_key.pem'));
    }

    /**
     * 获得随机字符串
     * @param $len      integer       需要的长度
     * @param $special  bool      是否需要特殊符号
     * @return string       返回随机字符串
     */
    public static function getRandomStr($len, $special = false)
    {
        $chars = [
            "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
            "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
            "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G",
            "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
            "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2",
            "3", "4", "5", "6", "7", "8", "9"
        ];
        if ($special) {
            $chars = array_merge($chars, [
                "!", "@", "#", "$", "?", "|", "{", "/", ":", ";",
                "%", "^", "&", "*", "(", ")", "-", "_", "[", "]",
                "}", "<", ">", "~", "+", "=", ",", "."
            ]);
        }
        $charsLen = count($chars) - 1;
        shuffle($chars);
        $str = '';
        for ($i = 0; $i < $len; $i++) {
            $str .= $chars[mt_rand(0, $charsLen)];
        }
        return $str;
    }
### PHP 实现微信支付 H5 V3 #### 准备工作 为了成功集成微信支付H5 V3,在PHP环境中需完成如下准备工作: - 获取商户号(`mch_id`)、API密钥(`api_key`)以及V3 API密钥(`api_v3_key`) - 下载并配置证书文件路径(`cert_path`), 包括私钥和公钥 - 设置回调通知URL (`notify_url`) - 安装必要的依赖库,如cURL用于发起HTTP请求[^1] #### 创建预订单接口调用实例 创建预订单是启动支付流程的第一步。下面是一个简单的PHP函数来构建此过程。 ```php <?php function createPreorder($total_fee, $out_trade_no){ // 构建请求体参数 $data = [ &#39;appid&#39; => &#39;YOUR_APPID&#39;, &#39;mchid&#39; => &#39;YOUR_MCH_ID&#39;, &#39;description&#39; => &#39;商品描述&#39;, &#39;out_trade_no&#39;=> $out_trade_no, "time_expire"=> date(&#39;YmdHis&#39;, strtotime(&#39;+1 hour&#39;)), "amount"=>[ "total"=>$total_fee * 100,//单位转换成分为整数形式 "currency"=>"CNY" ], "scene_info"=>[ "payer_client_ip"=>$_SERVER[&#39;REMOTE_ADDR&#39;], "device_type"=>"WEB", "h5_info"=>["type"=>"Wap"] ] ]; // 将数据编码为JSON字符串,并设置签名算法等必要头信息 $json_data=json_encode($data); $url="https://api.mch.weixin.qq.com/v3/pay/transactions/h5"; // 使用curl发送POST请求... } ?> ``` #### 处理响应与生成前端跳转链接 当收到成功的预付单返回后,则可以解析其结果以获取交易会话标识符(`prepay_id`),进而构造最终的重定向地址供浏览器访问。 ```php // 假设已获得$prepay_id变量存储着有效的预付款ID $h5PayUrl = sprintf( &#39;weixin://wxpay/bizpayurl?sign=%s&prepay_id=%s&package=Sign=WXPay&#39;, generateSignature(), // 自定义方法生成签名 urlencode($prepay_id) ); header("Location: {$h5PayUrl}"); exit(); ``` #### 验证服务器端的通知消息 每当发生状态变化时(比如支付成功),微信将会向指定的`notify_url`推送事件更新。因此需要编写逻辑处理这些异步通知。 ```php <?php // 解析来自微信服务器的数据包... if (verifyNotification()) { // 自定义验证函数 file_put_contents(&#39;./log.txt&#39;,"Payment received", FILE_APPEND | LOCK_EX ); } else { http_response_code(400); die(&#39;Invalid signature&#39;); } http_response_code(200); echo json_encode([&#39;return_code&#39;=>&#39;SUCCESS&#39;]); ?> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值