php thinkphp 抖音支付,订单同步接口分享

1. 抖音支付

需要获取抖音小程序的AppID,AppSecret,需要配置回调地址,Token获取SALT

官方地址:支付订单同步

以下干货仅针对于有一定开发基础的精英,0基础的止步。

php 复制代码
  public function DouyinPay($openId='',$id='',$body = '抖音担保支付'){

        $order=db('order')->where(['id'=>$id,'status'=>1])->find();//获取订单信息

        $outOrderNo = $order['orderno'];//开发者侧的订单号
        $totalAmount = $order['price'];//支付价格; 接口中参数支付金额单位为[分]
        $subject = "订单号:".$order['orderno']; //商品描述也就是标题
        $body = $body;
        $validTimestamp = 60 * 60;//订单过期时间(秒);
        $notifyUrl = "https://***/notify"; //这里可以忽略,走字节跳动小程序 -支付 -担保配置-设置回调地址
        //创建订单
        $response = $this->createOrder($outOrderNo, $totalAmount, $subject, $body, $validTimestamp, $notifyUrl);

        $this->success('成功',$response);
    }
        /**
     *	创建订单
     */
    public function CreateOrder($outOrderNo, $totalAmount, $subject, $body, $validTimestamp, $notifyUrl)
    {
        $params = [
            'app_id'       => '******',//小程序appid
            'out_order_no' => $outOrderNo,
            'total_amount' => $totalAmount * 100,
            'subject'      => $subject,
            'body'         => $body,
            'valid_time'   => $validTimestamp,
           'notify_url'   => $notifyUrl,
      
        ];

        $params = array_filter($params);
        $params['sign'] = $this->sign($params);

        $res = $this->posts(
            'https://developer.toutiao.com/api/apps/ecpay/v1/create_order',
            $params
        );
        return $res;
    }
    /**
     *	获取签名
     */
    public  function sign($map) {
        $rList = [];
        foreach($map as $k =>$v) {
            if ($k == "other_settle_params" || $k == "app_id" || $k == "sign" || $k == "thirdparty_id")
                continue;

            $value = trim(strval($v));
            if (is_array($v)) {
                $value = $this->arrayToStr($v);
            }

            $len = strlen($value);
            if ($len > 1 && substr($value, 0,1)=="\"" && substr($value, $len-1)=="\"")
                $value = substr($value,1, $len-1);
            $value = trim($value);
            if ($value == "" || $value == "null")
                continue;
            $rList[] = $value;
        }
        $rList[] = "*****";//这里是SALT
        sort($rList, SORT_STRING);
        return md5(implode('&', $rList));
    }
    // **************** 以下方法 是字节小程序支付 签名处理方式

    public function callbackSign($data) {
		//***这里的是配置salt的时候填写的Token令牌
        $array = array(

            '***',(string)$data['timestamp'],(string)$data['nonce'],		(string)htmlspecialchars_decode($data['msg'])

        );

        sort($array,SORT_STRING);

        $join_str = implode('',$array);

        return sha1($join_str);

    }


    public function arrayToStr($map) {
        $isMap =  $this->isArrMap($map);

        $result = "";
        if ($isMap){
            $result = "map[";
        }

        $keyArr = array_keys($map);
        if ($isMap) {
            sort($keyArr);
        }

        $paramsArr = array();
        foreach($keyArr as  $k) {
            $v = $map[$k];
            if ($isMap) {
                if (is_array($v)) {
                    $paramsArr[] = sprintf("%s:%s", $k, arrayToStr($v));
                } else  {
                    $paramsArr[] = sprintf("%s:%s", $k, trim(strval($v)));
                }
            } else {
                if (is_array($v)) {
                    $paramsArr[] = arrayToStr($v);
                } else  {
                    $paramsArr[] = trim(strval($v));
                }
            }
        }

        $result = sprintf("%s%s", $result, join(" ", $paramsArr));
        if (!$isMap) {
            $result = sprintf("[%s]", $result);
        } else {
            $result = sprintf("%s]", $result);
        }

        return $result;
    }

  public  function isArrMap($map) {
        foreach($map as $k =>$v) {
            if (is_string($k)){
                return true;
            }
        }

        return false;
    }
