当前位置:首页 > 行业动态 > 正文

如何利用PHP源码实现微信支付功能?

微信支付源码通常涉及多个文件和复杂的逻辑,无法在2050个字内完整展示。

<?php
class WechatPay
{
    private $appid;
    private $mch_id;
    private $key;
    private $notify_url;
    public function __construct($appid, $mch_id, $key, $notify_url)
    {
        $this>appid = $appid;
        $this>mch_id = $mch_id;
        $this>key = $key;
        $this>notify_url = $notify_url;
    }
    public function createOrder($out_trade_no, $total_fee, $body, $spbill_create_ip, $trade_type = 'JSAPI', $openid = '')
    {
        $params = [
            'appid' => $this>appid,
            'mch_id' => $this>mch_id,
            'nonce_str' => $this>getNonceStr(),
            'body' => $body,
            'out_trade_no' => $out_trade_no,
            'total_fee' => $total_fee,
            'spbill_create_ip' => $spbill_create_ip,
            'notify_url' => $this>notify_url,
            'trade_type' => $trade_type,
        ];
        if ($trade_type == 'JSAPI') {
            $params['openid'] = $openid;
        }
        $params['sign'] = $this>getSign($params);
        $xml = $this>arrayToXml($params);
        $response = $this>postXmlCurl($xml, 'https://api.mch.weixin.qq.com/pay/unifiedorder');
        $result = $this>xmlToArray($response);
        if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
            if ($trade_type == 'JSAPI') {
                $prepay_id = $result['prepay_id'];
                $params = [
                    'appId' => $this>appid,
                    'timeStamp' => strval(time()),
                    'nonceStr' => $this>getNonceStr(),
                    'package' => "prepay_id={$prepay_id}",
                    'signType' => 'MD5',
                ];
                $params['paySign'] = $this>getSign($params);
                return json_encode($params);
            } else {
                return $result;
            }
        } else {
            return false;
        }
    }
    public function handleNotify()
    {
        $data = file_get_contents("php://input");
        if (!empty($data)) {
            $data = simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA);
            $data = json_decode(json_encode($data), true);
            if ($data['return_code'] == 'SUCCESS' && $data['result_code'] == 'SUCCESS') {
                // 验证签名
                if ($this>checkSign($data)) {
                    // 处理业务逻辑,例如更新订单状态等
                    return 'SUCCESS';
                } else {
                    return 'FAIL';
                }
            } else {
                return 'FAIL';
            }
        } else {
            return 'FAIL';
        }
    }
    private function getNonceStr($length = 32)
    {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars)  1), 1);
        }
        return $str;
    }
    private function getSign($params)
    {
        ksort($params);
        $string = $this>toUrlParams($params);
        $string = "{$string}&key={$this>key}";
        $string = md5($string);
        return strtoupper($string);
    }
    private function checkSign($params)
    {
        $sign = $params['sign'];
        unset($params['sign']);
        ksort($params);
        $string = $this>toUrlParams($params);
        $string = "{$string}&key={$this>key}";
        $string = md5($string);
        return strtoupper($string) == $sign;
    }
    private function toUrlParams($params)
    {
        $buff = "";
        foreach ($params as $k => $v) {
            if ($k != "sign" && $v != "" && !is_array($v)) {
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }
    private 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;
    }
    private function xmlToArray($xml)
    {
        libxml_disable_entity_loader(true);
        $arr = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $arr;
    }
    private function postXmlCurl($xml, $url, $second = 30)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['ContentType: text/xml']);
        $data = curl_exec($ch);
        curl_close($ch);
        return $data;
    }
}

使用方法:

如何利用PHP源码实现微信支付功能?  第1张

$wechatPay = new WechatPay('your_appid', 'your_mch_id', 'your_key', 'your_notify_url');
$out_trade_no = 'your_out_trade_no'; // 商户订单号
$total_fee = 100; // 支付金额,单位为分
$body = '商品描述'; // 商品描述
$spbill_create_ip = 'user_ip'; // 用户IP地址
$trade_type = 'JSAPI'; // 交易类型,可选值为JSAPI、NATIVE、APP等
$openid = 'user_openid'; // 用户在商户appid下的唯一标识,仅适用于JSAPI支付方式
$result = $wechatPay>createOrder($out_trade_no, $total_fee, $body, $spbill_create_ip, $trade_type, $openid);
echo $result; // 输出给前端的参数,用于调起支付接口

各位小伙伴们,我刚刚为大家分享了有关“php微信支付源码”的知识,希望对你们有所帮助。如果您还有其他相关问题需要解决,欢迎随时提出哦!

0