• 技术文章 >后端开发 >php教程

    随着更新潮流,把PHP字节小程序担保支付类也更新了!

    藏色散人藏色散人2021-07-17 09:04:47转载852

    微信支付类更新结束,回头发现字节跳动也更新了支付,那么跟随着潮流,也把字节跳动支付类也更新了一下,新版使用最新版V1接口(担保支付简介),同时新增composer安装,便于集成框架使用(Github地址

    也可单独复制使用:

    composer require fengkui/pay

    (注:因业务需要,仅编写相关方法,尚未经过测试,仅供参考)

    首先把配置文件填写完整:

    // 支付相关配置
    private static $config = array(
    	'app_id'        => '', // App ID
    	'salt'          => '', // 支付密钥值
    	'notify_url'    => '', // 支付回调地址
    	'thirdparty_id' => '', // 第三方平台服务商 id,非服务商模式留空
    );

    支付类封装相关方法:

    method描述
    createOrder下单支付
    queryOrder订单查询
    notifyOrder订单回调验证
    createRefund订单退款
    queryRefund退款查询
    settle分账请求
    querySettle分账查询

    使用方法:

    <?php
    require_once('./vendor/autoload.php');
    
    $config = []; // 支付配置
    $order = [
        'order_sn' => time(), // 订单编号
        'total_amount' => 1, // 订单金额(分)
        'body' => '测试商品', // 商品名称
    ];
    
    $wechat = new fengkui\Pay\Bytedance($config);
    $re = $wechat->createOrder($order);
    die(json_encode($re)); // JSON化直接返回小程序客户端

    如下代码是封装好的完整支付类文件(Bytedance.php), 可以根据自己需求随意修改,详细的使用方法后期会有文档:

    <?php
    /**
     * @Author: [FENG] <1161634940@qq.com>
     * @Date:   2020-05-13 17:02:49
     * @Last Modified by:   [FENG] <1161634940@qq.com>
     * @Last Modified time: 2021-06-15T17:06:18+08:00
     */
    namespace fengkui\Pay;
    
    use fengkui\Supports\Http;
    
    /**
     * Bytedance 字节跳动支付
     * 小程序担保支付(V1)
     */
    class Bytedance
    {
        // 接口版本
        const EDITON = 'v1';
    
        // 统一下订单管理
        private static $ecpayUrl = 'https://developer.toutiao.com/api/apps/ecpay/';
        // 服务端预下单
        private static $createOrderUrl = 'https://developer.toutiao.com/api/apps/ecpay/v1/create_order';
        // 订单查询
        private static $queryOrderUrl = 'https://developer.toutiao.com/api/apps/ecpay/v1/query_order';
        // 退款
        private static $createRefundUrl = 'https://developer.toutiao.com/api/apps/ecpay/v1/create_refund';
        // 查询退款
        private static $queryRefundUrl = 'https://developer.toutiao.com/api/apps/ecpay/v1/query_refund';
        // 分账请求
        private static $settleUrl = 'https://developer.toutiao.com/api/apps/ecpay/v1/settle';
        // 查询分账
        private static $querySettleUrl = 'https://developer.toutiao.com/api/apps/ecpay/v1/query_settle';
        // 服务商进件
        private static $addMerchantUrl = 'https://developer.toutiao.com/api/apps/ecpay/saas/add_merchant';
        // 分账方进件
        private static $addSubMerchantUrl = 'https://developer.toutiao.com/api/apps/ecpay/saas/add_sub_merchant';
    
        // 支付相关配置
        private static $config = array(
            'app_id'        => '', // App ID
            'salt'          => '', // 支付密钥值
            'notify_url'    => '', // 支付回调地址
            'thirdparty_id' => '', // 第三方平台服务商 id,非服务商模式留空
        );
    
        /**
         * [__construct 构造函数]
         * @param [type] $config [传递支付相关配置]
         */
        public function __construct($config=NULL){
            $config && self::$config = array_merge(self::$config, $config);
        }
    
        /**
         * [createOrder 下单支付]
         * @param  [type] $order [description]
         * @return [type]        [description]
         * $order = array(
         *      'body'         => '', // 产品描述
         *      'total_amount' => '', // 订单金额(分)
         *      'order_sn'     => '', // 订单编号
         * );
         */
        public static function createOrder($order)
        {
            $config = self::$config;
            $params = [
                'app_id'        => $config['app_id'], // 是 小程序 AppID
                'out_order_no'  => (string)$order['order_sn'], // 是 开发者侧的订单号, 同一小程序下不可重复
                'total_amount'  => $order['total_amount'], // 是 支付价格; 接口中参数支付金额单位为[分]
                'subject'       => $order['body'], // 是 商品描述; 长度限制 128 字节,不超过 42 个汉字
                'body'          => $order['body'], // 是 商品详情
                'valid_time'    => 3600 * 2, // 是 订单过期时间(秒); 最小 15 分钟,最大两天
                // 'sign'          => '', // 是 开发者对核心字段签名, 签名方式见文档附录, 防止传输过程中出现意外
                // 'cp_extra'      => '', // 否 开发者自定义字段,回调原样回传
                // 'notify_url'    => $config['notify_url'], // 否 商户自定义回调地址
                // 'thirdparty_id' => '', // 否 第三方平台服务商 id,非服务商模式留空
                'disable_msg'   => 1, // 否 是否屏蔽担保支付的推送消息,1-屏蔽 0-非屏蔽,接入 POI 必传
                // 'msg_page'      => '', // 否 担保支付消息跳转页
                // 'store_uid'     => '', // 否 多门店模式下,门店 uid
            ];
            !empty($order['cp_extra']) && $params['cp_extra'] = $order['cp_extra'];
            !empty($config['notify_url']) && $params['notify_url'] = $config['notify_url'];
            !empty($config['thirdparty_id']) && $params['thirdparty_id'] = $config['thirdparty_id'];
            if (!empty($config['msg_page'])) {
                $params['disable_msg'] = 0;
                $params['msg_page'] = $config['msg_page'];
            }
    
            $params['sign'] = self::makeSign($params);
            // dump($params);die;
            $url = self::$createOrderUrl;
            $response = Http::post($url, json_encode($params));
            $result = json_decode($response, true);
            return $result;
        }
    
        /**
         * [queryOrder 订单查询]
         * @param  [type] $orderSn [开发者侧的订单号, 不可重复]
         * @return [type]          [description]
         */
        public static function queryOrder($orderSn)
        {
            $config = self::$config;
            $params = [
                'app_id' => $config['app_id'], // 小程序 AppID
                'out_order_no' => (string)$orderSn, // 开发者侧的订单号, 不可重复
                // 'sign' => '', // 开发者对核心字段签名, 签名方式见文档, 防止传输过程中出现意外
                // 'thirdparty_id' => '', // 服务商模式接入必传	第三方平台服务商 id,非服务商模式留空
            ];
    
            !empty($config['thirdparty_id']) && $params['thirdparty_id'] = $config['thirdparty_id'];
            $params['sign'] = self::makeSign($params);
    
            $url = self::$queryOrderUrl;
            $response = Http::post($url, json_encode($params));
            $result = json_decode($response, true);
            return $result;
        }
    
        /**
         * [notifyOrder 订单回调验证]
         * @return [array] [返回数组格式的notify数据]
         */
        public static function notifyOrder()
        {
            $data = $_POST; // 获取回调数据
            $config = self::$config;
            if (!$data || empty($data['msg']))
                die('暂无回调信息');
    
            $result = json_decode($data['msg'], true); // 进行签名验证
            // 判断签名是否正确  判断支付状态
            if ($result && $data['type']=='payment') {
                return $data;
            } else {
                return false;
            }
        }
    
        /**
         * [createRefund 订单退款]
         * @param  [type] $order [订单相关信息]
         * @return [type]        [description]
         * $order = array(
         *      'order_sn'     => '', // 订单编号
         *      'refund_sn'    => '', // 退款编号
         *      'total_amount' => '', // 订单金额(分)
         *      'body'         => '', // 退款原因
         * );
         */
        public static function createRefund($order)
        {
            $config = self::$config;
            $params = [
                'app_id'        => $config['app_id'], // 是	小程序 id
                'out_order_no'  => (string)$order['order_sn'], // 是	商户分配订单号,标识进行退款的订单
                'out_refund_no' => (string)$order['refund_sn'], // 是	商户分配退款号
                'refund_amount' => $order['total_amount'], // 是	退款金额,单位[分]
                'reason'        => $order['body'] ?? '用户申请退款', // 是	退款理由,长度上限 100
                // 'cp_extra'      => '', // 否	开发者自定义字段,回调原样回传
                // 'notify_url'    => '', // 否	商户自定义回调地址
                // 'sign'          => '', // 是	开发者对核心字段签名, 签名方式见文档, 防止传输过程中出现意外
                // 'thirdparty_id' => '', // 否,服务商模式接入必传	第三方平台服务商 id,非服务商模式留空
                'disable_msg'   => 1, // 否	是否屏蔽担保支付消息,1-屏蔽
                // 'msg_page'      => '', // 否	担保支付消息跳转页
                // 'all_settle'    => '', // 否	是否为分账后退款,1-分账后退款;0-分账前退款。分账后退款会扣减可提现金额,请保证余额充足
            ];
    
            !empty($order['cp_extra']) && $params['cp_extra'] = $order['cp_extra'];
            !empty($order['all_settle']) && $params['all_settle'] = $order['all_settle'];
            !empty($config['thirdparty_id']) && $params['thirdparty_id'] = $config['thirdparty_id'];
            if (!empty($config['msg_page'])) {
                $params['disable_msg'] = 0;
                $params['msg_page'] = $config['msg_page'];
            }
    
            $params['sign'] = self::makeSign($params);
    
            $url = self::$queryOrderUrl;
            $response = Http::post($url, json_encode($params));
            $result = json_decode($response, true);
            return $result;
        }
    
        /**
         * [queryRefund 退款查询]
         * @param  [type] $refundSn [开发者侧的订单号, 不可重复]
         * @return [type]           [description]
         */
        public static function queryRefund($refundSn)
        {
            $config = self::$config;
            $params = [
                'app_id' => $config['app_id'], // 小程序 AppID
                'out_refund_no' => $refundSn, // 开发者侧的退款号
                // 'sign' => '', // 开发者对核心字段签名, 签名方式见文档, 防止传输过程中出现意外
                // 'thirdparty_id' => '', // 服务商模式接入必传	第三方平台服务商 id,非服务商模式留空
            ];
    
            !empty($config['thirdparty_id']) && $params['thirdparty_id'] = $config['thirdparty_id'];
            $params['sign'] = self::makeSign($params);
    
            $url = self::$queryRefundUrl;
            $response = Http::post($url, json_encode($params));
            $result = json_decode($response, true);
            return $result;
        }
    
        /**
         * [notifyRefund 退款回调验证]
         * @return [array] [返回数组格式的notify数据]
         */
        public static function notifyRefund()
        {
            $data = $_POST; // 获取回调数据
            $config = self::$config;
            if (!$data || empty($data['status']))
                die('暂无回调信息');
    
            $result = json_decode($data['msg'], true); // 进行签名验证
            // 判断签名是否正确  判断支付状态
            if ($result && $data['status']!='FAIL') {
                return $data;
            } else {
                return false;
            }
        }
    
        /**
         * [settle 分账请求]
         * @param  [type] $order [分账信息]
         * @return [type]        [description]
         * $order = array(
         *      'body'         => '', // 产品描述
         *      'total_amount' => '', // 订单金额(分)
         *      'order_sn'     => '', // 订单编号
         * );
         */
        public static function settle($order)
        {
            $config = self::$config;
            $params = [
                'app_id'        => $config['app_id'], // 是 小程序 AppID
                'out_order_no'  => (string)$order['order_sn'], // 是 商户分配订单号,标识进行结算的订单
                'out_settle_no' => (string)$order['settle_sn'], // 是 开发者侧的结算号, 不可重复
                'settle_desc'   => $order['body'], // 是	结算描述,长度限制 80 个字符
                // 'cp_extra'      => '', // 否	开发者自定义字段,回调原样回传
                // 'notify_url'    => '', // 否	商户自定义回调地址
                // 'sign'          => '', // 是	开发者对核心字段签名, 签名方式见文档, 防止传输过程中出现意外
                // 'thirdparty_id' => '', // 否,服务商模式接入必传	第三方平台服务商 id,非服务商模式留空
                // 'settle_params' => '', // 否,其他分账方信息,分账分配参数 SettleParameter 数组序列化后生成的 json 格式字符串
            ];
    
            !empty($order['cp_extra']) && $params['cp_extra'] = $order['cp_extra'];
            !empty($order['settle_params']) && $params['settle_params'] = $order['settle_params'];
            !empty($config['thirdparty_id']) && $params['thirdparty_id'] = $config['thirdparty_id'];
            $params['sign'] = self::makeSign($params);
    
            $url = self::$settleUrl;
            $response = Http::post($url, json_encode($params));
            $result = json_decode($response, true);
            return $result;
        }
    
        /**
         * [querySettle 分账查询]
         * @param  [type] $settleSn [开发者侧的订单号, 不可重复]
         * @return [type]          [description]
         */
        public static function querySettle($settleSn)
        {
            $config = self::$config;
            $params = [
                'app_id' => $config['app_id'], // 小程序 AppID
                'out_settle_no' => $settleSn, // 开发者侧的分账号
                // 'sign' => '', // 开发者对核心字段签名, 签名方式见文档, 防止传输过程中出现意外
                // 'thirdparty_id' => '', // 服务商模式接入必传	第三方平台服务商 id,非服务商模式留空
            ];
    
            !empty($config['thirdparty_id']) && $params['thirdparty_id'] = $config['thirdparty_id'];
            $params['sign'] = self::makeSign($params);
    
            $url = self::$querySettleUrl;
            $response = Http::post($url, json_encode($params));
            $result = json_decode($response, true);
            return $result;
        }
    
        /**
         * [notifySettle 分账回调验证]
         * @return [array] [返回数组格式的notify数据]
         */
        public static function notifySettle()
        {
            $data = $_POST; // 获取回调数据
            $config = self::$config;
            if (!$data || empty($data['status']))
                die('暂无回调信息');
    
            $result = json_decode($data['msg'], true); // 进行签名验证
            // 判断签名是否正确  判断支付状态
            if ($result && $data['status']!='FAIL') {
                return $data;
            } else {
                return false;
            }
        }
    
        /**
         * [addMerchant 服务商进件]
         * @param [type]  $accessToken [授权码兑换接口调用凭证]
         * @param [type]  $componentId [小程序第三方平台应用]
         * @param integer $urlType     [链接类型:1-进件页面 2-账户余额页]
         */
        public static function addMerchant($accessToken, $componentId, $urlType=1)
        {
            $params = [
                'component_access_token' => $accessToken, // 是	授权码兑换接口调用凭证
                'thirdparty_component_id' => $componentId, // 是	小程序第三方平台应用 id
                'url_type' => $urlType, // 是	链接类型:1-进件页面 2-账户余额页
            ];
    
            $url = self::$addMerchantUrl;
            $response = Http::post($url, json_encode($params));
            $result = json_decode($response, true);
            return $result;
        }
    
        /**
         * [addSubMerchant 分账方进件]
         * @param [type]  $thirdpartyId [小程序第三方平台应用]
         * @param [type]  $merchantId   [商户 id,用于接入方自行标识并管理进件方。由服务商自行分配管理]
         * @param integer $urlType      [链接类型:1-进件页面 2-账户余额页]
         */
        public static function addSubMerchant($thirdpartyId, $merchantId, $urlType=1)
        {
            $params = [
                'thirdparty_id' => $thirdpartyId, // 是	小程序第三方平台应用 id
                'sub_merchant_id' => $merchantId, // 是	商户 id,用于接入方自行标识并管理进件方。由服务商自行分配管理
                'url_type' => $urlType, // 是	链接类型:1-进件页面 2-账户余额页
                // 'sign' => '', // 开发者对核心字段签名, 签名方式见文档, 防止传输过程中出现意外
            ];
    
            $params['sign'] = self::makeSign($params);
    
            $url = self::$addSubMerchantUrl;
            $response = Http::post($url, json_encode($params));
            $result = json_decode($response, true);
            return $result;
        }
    
        /**
         * [success 通知状态]
         */
        public static function success()
        {
            $array = ['err_no'=>0, 'err_tips'=>'success'];
            die(json_encode($array));
        }
    
        /**
         * [makeSign 生成秘钥]
         * @param  [type] $data [加密数据]
         * @return [type]       [description]
         */
        public static function makeSign($data) {
            $config = self::$config;
            $rList = array();
            foreach($data as $k => $v) {
                if ($k == "other_settle_params" || $k == "app_id" || $k == "sign" || $k == "thirdparty_id")
                    continue;
                $value = trim(strval($v));
                $len = strlen($value);
                if ($len > 1 && substr($value, 0,1)=="\"" && substr($value,$len, $len-1)=="\"")
                    $value = substr($value,1, $len-1);
                $value = trim($value);
                if ($value == "" || $value == "null")
                    continue;
                array_push($rList, $value);
            }
            array_push($rList, $config['salt']);
            sort($rList, 2);
            return md5(implode('&', $rList));
        }
    
    }
    推荐学习:《PHP视频教程

    以上就是随着更新潮流,把PHP字节小程序担保支付类也更新了!的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:冯奎博客fengkui.net,如有侵犯,请联系admin@php.cn删除
    专题推荐:PHP
    上一篇:深入浅析PHP中的组合模式 下一篇:浅谈PHP中的中介者模式
    VIP会员

    相关文章推荐

    • 关于微信支付小程序v3【附PHP完整后端代码】• 【记录】PHP微信小程序 微信支付v3的使用• 分享封装的一个PHP微信支付的类库(扫码、H5、小程序)• 小程序如何获取到openid和session_key

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网