微信小程序支付(PHP后端)

时间:2023-03-09 15:55:02
微信小程序支付(PHP后端)

1.申请开通小程序支付,我们正式开通的微信支付是在微信公众平台上,我们需要绑定之前的微信商户平台即可,这一点不过多强调

2.小程序支付开发步骤

(1)、统一下单

大家看到微信的统一下单接口密密麻麻的一大堆参数,千万不要害怕,有问题解决就是了。

<?php
//微信支付向外暴露的支付接口
public function pay()
{
$result = $this->weChatPay();
return $result;
} //请求微信统一下单接口
private function weChatPay()
{
$param = array(
'appid' => $this->APPID,//小程序id
'mch_id'=> $this->MCHID,//商户id
'spbill_create_ip'=>$_SERVER['REMOTE_ADDR'],//终端ip
'notify_url'=>$this->APPURL, //回调通知地址
'nonce_str'=> $this->createNoncestr(),//随机字符串
'out_trade_no'=>$this->outTradeNo,//商户订单编号
'total_fee'=>floatval($this->totalFee), //总金额
'openid'=>$this->openid,//用户openid
'trade_type'=>$this->TRADETYPE,//交易类型
'body' =>$this->BODY, //商品信息
);
//通过签名算法计算得出的签名值,详见签名生成算法
$param['sign'] = $this->getSign($param);
//将数组内容转为xml格式,向微信发出请求
$xmlData = $this->arrayToXml($param);
$xml_result = $this->postXmlCurl($xmlData,'https://api.mch.weixin.qq.com/pay/unifiedorder',60);
$result = $this->xmlToArray($xml_result);
return $result;
// var_dump($result);
/*
* array(9) {
["return_code"]=>
string(7) "SUCCESS"
["return_msg"]=>
string(2) "OK"
["appid"]=>
string(18) "wx2d4fefcfe1a39c9b"
["mch_id"]=>
string(10) "1420537902"
["nonce_str"]=>
string(16) "JASf0yXVuPknKm2J"
["sign"]=>
string(32) "BE3CF30459D01660BB9AB2DE0AD023CE"
["result_code"]=>
string(7) "SUCCESS"
["prepay_id"]=>
string(36) "wx29154208585459f31c6875691178935371"
["trade_type"]=>
string(5) "JSAPI"
}
} /*
* 对要发送到微信统一下单接口的数据进行签名
*/
protected function getSign($Obj){
foreach ($Obj as $k => $v){
$param[$k] = $v;
}
//签名步骤一:按字典序排序参数
ksort($param);
$String = $this->formatBizQueryParaMap($param, false);
//签名步骤二:在string后加入KEY
$String = $String."&key=".$this->KEY;
//签名步骤三:MD5加密
$String = md5($String);
//签名步骤四:所有字符转为大写
$result_ = strtoupper($String);
return $result_;
}
/*
*排序并格式化参数方法,签名时需要使用
*/
protected function formatBizQueryParaMap($paraMap, $urlencode)
{
$buff = "";
ksort($paraMap);
foreach ($paraMap as $k => $v)
{
if($urlencode)
{
$v = urlencode($v);
}
//$buff .= strtolower($k) . "=" . $v . "&";
$buff .= $k . "=" . $v . "&";
}
$reqPar = "";
if (strlen($buff) > 0)
{
$reqPar = substr($buff, 0, strlen($buff)-1);
}
return $reqPar;
} /*
* 生成随机字符串方法
*/
protected function createNoncestr($length = 32 ){
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str ="";
for ( $i = 0; $i < $length; $i++ ) {
$str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
}
return $str;
}
//数组转字符串方法
protected function arrayToXml($arr){
$xml = "<xml>";
foreach ($arr as $key=>$val)
{
if (is_numeric($val)){
$xml.="<".$key.">".$val."</".$key.">";
}else{
$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
}
}
$xml.="</xml>";
return $xml;
} //将xml字符串转换为数组
protected static function xmlToArray($xml){
$array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $array_data;
} //发送xml请求方法
private static function postXmlCurl($xml, $url, $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);
//post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt($ch, CURLOPT_TIMEOUT, 40);
set_time_limit(0);
//运行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");
}
}

(2)、处理微信的notify_url 通知地址

微信会把刚才生成的支付订单返回来,给我们做校验

异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。

/* 微信官方提醒:
* 商户系统对于支付结果通知的内容一定要做【签名验证】,
* 并校验返回的【订单金额是否与商户侧的订单金额】一致,
* 防止数据泄漏导致出现“假通知”,造成资金损失。
*/
$post = post_data();    //接受POST数据XML个数

function post_data(){
$receipt = $_REQUEST;
if($receipt==null){
$receipt = file_get_contents("php://input");
if($receipt == null){
$receipt = $GLOBALS['HTTP_RAW_POST_DATA'];
}
}
return $receipt;
}
//调用后台验证
WeiXinPay::payNotifyUrlCallback($post);
 /*
* 微信支付结果回调;
* */
public static function PayCallBack($result){
//查找对应的功能模块,返回信息内容
/*
* <xml>
<appid><![CDATA[wx24123c4370ec43b]]></appid>
<attach><![CDATA[测试测试]]></attach>
<bank_type><![CDATA[CFT]]></bank_type>
<fee_type><![CDATA[CNY]]></fee_type>
<is_subscribe><![CDATA[Y]]></is_subscribe>
<mch_id><![CDATA[10000100]]></mch_id>
<nonce_str><![CDATA[5d2b634f23F23da20af46e531c]]></nonce_str>
<openid><![CDATA[oUpF8uMEb4q23FEWG4Q23R268TekukE]]></openid>
<out_trade_no><![CDATA[140123153]]></out_trade_no>
<result_code><![CDATA[SUCCESS]]></result_code>
<sign><![CDATA[B552EDFW23G423G5DD0D78AB241]]></sign>
<sub_mch_id><![CDATA[10000100]]></sub_mch_id>
<time_end><![CDATA[20140903131540]]></time_end>
<total_fee>1</total_fee>
<coupon_fee><![CDATA[10]]></coupon_fee>
<coupon_count><![CDATA[1]]></coupon_count>
<coupon_type><![CDATA[CASH]]></coupon_type>
<coupon_id><![CDATA[10000]]></coupon_id>
<coupon_fee><![CDATA[100]]></coupon_fee>
<trade_type><![CDATA[JSAPI]]></trade_type>
<transaction_id><![CDATA[1004400740212312353532168]]></transaction_id>
</xml>
*/
if($result == null){
return;
}
if($result['result_code'] =='SUCCESS'){
    //支付成功
      //开始取出数据库订单数据进行校验
      //校验成功向微信发出请求成功
      WeiXinPay::return_success();
}
}
/*
* 给微信发送确认订单金额和签名正确,SUCCESS信息 -xzz0521
*/
public static function return_success(){
$return['return_code'] = 'SUCCESS';
$return['return_msg'] = 'OK';
$xml_post = '<xml>
<return_code>'.$return['return_code'].'</return_code>
<return_msg>'.$return['return_msg'].'</return_msg>
</xml>';
echo $xml_post;exit;
}
 

使用本代码,建议使用单个方法拼接,最终来组成逻辑代码

参考其他案例