微信小程序支付php代码参考

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sinat_14826983/article/details/83721623
在微信小程序中接入了支付功能,顺便记录下

微信支付文档https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1

$config = array( 
  'app_id'=>'xxx',
  'secret'=>"xxxxx",
  'sign_key'=>"xxxx", 
  'name'=>"支付测试", 
  'mch_id'=>'xxxxx' 
)
1.调用微信统一下单接口

$srcData = array(
        "appid"=>$app_id,//小程序app_id
        "attach"=>"支付测试",
        "body"=>"支付测试",
        "mch_id"=>$mch_id, //商户号
        "nonce_str"=>$nonce_str,//生产的随机数
        "notify_url"=>"https:xxxx/notify",//自己的支付回调地址
        "out_trade_no"=>$order_id,//自己平台的订单id
        "spbill_create_ip"=>"",//自己的服务器ip
        "total_fee"=>$money,//支付金额,单位为分
        "trade_type"=>"JSAPI",//支付类型
        "openid"=>$open_id,//用户open_id
);
//获取微信订单号
$wx_order = self::prepay_id($srcData);
//生成订单成功,返回加密数据给前端
if($wx_order['return_code'] == "SUCCESS"){
    $prepay_id = $wx_order['prepay_id'];
    if($prepay_id){
        //微信订单号
        $data['WX_ORDER_ID'] = $wx_order['prepay_id'];
        if($res){
            $pay_data = array(
                'appId'=>$app_id,
                'nonceStr'=>$nonce_str,
                'timeStamp'=>time(),
                'signType'=>"MD5",
                'package'=>"prepay_id=$prepay_id"
            );
            $sign = self::sign($pay_data);
            $pay_data['paySign'] = $sign;
            $pay_data['prepayId'] = $prepay_id;
            echo json_encode($pay_data);
        }
    }
}
//商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易会话标识后再在APP里面调起支付
function prepay_id($srcData){
        $plusCurl = curl('https://api.mch.weixin.qq.com/pay/unifiedorder');
        ksort($srcData);
        $srcStr = '';
        foreach ($srcData as $key => $val) {
            if ( $key!='key' && $val != '') {
                $srcStr .= '&' . $key . '=' . $val;
            }
        }
        $srcStr = substr($srcStr, 1);
        $signKey = $config['sign_key'];
        $str = $srcStr . '&key=' .$signKey;
        $signResult = strtoupper(md5($str));
        $params = "<xml>
<appid>{$srcData['appid']}</appid>
<attach>{$srcData['attach']}</attach>
<body>{$srcData['body']}</body>
<mch_id>{$srcData['mch_id']}</mch_id>
<nonce_str>{$srcData['nonce_str']}</nonce_str>
<notify_url>{$srcData['notify_url']}</notify_url>
<out_trade_no>{$srcData['out_trade_no']}</out_trade_no>
<spbill_create_ip>{$srcData['spbill_create_ip']}</spbill_create_ip>
<total_fee>{$srcData['total_fee']}</total_fee>
<trade_type>{$srcData['trade_type']}</trade_type>
<openid>{$srcData['openid']}</openid>
<sign>$signResult</sign>
</xml>";
        $res = $plusCurl->POST($params);
        $res = self::xml2array($res);
        return $res;
    }   

2.前端发起支付
3.服务器接受支付回调
function notify(){
    $inputData = file_get_contents('php://input');
    $inputData = self::xml2array($inputData);
    $notify_data = $inputData;
    if(!$notify_data){
        exit;
    }
    $order_id = $notify_data['out_trade_no'];
    //签名校验
    $verify = self::verify($notify_data);
    if($verify != $notify_data['sign']){
        self::retXml("FAIL","校验失败",$order_id);
    }else{
        if($notify_data['result_code'] != "SUCCESS"){
            self::retXml("SUCCESS","OK",$order_id);
        }
        //查询数据库订单
        $order =getOrder($order_id);
        if(!$order){
            self::retXml("FAIL","订单不存在",$order_id);
        }else{
            if($order['PAY_RES'] != 2){
                self::retXml("SUCCESS","OK",$order_id);
            }else if($order['OPEN_ID']!=$notify_data['openid']){
                self::retXml("FAIL","open_id错误",$order_id);
            }else{
                //金额单位转换
                $order_money = strval($order['MONEY']*100);
                $notify_money = strval($notify_data['cash_fee']);
                if($order_money!=$notify_money){
                    self::retXml("FAIL","金额错误",$order_id);
                }else{
                    //更新数据库订单状态
                    $pay_result = updateOrder($order_id,1);
                    if($pay_result){
                        $order['PAY_RES'] = 1;
                        $order['PAY_TIME'] = date("Y-m-d H:i:s");
                        HongbaoBLL::setGameCache($order);
                        self::retXml("SUCCESS","OK",$order_id);
                    }else{
                        self::retXml("FAIL","网络异常",$order_id);
                    }
                }
            }
        }

    }
}

 //xml格式输出回调微信支付通知;
    function retXml($code,$message,$order_id=''){
        $ret = "<xml>
<return_code><![CDATA[$code]]></return_code>
<return_msg><![CDATA[$message]]></return_msg>
</xml>";
       
        echo  $ret;exit;
    }
    /**
     * XML转为数组
     */
    function xml2array($xml){
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        return json_decode(json_encode((array) simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
    }
   //生成签名

 function sign($srcData){
    ksort($srcData);
    $srcStr = '';
    foreach ($srcData as $key => $val) {
        if ( $key!='key' && $val != '') {
            $srcStr .= '&' . $key . '=' . $val;
        }
    }
    $srcStr = substr($srcStr, 1);
    $app_id = $srcData['appId'];
    $signKey = $config['sign_key'];
    $str = $srcStr . '&key=' .$signKey;
    //echo $str;
    $signResult = strtoupper(md5($str));
    return $signResult;
}
/**
 * 支付回调签名校验
 */
function verify($data)
{
    $str = '';
    ksort($data);
    foreach ($data as $key => $val) {
        if ($key != 'sign' && $val != '') {
            $str .= '&' . $key . '=' . $val;
        }
    }
    $str = substr($str, 1);
    $app_id = $data['appid'];
    $config = WechatTool::getConfig($app_id);
    $signKey = $config['sign_key'];
    $verify = strtoupper(md5($str . '&key=' . $signKey));
    return $verify;
}

 微信支付的加密解密方式,数据组装都是一样的规则,后面还有企业付款到零钱,退款等,基本差不多,像退款或者企业付款到零钱的加密可能需要双向证书验证,可参考
https://blog.csdn.net/sinat_14826983/article/details/83722020 的curl_post_ssl方法



展开阅读全文

没有更多推荐了,返回首页