原生PHP接入微信支付完整代码示例

前言:

这是完整的PHP接入微信支付的代码,供未开发过H5微信支付的小白参考,可以根据自己的实际情况进行修改。

效果:

原生PHP写的,可以直接对接微信H5支付

  • 获取必要的信息
  1. 公众号APPID
  2. 微信支付商户号 【上微信商户就有】
  3. APIKEY【账户设置-安全设置-API安全-API密钥-设置API密钥】
  4. 添加H5支付域名【产品中心-H5支付-开发配置-H5支付域名-新增自己的域名】

 

 

  • 代码说明
    1. 三个php代码,需要放在同一文件夹中
    2. dbFun.php  这个是数据库链接文件,进入修改数据库配置

 

                 3.wxPay.php 这是支付页面。请根据注释备注修改信息。

你的域名/wxPay.php?money=100&out_trade_no=222

修改对应的money值【金额,单位分】和out_trade_no【订单号】的值

代码:

dbFun.php:


<?php

// 数据库配置
/**
 * 请填写数据库信息
 */
$dbConfig = array(
    'DB_HOST'               => '127.0.0.1',
    'DB_NAME'               => 'fastadmin',   //数据库名
    'DB_USER'               => 'fastadmin',   //用户名
    'DB_PWD'                => 'qq577785156',  //密码
    'DB_PORT'               => '3306',
);




// 数据库连接
$dbLink = false;

// 连接数据库
function dbConnect()
{
    global $dbConfig;
    global $dbLink;

    $dbLink = mysqli_connect(
        $dbConfig['DB_HOST'],
        $dbConfig['DB_USER'],
        $dbConfig['DB_PWD'],
        $dbConfig['DB_NAME']
    );
    if (!($dbLink)) {
        return false;
    }

    mysqli_set_charset($dbLink, 'utf-8');
    return true;
}

// 获取多条记录
function dbSelect($lnk, $sql) {
    $res = mysqli_query($lnk, $sql);
    if (false === $res) {
        return false;
    }


    $cnt = mysqli_num_rows($res);
    if ($cnt == 0) {
        mysqli_free_result($res);
        return null;
    }

    $data = array();
    while ($row = mysqli_fetch_assoc($res)) {
        array_push($data, $row);
    }
    mysqli_free_result($res);

    return $data;
}

// 获取单条记录
function dbFind($lnk, $sql) {
    $res = mysqli_query($lnk, $sql);
    if (false === $res) {
        return false;
    }

    $cnt = mysqli_num_rows($res);
    if ($cnt == 0) {
        mysqli_free_result($res);
        return null;
    }

    $data = mysqli_fetch_assoc($res);
    mysqli_free_result($res);

    return $data;
}

// 执行数据库操作
function dbExecute($lnk, $sql) {
    $res = mysqli_query($lnk, $sql);
    if (false === $res) {
        return false;
    }

    return true;
}

// 生成订单编号
function generateOrderNo()
{
    global $dbLink;
    do {
        list($usec , $sec) = explode(' ', microtime());
        $s = sprintf('%s%03d%03d', date('YmdHis'), intval(floatval($usec) * 1000), rand(1, 999));
        $sql = sprintf('select id from t_activity_order where order_no="%s"', $s);
        $data = dbFind($dbLink, $sql);
        if (empty($data)) {
            return $s;
        }
    } while (true);
}

function payLog($msg)
{
    // 日志路径
    $path = '/zdrwkj/www/logs/pay-' . date('Y-m-d') . '.log';

    // 根据类型记录信息
    $s = $msg;
    $type = gettype($msg);
    if ($type == 'object' || $type == 'array') {
        $s = var_export($msg, true);
    }

    // 写入日志
    $fp = fopen($path, "a");
    fwrite($fp, date('Y-m-d H:i:s') . "\t");
    fwrite($fp, $s);
    fwrite($fp, "\r\n");
    fclose($fp);
}

?>

wxPay.php

<?php
$money= $_GET['money'];                     //充值金额 微信支付单位为分  --通过GET方式输出
$userip = get_client_ip();

//需要修改的内容
$appid  = "wx****a17";                  //公众号APPID 通过微信支付商户资料审核后邮件发送
$mch_id = "1****7751";                   //微信支付商户号 PartnerID 通过微信支付商户资料审核后邮件发送
$key    = "a12345****56789";                // 帐户设置-安全设置-API安全-API密钥-设置API密钥
$notify_url = "https://****.cn/testPay/getNotify.php";      //回调地址
$scene_info ='{"h5_info":{"type":"Wap","wap_url":"https://****.cn","wap_name":"支付"}}';//只要修改wap_url这个参数
$body = "H5充值";                       //名称
$out_trade_no = date('YmdHis').rand(1000,9999);   //订单号
//需要修改的内容


