php 微信native扫码支付

7 篇文章 1 订阅
4 篇文章 0 订阅

 Native支付是商户系统按微信支付协议生成支付二维码,用户再用微信“扫一扫”完成支付的模式。该模式适用于PC网站支付、实体店单品或订单支付、媒体广告支付等场景。

支付类:

<?php

/**
 * Created by PhpStorm.
 * User: 827169570@qq.com
 * Date: 2020/10/16
 * Time: 23:01
 */
namespace app\v1\controller;


use app\common\controller\Checking;
use think\Controller;
use think\Exception;

class Wxnative extends Controller
{
    const APPID='';
    const MCHID='';
    const KEY='';
    const NOTIFYURL='';//支付成功异步回调地址
    //微信支付参数
    /**
     * 微信支付-发起订单.
     *
     * @param float  $totalFee   收款总费用 单位元
     * @param string $outTradeNo 唯一的订单号
     * @param string $orderName  订单名称
     * @param string $notifyUrl  支付结果通知url 不要有问号
     * @param string $timestamp  订单发起时间
     *
     * @return array
     */
    public function wxNativePay($totalFee, $outTradeNo, $body= '充值'){
        header('Content-type:text/html; Charset=utf-8');
//
//        $totalFee=0.01; $outTradeNo=time();$orderName = '充值';
        //获取微信支付参数
        //订单发起时间
        $timestamp = time();
        $unified = array(
            'appid' => self::APPID,
            'attach' => 'pay',
            'body' => $body,
            'mch_id' => self::MCHID,
            'nonce_str' => $this->createNonceStr(),
            'notify_url' => self::NOTIFYURL,
            'out_trade_no' => $outTradeNo,
            'spbill_create_ip' => $this->get_client_ip(),
            'total_fee' => intval($totalFee * 100),//单位 转为分
            'trade_type' => 'NATIVE',
        );
        $unified['sign'] = $this->getSign($unified, self::KEY);
        $responseXml = $this->curlPost('https://api.mch.weixin.qq.com/pay/unifiedorder', $this->arrayToXml($unified));

        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $unifiedOrder = simplexml_load_string($responseXml, 'SimpleXMLElement', LIBXML_NOCDATA);

        if (false === $unifiedOrder) {
            Checking::response(201,'parse xml error');
        }
        if ('SUCCESS' != $unifiedOrder->return_code) {
            Checking::response(202,$unifiedOrder->return_msg);
        }
        if ('SUCCESS' != $unifiedOrder->result_code) {
            Checking::response(203,$unifiedOrder->err_code);
        }
        $codeUrl = (array) ($unifiedOrder->code_url);
        if (!$codeUrl[0]) {
            Checking::response(203,'get code_url error');
        }
        //生成二维码 这里利用qrcode类库生成的二维码  可根据自己业务进行修改
        return $this->wePayQRCode($codeUrl[0]);

    }

    //获取随机字符串-weChatPay
    public function createNonceStr($length = 16){
        $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        $str = '';
        for ($i = 0; $i < $length; ++$i) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }

    //获取当前服务器时间-weChatPay
    public function get_client_ip(){
        if ($_SERVER['REMOTE_ADDR']) {
            $cip = $_SERVER['REMOTE_ADDR'];
        } elseif (getenv('REMOTE_ADDR')) {
            $cip = getenv('REMOTE_ADDR');
        } elseif (getenv('HTTP_CLIENT_IP')) {
            $cip = getenv('HTTP_CLIENT_IP');
        } else {
            $cip = 'unknown';
        }
        return $cip;
    }

    //获取签名
    public function getSign($params, $key){
        ksort($params, SORT_STRING);
        $unSignParaString = $this->formatQueryParaMap($params, false);
        $signStr = strtoupper(md5($unSignParaString.'&key='.$key));
        return $signStr;
    }

    //生成签名
    public function formatQueryParaMap($paraMap, $urlEncode = false){
        $buff = '';
        ksort($paraMap);
        foreach ($paraMap as $k => $v) {
            if (null != $v && 'null' != $v) {
                if ($urlEncode) {
                    $v = urlencode($v);
                }
                $buff .= $k.'='.$v.'&';
            }
        }
        $reqPar = '';
        if (strlen($buff) > 0) {
            $reqPar = substr($buff, 0, strlen($buff) - 1);
        }
        return $reqPar;
    }

    //发送微信支付请求
    public function curlPost($url = '', $postData = '', $options = array())
    {
        if (is_array($postData)) {
            $postData = http_build_query($postData);
        }
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数
        if (!empty($options)) {
            curl_setopt_array($ch, $options);
        }
        //https请求 不验证证书和host
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $data = curl_exec($ch);
        curl_close($ch);
        return $data;
    }

    //将数组转为xml
    public function arrayToXml($arr){
        $xml = '<xml>';
        foreach ($arr as $key => $val) {
            if (is_numeric($val)) {
                $xml .= '<'.$key.'>'.$val.'</'.$key.'>';
            } else {
                $xml .= '<'.$key.'><![CDATA['.$val.']]></'.$key.'>';
            }
        }
        $xml .= '</xml>';
        return $xml;
    }

    //生成微信支付二维码
    public function wePayQRCode($url){
        include '../extend/wxPay/example/phpqrcode/phpqrcode.php';
        $value = $url;//二维码内容
        $errorCorrectionLevel = 'L';//容错级别
        $matrixPointSize = 5;//生成图片大小
        //生成二维码图片
        try {
            $filename = 'qrcode/'.'local'.time().'.png';
            \QRcode::png($value, $filename, $errorCorrectionLevel, $matrixPointSize, 2);
            $QR = $filename;//已经生成的原始二维码图片文件
            $QR = imagecreatefromstring(file_get_contents($QR));
            //输出图片
            imagepng($QR, 'qrcode/'.'qrcode.png');
            imagedestroy($QR);
            return $filename;
        }catch (Exception $exception){
            Checking::response($exception->getCode(),$exception->getMessage());
        }

    }
}

 调用支付

 $wx= new Wxnative();
 $order_num=Checking::orderNum();
 $payUrl= API_URL.'/'.$wx->wxNativePay($money,$order_num);

回调数据接收

public function wxpayNotify(){
        $params = trim(file_get_contents('php://input'));
        $xml = (array)simplexml_load_string( $params, 'SimpleXMLElement', LIBXML_NOCDATA ); //将微信返回的XML 转换成数组
        if ('SUCCESS' == $xml['return_code']) {
            //成功回调异步通知地址
            //订单支付成功
            $data['out_trade_no'] = $xml['out_trade_no'];
            $data['pay_number'] = $xml['openid'];
            $data['trade_num'] = $xml['transaction_id'];
            $data['pay_time'] = $xml['time_end'];
            Checking::writeLog(json_encode($data),'回调开始','newWxpay.txt');
            Db::startTrans();
            try {
                #业务逻辑
        } else {
            Db::rollback();
            Checking::writeLog('异步通知地址回调失败','异步通知地址回调失败','newWxpay.txt');
        }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦夏夜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值