php实现公众号支付demo,PHP微信公众号支付demo
备注:以下代码基于PHP laravel框架,引用了自带的函数。array_get($array, "key") 为数组中取元素,类似于$array["key"]
后端发起支付
/**
* 微信公众号支付请求
* @param $userOpenId 用户uid
* @param $orderNumber 商户订单编号
* @param $money 支付金额,元为单位
* @param $notify_url 回调地址
* @param $body 支付提醒文案
* @param $wechatConfig
* @return array|bool
*/
function wechatPay($userOpenId, $orderNumber, $money, $notify_url, $body, $wechatConfig)
{
//将预支付订单提交到微信支付
$url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; //微信统一下单请求地址
$data = [
"openid" => $userOpenId,
"appid" => array_get($wechatConfig, "app_id"), //微信appId
"mch_id" => array_get($wechatConfig, "merchant_id"), //微信商户id
"nonce_str" => uniqid(),
"body" => $body,
"out_trade_no" => $orderNumber,
"total_fee" => $money * 100, //微信订单金额以分为单位
"spbill_create_ip" => getClientIP(),
"notify_url" => $notify_url,
"trade_type" => "JSAPI",
];
$signData = wechat_sign($data, array_get($wechatConfig, "pay_miyao")); //获取签名,需要进入商户平台配置好支付秘钥
$data['sign'] = $signData;
$result = postXmlCurl(arrayToXml($data), $url, false, 30);
$result = xmlToArray($result);
if (array_get($result, "return_code") != "SUCCESS" && array_get($result, "result_code") != "SUCCESS") {
return false; //请求支付失败
}
$data = [
"appId" => array_get($wechatConfig, "app_id"),
"timeStamp" => (string)time(),
"nonceStr" => uniqid(),
"package" => "prepay_id=".array_get($result, "prepay_id"),
"signType" => "MD5",
];
$sign = wechat_sign($data, array_get($wechatConfig, "pay_miyao"));
$data["paySign"] = $sign;
return $data;
}
/**
* 微信支付签名
* @param $data 要加密的参数
* @param $pay_miyao 微信支付秘钥
* @return string
*/
function wechat_sign($data, $pay_miyao)
{
ksort($data);
$res = "";
foreach ($data as $key => $value) {
if (!$value) continue; //参数值为空时不参与签名
$res .= $key."=".$value."&";
}
$stringSignTemp = $res."key=".$pay_miyao;
return strtoupper(md5($stringSignTemp));
}
/**
* xml to array
* @param $result
*/
function xmlToArray($xml)
{
libxml_disable_entity_loader(true);
$result = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $result;
}
/**
* @param $arr
* @return string
*/
function arrayToXml($arr)
{
$xml = "";
foreach ($arr as $key=>$val) {
$xml.="".$val."".$key.">";
}
$xml.="";
return $xml;
}
/**
* 微信支付xml请求
* @param $xml
* @param $url
* @param bool $useCert
* @param int $second
* @return mixed
* @throws \Exception
*/
function postXmlCurl($xml, $url, $useCert = false, $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);
if($useCert == true){
//设置证书 微信支付不需要证书,此处证书验证可以忽略
//使用证书:cert 与 key 分别属于两个.pem文件
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLCERT, base_path("public/xxx/apiclient_cert.pem"));
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLKEY, base_path("public/xxx/apiclient_key.pem"));
}
//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);
throw new \Exception("curl出错,错误码:$error");
}
}
发起成功,微信正常返回demo
返回示例
{
"code": "0",
"msg": "请求成功",
"data": {
"payInfo": {
"appId": "wx04134e1774abedc3",
"timeStamp": "1561415899",
"nonceStr": "5d1150db6d2f1",
"package": "prepay_id=wx24153838009174ad41d109091656422500",
"signType": "MD5",
"paySign": "7D459540ACBA6A48BB3CA2E0DDB9453F"
}
}
}
微信支付回调
/**
* 微信支付回调
* @return string
*/
public function notify()
{
$request = file_get_contents("php://input");
$notifyArrData = xmlToArray($request);
//将回调签名单独拿出来
$sign = array_get($notifyArrData, "sign");
unset($notifyArrData['sign']);
//签名验证(商户平台配置,和请求支付的秘钥为同一个)
$miyao = "";
$signData = wechat_sign($notifyArrData, $miyao);
if ($signData != $sign) {
return arrayToXml(["return_code" => "FAIL", "return_msg" => "FAIL"]);
}
//支付结果验证
$resultCode = array_get($notifyArrData, "result_code");
$returnCode = array_get($notifyArrData, "return_code");
if ($resultCode != "SUCCESS" || $returnCode != "SUCCESS") {
return arrayToXml(["return_code" => "FAIL", "return_msg" => "FAIL"]);
}
$payOrderNumber = array_get($notifyArrData, "out_trade_no"); //获取商户支付订单号
$outOrderNumber = array_get($notifyArrData, "transaction_id"); //获取微信订单号
//设置订单支付成功(处理订单支付完成以后的业务逻辑)
$result = true;
if ($result) {
return arrayToXml(["return_code" => "SUCCESS", "return_msg" => "OK"]);
}
return arrayToXml(["return_code" => "FAIL", "return_msg" => "FAIL"]);
}
后记
剩下的事情就交给前端了,有什么问题可以留言哈。
php实现公众号支付demo,PHP微信公众号支付demo相关推荐
- php公众号提现功能,微信公众号打赏的钱怎么提现_微信公众号打赏功能_微信公众号打赏从哪里取出来...
微信公众号打赏的钱怎么提现,微信公众号打赏功能.微信公众号之前打赏功能可以立即取现,但是最近出现了一些变动,会有人问微信公众号打赏为什么不能立刻取现?小编为大家带来了微信公众号打赏取现时间调整. 微信 ...
- 如何开发微信公众号以及如何运营微信公众号
微信公众号已经成为了企业.个人和组织进行品牌推广.宣传和营销的重要平台.但是,如何开发和运营微信公众号并不是一件容易的事情.本文将从以下几个方面来介绍如何开发和运营微信公众号. 一.微信公众号的开发 ...
- h5网页使用微信支付JSAPI(申请微信服务号配置域名、获取用户code、配置JSAPI授权目录)
场景: 要在别人家的微信公众号内放入我们的h5网页,涉及到支付只能使用JSAPI支付.从一无所有到成功上线的记录--真难 官方链接地址 1. 微信服务号配置 前提:必须要有一个微信服务号,而且要完成微 ...
- 微信公众号数据2019_历史微信公众号排名,微信公众号新榜排名
历史微信公众号排名,微信公众号新榜排名 公众号排名优化的注意事项及细节今天给大家分享一下,作为微信公众号的排名优化对于大多数人来说都已经知道了有这个渠道的事情,其实很多的新产品及渠道出来以后有不少的人 ...
- silk lobe资源公众号_优化政务微信公众号实现资源共享
原标题:优化政务微信公众号实现资源共享 随着微信公众号和智能APP的兴起和广泛应用,越来越多的政府微信平台开始兴起.近年来,各级政府部门顺应大趋势,充分利用"互联网"技术开展政府服 ...
- qq公众平台出错了609_微信公众号粉丝去哪买?有哪些购买渠道?
微信公众号的粉丝是可以购买的,如果你申请了微信公众号,想要以营利为主的话,需要去不断的增加公众号粉丝的数量才行,这些粉丝现在是可以去购买到的,微信公众号粉丝去哪买呢? 1.可以找专业的平台去购买微信公 ...
- python爬取微信公众号_Python爬取微信公众号(中间人代理法)
1.环境:ubuntu16.04 + redis + mysql + python3.5 + anyproxy + android + pm2 + npm + node 一台爬虫服,python3环境 ...
- 广州医保个账支付接口开发 微信医保支付
一.背景说明 微信医保支付是由微信与各地人社局联合推出的"线上医保移动支付"的结算方式.对用户而言,在人社局指定的医院就医后,可以直接通过微信进行医保支付结算,无需线下窗口排队:对 ...
- java微信无感支付怎么开通_微信无感支付是什么,微信无感支付开通方法-下载吧...
微信无感支付是什么?现在已经是到了春运了,开车回家的人也是越来越多.现在开车行走在高速公路上时,缴费也是一件很方便的事情了,微信在最近也推出了"无感支付",下面和大家分享一下微信无 ...
- 腾讯:微信号能修改,微信帐号不允许修改
点击上方[全栈开发者社区]→右上角[...]→[设为星标⭐] 2020 年了,微信号终于可以修改了. 但是干完坏事,改个微信号就能溜之大吉? 你要知道微信号.微信帐号,是不一样的. 近期腾讯微信官方带 ...
最新文章
- fir滤波器c++程序_电气信息类专业课程之matlab系统仿真 第三章 滤波器的种类(1)...
- 基因分子生物学~强和弱化学键
- codevs1026 逃跑的拉尔夫(搜索)
- N - C语言实验——各位数字之和排序
- 使用eclipse搭建maven项目Java web项目
- 社会资源全整合 视频监控全覆盖
- 353万播放0转化背后,虚假繁荣的微博生态
- RGB和CMYK的区别
- pycharm 2018永久破解激活补丁 附安装教程
- Android Studio Emulator 报错 detected adb
- 读书笔记《推荐系统实战》| 好的推荐系统
- [学习SLAM]数学中的几何变换-向量叉乘/旋转轴、旋转角度和旋转矩阵/坐标系变换
- 傅里叶变换和小波变换:时间序列异常检测
- Unity3D 鼠标选择物体高光显示信息
- 【RW007系列综合实战3】柿饼派上怎样更新RW007固件和驱动?
- 【深度学习】时间注意力模块与空间注意力模块
- 零基础小白怎么自学UI设计?自学UI设计有什么方法?
- 高斯-约当(Gauss-Jordan)消元法——c++代码实现
- 大数据-大数据学习过程
- ds3617xs 华擎J3455 无线网卡m.2 E key接口扩展2个M.2 E key接口
热门文章
- 1.1	半导体基础知识
- matlab神经网络工具箱
- matlab神经网络训练方法,matlab神经网络模型导出
- c语言单片机用法,单片机 C语音开发 sbit使用方法··
- 【BCM】博通 linux-4.19 gcc-9.2 toolchain 环境搭建
- 计算机声音控制程序,win10电脑利用EarTrumpet音量控制应用程序使用教程 | 专业网吧维护...
- 学习《华为基本法》(6):公司的成长
- com.android.packageinstaller,Android PackageInstaller 安装和卸载
- HTML5 Audio时代的MIDI音乐文件播放 .
- 五子棋聊天java_java带聊天的五子棋 适合新手