$nonce_str = createNoncestr();
$total_fee = $money;
$spbill_create_ip = $userip;
$trade_type = 'MWEB';//交易类型 具体看API 里面有详细介绍
$signA ="appid=$appid&attach=$out_trade_no&body=$body&mch_id=$mch_id&nonce_str=$nonce_str&notify_url=$notify_url&out_trade_no=$out_trade_no&scene_info=$scene_info&spbill_create_ip=$spbill_create_ip&total_fee=$total_fee&trade_type=$trade_type";
$strSignTmp = $signA."&key=$key"; //拼接字符串  注意顺序微信有个测试网址 顺序按照他的来 直接点下面的校正测试 包括下面XML  是否正确
$sign = strtoupper(MD5($strSignTmp)); // MD5 后转换成大写
$post_data = "<xml>
                    <appid>$appid</appid>
                    <mch_id>$mch_id</mch_id>
                    <body>$body</body>
                    <out_trade_no>$out_trade_no</out_trade_no>
                    <total_fee>$total_fee</total_fee>
                    <spbill_create_ip>$spbill_create_ip</spbill_create_ip>
                    <notify_url>$notify_url</notify_url>
                    <trade_type>$trade_type</trade_type>
                    <scene_info>$scene_info</scene_info>
                    <attach>$out_trade_no</attach>
                    <nonce_str>$nonce_str</nonce_str>
                    <sign>$sign</sign>
            </xml>";//拼接成XML 格式
$url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//微信传参地址
$dataxml = postXmlCurl($post_data,$url); //后台POST微信传参地址  同时取得微信返回的参数
$objectxml = (array)simplexml_load_string($dataxml, 'SimpleXMLElement', LIBXML_NOCDATA); //将微信返回的XML 转换成数组
function createNoncestr( $length = 32 ){
    $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
    $str ="";
    for ( $i = 0; $i < $length; $i++ )  {
        $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
    }
    return $str;
}
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);
    //设置header
    curl_setopt($ch, CURLOPT_HEADER, FALSE);
    //要求结果为字符串且输出到屏幕上
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    //post提交方式
    curl_setopt($ch, CURLOPT_POST, TRUE);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
    //运行curl
    $data = curl_exec($ch);
    //返回结果
    if($data){
        curl_close($ch);
        return $data;
    }else{
        $error = curl_errno($ch);
        curl_close($ch);
        echo "curl出错,错误码:$error"."<br>";
    }
}
function get_client_ip($type = 0) {
    $type       =  $type ? 1 : 0;
    $ip         =   'unknown';
    if ($ip !== 'unknown') return $ip[$type];
    if($_SERVER['HTTP_X_REAL_IP']){//nginx 代理模式下,获取客户端真实IP
        $ip=$_SERVER['HTTP_X_REAL_IP'];
    }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {//客户端的ip
        $ip     =   $_SERVER['HTTP_CLIENT_IP'];
    }elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {//浏览当前页面的用户计算机的网关
        $arr    =   explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        $pos    =   array_search('unknown',$arr);
        if(false !== $pos) unset($arr[$pos]);
        $ip     =   trim($arr[0]);
    }elseif (isset($_SERVER['REMOTE_ADDR'])) {
        $ip     =   $_SERVER['REMOTE_ADDR'];//浏览当前页面的用户计算机的ip地址
    }else{
        $ip=$_SERVER['REMOTE_ADDR'];
    }
    // IP地址合法验证
    $long = sprintf("%u",ip2long($ip));
    $ip   = $long ? array($ip, $long) : array('0.0.0.0', 0);
    return $ip[$type];
}
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>微信支付</title>
    <style type="text/css">
        body{
            font-family: "Microsoft YaHei";
        }
        .pay-box{
            position: absolute;
            top: 50%;
            margin-top: -516px;
            left: 50%;
            margin-left: -320px;
        }
        .ico{
            width: 240px;
            height: 240px;
            border-radius: 120px;
            background: #3FB837;
            color: #fff;
            display: inline-block;
            font-size: 160px;
            line-height: 240px;
        }
        .txt{
            font-size: 42px;
            padding-top: 30px;
            color: #333;
        }
        .val{
            font-size: 80px;
            font-weight: bold;
        }
        .pay{
            width: 640px;
            height: 100px;
            margin-top: 100px;
            padding: 20px;
            border-radius: 10px;
            font-size:42px;
            color: #fff;
            background: #07BF05;
            border: 0px;
            text-align: center;
        }
        a{
            color: #fff;
            background: transparent !important;
        }
    </style>
