• Linux
  • apache
  • centos
  • Git版本管理
  • Linux基本命令
  • linux配置与优化
  • Nginx
  • PHP
  • Redis
  • Supervisor
  • Swoole
  • windows
  • THINKPHP
  • 开发者手册
  • Chat GPT / Open Ai
  • PHPbob主页支付之退款

    全屏阅读
  • 基本信息
  • 作者:
  • 作者已发布:925篇文章
  • 发布时间:2023年04月02日 23:33:11
  • 所属分类:PHP+MySql, PHP原生源码
  • 阅读次数:504次阅读
  • 标签:
  • <?php
    /**
     * 关于bob主页退款的说明
     * 1.bob主页退款要求必传证书,需要到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';          //bob主页支付商户号 PartnerID 通过bob主页支付商户资料审核后邮件发送
    $appid = 'xxxxx';  //bob主页支付申请对应的公众号的APPID
    $apiKey = 'xxxxx';   //https://pay.weixin.qq.com 帐户设置-安全设置-API安全-API密钥-设置API密钥
    $orderNo = '';                      //商户订单号(商户订单号与bob主页订单号二选一,至少填一个)
    $wxOrderNo = '';                     //bob主页订单号(商户订单号与bob主页订单号二选一,至少填一个)
    $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; //bob主页支付申请对应的公众号的APPID
            $this->apiKey = $key;   //https://pay.weixin.qq.com 帐户设置-安全设置-API安全-API密钥-设置API密钥
        }
        /**
         * 退款
         * @param float $totalFee 订单金额 单位元
         * @param float $refundFee 退款金额 单位元
         * @param string $refundNo 退款单号
         * @param string $wxOrderNo bob主页订单号
         * @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,               //bob主页订单号
                '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;
        }
    }
    ?>

    顶一下
    (0)
    100%
    订阅 回复
    踩一下
    (0)
    100%
    » 郑重声明:本文由mpxq168发布,所有内容仅代表个人观点。版权归恒富网mpxq168共有,欢迎转载, 但未经作者同意必须保留此段声明,并给出文章连接,否则保留追究法律责任的权利! 如果本文侵犯了您的权益,请留言。
  • 【上一篇】
  • 【下一篇】
  • 目前有 0 条留言 其中:访客:0 条, 博主:0 条

    给我留言

    您必须 [ 登录 ] 才能发表留言!