php 小程序服务商支付模式

不明白可以直接评论留言

详见微信支付-开发文档:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_sl_api.php?chapter=9_1

 /**
     * @Notes: 小程序服务商支付模式 测试(完)
     * @Date: 2020-10-19 16:13
     */
    public function add_pay()
    {
        $appid        = $this->mch_appid; //  服务商的APPID
        $mch_id       = $this->mch_id; //  微信支付分配的商户号
        $key          = $this->key; // 服务商户支付秘钥
        $sub_appid    = $this->appid; //当前调起支付的小程序APPID
        $sub_mch_id   = $this->sub_mch_id; // 微信支付分配的子商户号 子商户号
        $body         = "测试";
        $out_trade_no = "1415659990";//订单号
        $openid       = $this->userInfo['openid']??"";// 用户openid
        $total_fee    = 0.01;// 支付金额
        $notify_url   = "/";//支付成功回掉
        $res          = Pay::get_pay($appid, $mch_id, $key, $sub_appid, $sub_mch_id, $body, $out_trade_no, $openid, $total_fee, $notify_url);
        
    }

pay 文件

<?php
/**
 * Desc:小程序服务商支付模式
 * Date: 2020-10-19 13:18
 */

namespace app\model;

use think\Db;
use think\Cache;
use think\Exception;
use think\facade\Config;
use think\Request;

class Pay
{

    /**
     * @Notes: 订单支付
     * @Date: 2020-10-19 13:20
     * $appid   服务商的APPID
     * $mch_id  商户号
     * $key 服务商key
     * $sub_appid   小程序的APPID
     * $sub_mch_id  子商户号
     * $body    商品描述
     * $out_trade_no    商户订单号
     * $openid  用户标示
     * $total_fee   货币类型
     * $notify_url  通知地址
     */
    public static function get_pay($appid = '', $mch_id = '', $key = '', $sub_appid = '', $sub_mch_id = '', $body = '', $out_trade_no = '', $openid = '', $fee = 0.00, $notify_url = '')
    {
        $ip               = $_SERVER['SERVER_ADDR'];
        $nonce_str        = nonce_str();//随机字符串
        $spbill_create_ip = $ip;//服务器IP
        $trade_type       = 'JSAPI';//交易类型 默认
        $total_fee        = $fee * 100;// 微信支付单位是分,所以这里需要*100


        //这里是按照顺序的 因为下面的签名是按照顺序 排序错误 肯定出错
        $post['appid']            = $appid;
        $post['body']             = $body;
        $post['mch_id']           = $mch_id;
        $post['nonce_str']        = $nonce_str; //随机字符串
        $post['notify_url']       = $notify_url;
        $post['sub_openid']       = $openid;  //支付者在子商户的openid
        $post['out_trade_no']     = $out_trade_no;
        $post['spbill_create_ip'] = $spbill_create_ip; //终端的ip
        $post['sub_appid']        = $sub_appid;
        $post['sub_mch_id']       = $sub_mch_id;
        $post['total_fee']        = $total_fee; //总金额 最低为一块钱 必须是整数
        $post['trade_type']       = $trade_type;
//        p($post,1);
        $sign     = Dev::get_sign($post, $key);
        $post_xml = "<xml>
                        <appid>$appid</appid>
                        <body>$body</body>
                        <mch_id>$mch_id</mch_id>
                        <nonce_str>$nonce_str</nonce_str>
                        <notify_url>$notify_url</notify_url>
                        <out_trade_no>$out_trade_no</out_trade_no>
                        <spbill_create_ip>$spbill_create_ip</spbill_create_ip>
                        <sub_appid>$sub_appid</sub_appid>
                        <sub_mch_id>$sub_mch_id</sub_mch_id>
                        <sub_openid>$openid</sub_openid>
                        <total_fee>$total_fee</total_fee>
                        <trade_type>$trade_type</trade_type>
                        <sign>$sign</sign>
                    </xml>";
        //统一接口prepay_id
        $url   = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
        $xml   = http_request($url, $post_xml);
        $array = self::xml($xml);//全要大写
        write_log($array, 'get_pay');

        if ($array['RETURN_CODE'] == 'SUCCESS' && $array['RESULT_CODE'] == 'SUCCESS') {
            $time = time();
            $tmp  = [];//临时数组用于签名
            //$tmp['appId']         = $appid;
            $tmp['appId']         = $sub_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 参数值,提交格式如:prepay_id=*
            $data['paySign']      = Dev::get_sign($tmp, $key);//签名,具体签名方案参见微信公众号支付帮助文档;
            $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'];
        }
        return json_encode($data);
    }

    //获取xml
    private static function xml($xml)
    {
        $p = xml_parser_create();
        xml_parse_into_struct($p, $xml, $vals, $index);
        xml_parser_free($p);
        $data = [];
        foreach ($index as $key => $value) {
            if ($key == 'xml' || $key == 'XML') continue;
            $tag        = $vals[$value[0]]['tag'];
            $value      = $vals[$value[0]]['value'];
            $data[$tag] = $value;
        }
        return $data;
    }

}

//随机32位字符串
function nonce_str()
{
    $result = '';
    $str    = 'QWERTYUIOPASDFGHJKLZXVBNMqwertyuioplkjhgfdsamnbvcxz';
    for ($i = 0; $i < 32; $i++) {
        $result .= $str[rand(0, 48)];
    }
    return $result;
}

/**
 * curl请求
 * @param $url
 * @param null $data
 * @param array $headers
 * @return bool|string
 */
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;
}

Dev文件

<?php
/**
 * 生成微信签名
 * Date: 2020-10-19
 * Time: 10:41
 */
namespace app\model;

class Dev
{
    //作用:生成签名
    public static function get_sign($params, $secret) {
        foreach ($params as $k => $v) {
            $Parameters[$k] = $v;
        }
        //签名步骤一:按字典序排序参数
        ksort($Parameters);
        $String = self::formatBizQueryParaMap($Parameters, false);
        //签名步骤二:在string后加入KEY
        $String = $String . "&key=" . $secret;
        //签名步骤三:MD5加密
        $String = md5($String);
        //签名步骤四:所有字符转为大写
        $result_ = strtoupper($String);
        return $result_;
    }


    ///作用:格式化参数,签名过程需要使用
    public static function formatBizQueryParaMap($paraMap, $urlencode) {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v) {
            if ($urlencode) {
                $v = urlencode($v);
            }
            $buff .= $k . "=" . $v . "&";
        }
        $reqPar="";
        if (strlen($buff) > 0) {
            $reqPar = substr($buff, 0, strlen($buff) - 1);
        }
        return $reqPar;
    }

}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荔枝学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值