博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于微信支付,退款操作,原路返回
阅读量:5108 次
发布时间:2019-06-13

本文共 4792 字,大约阅读时间需要 15 分钟。

有这样的场景,用户购买商品。但是退款的时候要去除运费。

或者,用户购买多个商家的商品,统一支付。但是用户只退其中一个商家的商品。
又或者,用户一个订单购买多个商品。只退其中一个商品。

微信退款接口可以满足这些需求,前提是总的退款金额不能超过总的支付金额。

支付的时候,不需要证书。
但是退款的时候,需要提供证书。

下面看看实际的情况。

422101-20181102171648210-83668427.jpg

422101-20181102171652639-1818066664.jpg

422101-20181102171655951-1805048609.jpg

从上图可以看出,我支付2分钱,可以一次性退。

也可以,一次退1分,分两次退还。

而且,用银行卡就退到银行卡,用信用卡就退到信用卡。

422101-20181102171941847-1320596860.png

这些支付,退款相关的信息,可以在管理后台中统一管理。或者写到配置文件中。

422101-20181102172042785-188654462.png

422101-20181102172047557-1789472533.png

退款需要证书,需要到微信商户平台进行下载。(开放平台【app】,公众平台【微信,pc,小程序】)分别有一个商户号。

退款的时候,需要提供支付的订单号或者微信提供的transaction_id。每一个退款都有自己的退款号(确保不要相同)。

一笔退款失败后重新提交,请不要更换退款单号,请使用原商户退款单号。

private function refundWx($data)    {        Clog::setLog($data);        vendor('Wxpay.WxPay');        $input = new WxPayRefund();        $input->SetOut_trade_no($data['out_trade_no']);        $input->SetAppid($data['app_id']);        $input->SetMch_id($data['mch_id']);        $input->SetOut_refund_no($data['out_trade_no'] . 'R');        $input->SetTotal_fee($data['price']);        $input->SetRefund_fee($data['price']);        $input->SetOp_user_id($data['mch_id']);        $input->key = $data['key'];        $path = C('WX_KEY_PATH');        switch ($data['type']) {            case 1:                $path = $path . 'open/';                break;            case 2:                $path = $path . 'public/';                break;        }        $response = WxPayApi::refund($input, $path);        if ($response['return_code'] == 'SUCCESS' && $response['result_code'] == 'SUCCESS') {            return true;        } else {            return false;        }}
/**     *      * 申请退款,WxPayRefund中out_trade_no、transaction_id至少填一个且     * out_refund_no、total_fee、refund_fee、op_user_id为必填参数     * appid、mchid、spbill_create_ip、nonce_str不需要填入     * @param WxPayRefund $inputObj     * @param int $timeOut     * @throws WxPayException     * @return 成功时返回,其他抛异常     */    public static function refund($inputObj, $path, $timeOut = 6)    {        $url = "https://api.mch.weixin.qq.com/secapi/pay/refund";        //检测必填参数        if(!$inputObj->IsOut_trade_noSet() && !$inputObj->IsTransaction_idSet()) {            throw new WxPayException("退款申请接口中,out_trade_no、transaction_id至少填一个!");        }else if(!$inputObj->IsOut_refund_noSet()){            throw new WxPayException("退款申请接口中,缺少必填参数out_refund_no!");        }else if(!$inputObj->IsTotal_feeSet()){            throw new WxPayException("退款申请接口中,缺少必填参数total_fee!");        }else if(!$inputObj->IsRefund_feeSet()){            throw new WxPayException("退款申请接口中,缺少必填参数refund_fee!");        }else if(!$inputObj->IsOp_user_idSet()){            throw new WxPayException("退款申请接口中,缺少必填参数op_user_id!");        }          $inputObj->SetNonce_str(self::getNonceStr());//随机字符串                $inputObj->SetSign();//签名        $xml = $inputObj->ToXml();        $startTimeStamp = self::getMillisecond();//请求开始时间        $response = self::postXmlCurl($xml, $url, true, $timeOut, $path);        $result = WxPayResults::Init($response);        self::reportCostTime($url, $startTimeStamp, $result);//上报请求花费时间                return $result;}
/**     * 以post方式提交xml到对应的接口url     *      * @param string $xml  需要post的xml数据     * @param string $url  url     * @param bool $useCert 是否需要证书,默认不需要     * @param int $second   url执行超时时间,默认30s     * @throws WxPayException     */    private static function postXmlCurl($xml, $url, $useCert = false, $second = 30, $certPath = '')    {               $ch = curl_init();        //设置超时        curl_setopt($ch, CURLOPT_TIMEOUT, $second);                //如果有配置代理这里就设置代理        if(WxPayConfig::CURL_PROXY_HOST != "0.0.0.0"             && WxPayConfig::CURL_PROXY_PORT != 0){            curl_setopt($ch,CURLOPT_PROXY, WxPayConfig::CURL_PROXY_HOST);            curl_setopt($ch,CURLOPT_PROXYPORT, WxPayConfig::CURL_PROXY_PORT);        }        curl_setopt($ch,CURLOPT_URL, $url);        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验        //设置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, $certPath . 'apiclient_cert.pem');            curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');            curl_setopt($ch,CURLOPT_SSLKEY, $certPath . '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 WxPayException("curl出错,错误码:$error");        }}

具体的参考:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4

转载于:https://www.cnblogs.com/jiqing9006/p/9897532.html

你可能感兴趣的文章
git学习——<五>git分支
查看>>
突然感到人生很绝望_
查看>>
crontab 在指定时间范围每隔2小时执行一次和指定时间执行实例
查看>>
IIS7:通过脚本来配置ftp站点
查看>>
JAVA处理文件压缩
查看>>
淘宝用户杭州30个小区分布,根据默认收货地址统计用户id
查看>>
一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10
查看>>
北京信息科技大学第十一届程序设计竞赛(重现赛)I
查看>>
【3-5】函数及递归
查看>>
转 Python的WinReg项通过子键循环
查看>>
二叉树思想
查看>>
SpringBoot入门(四)静态资源
查看>>
本机ping不通虚拟机,但虚拟机可以ping通本机时怎么解决
查看>>
2013-03-26 星期二
查看>>
Java基础篇——编码注释规范
查看>>
VMware下利用ubuntu13.04建立嵌入式开发环境之二
查看>>
Longest Palindromic Substring
查看>>
jQuery插件——Validation Plugin表单验证
查看>>
Web前端学习笔记:Bootstrap框架
查看>>
restrict和volatile的作用
查看>>