APP支付提现功能是我们常用的一个功能,接下来我们来对接APP的微信退款功能
1.选择接入模式 (商户平台申请)成为普通商户
2.参数申请 开放平台申请APPID ,商户号平台申请mchid
3.绑定APPID及mchid
4.配置API key API v3密钥主要用于平台证书解密、回调信息解密,具体使用方式可参见接口规则文档中证书和回调报文解密章节。请根据以下步骤配置API key:登录
微信商户平台,进入【账户中心 > API安全 > API安全】目录,点击【APIV3密钥】。
5.下载并配置商户证书,商户可登录微信商户平台,在【账户中心】->【API安全】->【API证书】目录下载证书
6.生成证书串
7. 详情可见 APP支付接入准备
你好!有很多人在接入微信退款功能时无从下下手,那么在本篇文件,带你详细的了解并实现微信退款功能,废话不多说,咱们开始
微信支付官方文档
//微信 支付配置
'Wxpay_config' => array (
'appid' => '', //微信开放平台上的应用id
'secret' => '', //微信开放平台上的应用secret
'mch_id' => '', //微信申请成功之后邮件中的商户id
'api_key' => '', //商户秘钥在微信商户平台上自己设定的api密钥 32位
'notify_url' => '', //支付回调地址
'huiyuan_notify' => '' //会员支付回调地址
),```
//方法调用,和结果的逻辑判断
public function refund($id)
{
$goodInfo = $this->Order->where('id',$id)->find()->toArray();
$result = $this->weChatrefund($goodInfo['order_no'],$goodInfo['transaction_id'],intval(strval($goodInfo['price']))*100);
if($result['return_code'] =='SUCCESS'){
Db::startTrans();
try {
if ($result['result_code']=='SUCCESS'){
//退款成功
}elseif ($result['result_code']=='FAIL'){
//退款失败
}
Db::commit();
return success_msg();
} catch (\Exception $e) {
// 回滚事务
Db::rollback();
//验签失败
$arr = [
'desc' => '用户' . $goodInfo['sell_id'] . 'ali在方法alirefund退款' . '错误' . $e->getMessage(), time(),
'create_time' => date('Y-m-d H:i:s',time())
];
$this->Message->create($arr);
}
return error_msg();
}else{
//验签失败
$arr = [
'desc' => '用户' . $goodInfo['sell_id'] . 'wx在方法refund退款' . '错误' . json_encode($result), time(),
'create_time' => date('Y-m-d H:i:s',time())
];
$this->Message->create($arr);
}
}
退款在进行**UCRL**请求时必须需要使用证书:cert 与 key 分别属于两个.pem文件
private $SSLCERT_PATH = "/data/wxpay/apiclient_cert.pem"; //微信证书
private $SSLKEY_PATH = "/data/wxpay/apiclient_key.pem"; //商品规格
/*
* 微信退款 商品退款
* @access public
* @param string $order_no 本系统订单
* @param string $transaction_id 微信的订单号(不是自己升成的)
* @param int $price 金额
*/
private function weChatrefund($order_no,$transaction_id,$price)
{
$param = array(
'appid'=> config('app.Wxpay_config.appid'), //APPID
'mch_id'=> config('app.Wxpay_config.mch_id'),//商户ID
'nonce_str'=> $this->createNoncestr(),
'out_refund_no'=> $order_no, //app商品的订单号
'transaction_id'=> $transaction_id,//微信订单号 (该订单号由微信支付成功回调中返回)
'total_fee'=> $price, //订单金额
'refund_fee'=> $price,//退款金额
);
$param['sign'] = $this->getSign($param);
$xmldata = $this->arrayToXml($param);
$xmlresult = $this->postXmlSSLCurl($xmldata,'https://api.mch.weixin.qq.com/secapi/pay/refund');
$result = $this->xmlToArray($xmlresult);
return $result;
}
/*
生成签名
*/
function getSign($Obj)
{
foreach ($Obj as $k => $v)
{
$Parameters[strtolower($k)] = $v;
}
//签名步骤一:按字典序排序参数
ksort($Parameters);
$String = $this->formatBizQueryParaMap($Parameters, false);
//echo "【string】 =".$String."";
//签名步骤二:在string后加入KEY
$String = $String."&key=".config('app.Wxpay_config.api_key');
// echo "
";
//签名步骤三:MD5加密
$result_ = strtoupper(md5($String));
return $result_;
}
//数组转xml
function arrayToXml($arr)
{
$xml = "" ;
foreach ($arr as $key=>$val)
{
if (is_numeric($val))
{
$xml.="<".$key.">".$val."".$key.">";
}
else
$xml.="<".$key.">.$val."]]>".$key.">";
}
$xml.="";
return $xml;
}
//需要使用证书的请求
private function postXmlSSLCurl($xml,$url,$second=30)
{
$ch = curl_init(); //初始化curl
//设置超时时间
curl_setopt($ch,CURLOPT_TIMEOUT,$second);
//这里设置代理,如果有的话
//curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
//curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
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);
//设置证书
//使用证书:cert 与 key 分别属于两个.pem文件
//默认格式为PEM,可以注释
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLCERT, $this->SSLCERT_PATH);
//默认格式为PEM,可以注释
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLKEY,$this->SSLKEY_PATH);
//post提交方式
curl_setopt($ch,CURLOPT_POST, true);
curl_setopt($ch,CURLOPT_POSTFIELDS,$xml);
$data = curl_exec($ch);
//返回结果
if($data){
curl_close($ch);
return $data;
}
else {
$error = curl_errno($ch);
echo "curl出错,错误码:$error"."
";
curl_close($ch);
return false;
}
}
/**
* XML转数组
* @param unknown $xml
* @return mixed
*/
function xmlToArray($xml)
{
//将XML转为array
$array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $array_data;
}