php实现抖音小程序支付

 

开发者发起下单_小程序_抖音开放平台

第一步、抖音小程序发起支付

tt.pay_小程序_抖音开放平台

前端提交订单数据到后端接口,然后使用 tt.pay发起支付

请求参数

属性

类型

必填

说明

order_id

string

担保交易服务端订单号

order_token

string

担保交易订单号 token

methods: {

    requestPayment() {
      tt.showLoading();
	    getDeviceId().then(deviceId => {
	      tt.request({
		url: 'https://xxx.comm',
		method: 'POST',
		header: {
			'Content-Type': 'application/json',
			'token': '75dda91d-cb3d-4126-8f63-decee26e9ada'
		  },
		data: {
		  amount: 1,
		  device_id: deviceId ,
		  sid: 8 ,
		  uid: 1572 ,
		  pricebuy: 1 ,
		  lx: 2 ,
		  priced: 1 ,
		  sum: 1 ,
		  buytype: '抖音' ,
		},

		success: (res) => {
		  console.log('orderInfo是:', res.data.data);
		  console.log('order_id:', res.data.data.order_id);
		  console.log('order_id:', res.data.data.order_token);
		  tt.pay({
			orderInfo: {
			  order_id: res.data.data.order_id,
			  order_token:res.data.data.order_token
			},
			service: 5,
			success(res) {
			  if (res.code == 0) {
				// 支付成功处理逻辑,只有res.code=0时,才表示支付成功
				// 但是最终状态要以商户后端结果为准
			  }
			},
			fail(res) {
			  // 调起收银台失败处理逻辑
			},
		  });
	
		  tt.hideLoading();
		}
	      });
	    });
    }
  }

第二步、后端请求抖音预支付接口

1.使用预下单接口

//amount金额  subject标题 body详情  out_trade_no订单号  notify_url回调地址
public function pay($amount,$subject,$body,$out_trade_no,$notify_url)
    {
        $site=config('site');
        
        if($amount<=0){
            $this->error(__('金额不对'));
        }
        
        $amount=$amount*100;
        $url = 'https://developer.toutiao.com/api/apps/ecpay/v1/create_order';
        $data = [
            "app_id" => $site['douyin']['appid'],
            "out_order_no" =>$out_trade_no,
            "total_amount" => $amount,
            "subject" => $subject,
            "body" => $body,
            "valid_time" => 180,
            "cp_extra" =>$subject,
            "notify_url" => $notify_url
        ];
        $data['sign']= dysign($data,$site['douyin']['salt']);
        $res= jsonPost($url,$data);
        $res=json_decode($res,true);
        if(!is_array($res)){
            $this->error($res);
        }
        if($res['err_no']!=0){
            $this->error($res['err_tips']);
        }
        $payData=$res['data'];
        $this->success('订单提交成功 正在跳转支付',$payData);
    }

2.支付签名 

//支付签名
function sign($map,$salt) {
    $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 = 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));
}

3.http请求

   function jsonPost($url, $postData, $customHeaders = []) {
        // 初始化curl
        $ch = curl_init($url);

        // 设置curl选项
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 注意:不推荐在生产环境中禁用SSL验证
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 返回结果而不是直接输出
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 跟随重定向
        curl_setopt($ch, CURLOPT_POST, true); // 发送POST请求
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData)); // JSON格式数据
        // 设置HTTP头
        curl_setopt($ch, CURLOPT_HTTPHEADER, $customHeaders);

        // 执行请求
        $response = curl_exec($ch);

        // 检查是否有错误发生
        if (curl_errno($ch)) {
            $error = 'Curl error: ' . curl_error($ch);
            curl_close($ch); // 关闭curl资源
            return $error; // 返回错误信息
        }

        curl_close($ch); // 关闭curl资源

        // 直接返回原始响应,不进行json_decode
        return $response;
    }

第三步回调处理

    public function notify(){

        $post = file_get_contents('php://input');
        $post=json_decode($post,true);
        $token='token';//抖音后台配置的token
        $post['token']=$token;
        $sign=$this->callbackSign($post);
        if($sign!=$post['msg_signature']){
            echo "签名失败";
           
        }
        $return=json_encode(["err_no"=>0,"err_tips"=>'success']);
        echo $return;exit;
    }

