微信二维码支付服务

随着移动支付的普及,微信成为了国内使用最广泛的支付方式之一。微信支付提供了多种支付方式,二维码支付也受到了越来越多用户的欢迎。本文将介绍如何使用PHP实现微信二维码支付。

一、前置条件

在开始之前,需要准备以下几个条件:

  1. 微信开发者账号
  2. 微信支付功能申请通过
  3. PHP开发环境的搭建
  4. 微信支付SDK

二、微信支付流程

微信支付的流程可以简单概括为以下几步:

  1. 用户打开商户的支付页面并选择支付方式
  2. 商户将用户的订单信息发送给微信支付
  3. 微信支付生成二维码并返回给商户
  4. 商户将二维码展示给用户
  5. 用户使用微信扫描二维码并完成支付
  6. 微信支付向商户发送支付结果通知

为了实现微信二维码支付,我们需要按照上述流程实现功能。

<?php

namespace common;


use app\common\controller\Common;
use app\common\model\LibWechatConfig;

/**
 * 提供微信支付服务管理服务
 * @name WxCodePay.php
 * @package jypp
 * @category model
 * @link http://www.chanekeji.com
 * @author mengchen
 * @version 1.0
 * @copyright CHANGE INC
 * @since 2023-02-15
 */
class WxPay
{
    public $key; //支付秘钥需要更改成自己的
    public $appId; //APPID需要更改为自己的
    public $mchId; //商户号需要更改成自己的
    public $secret; //开发者密码需要更改为自己的
    public $uoUrl = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; //无需更改 统一下单API地址
    public $notifyURL;   //支付通知地址需要更改成你自己服务器的地址

    public function __construct()
    {   
        $LibWechatConfig = new LibWechatConfig();
        $config = $LibWechatConfig->findConfigKeyValue('wechat');
        $this->appId = $config['wx_appid'];
        $this->mchId = $config['wx_mchid'];
        $this->secret = $config['wx_secret'];
        $this->key = $config['wx_pay_key'];
        $this->notifyURL = $config['wx_notify_url'];
    }

    //获取签名
    public function getSign($arr)
    {
        //去除数组的空值
        array_filter($arr);
        if (isset($arr['sign'])) {
            unset($arr['sign']);
        }
        //排序
        ksort($arr);
        //组装字符
        $str = $this->arrToUrl($arr) . '&key=' . $this->key;
        //使用md5 加密 转换成大写 
        return strtoupper(md5($str));
    }

    //获取带签名的数组
    public function setSign($arr)
    {
        $arr['sign'] = $this->getSign($arr);
        return $arr;
    }

    //校验签名
    public function checkSign($arr)
    {
        //生成新签名
        $sign = $this->getSign($arr);
        //和数组中原始签名比较
        if ($sign == $arr['sign']) {
            return true;
        } else {
            return false;
        }
    }

    //数组转URL字符串 不带key
    public function arrToUrl($arr)
    {
        return urldecode(http_build_query($arr));
    }

    //记录到文件
    public  function logs($file, $data)
    {
        $data = is_array($data) ? print_r($data, true) : $data;
        file_put_contents('./logs/' . $file, $data);
    }

    public function getPost()
    {
        return file_get_contents('php://input');
    }

    //Xml 文件转数组
    public function XmlToArr($xml)
    {
        if ($xml == '') return '';
        libxml_disable_entity_loader(true);
        $arr = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $arr;
    }

    //数组转XML
    public function ArrToXml($arr)
    {
        if (!is_array($arr) || count($arr) == 0) return '';

        $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;
    }

    //post 字符串到接口
    public function postStr($url, $postfields)
    {
        $ch = curl_init();
        $params[CURLOPT_URL] = $url;    //请求url地址
        $params[CURLOPT_HEADER] = false; //是否返回响应头信息
        $params[CURLOPT_RETURNTRANSFER] = true; //是否将结果返回
        $params[CURLOPT_FOLLOWLOCATION] = true; //是否重定向
        $params[CURLOPT_POST] = true;
        $params[CURLOPT_SSL_VERIFYPEER] = false; //禁用证书校验
        $params[CURLOPT_SSL_VERIFYHOST] = false;
        $params[CURLOPT_POSTFIELDS] = $postfields;
        curl_setopt_array($ch, $params); //传入curl参数
        $content = curl_exec($ch); //执行
        curl_close($ch); //关闭连接
        return $content;
    }

    //统一下单
    public function unifiedorder($params)
    {
        //获取到带签名的数组
        $params = $this->setSign($params);
        //数组转xml
        $xml = $this->ArrToXml($params);
        //发送数据到统一下单API地址
        $data = $this->postStr($this->uoUrl, $xml);
        $arr = $this->XmlToArr($data);
        if ($arr['result_code'] == 'SUCCESS' && $arr['return_code'] == 'SUCCESS') {
            return $arr;
        } else {
            $this->logs('error.txt', $data);
            return false;
        }
    }
}
    /**
     * 生成微信支付二维码
     */
    public function getWxpay($orderNum, $total, $body, $isH5 = false)
    {
        $pay = new WxPay();
        $tradeType = 'NATIVE';
        if ($isH5) {
            $tradeType = 'MWEB';
        }
        $params = [
            'appid' => $pay->appId,
            'mch_id' => $pay->mchId,
            'nonce_str' => md5(time()),
            'body' => $body,
            'out_trade_no' => $orderNum,
            'total_fee' => $total * 100,
            'spbill_create_ip' => $_SERVER['SERVER_ADDR'],
            'notify_url' => $pay->notifyURL,
            'trade_type' => $tradeType,
            'product_id' => $orderNum
        ];
        $result = $pay->unifiedorder($params);
        return $result['code_url'];
    }

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

swoole~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值