前言:
这是完整的PHP接入微信支付的代码,供未开发过H5微信支付的小白参考,可以根据自己的实际情况进行修改。
效果:
原生PHP写的,可以直接对接微信H5支付
- 获取必要的信息
- 公众号APPID
- 微信支付商户号 【上微信商户就有】
- APIKEY【账户设置-安全设置-API安全-API密钥-设置API密钥】
- 添加H5支付域名【产品中心-H5支付-开发配置-H5支付域名-新增自己的域名】
- 代码说明
- 三个php代码,需要放在同一文件夹中
- 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¬ify_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;
}
}
结尾:
欢迎大家补充、完善这篇文章,为后来者提供更多帮助。感谢!欢迎转载,分享有心,请保留转载地址,谢谢!