第一步、抖音小程序发起支付
前端提交订单数据到后端接口,然后使用 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));
- }