首页 >后端开发 >php教程 >随着更新潮流,把PHP字节小程序担保支付类也更新了!

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

藏色散人
藏色散人转载
2021-07-16 15:23:314256浏览

微信支付类更新结束,回头发现字节跳动也更新了支付,那么跟随着潮流,也把字节跳动支付类也更新了一下,新版使用最新版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(&#39;./vendor/autoload.php&#39;);

$config = []; // 支付配置
$order = [
    &#39;order_sn&#39; => time(), // 订单编号
    &#39;total_amount&#39; => 1, // 订单金额(分)
    &#39;body&#39; => &#39;测试商品&#39;, // 商品名称
];

$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 = &#39;v1&#39;;

    // 统一下订单管理
    private static $ecpayUrl = &#39;https://developer.toutiao.com/api/apps/ecpay/&#39;;
    // 服务端预下单
    private static $createOrderUrl = &#39;https://developer.toutiao.com/api/apps/ecpay/v1/create_order&#39;;
    // 订单查询
    private static $queryOrderUrl = &#39;https://developer.toutiao.com/api/apps/ecpay/v1/query_order&#39;;
    // 退款
    private static $createRefundUrl = &#39;https://developer.toutiao.com/api/apps/ecpay/v1/create_refund&#39;;
    // 查询退款
    private static $queryRefundUrl = &#39;https://developer.toutiao.com/api/apps/ecpay/v1/query_refund&#39;;
    // 分账请求
    private static $settleUrl = &#39;https://developer.toutiao.com/api/apps/ecpay/v1/settle&#39;;
    // 查询分账
    private static $querySettleUrl = &#39;https://developer.toutiao.com/api/apps/ecpay/v1/query_settle&#39;;
    // 服务商进件
    private static $addMerchantUrl = &#39;https://developer.toutiao.com/api/apps/ecpay/saas/add_merchant&#39;;
    // 分账方进件
    private static $addSubMerchantUrl = &#39;https://developer.toutiao.com/api/apps/ecpay/saas/add_sub_merchant&#39;;

    // 支付相关配置
    private static $config = array(
        &#39;app_id&#39;        => &#39;&#39;, // App ID
        &#39;salt&#39;          => &#39;&#39;, // 支付密钥值
        &#39;notify_url&#39;    => &#39;&#39;, // 支付回调地址
        &#39;thirdparty_id&#39; => &#39;&#39;, // 第三方平台服务商 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(
     *      &#39;body&#39;         => &#39;&#39;, // 产品描述
     *      &#39;total_amount&#39; => &#39;&#39;, // 订单金额(分)
     *      &#39;order_sn&#39;     => &#39;&#39;, // 订单编号
     * );
     */
    public static function createOrder($order)
    {
        $config = self::$config;
        $params = [
            &#39;app_id&#39;        => $config[&#39;app_id&#39;], // 是 小程序 AppID
            &#39;out_order_no&#39;  => (string)$order[&#39;order_sn&#39;], // 是 开发者侧的订单号, 同一小程序下不可重复
            &#39;total_amount&#39;  => $order[&#39;total_amount&#39;], // 是 支付价格; 接口中参数支付金额单位为[分]
            &#39;subject&#39;       => $order[&#39;body&#39;], // 是 商品描述; 长度限制 128 字节,不超过 42 个汉字
            &#39;body&#39;          => $order[&#39;body&#39;], // 是 商品详情
            &#39;valid_time&#39;    => 3600 * 2, // 是 订单过期时间(秒); 最小 15 分钟,最大两天
            // &#39;sign&#39;          => &#39;&#39;, // 是 开发者对核心字段签名, 签名方式见文档附录, 防止传输过程中出现意外
            // &#39;cp_extra&#39;      => &#39;&#39;, // 否 开发者自定义字段,回调原样回传
            // &#39;notify_url&#39;    => $config[&#39;notify_url&#39;], // 否 商户自定义回调地址
            // &#39;thirdparty_id&#39; => &#39;&#39;, // 否 第三方平台服务商 id,非服务商模式留空
            &#39;disable_msg&#39;   => 1, // 否 是否屏蔽担保支付的推送消息,1-屏蔽 0-非屏蔽,接入 POI 必传
            // &#39;msg_page&#39;      => &#39;&#39;, // 否 担保支付消息跳转页
            // &#39;store_uid&#39;     => &#39;&#39;, // 否 多门店模式下,门店 uid
        ];
        !empty($order[&#39;cp_extra&#39;]) && $params[&#39;cp_extra&#39;] = $order[&#39;cp_extra&#39;];
        !empty($config[&#39;notify_url&#39;]) && $params[&#39;notify_url&#39;] = $config[&#39;notify_url&#39;];
        !empty($config[&#39;thirdparty_id&#39;]) && $params[&#39;thirdparty_id&#39;] = $config[&#39;thirdparty_id&#39;];
        if (!empty($config[&#39;msg_page&#39;])) {
            $params[&#39;disable_msg&#39;] = 0;
            $params[&#39;msg_page&#39;] = $config[&#39;msg_page&#39;];
        }

        $params[&#39;sign&#39;] = 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 = [
            &#39;app_id&#39; => $config[&#39;app_id&#39;], // 小程序 AppID
            &#39;out_order_no&#39; => (string)$orderSn, // 开发者侧的订单号, 不可重复
            // &#39;sign&#39; => &#39;&#39;, // 开发者对核心字段签名, 签名方式见文档, 防止传输过程中出现意外
            // &#39;thirdparty_id&#39; => &#39;&#39;, // 服务商模式接入必传	第三方平台服务商 id,非服务商模式留空
        ];

        !empty($config[&#39;thirdparty_id&#39;]) && $params[&#39;thirdparty_id&#39;] = $config[&#39;thirdparty_id&#39;];
        $params[&#39;sign&#39;] = 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[&#39;msg&#39;]))
            die(&#39;暂无回调信息&#39;);

        $result = json_decode($data[&#39;msg&#39;], true); // 进行签名验证
        // 判断签名是否正确  判断支付状态
        if ($result && $data[&#39;type&#39;]==&#39;payment&#39;) {
            return $data;
        } else {
            return false;
        }
    }

    /**
     * [createRefund 订单退款]
     * @param  [type] $order [订单相关信息]
     * @return [type]        [description]
     * $order = array(
     *      &#39;order_sn&#39;     => &#39;&#39;, // 订单编号
     *      &#39;refund_sn&#39;    => &#39;&#39;, // 退款编号
     *      &#39;total_amount&#39; => &#39;&#39;, // 订单金额(分)
     *      &#39;body&#39;         => &#39;&#39;, // 退款原因
     * );
     */
    public static function createRefund($order)
    {
        $config = self::$config;
        $params = [
            &#39;app_id&#39;        => $config[&#39;app_id&#39;], // 是	小程序 id
            &#39;out_order_no&#39;  => (string)$order[&#39;order_sn&#39;], // 是	商户分配订单号,标识进行退款的订单
            &#39;out_refund_no&#39; => (string)$order[&#39;refund_sn&#39;], // 是	商户分配退款号
            &#39;refund_amount&#39; => $order[&#39;total_amount&#39;], // 是	退款金额,单位[分]
            &#39;reason&#39;        => $order[&#39;body&#39;] ?? &#39;用户申请退款&#39;, // 是	退款理由,长度上限 100
            // &#39;cp_extra&#39;      => &#39;&#39;, // 否	开发者自定义字段,回调原样回传
            // &#39;notify_url&#39;    => &#39;&#39;, // 否	商户自定义回调地址
            // &#39;sign&#39;          => &#39;&#39;, // 是	开发者对核心字段签名, 签名方式见文档, 防止传输过程中出现意外
            // &#39;thirdparty_id&#39; => &#39;&#39;, // 否,服务商模式接入必传	第三方平台服务商 id,非服务商模式留空
            &#39;disable_msg&#39;   => 1, // 否	是否屏蔽担保支付消息,1-屏蔽
            // &#39;msg_page&#39;      => &#39;&#39;, // 否	担保支付消息跳转页
            // &#39;all_settle&#39;    => &#39;&#39;, // 否	是否为分账后退款,1-分账后退款;0-分账前退款。分账后退款会扣减可提现金额,请保证余额充足
        ];

        !empty($order[&#39;cp_extra&#39;]) && $params[&#39;cp_extra&#39;] = $order[&#39;cp_extra&#39;];
        !empty($order[&#39;all_settle&#39;]) && $params[&#39;all_settle&#39;] = $order[&#39;all_settle&#39;];
        !empty($config[&#39;thirdparty_id&#39;]) && $params[&#39;thirdparty_id&#39;] = $config[&#39;thirdparty_id&#39;];
        if (!empty($config[&#39;msg_page&#39;])) {
            $params[&#39;disable_msg&#39;] = 0;
            $params[&#39;msg_page&#39;] = $config[&#39;msg_page&#39;];
        }

        $params[&#39;sign&#39;] = 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 = [
            &#39;app_id&#39; => $config[&#39;app_id&#39;], // 小程序 AppID
            &#39;out_refund_no&#39; => $refundSn, // 开发者侧的退款号
            // &#39;sign&#39; => &#39;&#39;, // 开发者对核心字段签名, 签名方式见文档, 防止传输过程中出现意外
            // &#39;thirdparty_id&#39; => &#39;&#39;, // 服务商模式接入必传	第三方平台服务商 id,非服务商模式留空
        ];

        !empty($config[&#39;thirdparty_id&#39;]) && $params[&#39;thirdparty_id&#39;] = $config[&#39;thirdparty_id&#39;];
        $params[&#39;sign&#39;] = 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[&#39;status&#39;]))
            die(&#39;暂无回调信息&#39;);

        $result = json_decode($data[&#39;msg&#39;], true); // 进行签名验证
        // 判断签名是否正确  判断支付状态
        if ($result && $data[&#39;status&#39;]!=&#39;FAIL&#39;) {
            return $data;
        } else {
            return false;
        }
    }

    /**
     * [settle 分账请求]
     * @param  [type] $order [分账信息]
     * @return [type]        [description]
     * $order = array(
     *      &#39;body&#39;         => &#39;&#39;, // 产品描述
     *      &#39;total_amount&#39; => &#39;&#39;, // 订单金额(分)
     *      &#39;order_sn&#39;     => &#39;&#39;, // 订单编号
     * );
     */
    public static function settle($order)
    {
        $config = self::$config;
        $params = [
            &#39;app_id&#39;        => $config[&#39;app_id&#39;], // 是 小程序 AppID
            &#39;out_order_no&#39;  => (string)$order[&#39;order_sn&#39;], // 是 商户分配订单号,标识进行结算的订单
            &#39;out_settle_no&#39; => (string)$order[&#39;settle_sn&#39;], // 是 开发者侧的结算号, 不可重复
            &#39;settle_desc&#39;   => $order[&#39;body&#39;], // 是	结算描述,长度限制 80 个字符
            // &#39;cp_extra&#39;      => &#39;&#39;, // 否	开发者自定义字段,回调原样回传
            // &#39;notify_url&#39;    => &#39;&#39;, // 否	商户自定义回调地址
            // &#39;sign&#39;          => &#39;&#39;, // 是	开发者对核心字段签名, 签名方式见文档, 防止传输过程中出现意外
            // &#39;thirdparty_id&#39; => &#39;&#39;, // 否,服务商模式接入必传	第三方平台服务商 id,非服务商模式留空
            // &#39;settle_params&#39; => &#39;&#39;, // 否,其他分账方信息,分账分配参数 SettleParameter 数组序列化后生成的 json 格式字符串
        ];

        !empty($order[&#39;cp_extra&#39;]) && $params[&#39;cp_extra&#39;] = $order[&#39;cp_extra&#39;];
        !empty($order[&#39;settle_params&#39;]) && $params[&#39;settle_params&#39;] = $order[&#39;settle_params&#39;];
        !empty($config[&#39;thirdparty_id&#39;]) && $params[&#39;thirdparty_id&#39;] = $config[&#39;thirdparty_id&#39;];
        $params[&#39;sign&#39;] = 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 = [
            &#39;app_id&#39; => $config[&#39;app_id&#39;], // 小程序 AppID
            &#39;out_settle_no&#39; => $settleSn, // 开发者侧的分账号
            // &#39;sign&#39; => &#39;&#39;, // 开发者对核心字段签名, 签名方式见文档, 防止传输过程中出现意外
            // &#39;thirdparty_id&#39; => &#39;&#39;, // 服务商模式接入必传	第三方平台服务商 id,非服务商模式留空
        ];

        !empty($config[&#39;thirdparty_id&#39;]) && $params[&#39;thirdparty_id&#39;] = $config[&#39;thirdparty_id&#39;];
        $params[&#39;sign&#39;] = 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[&#39;status&#39;]))
            die(&#39;暂无回调信息&#39;);

        $result = json_decode($data[&#39;msg&#39;], true); // 进行签名验证
        // 判断签名是否正确  判断支付状态
        if ($result && $data[&#39;status&#39;]!=&#39;FAIL&#39;) {
            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 = [
            &#39;component_access_token&#39; => $accessToken, // 是	授权码兑换接口调用凭证
            &#39;thirdparty_component_id&#39; => $componentId, // 是	小程序第三方平台应用 id
            &#39;url_type&#39; => $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 = [
            &#39;thirdparty_id&#39; => $thirdpartyId, // 是	小程序第三方平台应用 id
            &#39;sub_merchant_id&#39; => $merchantId, // 是	商户 id,用于接入方自行标识并管理进件方。由服务商自行分配管理
            &#39;url_type&#39; => $urlType, // 是	链接类型:1-进件页面 2-账户余额页
            // &#39;sign&#39; => &#39;&#39;, // 开发者对核心字段签名, 签名方式见文档, 防止传输过程中出现意外
        ];

        $params[&#39;sign&#39;] = 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 = [&#39;err_no&#39;=>0, &#39;err_tips&#39;=>&#39;success&#39;];
        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[&#39;salt&#39;]);
        sort($rList, 2);
        return md5(implode(&#39;&&#39;, $rList));
    }

}
推荐学习:《PHP视频教程

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

声明:
本文转载于:冯奎博客fengkui.net。如有侵权,请联系admin@php.cn删除