php实现微信支付之退款功能
时间:2019-04-15
本文章向大家介绍php实现微信支付之退款功能,主要包括php实现微信支付之退款功能使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
网上的很多PHP微信支付接入教程都颇为复杂,且需要配置和引入较多的文件,本人通过整理后给出一个单文件版的,希望可以给各位想接入微信支付的带来些许帮助和借鉴意义。
直接运行该文件即可给指定的微信用户退款。
需要注意的事项:
1.微信退款到零钱要求必传证书,需要到这里账户中心->账户设置->API安全->下载证书,然后修改代码中的证书路径
2.该文件需放到支付授权目录下,可以在微信支付商户平台->产品中心->开发配置中设置。
3.如提示签名错误可以通过微信支付签名验证工具进行验证:微信公众平台支付接口调试工具
4.错误码参照:参照地址
代码如下:
<?php /** * 关于微信退款的说明 * 1.微信退款要求必传证书,需要到https://pay.weixin.qq.com 账户中心->账户设置->API安全->下载证书,证书路径在第119行和122行修改 * 2.错误码参照 :https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4 */ header('Content-type:text/html; Charset=utf-8'); $mchid = 'xxxxx'; //微信支付商户号 PartnerID 通过微信支付商户资料审核后邮件发送 $appid = 'xxxxx'; //微信支付申请对应的公众号的APPID $apiKey = 'xxxxx'; //https://pay.weixin.qq.com 帐户设置-安全设置-API安全-API密钥-设置API密钥 $orderNo = ''; //商户订单号(商户订单号与微信订单号二选一,至少填一个) $wxOrderNo = ''; //微信订单号(商户订单号与微信订单号二选一,至少填一个) $totalFee = 0.01; //订单金额,单位:元 $refundFee = 0.01; //退款金额,单位:元 $refundNo = 'refund_'.uniqid(); //退款订单号(可随机生成) $wxPay = new WxpayService($mchid,$appid,$apiKey); $result = $wxPay->doRefund($totalFee, $refundFee, $refundNo, $wxOrderNo,$orderNo); if($result===true){ echo 'refund success';exit(); } echo 'refund fail'; class WxpayService { protected $mchid; protected $appid; protected $apiKey; public $data = null; public function __construct($mchid, $appid, $key) { $this->mchid = $mchid; //https://pay.weixin.qq.com 产品中心-开发配置-商户号 $this->appid = $appid; //微信支付申请对应的公众号的APPID $this->apiKey = $key; //https://pay.weixin.qq.com 帐户设置-安全设置-API安全-API密钥-设置API密钥 } /** * 退款 * @param float $totalFee 订单金额 单位元 * @param float $refundFee 退款金额 单位元 * @param string $refundNo 退款单号 * @param string $wxOrderNo 微信订单号 * @param string $orderNo 商户订单号 * @return string */ public function doRefund($totalFee, $refundFee, $refundNo, $wxOrderNo='',$orderNo='') { $config = array( 'mch_id' => $this->mchid, 'appid' => $this->appid, 'key' => $this->apiKey, ); $unified = array( 'appid' => $config['appid'], 'mch_id' => $config['mch_id'], 'nonce_str' => self::createNonceStr(), 'total_fee' => intval($totalFee * 100), //订单金额 单位 转为分 'refund_fee' => intval($refundFee * 100), //退款金额 单位 转为分 'sign_type' => 'MD5', //签名类型 支持HMAC-SHA256和MD5,默认为MD5 'transaction_id'=>$wxOrderNo, //微信订单号 'out_trade_no'=>$orderNo, //商户订单号 'out_refund_no'=>$refundNo, //商户退款单号 'refund_desc'=>'商品已售完', //退款原因(选填) ); $unified['sign'] = self::getSign($unified, $config['key']); $responseXml = $this->curlPost('https://api.mch.weixin.qq.com/secapi/pay/refund', self::arrayToXml($unified)); $unifiedOrder = simplexml_load_string($responseXml, 'SimpleXMLElement', LIBXML_NOCDATA); if ($unifiedOrder === false) { die('parse xml error'); } if ($unifiedOrder->return_code != 'SUCCESS') { die($unifiedOrder->return_msg); } if ($unifiedOrder->result_code != 'SUCCESS') { die($unifiedOrder->err_code); } return true; } public static function curlGet($url = '', $options = array()) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 30); if (!empty($options)) { curl_setopt_array($ch, $options); } //https请求 不验证证书和host curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $data = curl_exec($ch); curl_close($ch); return $data; } public function curlPost($url = '', $postData = '', $options = array()) { if (is_array($postData)) { $postData = http_build_query($postData); } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数 if (!empty($options)) { curl_setopt_array($ch, $options); } //https请求 不验证证书和host curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //第一种方法,cert 与 key 分别属于两个.pem文件 //默认格式为PEM,可以注释 curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/cert/apiclient_cert.pem'); //默认格式为PEM,可以注释 curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLKEY,getcwd().'/cert/apiclient_key.pem'); //第二种方式,两个文件合成一个.pem文件 // curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/all.pem'); $data = curl_exec($ch); curl_close($ch); return $data; } public static function createNonceStr($length = 16) { $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; $str = ''; for ($i = 0; $i < $length; $i++) { $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } public static 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; } 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; } } ?>
github下载地址
相关文章:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
- (24) 异常 (上) / 计算机程序的思维逻辑
- Python3.6新特性官方文档中文版
- (23) 枚举的本质 / 计算机程序的思维逻辑
- (22) 代码的组织机制 / 计算机程序的思维逻辑
- Python开发微信公众号后台(系列二)
- (21) 内部类的本质 / 计算机程序的思维逻辑
- (20) 为什么要有抽象类? / 计算机程序的思维逻辑
- Python云计算框架:Openstack源码分析之RabbitMQ(一)
- (38) 剖析ArrayList / 计算机程序的思维逻辑
- 破解验证,让爬取更随心所欲!
- Visual Studio Code v0.9.1 发布
- (39) 剖析LinkedList / 计算机程序的思维逻辑
- 我的Android进阶之旅------>Android采用AES+RSA的加密机制对http请求进行加密
- 看到那个Edward 了吗?对!其实它是个Python库
- php概述
- php教程
- php环境搭建
- PHP书写格式
- php变量
- php常量
- PHP注释
- php数组
- php字符串 string
- PHP整型 integer
- PHP浮点型 float
- php布尔型
- php数据类型之数组
- php数据类型之对象
- php数据类型之null
- php数据类型之间的转换
- php运算符
- php表达式
- PHP循环控制
- PHP流程控制
- php函数
- php全局变量
- PHP魔术变量
- php命名空间
- php 日期
- PHP包含文件
- php文件
- PHP 文件上传
- php Cookies
- php Sessions
- php email
- php安全email
- php错误处理
- PHP异常处理
- php过滤器
- PHP 高级过滤器
- php json
- php 表单
- PHP MySQL 简介
- PHP 连接 MySQL
- php创建数据库
- php 创建表
- php mysq 插入数据
- PHP MySQL 插入多条数据
- PHP MySQL 预处理语句
- php mysql 读取数据
- php mysql where
- PHP MySQL Order By
- PHP MySQL Update
- PHP MySQL Delete
- php ODBC
- Springboot thymeleaf热部署
- Java初始化List的6种方式
- Java遍历Map对象的四种方式
- 【SpringBoot源码解析】第三章:SpringBoot通过打成war包的方式是如何启动的
- 让你编码嗨到停不下来的8个VSCode插件
- 【SpringBoot源码解析】第四章:SpringBoot是如何自动装配SpringMvc的
- 【SpringBoot源码解析】第二章:SpringBoot是如何通过内置Tomcat启动的
- 技术译文 | How Can ScaleFlux Handle MySQL Workload?
- 技术译文 | MySQL 8 需要多大的 innodb_buffer_pool_instances 值(上)
- 前端登录,这一篇就够了
- 技术译文 | MySQL 8 需要多大的 innodb_buffer_pool_instances 值(下)
- 创建线程到底有多少种方式?
- CANet|拼接注意力网络
- SQL 中判断条件的先后顺序,会引起索引失效么?
- 一个超酷的开源uHand2.0机械手掌项目