</head>
<body>
<div class="pay-box" style="text-align: center;">
    <div class="ico">
        ¥
    </div>
    <div class="txt">
        支付金额
    </div>
    <div class="val">
        ¥<span><?php echo $total_fee/100 ?></span>
        <!-- 这里使用原生PHP echo输出需要支付的价格 -->
    </div>
    <a class="pay" href="<?php echo $objectxml['mweb_url'] ?>"><button class="pay">确认支付</button></a>
    <!-- 这里点击调起微信支付页面 mweb_url  -->
</div>
</body>
</html>

getNotify.php

<?php
header('Access-Control-Allow-Origin: *');
header('Content-type:text/html; Charset=utf-8');
require_once "dbFun.php";
define('PHPS_PATH', dirname(__FILE__).DIRECTORY_SEPARATOR);


//===================================需要修改的资料==============================
$mchid = '15****51';          //微信支付商户号 PartnerID 通过微信支付商户资料审核后邮件发送
$appid = 'wx****a17';  //公众号APPID 通过微信支付商户资料审核后邮件发送
$apiKey = 'a12****56789';   // 帐户设置-安全设置-API安全-API密钥-设置API密钥
//===================================需要修改的资料==============================


$wxPay = new WxpayService_PC2($mchid,$appid,$apiKey);
$result = $wxPay->notify();
if($result){
    if(array_key_exists("return_code", $result)&& array_key_exists("result_code", $result)&& $result["return_code"] == "SUCCESS"&& $result["result_code"] == "SUCCESS"){
//===============================================完成你的逻辑======================================================
        //例如连接数据库,获取付款金额$result['total_fee'],获取订单号$result['out_trade_no'],修改数据库中的订单状态等;
        $postStr = file_get_contents('php://input');;
        $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
        $arr = (array)$postObj;
        $arr = json_encode($arr);    //这个就是所有信息数组
        dbConnect();    //链接数据库
        $out_trade_no = $arr['out_trade_no'];   //这是订单编号
        $total_fee  = $arr['total_fee'] ;   //这是付款金额,记得单位是分
        $sql = sprintf("INSERT INTO fa_wx_wish_b(rich_content) VALUES ('%s') ", $a);  //操作数据库的语句
        $activityOrder = dbExecute($dbLink, $sql);    //进行数据库操作
        
//===============================================完成你的逻辑======================================================
        mysqli_close($dbLink);  //关闭数据库
        return true;
    }

}else{
    dbConnect();
    $a = json_encode($_POST);
    $sql = sprintf("INSERT INTO fa_wx_wish_b(rich_content) VALUES ('%s') ", 'err');
    $activityOrder = dbExecute($dbLink, $sql);
    mysqli_close($dbLink);
    echo 'pay error';
}


class WxpayService_PC2
{
    protected $mchid;
    protected $appid;
    protected $apiKey;
    public function __construct($mchid, $appid, $key)
    {
        $this->mchid = $mchid;
        $this->appid = $appid;
        $this->apiKey = $key;
    }
    public function notify()
    {
        $config = array(
            'mch_id' => $this->mchid,
            'appid' => $this->appid,
            'key' => $this->apiKey,
        );
//        $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
        $postStr = file_get_contents('php://input');;
        $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
        if ($postObj === false) {
            die('parse xml error');
        }
        if ($postObj->return_code != 'SUCCESS') {
            die($postObj->return_msg);
        }
        if ($postObj->result_code != 'SUCCESS') {
            die($postObj->err_code);
        }
        $arr = (array)$postObj;
        unset($arr['sign']);
        if (self::getSign($arr, $config['key']) == $postObj->sign) {
            echo '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
            return $arr;
        }
    }
    /**
     * 获取签名
     */
    public static function getSign($params, $key)
    {
        ksort($params, SORT_STRING);
        $unSignParaString = self::formatQueryParaMap($params, false);
        $signStr = strtoupper(md5($unSignParaString . "&key=" . $key));
        return $signStr;
    }
    protected static 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;
    }
}

结尾:

欢迎大家补充、完善这篇文章,为后来者提供更多帮助。感谢!欢迎转载,分享有心,请保留转载地址,谢谢!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

阿桂

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

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

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

打赏作者

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

抵扣说明:

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

余额充值