c 复制代码
    // **************** 以下方法 是回调


    public function notify()
    {
        $notify = \request()->param();
    //  验签
        if ($notify['msg_signature'] !== $this->callbackSign($notify)) {
           return false;

        } else {
            //获取订单信息
            $order=(string)htmlspecialchars_decode($notify['msg']);
            $order = json_decode($order, true);
            //处理订单,获取订单号
       
            $sn =  $order['cp_orderno'];
            $do2='订单的处理';
            if($do2){
              
                $data = ['err_no' => '0', 'err_tips' => 'success'];
                return json($data);
            }else{
                db()->rollback();
                return false;
            }
           // Log::info('抖音担保支付效验成功');
        }

    }
      public function posts(string $url, array $params = [], array $headers = [])
    {
        $headers[] = 'Content-type: application/json';

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $output = curl_exec($ch);
        curl_close($ch);

        return json_decode($output, true);
    }

不要单纯以为只要支付完成就OK了,下面还需要订单同步到抖音,下场如下

2.订单同步

这里不需要申请额外的参数,大致分为三步(1.获取token,2.组装商品,3.组装订单)

代码如下:

php 复制代码
     /**
     * 订单推送到抖音
     * @param $data array 订单数据
     * @note order_status 与 status须保持一致,但类型不同
     * @return array
     */
    public  function pushOrder($id=''){
        $data=[];//获取订单信息
        $api = "https://developer.toutiao.com/api/apps/order/v2/push";
        $openid ='';//获取下单用户openid
  		//组装商品
        $item_list = [['item_code' => '购买会员卡','img'=>'https://***/logo.jpg',
            'title'=>'会员服务','amount'=>1,'price'=>(int)($data['price']*100)]];//参数对应请查看官方文档,注意字段类型
           // 组装订单
        $detail = [
            'order_id'=>$data['orderno'],'create_time'=>strtotime($data['add_time'])*1000,'status'=>"已支付",'amount'=>1,
            'total_price'=>(int)($data['price']*100),'detail_url'=>"pages/me/vip/vip",'item_list'=>$item_list];
              dump($detail);
              
        $param = ['access_token'=>$this->getAccessTokens(),'app_name'=>"douyin",
            'open_id'=>$openid,'update_time'=>$this->getMillisecond(),'order_detail'=>json_encode($detail),'order_type'=>0,'order_status'=>1,'payment_order_no'=>$data['orderno']];
     
        $result =$this->posts($api,$param);//请求
      
    }
     /**
     * 获取AccessToken
     */
    public  function getAccessTokens(){
        $api = "https://developer.toutiao.com/api/apps/v2/token";
			  $param = ['appid'=>'***','secret'=>'***','grant_type'=>"client_credential"];
        $access_token = Cache::get('dy_accessToken');
        if(empty($access_token)){
            $data = $this->posts($api,$param);
         //   dump($result);die;
         //   $data = json_decode($result,true);
            if($data['err_no'] == 0){
                $access_token = $data['data']['access_token'];
                Cache::set('dy_accessToken',$access_token,$data['data']['expires_in']);
            }
        }
        return $access_token;
    }
       public  function getMillisecond() {
        list($t1, $t2) = explode(' ', microtime());
        return (float)sprintf('%.0f',(floatval($t1)+floatval($t2))*1000);
    }
相关推荐
BingoGo1 小时前
PHP 15 个高效开发的小技巧
后端·php
JaguarJack3 小时前
PHP 15 个高效开发的小技巧
后端·php
魔众18 小时前
ModStartCMS v9.7.0 组件升级优化,模块升级提醒,访问明细导出
php·cms
一人の梅雨21 小时前
京东商品详情深度解析:从接口调用到商业价值挖掘的技术实现
服务器·数据库·php
帅帅梓21 小时前
docker网络
网络·docker·php
吃鱼吃鱼吃不动了1 天前
什么是负载均衡?
开发语言·php
BingoGo1 天前
PHP 开发者应该理解的 Linux 入门权限指南
后端·php
苏琢玉1 天前
再也不用翻一堆日志!一键部署轻量级错误监控系统,帮你统一管理 PHP 报错
go·github·php
JaguarJack1 天前
PHP 开发者应该理解的 Linux 入门权限指南
后端·php
2301_793167991 天前
网络管理部分
linux·运维·服务器·网络·php