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"]);

}

后记

剩下的事情就交给前端了,有什么问题可以留言哈。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值