回调签名

   public   function callbackSign(array $params) {
            $data = [
                $params['timestamp'],
                (string) $params['nonce'],
                (string) $params['msg'],
                (string) $params['token'],
            ];

            sort($data, SORT_STRING);

            return hash('sha1', join('', $data));
        }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/682020.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

css动画案例练习之会展开的魔方和交错的小块

这里写目录标题 一级目录二级目录三级目录 下面开始案例的练习&#xff0c;建议第一个动手操作好了再进行下一个一、交错的小块效果展示1.大致思路1.基本结构2.实现动态移动 2.最终版代码 二、会展开的魔方1.大致思路1.基本结构;2.静态魔方的构建3.让静态的魔方动起来 2.最终版…

Springboot高手之路01-AOP

文章目录 登录校验拦截器 基于拦截器实现登录校验功能全局异常处理器 登录校验 拦截器 拦截器是spring中提供的 所以第一步就是把拦截器交给spring管理 不管是过滤器还是拦截器都是需要配置路径 /** 拦截所有 拦截器放行直接是true 是否运行访问对应的web资源 拦截器实现Ha…

动态规划6:63. 不同路径 II

动态规划解题步骤&#xff1a; 1.确定状态表示&#xff1a;dp[i]是什么 2.确定状态转移方程&#xff1a;dp[i]等于什么 3.初始化&#xff1a;确保状态转移方程不越界 4.确定填表顺序&#xff1a;根据状态转移方程即可确定填表顺序 5.确定返回值 题解&#xff1a;63. 不同…

通用漏洞-基于同源策略的cors与jsonp域名接管

脚本参考&#xff1a;https://www.cnblogs.com/haorancracker/articles/17699536.html) 1.cors&jsonp 在csrf的学习中&#xff0c;我们了解到解决第三方网站采取的发包操作&#xff0c;最简单的策略就是同源策略sof&#xff0c;即为同协议&#xff0c;同域名&#xff0c;…

C++设计模式-单例模式,反汇编

文章目录 25. 单例模式25.1. 饿汉式单例模式25.2. 懒汉式单例模式25.2.1. 解决方案125.2.2. 解决方案2 &#xff08;推荐写法&#xff09; 运行在VS2022&#xff0c;x86&#xff0c;Debug下。 25. 单例模式 单例即该类只能有一个实例。 应用&#xff1a;如在游戏开发中&#x…

VS2022,DLL1调用lib,lib调用DLL2

DLL1调用lib&#xff0c;lib调用DLL2 问题1&#xff1a;为什么在dll1中需要引入dll2的.lib文件 当你有一个工程&#xff08;dll1&#xff09;调用静态库&#xff08;lib&#xff09;&#xff0c;而静态库&#xff08;lib&#xff09;又调用另一个DLL&#xff08;dll2&#xf…

BPTT算法详解:深入探究循环神经网络(RNN)中的梯度计算【原理理解】

引言 在深度学习领域中&#xff0c;我们经常处理的是独立同分布&#xff08;i.i.d&#xff09;的数据&#xff0c;比如图像分类、文本生成等任务&#xff0c;其中每个样本之间相互独立。然而&#xff0c;在现实生活中&#xff0c;许多数据具有时序结构&#xff0c;例如语言模型…

基于EasyX的贪吃蛇小游戏 - C语言

游戏基本功能演示&#xff1a; 1.主菜单界面 2.自定难度界面 在这里可以自行设定游戏的难度&#xff0c;包括蛇的移动速度&#xff0c;初始节数&#xff0c;以及默认模式&#xff0c;参考线&#xff08;网格&#xff09;。这些设定的数据都会在右上角的游戏属性栏中实时显示。…

二叉树的算法题目

二叉树的遍历题目 二叉树遍历一般包含三种分别为&#xff1a;根左右、左根右、左右根&#xff08;又称为前序遍历、中序遍历、后序遍历&#xff09; 方法一&#xff1a;使用递归遍历 方法二&#xff1a;使用迭代使用栈 我们以左根右&#xff08;中序遍历&…

Spring系列-SpringMvc父子容器启动原理解析

1、Spring整合SpringMVC 特性&#xff1a; 说到Spring整合SpringMVC唯一的体现就是父子容器&#xff1a; 通常我们会设置父容器&#xff08;Spring&#xff09;管理Service、Dao层的Bean, 子容器(SpringMVC)管理Controller的Bean .子容器可以访问父容器的Bean, 父容器无法访…

【PCB]射频电路pcb设计

学习改变命运&#xff0c;技能成就未来&#xff01;❤~~ 1射频信号的基础知识及工作原理介绍 射频的基础知识介绍 2射频板PCB的布局要求 3射频板布局要求 4屏蔽帐设计 5射频板的层叠阻抗设计 6射频板的PCB布线原则 7射频板的PCB布线要求 8射频板的设计实战

王道408数据结构CH1_绪论

概述 1.数据结构 1.1 数据结构三要素 逻辑结构 存储结构 顺序存储、链式存储、索引存储、散列存储 数据的运算

做自媒体素材哪里找?做自媒体必备的几个高质量素材网站分享

在自媒体的世界里&#xff0c;内容是王道。无论是视频还是文章&#xff0c;优秀的自媒体作品都需要有力的内容和高质量的素材作支撑。今天&#xff0c;我为大家整理了一些优质的素材网站&#xff0c;帮助每一位自媒体创作者&#xff0c;无论新手还是老手&#xff0c;都能找到适…

鸿蒙状态管理-@Builder自定义构建函数

Builder 将重复使用的UI元素抽象成一个方法 在build方法里调用 使其成为 自定义构建函数 Entry Component struct BuilderCase {build() {Column(){Row(){Text("西游记").fontSize(20)}.justifyContent(FlexAlign.Center).backgroundColor("#f3f4f5").hei…

Etcd Raft架构设计和源码剖析2:数据流

Etcd Raft架构设计和源码剖析2&#xff1a;数据流 | Go语言充电站 前言 之前看到一幅描述etcd raft的流程图&#xff0c;感觉非常直观&#xff0c;但和自己看源码的又有些不同&#xff0c;所以自己模仿着画了一下&#xff0c;再介绍一下。 下图从左到右依次分为4个部分&…

如何检查网站文件是否有病毒

本周有一个客户&#xff0c;购买Hostease的主机&#xff0c; 客户购买的是Linux虚拟主机&#xff0c;带cPanel面板的。询问我们的在线客服&#xff0c;他想检查下他的网站程序是否有病毒文件。Hostease虚拟主机附带病毒扫描软件功能&#xff0c;可以协助检查网站程序是否有病毒…

HTML静态网页成品作业(HTML+CSS)—— 节日端午节介绍网页(5个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有5个页面。 二、作品演示 三、代…

算法训练营第四十六天 | 卡码网52 携带研究材料、LeetCode 518 零钱兑换II、LeetCode 377 组合总和IV

写在前面 这次算法训练营题目&#xff0c;其实完全是按照代码随想录一路跟着来的&#xff0c;上面也有更好的、讲得更清楚的题解&#xff0c;有需要的小伙伴可以去那里看。 我这里是之前已经大体刷过一遍&#xff0c;为了应对有可能会考到的面试题&#xff0c;现在在跟着一个专…

MySQL—多表查询—外连接

一、引言 学到内连接&#xff0c;它是查询的数据两张表交集的部分。而接下来看看外连接。 外连接查询语法&#xff1a;&#xff08;分为两种&#xff09; 1、左外连接 语法结构&#xff1a; 表1 LEFT [OUTER] JOIN 表2 ON 条件 ...; ( ... left out join on ...) 注意&#x…

kafka-消费者服务搭建配置简单消费(SpringBoot整合Kafka)

文章目录 1、使用efak 创建 主题 my_topic1 并建立6个分区并给每个分区建立3个副本2、创建生产者发送消息3、application.yml配置4、创建消费者监听器5、创建SpringBoot启动类6、屏蔽 kafka debug 日志 logback.xml7、引入spring-kafka依赖 1、使用efak 创建 主题 my_topic1 并…