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);
    }
相关推荐
魔众24 分钟前
一个桌面工具条系统,插件一键启动,快速扩展提高工作效率
开源·php·laravel·blog
raysync8883 小时前
替代传统FTP传输,镭速大数据传输系统实现安全高效数据流转!
开发语言·安全·php
cr.sheeper3 小时前
CTFHUB-web进阶-php
开发语言·php
Clockwiseee3 小时前
PHP之伪协议
android·开发语言·php
跨境商城搭建开发4 小时前
一个服务器可以搭建几个网站?搭建一个网站的流程介绍
运维·服务器·前端·vue.js·mysql·npm·php
hackeroink4 小时前
【网络安全零基础入门】PHP环境搭建、安装Apache、安装与配置MySQL(非常详细)零基础入门到精通,收藏这一篇就够(01)_php安装配置教程
web安全·php·apache
?333337 小时前
CTFHub Web进阶-PHP-Bypass disable_function攻略
开发语言·安全·web安全·php
hking1117 小时前
upload-labs关卡记录12
web安全·php
网安-轩逸8 小时前
基于ISO 21434的汽车网络安全实践
web安全·汽车·php