顺晟科技
2021-06-16 10:31:59
342
事先准备工作
1.开通公众号/小程序支付
2.商户号后台设置支付目录、回调目录、白名单等设置。
3.记录商户号标识(mchid)和生成支付键
需要准备辅助函数
//- 支付相关-
//随机32位字符串
public function nonce_str(){
$ result=
$ str=' qwertyuiopadghjklzvbnmqwertyuioplkjhgfdsamnbvcxz ';
for($ I=0;$ i32$i ){
$结果=$str[rand(0,48)];
}
返回$结果
}
//生成订单号
公共函数order_number(){
返回日期(' Ymd ',时间())。时间()。兰特(10,99);//18位
}
//签名$数据要先排好顺序
公共功能标志($data,$mch_key){
$ stringA=
ks ort($ data);
foreach ($data as $key=$value){
if(!$value)继续;
if($stringA) $stringA .=''.$key .'='.$值
else $stringA=$key .'='.$值
}
$ wx _ key=$ mch _ key
$stringSignTemp=$stringA .key=' .$ wx _ key//申请支付后有给予一个商户账号和密码,登陆后自己设置键
返回strtopol(MD5($ StringSignTemp));
}
/**
* [http_request CURL请求函数版本一发送数组或字符串]
* @ param[类型]$ URL[描述]
* @ param[类型]$数据[描述]
* @param数组$ headers[描述]
* @ return[类型][描述]
*/
公共函数http_request($url,$data=null,$headers=array()){
$ curl=curl _ init();
if(count($headers)=1 ){
curl_setopt($curl,CURLOPT_HTTPHEADER,$ headers);
}
curl_setopt($curl,CURLOPT_URL,$ URL);
curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,FALSE);
curl_setopt($curl,CURLOPT_SSL_VERIFYHOST,FALSE);
if(!空($data)){
curl_setopt($curl,CURLOPT_POST,1);
curl_setopt($curl,CURLOPT _ POSTFIELDS,$ data);
}
curl_setopt($curl,CURLOPT_RETURNTRANSFER,1);
$ output=curl _ exec($ curl);
curl _ close($ curl);
返回$输出
}
/**
* [curl_post CURL请求函数版本2发送json]
* @param [String] $url [请求网址]
* @param [Array] $post_data [请求数组]
* @返回[数组] [返回请求结果数组]
*/
public function curl_post($url,$post_data=''){
$ requestUrl=$ url
if ($post_data=='') {
$ data _ string=" { }
}else{
$ data=$ post _ data
$data_string=json_encode($data,JSON _ UNESCAPED _ UNICODE);
}
$ ch=curl _ init($ request URl);
curl_setopt($ch,CURLOPT_CUSTOMREQUEST,' POST ');
curl_setopt($ch,CURLOPT _ POSTFIELDS,$ data _ string);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_HTTPHEADER,array(
内容-:型应用程序/json ',
内容-长度: '。strlen($data_string)
));
$ result=curl _ exec($ ch);
if (curl_errno($ch)) {
curl _ close($ ch);
print curl _ error($ ch);
}else{
$result=json_decode($result,true);
curl _ close($ ch);
返回$结果
}
}
/**
* [xml xml转数组]
* @ param[类型]$ XML[描述]
* @ return[类型][描述]
*/
公共函数xml($xml){
//禁止引用外部可扩展标记语言实体
libxml _ disable _ entity _ loader(true);
$ values=JSON _ decode(JSON _ encode(simple XML _ load _ string($ XML,' SimpleXMLElement ',LIBXML_NOCDATA)),true);
返回$ values
}
支付核心
/**
*[支付支付]
* @ return[类型][描述]
*/
公共职能支付(){
//支付金额
$费用=0.01
//公众号或小程序应用编号
$ appid=
//商品描述
$body='XX服务购买;
//商户身份
$ mch _ id=
//商户键
$ mch _ key=
//随机字符串
$ nonce _ str=$ this-nonce _ str();
//异步回调URL(需在商户平台添加白名单)
$ notify _ url=
//用户信息
$ openid=
//商户订单号
$ out _ trade _ no=$ this-order _ number();
//用户信息
$ openid=
//终端IP(服务器IP)
$ spbill _ create _ ip=
//单位为分
$ total _ fee=$ fee * 100
//交易类型默认
$ trade _ type=' JSAPI
//这里是按照顺序的因为下面的签名是按照顺序排序错误肯定出错
$ post[' appid ']=$ appid;
$ post[' body ']=$ body;
$ post[' mch _ id ']=$ mch _ id;
$ post[' nonce _ str ']=$ nonce _ str;
$ post[' notify _ URL ']=$ notify _ URL;
$ post[' open id ']=$ open id;
$ post[' out _ trade _ no ']=$ out _ trade _ no;
$ post[' sp bill _ create _ IP ']=$ sp bill _ create _ IP;
$ post[' total _ fee ']=$ total _ fee;
$ post[' trade _ type ']=$ trade _ type;
//生成签名
$sign=$this-sign($post,$ mch _ key);
//统一下单可扩展置标语言数据包生成
$post_xml='xml
appid .$appid ./appid
身体$body ./body
mch_id ' .$mch_id ./mch_id
nonce_str ' .$nonce_str ./nonce_str
notify_url ' .$notify_url ./notify_url
openid .$openid ./openid
out_trade_no ' .$out_trade_no.'/out_trade_no
spbill_create_ip ' .$spbill_create_ip ./spbill_create_ip
总费用.$total_fee,'/total_fee
交易类型.$trade_type ./trade_type
签名。$符号签名
/XML ';
//统一接口接口
$ URL='https://api.mch.weixin.qq.com/pay/unifiedorder';
//下单
$xml=$this-http_request($url,$ post _ XML);
//对下单结果解包(XML)
$ array=$ this-XML($ XML);
if($ array[' return _ code ']=' SUCCESS ' $ array[' result _ code ']==' SUCCESS '){
$ time=time();
$ tmp=array();//临时数组用于签名
$ tmp[' AppID ']=$ AppID;
$ tmp[' non estr ']=$ nonce _ str;
$tmp['package']='预付费_id=' .$array['预付款_ id '];
$ tmp[' SignType ']=' MD5 ';
$ tmp[' TiMer ']=' $ TiMer ';
$ data[' state ']=1;
$ data[' TiMer ']=' $ TiMer ';//时间戳
$ data[' non estr ']=$ nonce _ str;//随机字符串
$ data[' SignType ']=' MD5 ';//签名算法,暂支持讯息摘要5
$data['package']='预付费_id=' .$array['预付款_ id '];//统一下单接口返回的预付编号参数值
$ data[' paySign ']=$ this-sign($ tmp);//签名,具体签名方案参见微信公众号支付帮助文档;
$ data[' out _ trade _ no ']=$ out _ trade _ no;
}else{
$ data[' state ']=0;
$data['text']='错误;
$ data[' RETURN _ CODE ']=$ array[' RETURN _ CODE '];
$ data[' RETURN _ MSG ']=$ array[' RETURN _ MSG '];
}
//订单储存到本地
$pay_data=array(
order_id'=$out_trade_no,
total_pay'=$fee,
付款状态'='未支付,
pay_time'=time()
);
//输出订单数据到前端,调用支付软件开发工具包(软件开发工具包)
echo json_encode($data,true);
}
异步回调
可扩展标记语言转数组函数
函数xmlToArray($xml)
{
//禁止引用外部可扩展标记语言实体
libxml _ disable _ entity _ loader(true);
$ values=JSON _ decode(JSON _ encode(simple XML _ load _ string($ XML,' SimpleXMLElement ',LIBXML_NOCDATA)),true);
返回$ values
}
异步回调验证
$ pay _ data=file _ get _ contents(' PHP ://input ');
$ pay _ data=xmlToArray($ pay _ data);
if($ pay _ data[' result _ code ']=' SUCCESS ' $ pay _ data[' return _ code ']==' SUCCESS '){
//此处为订单成功回调后的业务逻辑
//注:要验证订单真实性
}else{
//支付失败的业务逻辑,记录异常
}
备注
1.订单数据返回到前端之前,将订单信息插入到订单表,用来异步回调时核对账单。
2.异步回调要做好订单验证,相关验证软件开发工具包(软件开发工具包)可以去微信支付开发文档查看。
3.本代码支持微信公众号和小程序的支付插件支付。
4.本代码需要根据自身业务需求进行封装使用。
11
2022-12
17
2022-03
18
2021-11
19
2021-06
16
2021-06
16
2021-06