第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > 微信小程序 统一支付 php 微信/微信小程序统一下单(PHP版)

微信小程序 统一支付 php 微信/微信小程序统一下单(PHP版)

时间:2019-04-10 05:45:57

相关推荐

微信小程序 统一支付 php 微信/微信小程序统一下单(PHP版)

事先准备工作

1.开通公众号/小程序支付

2.商户号后台设置支付目录、回调目录、白名单等设置。

3.记录商户号ID(mchid)和生成支付key

需要准备辅助函数

//-----------------支付相关-----------------

//随机32位字符串

public function nonce_str(){

$result = '';

$str = 'QWERTYUIOPASDFGHJKLZXVBNMqwertyuioplkjhgfdsamnbvcxz';

for ($i=0;$i<32;$i++){

$result .= $str[rand(0,48)];

}

return $result;

}

//生成订单号

public function order_number(){

return date('Ymd',time()).time().rand(10,99);//18位

}

//签名 $data要先排好顺序

public function sign($data, $mch_key){

$stringA = '';

ksort($data);

foreach ($data as $key=>$value){

if(!$value) continue;

if($stringA) $stringA .= '&'.$key."=".$value;

else $stringA = $key."=".$value;

}

$wx_key = $mch_key;

$stringSignTemp = $stringA.'&key='.$wx_key;//申请支付后有给予一个商户账号和密码,登陆后自己设置key

return strtoupper(md5($stringSignTemp));

}

/**

* [http_request CURL请求函数版本1 发送数组或字符串]

* @param [type] $url [description]

* @param [type] $data [description]

* @param array $headers [description]

* @return [type][description]

*/

public function 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 (!empty($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);

return $output;

}

/**

* [curl_post CURL请求函数 版本2 发送json]

* @param [String] $url [请求URL]

* @param [Array] $post_data [请求数组]

* @return [Array][返回请求结果数组]

*/

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($requestUrl);

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(

'Content-Type: application/json',

'Content-Length: ' . 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);

return $result;

}

}

/**

* [xml xml转数组]

* @param [type] $xml [description]

* @return [type] [description]

*/

public function xml($xml){

//禁止引用外部xml实体

libxml_disable_entity_loader(true);

$values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);

return $values;

}

支付核心

/**

* [Pay 支付]

* @return [type] [description]

*/

public function Pay() {

//支付金额

$fee = 0.01;

//公众号或小程序appid

$appid= '';

//商品描述

$body= 'XX服务购买';

//商户ID

$mch_id= '';

//商户key

$mch_key= '';

//随机字符串

$nonce_str = $this->nonce_str();

//异步回调URL(需在商户平台添加白名单)

$notify_url = '';

//用户openid

$openid= '';

//商户订单号

$out_trade_no = $this->order_number();

//用户openid

$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['openid']= $openid;

$post['out_trade_no'] = $out_trade_no;

$post['spbill_create_ip'] = $spbill_create_ip;

$post['total_fee'] = $total_fee;

$post['trade_type'] = $trade_type;

//生成签名

$sign = $this->sign($post, $mch_key);

//统一下单XML数据包生成

$post_xml = '

'.$appid.'

'.$mch_id.'

'.$nonce_str.'

'.$notify_url.'

'.$openid.'

'.$out_trade_no.'

'.$spbill_create_ip.'

'.$total_fee.'

'.$trade_type.'

'.$sign.'

';

//统一接口接口

$url = 'https://api.mch./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['nonceStr'] = $nonce_str;

$tmp['package'] = 'prepay_id='.$array['prepay_id'];

$tmp['signType'] = 'MD5';

$tmp['timeStamp'] = "$time";

$data['state'] = 1;

$data['timeStamp'] = "$time"; //时间戳

$data['nonceStr'] = $nonce_str;//随机字符串

$data['signType'] = 'MD5'; //签名算法,暂支持 MD5

$data['package'] = 'prepay_id='.$array['prepay_id'];//统一下单接口返回的 prepay_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_status' => '未支付',

'pay_time' => time()

);

//输出订单数据到前端,调用支付SDK

echo json_encode($data, true);

}

异步回调

xml转数组函数

function xmlToArray($xml)

{

//禁止引用外部xml实体

libxml_disable_entity_loader(true);

$values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);

return $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.异步回调要做好订单验证,相关验证SDK可以去微信支付开发文档查看。

3.本代码支持微信公众号和小程序的JSAPI支付。

4.本代码需要根据自身业务需求进行封装使用。

标签: 微信 php

顶一下

(0)

0%

踩一下

(0)

0%

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。