返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >PHP 实现微信Native扫码支付
  • 438
分享到

PHP 实现微信Native扫码支付

开发语言php微信thinkphp 2023-09-25 13:09:25 438人浏览 安东尼
摘要

目录 一、安装微信SDK 二、准备请求资料 三、引入和定义 四、Native下单 五、Native调起支付 六、Native异步通知 一、安装微信SDK composer require wechatpay/wech

目录

一、安装微信SDK

二、准备请求资料

三、引入和定义

四、Native下单

五、Native调起支付

六、Native异步通知


一、安装微信SDK

composer require wechatpay/wechatpay

二、准备请求资料

appid:开放平台

mchid:商户平台

商户api证书:商户平台-账户中心-api安全(申请)

商户API秘钥:商户平台-账户中心-api安全(申请)

商户证书序列号:开放平台-API管理

apiv3_key:商户平台-api安全

微信支付平台证书:(在项目根目录执行命令,保证sdk已安装 证书保存文件夹已经创建 outputFilePath 保存地址是项目地址中的文件夹)

PHP vendor/bin/CertificateDownloader.php -k ${apiV3key} -m ${mchId} -f ${mchPrivateKeyFilePath} -s ${mchSerialNo} -o ${outputFilePath}

${apiV3key} 替换成apiV3key秘钥

${mchId} 替换成商户号

${mchPrivateKeyFilePath} 替换成商户私钥路径

${mchSerialNo} 替换成商户证书序列号

${outputFilePath} 替换成微信支付证书要保存的路径

三、引入和定义

use WeChatPay\Builder;use WeChatPay\Crypto\AesGCm;use WeChatPay\Crypto\Rsa;use WeChatPay\FORMatter;use WeChatPay\Util\PemUtil;    private const APPID     = '';        //appid    private const MCHID     = '';        //商户号    private const CERT_NUM  = '';        //商户证书序列号    private const APIV3_KEY = '';        //apiv3秘钥

四、Native下单

返回一个code_url 后端生成二维码显示给前端

    //Native下单    public function paymentCode($out_trade_no, $description, $notify_url, $total)    {        // 微信配置        $merchantId = self::MCHID;  // 商户号        $appid      = self::APPID;  // appid        // 从本地文件中加载「商户API私钥」,「商户API私钥」会用来生成请求的签名        $merchantPrivateKeyFilePath = 'file://' . ROOT_PATH . '\app\...私钥路径..\apiclient_key.pem';        $merchantPrivateKeyInstance =  Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);        // 「商户API证书」的「证书序列号」        $merchantCertificateSerial = self::CERT_NUM;        // 从本地文件中加载「微信支付平台证书」,用来验证微信支付应答的签名        $platformCertificateFilePath = 'file://' . ROOT_PATH . '\app\...支付证书路径...\wechatpay_123456.pem';        $platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);        // 从「微信支付平台证书」中获取「证书序列号」        $platformCertificateSerial = PemUtil::parseCertificateSerialNo($platformCertificateFilePath);        // 构造一个 APIv3 客户端实例        $instance = Builder::factory([            'mchid'      => $merchantId,            'serial'     => $merchantCertificateSerial,            'privateKey' => $merchantPrivateKeyInstance,            'certs'      => [                $platformCertificateSerial => $platformPublicKeyInstance,            ],        ]);        try {            $resp = $instance                ->chain('v3/pay/transactions/native')                ->post(['json' => [                    'mchid'        => $merchantId,                    'out_trade_no' => $out_trade_no,                    'appid'        => $appid,                    'description'  => $description,                    'notify_url'   => $notify_url,                    'amount'       => [                        'total'    => $total * 100,                        'currency' => 'CNY'                    ],                ]]);            echo $resp->getStatusCode(), PHP_EOL;            echo $resp->getBody(), PHP_EOL;        //返回的code_url        } catch (\Exception $e) {            // 进行错误处理                echo $e->getMessage(), PHP_EOL;            if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {                $r = $e->getResponse();                echo $r->getStatusCode() . ' ' . $r->getReasonPhrase(), PHP_EOL;                echo $r->getBody(), PHP_EOL, PHP_EOL, PHP_EOL;            }            echo $e->getTraceAsString(), PHP_EOL;        }    }

五、Native调起支付

用户扫码即调起

六、Native异步通知

    // 异步通知    public function wxPayNotify()    {        $headers = $this->request->header();        $inWechatpaySignature = $headers['wechatpay-signature'];   // 应答heade中对应数据:应答签名        $inWechatpayTimestamp = $headers['wechatpay-timestamp'];   // 应答heade中对应数据:应答时间戳        $inWechatpaySerial    = $headers['wechatpay-serial'];      // 应答heade中对应数据:应答平台证书序列号        $inWechatpayNonce     = $headers['wechatpay-nonce'];       // 应答heade中对应数据:应答随机字符串        $inBody               = file_get_contents('php://input');  // 应答主体:请根据实际情况获取,例如: file_get_contents('php://input');        $apiv3Key             = self::APIV3_KEY;                   // 在商户平台上设置的APIv3密钥        // 根据通知的平台证书序列号,查询本地平台证书文件,        $platformPublicKeyInstance = Rsa::from('file://' . ROOT_PATH . '\app\..路径..\wxpay_cert\wechatpay_1234563.pem', Rsa::KEY_TYPE_PUBLIC);        // 检查通知时间偏移量,允许5分钟之内的偏移        $timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int)$inWechatpayTimestamp);        $verifiedStatus   = Rsa::verify(            // 构造验签名串            Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, $inBody),            $inWechatpaySignature,            $platformPublicKeyInstance        );        if ($timeOffsetStatus && $verifiedStatus) {            // 转换通知的JSON文本消息为PHP Array数组            $inBodyArray = (array)json_decode($inBody, true);            // 使用PHP7的数据解构语法,从Array中解构并赋值变量            ['resource' => [                'ciphertext'      => $ciphertext,                'nonce'           => $nonce,                'associated_data' => $aad            ]] = $inBodyArray;            // 加密文本消息解密            $inBodyResource = AesGcm::decrypt($ciphertext, $apiv3Key, $nonce, $aad);            // 把解密后的文本转换为PHP Array数组            $inBodyResourceArray = (array)json_decode($inBodyResource, true);            // print_r($inBodyResourceArray); // 打印解密后的结果            $out_trade_no = $inBodyResourceArray['out_trade_no'];            $trade_state  = $inBodyResourceArray['trade_state'];            $total        = $inBodyResourceArray['amount']['total'];            if (Db::name('记录表')->where('out_trade_no', $out_trade_no)->find()) {                http_response_code(200);                $data =  [                    'code'    => 'SUCCESS',                    'message' => '成功'                ];                return json_encode($data);            } else {               //订单处理业务                http_response_code(200);                $data =  [                    'code'    => 'SUCCESS',                    'message' => '成功'                ];                return JSON_encode($data);            }        } else {            // 调用微信查询订单API        }    }}

来源地址:https://blog.csdn.net/arlene12345/article/details/130883343

--结束END--

本文标题: PHP 实现微信Native扫码支付

本文链接: https://lsjlt.com/news/417413.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作