php对接携程验票核销

首先吐槽一下,携程的对接太麻烦了,能不对接就不对接

所有接口都需要对接才能上线,相对抖音美团的麻烦的不是一丁半点,估计这是第一次对接也是最后一次对接

php 复制代码
<?php

namespace app\api\controller;

use addons\epay\library\Service;
use app\admin\model\Chanpin;
use app\admin\model\Citydai;
use app\admin\model\Indeximage;
use app\admin\model\mp\Goods;
use app\admin\model\mp\Goodsitem;
use app\admin\model\mptwo\Xcorder;
use app\admin\model\order\OrderZong;
use app\admin\model\Trace;
use app\common\controller\Api;
use app\common\model\Area;
use app\common\model\User as UserModel;
use fast\Random;
use think\Config;
use think\Db;
use think\Exception;
use think\Request;

/**
 * 三方接口
 */
class Queuexc extends Api
{
    protected $noNeedLogin = '*';
    protected $noNeedRight = '*';

    private $ACCOUNT_ID = "9436***9b9345";

    protected $AES_KEY = "2966***0ce0f";
    protected $AES_IV = "70cd11a***281d11";
    protected $AES_VECTOR = "";
    protected $SIGN_KEY = "283fbbd87***5d47714c33b4bc";

    //回调
    public function notifyx(Request $request)
    {
        $datetime = date('Y-m-d H:i:s');
        $filename = 'log/' . date('Ymd') . '.txt';
        @file_put_contents($filename, $datetime . 'Start' . PHP_EOL, FILE_APPEND);

        $postStr = file_get_contents('php://input');
        @file_put_contents($filename, $datetime . '-接收数据:' . $postStr . PHP_EOL, FILE_APPEND);
//
//        $paytype = $request->param('paytype');
        $params = $request->param();
        @file_put_contents($filename, $datetime . '-接收数据params:' . json_encode($params, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);
        $pushData = json_decode($postStr, true);
        $header = $pushData['header'];
        $encryptBody = $pushData['body'];
        @file_put_contents($filename, $datetime . '-接收数据$header:' . json_encode($header, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);
        @file_put_contents($filename, $datetime . '-接收数据$encryptBody:' . json_encode($encryptBody, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);

        if ($header['serviceName'] == 'CreatePreOrder') {
            //预下单创建
//    $this->CreatePreOrder($pushData);
            $a = $this->decrypt($encryptBody, $this->AES_KEY, $this->AES_IV);
            //转成数组
            $bodyArr = json_decode($a, true);
            //先看之前有没有存进去
            $order_info = Xcorder::where([
                'otaOrderId' => $bodyArr['otaOrderId']
            ])->find();
            if ($order_info) {
                @file_put_contents($filename, $datetime . '-接收数据$bodyArr:' . json_encode($bodyArr, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);
                $res = [
                    'header' => [
                        'resultCode' => '0000',
                        'resultMessage' => '预下单创建成功(之前有)',
                    ],
                    'body' => [
                        'otaOrderId' => $order_info['otaOrderId'],
                        'supplierOrderId' => $order_info['supplierOrderId'],
                        'items' => [
                            [
                                'PLU' => $order_info['PLU'],
                                'inventorys' => [
                                    'useDate' => date('Y-m-d'),
                                    'quantity' => $order_info['quantity']
                                ]
                            ]
                        ]
                    ]
                ];
                //1、body转json字符串
                $bodyJson = json_encode($res['body'], JSON_UNESCAPED_UNICODE);
                //2、AES加密
                $encryptBody = $this->encrypt($bodyJson, $this->AES_KEY, $this->AES_IV);
//        {"requestTime":"2026-08-08 10:07:21","accountId":"9436dc17899b9345","sign":"da921cc33e0930f7b8045803c89f962b","serviceName":"CreatePreOrder","version":"1.0"}
                //3、头部参数
                $serviceName = $header['serviceName'];
                $requestTime = $header['requestTime'];
                $version = $header['version'];

                //4、签名字符串拼接规则:accountId+serviceName+requestTime+加密后的body+version+signKey
                $signSource = $this->ACCOUNT_ID . $serviceName . $requestTime . $encryptBody . $version . $this->SIGN_KEY;
                $sign = strtolower(md5($signSource));

                //5、最终推送完整报文
                $pushDatares = [
                    "header" => [
                        'resultCode' => '0000',
                        'resultMessage' => '预下单创建成功(之前有)',
                    ],
                    "body" => $encryptBody
                ];

//        echo json_encode($pushData);
                $res = json_encode($pushDatares, JSON_UNESCAPED_UNICODE);
                @file_put_contents($filename, $datetime . '-$res:-------------------------------------------------------------' . PHP_EOL, FILE_APPEND);
                @file_put_contents($filename, $datetime . '-接收数据$res:' . json_encode($res, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);
                return $res;
            } else {
                //存入携程订单表
                $xcorder = [
                    'otaOrderId' => $bodyArr['otaOrderId'],
                    'useStartDate' => $bodyArr['items'][0]['useStartDate'],
                    'sequenceId' => $bodyArr['sequenceId'],
                    'useEndDate' => $bodyArr['items'][0]['useEndDate'],
                    'price' => $bodyArr['items'][0]['price'],
                    'priceCurrency' => $bodyArr['items'][0]['priceCurrency'],
                    'salePrice' => $bodyArr['items'][0]['salePrice'],
                    'salePriceCurrency' => $bodyArr['items'][0]['salePriceCurrency'],
                    'supplierOrderId' => 'xc' . time() . rand(100000, 999999),
                    'PLU' => $bodyArr['items'][0]['PLU'],
                    'quantity' => $bodyArr['items'][0]['quantity'],
                    'useDate' => date('Y-m-d'),
                    'createtime' => time(),
                    'status' => 11,
                ];
                $xcorderres = Xcorder::create($xcorder);
                @file_put_contents($filename, $datetime . '-接收数据$bodyArr:' . json_encode($bodyArr, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);
                $res = [
                    'header' => [
                        'resultCode' => '0000',
                        'resultMessage' => '预下单创建成功',
                    ],
                    'body' => [
                        'otaOrderId' => $xcorder['otaOrderId'],
                        'supplierOrderId' => $xcorder['supplierOrderId'],
                        'items' => [
                            [
                                'PLU' => $xcorder['PLU'],
                                'inventorys' => [
                                    'useDate' => date('Y-m-d'),
                                    'quantity' => $xcorder['quantity']
                                ]
                            ]
                        ]
                    ]
                ];
                //1、body转json字符串
                $bodyJson = json_encode($res['body'], JSON_UNESCAPED_UNICODE);
                //2、AES加密
                $encryptBody = $this->encrypt($bodyJson, $this->AES_KEY, $this->AES_IV);
//        {"requestTime":"2026-08-08 10:07:21","accountId":"9436dc17899b9345","sign":"da921cc33e0930f7b8045803c89f962b","serviceName":"CreatePreOrder","version":"1.0"}
                //3、头部参数
                $serviceName = $header['serviceName'];
                $requestTime = $header['requestTime'];
                $version = $header['version'];

                //4、签名字符串拼接规则:accountId+serviceName+requestTime+加密后的body+version+signKey
                $signSource = $this->ACCOUNT_ID . $serviceName . $requestTime . $encryptBody . $version . $this->SIGN_KEY;
                $sign = strtolower(md5($signSource));

                //5、最终推送完整报文
                $pushDatares = [
                    "header" => [
                        'resultCode' => '0000',
                        'resultMessage' => '预下单创建成功',
                    ],
                    "body" => $encryptBody
                ];

//        echo json_encode($pushData);
                $res = json_encode($pushDatares, JSON_UNESCAPED_UNICODE);
                @file_put_contents($filename, $datetime . '-$res:-------------------------------------------------------------' . PHP_EOL, FILE_APPEND);
                @file_put_contents($filename, $datetime . '-接收数据$res:' . json_encode($res, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);
                return $res;
            }

        } elseif ($header['serviceName'] == 'PayPreOrder') {
            //预下单支付
            $a = $this->decrypt($encryptBody, $this->AES_KEY, $this->AES_IV);
            //转成数组
            $bodyArr = json_decode($a, true);
//        dump($bodyArr);exit;
            @file_put_contents($filename, $datetime . '-接收数据$bodyArr:' . json_encode($bodyArr, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);
            $otaOrderId = $bodyArr['otaOrderId'];
            $supplierOrderId = $bodyArr['supplierOrderId'];
            $itemId = $bodyArr['items'][0]['itemId'];
            $order_info = Xcorder::where([
                'supplierOrderId' => $supplierOrderId,
                'status' => 11
            ])->find();
            if ($order_info) {
                //让订单变为已支付
                $order_info->status = 2;
                $order_info->itemId = $bodyArr['items'][0]['itemId'];
                $order_info->save();
                $res = [
                    'header' => [
                        'resultCode' => '0000',
                        'resultMessage' => '预下单支付成功',
                    ],
                    'body' => [
                        'otaOrderId' => $bodyArr['otaOrderId'],
                        'supplierOrderId' => $bodyArr['supplierOrderId'],
                        'supplierConfirmType' => 1,
                        'voucherSender' => 1,
                        'items' => [
                            [
                                'itemId' => $bodyArr['items'][0]['itemId'],
                                'isCredentialVouchers' => 0
                            ]
                        ]
                    ]
                ];
                //1、body转json字符串
                $bodyJson = json_encode($res['body'], JSON_UNESCAPED_UNICODE);
                //2、AES加密
                $encryptBody = $this->encrypt($bodyJson, $this->AES_KEY, $this->AES_IV);
//        {"requestTime":"2026-08-08 10:07:21","accountId":"9436dc179b9345","sign":"da921cc33e045803c89f962b","serviceName":"CreatePreOrder","version":"1.0"}
                //3、头部参数
                $serviceName = $header['serviceName'];
                $requestTime = $header['requestTime'];
                $version = $header['version'];

                //4、签名字符串拼接规则:accountId+serviceName+requestTime+加密后的body+version+signKey
                $signSource = $this->ACCOUNT_ID . $serviceName . $requestTime . $encryptBody . $version . $this->SIGN_KEY;
                $sign = strtolower(md5($signSource));

                //5、最终推送完整报文
                $pushDatares = [
                    "header" => [
                        'resultCode' => '0000',
                        'resultMessage' => '预下单支付成功',
                    ],
                    "body" => $encryptBody
                ];

//        echo json_encode($pushData);
                $res = json_encode($pushDatares, JSON_UNESCAPED_UNICODE);
                return $res;
            } else {
                $res = [
                    'header' => [
                        'resultCode' => '000',
                        'resultMessage' => '预下单支付成功',
                    ],
                    'body' => [
                        'otaOrderId' => $bodyArr['otaOrderId'],
                        'supplierOrderId' => $bodyArr['supplierOrderId'],
                        'supplierConfirmType' => 1,
                        'voucherSender' => 1,
                        'items' => [
                            [
                                'itemId' => $bodyArr['items'][0]['itemId'],
                                'isCredentialVouchers' => 0
                            ]
                        ]
                    ]
                ];
                //1、body转json字符串
                $bodyJson = json_encode($res['body'], JSON_UNESCAPED_UNICODE);
                //2、AES加密
                $encryptBody = $this->encrypt($bodyJson, $this->AES_KEY, $this->AES_IV);
//        {"requestTime":"2026-08-08 10:07:21","accountId":"9436dc17899b9345","sign":"da921cc33e0930f7b8045803c89f962b","serviceName":"CreatePreOrder","version":"1.0"}
                //3、头部参数
                $serviceName = $header['serviceName'];
                $requestTime = $header['requestTime'];
                $version = $header['version'];

                //4、签名字符串拼接规则:accountId+serviceName+requestTime+加密后的body+version+signKey
                $signSource = $this->ACCOUNT_ID . $serviceName . $requestTime . $encryptBody . $version . $this->SIGN_KEY;
                $sign = strtolower(md5($signSource));

                //5、最终推送完整报文
                $pushDatares = [
                    "header" => [
                        'resultCode' => '0000',
                        'resultMessage' => '预下单支付成功',
                    ],
                    "body" => $encryptBody
                ];

//        echo json_encode($pushData);
                $res = json_encode($pushDatares, JSON_UNESCAPED_UNICODE);
                return $res;
            }
        } elseif ($header['serviceName'] == 'CancelOrder') {

            //header的数据
            if ($header['accountId'] != $this->ACCOUNT_ID) {
                return json_encode([
                    'header' => [
                        'resultCode' => '0003',
                        'resultMessage' => '账号异常',
                    ]
                ], JSON_UNESCAPED_UNICODE);
            }
            //验证签名是否一样
            $signSource = $this->ACCOUNT_ID . $header['serviceName'] . $header['requestTime'] . $encryptBody . $header['version'] . $this->SIGN_KEY;
            $sign = strtolower(md5($signSource));
//        @file_put_contents($filename, $datetime . '-接收数据$sign:' . $sign . PHP_EOL, FILE_APPEND);
            if ($sign != $header['sign']) {
//            @file_put_contents($filename, $datetime . '-接收数据签名验证失败' . PHP_EOL, FILE_APPEND);
                return json_encode([
                    'header' => [
                        'resultCode' => '0002',
                        'resultMessage' => '签名验证失败',
                    ]
                ], JSON_UNESCAPED_UNICODE);
            }
            $a = $this->decrypt($encryptBody, $this->AES_KEY, $this->AES_IV);
            //转成数组
            $bodyArr = json_decode($a, true);


            $itemId = $bodyArr['items'][0]['itemId'];
            $order_info = Xcorder::where([
                'itemId' => $itemId
            ])->find();
            if ($order_info) {
                if ($order_info['otaOrderId'] != $bodyArr['otaOrderId']) {
                    return json_encode([
                        'header' => [
                            'resultCode' => '2001',
                            'resultMessage' => '订单号异常',
                        ]
                    ], JSON_UNESCAPED_UNICODE);
                }
                if ($order_info['quantity'] != $bodyArr['items'][0]['quantity']) {
                    return json_encode([
                        'header' => [
                            'resultCode' => '2004',
                            'resultMessage' => '取消数量异常',
                        ]
                    ], JSON_UNESCAPED_UNICODE);
                }
                if($order_info['status'] == 8){
                    return json_encode([
                        'header' => [
                            'resultCode' => '2002',
                            'resultMessage' => '该订单已经使用',
                        ]
                    ], JSON_UNESCAPED_UNICODE);
                }
                @file_put_contents($filename, $datetime . '-接收数据[订单取消]$bodyArr:' . json_encode($bodyArr, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);
                $res = [
                    'header' => [
                        'resultCode' => '0000',
                        'resultMessage' => '订单取消',
                    ],
                    'body' => [
                        'supplierConfirmType' => 1,
                        'items' => [[
                            'itemId' => $bodyArr['items'][0]['itemId'],
                            'vouchers' => [
                                'voucherId' => $bodyArr['items'][0]['itemId']
                            ]
                        ]]
                    ]
                ];
                //1、body转json字符串
                $bodyJson = json_encode($res['body'], JSON_UNESCAPED_UNICODE);
                //2、AES加密
                $encryptBody = $this->encrypt($bodyJson, $this->AES_KEY, $this->AES_IV);
//        {"requestTime":"2026-08-08 10:07:21","accountId":"9436dc17899b9345","sign":"da921cc33e0930f7b8045803c89f962b","serviceName":"CreatePreOrder","version":"1.0"}
                //3、头部参数
                $serviceName = $header['serviceName'];
                $requestTime = $header['requestTime'];
                $version = $header['version'];

                //4、签名字符串拼接规则:accountId+serviceName+requestTime+加密后的body+version+signKey
                $signSource = $this->ACCOUNT_ID . $serviceName . $requestTime . $encryptBody . $version . $this->SIGN_KEY;
                $sign = strtolower(md5($signSource));
// $encryptBody = 1;
                //5、最终推送完整报文
                $pushDatares = [
                    "header" => [
                        'resultCode' => '0000',
                        'resultMessage' => '订单取消',
                    ],
                    "body" => $encryptBody
                ];
                //订单改变状态
                $order_info->status = 5;
                $order_info->voucherId = $bodyArr['items'][0]['itemId'];
                $order_info->save();

//        echo json_encode($pushData);
                $res = json_encode($pushDatares, JSON_UNESCAPED_UNICODE);
                return $res;
            } else {
                $res = [
                    'header' => [
                        'resultCode' => '0000',
                        'resultMessage' => '订单已取消',
                    ],
                    'body' => [
                        'supplierConfirmType' => 1,
                        'items' => [[
                            'itemId' => $bodyArr['items'][0]['itemId'],
                            'vouchers' => [
                                'voucherId' => $bodyArr['items'][0]['itemId']
                            ]
                        ]]
                    ]
                ];
                //1、body转json字符串
                $bodyJson = json_encode($res['body'], JSON_UNESCAPED_UNICODE);
                //2、AES加密
                $encryptBody = $this->encrypt($bodyJson, $this->AES_KEY, $this->AES_IV);
//        {"requestTime":"2026-08-08 10:07:21","accountId":"9436dc17899b9345","sign":"da921cc33e0930f7b8045803c89f962b","serviceName":"CreatePreOrder","version":"1.0"}
                //3、头部参数
                $serviceName = $header['serviceName'];
                $requestTime = $header['requestTime'];
                $version = $header['version'];

                //4、签名字符串拼接规则:accountId+serviceName+requestTime+加密后的body+version+signKey
                $signSource = $this->ACCOUNT_ID . $serviceName . $requestTime . $encryptBody . $version . $this->SIGN_KEY;
                $sign = strtolower(md5($signSource));
// $encryptBody = 1;
                //5、最终推送完整报文
                $pushDatares = [
                    "header" => [
                        'resultCode' => '0000',
                        'resultMessage' => '订单已取消',
                    ],
                    "body" => $encryptBody
                ];
                $res = json_encode($pushDatares, JSON_UNESCAPED_UNICODE);
                return $res;
            }

        } elseif ($header['serviceName'] == 'QueryOrder') {
            //header的数据
            if ($header['accountId'] != $this->ACCOUNT_ID) {
                return json_encode([
                    'header' => [
                        'resultCode' => '0003',
                        'resultMessage' => '账号异常',
                    ]
                ], JSON_UNESCAPED_UNICODE);
            }
            //验证签名是否一样
            $signSource = $this->ACCOUNT_ID . $header['serviceName'] . $header['requestTime'] . $encryptBody . $header['version'] . $this->SIGN_KEY;
            $sign = strtolower(md5($signSource));
//        @file_put_contents($filename, $datetime . '-接收数据$sign:' . $sign . PHP_EOL, FILE_APPEND);
            if ($sign != $header['sign']) {
//            @file_put_contents($filename, $datetime . '-接收数据签名验证失败' . PHP_EOL, FILE_APPEND);
                return json_encode([
                    'header' => [
                        'resultCode' => '0002',
                        'resultMessage' => '签名验证失败',
                    ]
                ], JSON_UNESCAPED_UNICODE);
            }
            //查询订单
            $a = $this->decrypt($encryptBody, $this->AES_KEY, $this->AES_IV);
            //转成数组
            $bodyArr = json_decode($a, true);

            $otaOrderId = $bodyArr['otaOrderId'];
            $order_info = Xcorder::where([
                'supplierOrderId' => $bodyArr['supplierOrderId'],
                'otaOrderId' => $otaOrderId,
            ])->find();
            if ($order_info) {
                $useQuantity = $order_info['useQuantity'];
                $cancelQuantity = 0;

                if ($order_info['status'] == 5) {
                    $cancelQuantity = 1;
                }
                @file_put_contents($filename, $datetime . '-接收数据$bodyArr:' . json_encode($bodyArr, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);
                $res = [
                    'header' => [
                        'resultCode' => '0000',
                        'resultMessage' => '订单查询',
                    ],
                    'body' => [
                        'otaOrderId' => $bodyArr['otaOrderId'],
                        'supplierOrderId' => $bodyArr['supplierOrderId'],
                        'items' => [[
                            'itemId' => $order_info['itemId'],
                            'orderStatus' => $order_info['status'],
                            'quantity' => $order_info['quantity'],
                            'useQuantity' => $useQuantity,
                            'cancelQuantity' => $cancelQuantity
                        ]]
                    ]
                ];
                //1、body转json字符串
                $bodyJson = json_encode($res['body'], JSON_UNESCAPED_UNICODE);
                //2、AES加密
                $encryptBody = $this->encrypt($bodyJson, $this->AES_KEY, $this->AES_IV);
//        {"requestTime":"2026-08-08 10:07:21","accountId":"9436dc17899b9345","sign":"da921cc33e0930f7b8045803c89f962b","serviceName":"CreatePreOrder","version":"1.0"}
                //3、头部参数
                $serviceName = $header['serviceName'];
                $requestTime = $header['requestTime'];
                $version = $header['version'];

                //4、签名字符串拼接规则:accountId+serviceName+requestTime+加密后的body+version+signKey
                $signSource = $this->ACCOUNT_ID . $serviceName . $requestTime . $encryptBody . $version . $this->SIGN_KEY;
                $sign = strtolower(md5($signSource));

                //5、最终推送完整报文
                $pushDatares = [
                    "header" => [
                        'resultCode' => '0000',
                        'resultMessage' => '订单查询',
                    ],
                    "body" => $encryptBody
                ];

                // echo json_encode($pushData);
                $res = json_encode($pushDatares, JSON_UNESCAPED_UNICODE);
                return $res;
            } else {
                $useQuantity = $cancelQuantity = 0;
                $res = [
                    'header' => [
                        'resultCode' => '4001',
                        'resultMessage' => '订单号异常',
                    ],
                    'body' => [
                        'otaOrderId' => $bodyArr['otaOrderId'],
                        'supplierOrderId' => $bodyArr['supplierOrderId']
                    ]
                ];
                //1、body转json字符串
                $bodyJson = json_encode($res['body'], JSON_UNESCAPED_UNICODE);
                //2、AES加密
                $encryptBody = $this->encrypt($bodyJson, $this->AES_KEY, $this->AES_IV);
//        {"requestTime":"2026-08-08 10:07:21","accountId":"9436dc17899b9345","sign":"da921cc33e0930f7b8045803c89f962b","serviceName":"CreatePreOrder","version":"1.0"}
                //3、头部参数
                $serviceName = $header['serviceName'];
                $requestTime = $header['requestTime'];
                $version = $header['version'];

                //4、签名字符串拼接规则:accountId+serviceName+requestTime+加密后的body+version+signKey
                $signSource = $this->ACCOUNT_ID . $serviceName . $requestTime . $encryptBody . $version . $this->SIGN_KEY;
                $sign = strtolower(md5($signSource));

                //5、最终推送完整报文
                $pushDatares = [
                    "header" => [
                        'resultCode' => '4001',
                        'resultMessage' => '订单号异常',
                    ],
                    "body" => $encryptBody
                ];

                // echo json_encode($pushData);
                $res = json_encode($pushDatares, JSON_UNESCAPED_UNICODE);
                return $res;
            }
        } elseif ($header['serviceName'] == 'CancelPreOrder') {
            //预下单取消
            $a = $this->decrypt($encryptBody, $this->AES_KEY, $this->AES_IV);
            //转成数组
            $bodyArr = json_decode($a, true);

            $order_info = Xcorder::where([
                'otaOrderId' => $bodyArr['otaOrderId'],
                'status' => 11
            ])->find();
            if ($order_info) {

                //5、最终推送完整报文
                $pushDatares = [
                    "header" => [
                        'resultCode' => '0000',
                        'resultMessage' => '预下单取消成功',
                    ]
                ];
                //订单改变状态
                $order_info->status = 14;
                $order_info->save();

//        echo json_encode($pushData);
                $res = json_encode($pushDatares, JSON_UNESCAPED_UNICODE);
                return $res;
            } else {
                $res = [
                    'header' => [
                        'resultCode' => '0000',
                        'resultMessage' => '预下单已取消成功',
                    ]
                ];
                //5、最终推送完整报文
                $pushDatares = [
                    'header' => [
                        'resultCode' => '0000',
                        'resultMessage' => '预下单已取消成功',
                    ]
                ];
                $res = json_encode($pushDatares, JSON_UNESCAPED_UNICODE);
                return $res;
            }

        }
    }

    public function CreatePreOrder_one()
    {
        // 沙箱密钥配置
        $config = [
            'accountId' => '9436d899b9345',
            'signKey' => '283fbbd87dd29d915d47714c33b4bc',
            'aesKey' => '2966eb3270ce0f',
            'aesIv' => '70cdaa0281d11',
        ];

// 获取携程POST推送的全部json参数
        $pushData = $this->request->post();
        // dump($postJson);exit;
        // $pushData = json_decode($postJson,true);

        $header = $pushData['header'];
        $encryptBody = $pushData['body'];

//1、组装签名字符串验签
        $signRaw = $header['accountId'] . $header['serviceName'] . $header['requestTime'] . $encryptBody . $header['version'] . $config['signKey'];
        $localSign = strtolower(md5($signRaw));

        if ($localSign !== $header['sign']) {
            exit(json_encode(["code" => -1, "msg" => "签名校验失败"]));
        }

// //2、AES‑128‑CBC解密body密文
//         function aesDecrypt($cipherText,$key,$iv){
//             return openssl_decrypt($cipherText, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
//         }
//         $originJson = aesDecrypt($encryptBody,$config['aesKey'],$config['aesIv']);
//         $orderInfo = json_decode($originJson,true);

// //打印解密之后的预订单详情,里面包含 otaOrderId、voucherId核销券码
//         echo "<pre>";
//         print_r($orderInfo);

// //3、返回携程成功回执
//         echo json_encode([
//             "code" => 0,
//             "msg"  => "success"
//         ]);
        $a = $this->decrypt($encryptBody, $this->AES_KEY, $this->AES_IV);
        //转成数组
        $bodyArr = json_decode($a, true);
        $this->CreatePreOrder_two($bodyArr);
//        dump($a);exit;
//        $result = json_decode(\fast\Http::post('https://ttdopen.ctrip.com/api/order/notice.do', $params), true);
//        halt($result);
//        // if($result['status'] != 200){
//        //     throw new \Exception($result['message']);
//        // }
//        // return $result['data'];
//        return $result;
    }

    public function CreatePreOrder_two($bodyArr)
    {
        //1、body转json字符串
        $bodyJson = json_encode($bodyArr, JSON_UNESCAPED_UNICODE);
        //2、AES加密
        $encryptBody = $this->encrypt($bodyJson);

        //3、头部参数
        $serviceName = "CreatePreOrder";
        $requestTime = "2026-08-06 16:52:40";
        $version = "1.0";

        //4、签名字符串拼接规则:accountId+serviceName+requestTime+加密后的body+version+signKey
        $signSource = $this->ACCOUNT_ID . $serviceName . $requestTime . $encryptBody . $version . $this->SIGN_KEY;
        $sign = strtolower(md5($signSource));

        //5、最终推送完整报文
        $pushData = [
            "header" => [
                "requestTime" => $requestTime,
                "accountId" => $this->ACCOUNT_ID,
                "sign" => $sign,
                "serviceName" => $serviceName,
                "version" => $version
            ],
            "body" => $encryptBody
        ];

        echo json_encode($pushData);
        $result = json_decode(\fast\Http::post('https://ttdopen.ctrip.com/api/order/notice.do', json_encode($pushData)), true);
        halt($result);
    }

    /***
     *
     */

    /**
     * 添加PKCS5填充
     * @param string $string
     * @param int $blocksize
     * @return string
     */
    private function addPkcs5Padding($string, $blocksize = 16)
    {
        $pad = $blocksize - (strlen($string) % $blocksize);
        $string .= str_repeat(chr($pad), $pad);
        return $string;
    }

    /**
     * 去除PKCS5填充
     * @param string $string
     * @return string|bool
     */
    private function stripPkcs5Padding($string, $blocksize = 16)
    {
        $pad = ord(substr($string, -1));
        if ($pad < 1 || $pad > $blocksize) {
            return false;
        }
        return substr($string, 0, strlen($string) - $pad);
    }

    /**
     * 解码字节
     * @param string $hex
     * @return string
     */
//    private function decodeBytes($hex)
//    {
//        $str = '';
//        for ($i = 0; $i < strlen($hex); $i += 2) {
//            $tmpValue = (((ord($hex[$i]) - ord('a')) & 0xf) << 4) + ((ord($hex[$i + 1]) - ord('a')) & 0xf);
//            $str .= chr($tmpValue);
//        }
//        return $str;
//    }

    /**
     * 编码字节
     * @param string $string
     * @return string
     */
    private function encodeBytes($string)
    {
        $str = '';
        for ($i = 0; $i < strlen($string); $i++) {
            $tmpValue = ord($string[$i]);
            $ch = ($tmpValue >> 4 & 0xf) + ord('a');
            $str .= chr($ch);
            $ch = ($tmpValue & 0xf) + ord('a');
            $str .= chr($ch);
        }
        return $str;
    }

    /**
     * 解密
     * @param string $encryptedText
     * @param string $secretKey
     * @param string $vector
     * @return string|bool
     */
//    public function decrypt($encryptedText, $secretKey, $vector)
//    {
//        $decrypted = openssl_decrypt($this->decodeBytes($encryptedText),
//            'AES-128-CBC', $secretKey, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $vector);
//        if ($decrypted === false) {
//            return false;
//        }
//        return $this->stripPkcs5Padding($decrypted);
//    }

    /**
     * 加密
     * @param string $decData
     * @param string $secretKey
     * @param string $vector
     * @return string
     */
    public function encrypt(string $decData, string $secretKey, string $vector): string
    {
        $base = openssl_encrypt($this->addPkcs5Padding($decData, 16),
            'AES-128-CBC', $secretKey, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $vector);
        return $this->encodeBytes($base);
    }

    /**
     * Encrypt plain text into cipher text
     * @param string $plainText
     * @return string
     */
//    public function encrypt(string $plainText): string
//    {
//        $encrypted = openssl_encrypt(
//            $plainText,
//            'AES-128-CBC',
//            $this->AES_KEY,
//            OPENSSL_RAW_DATA,
//            $this->AES_IV
//        );
//        // java是base64,不要手写十六进制
//        return base64_encode($encrypted);
//    }
//
//    /**
//     * Convert cipher back to plain text
//     * @param string $cipherText
//     * @return string
//     */
//    public function decrypt(string $cipherText): string {
//        try {
//            $bytes = '';
//            for ($i = 0; $i < strlen($cipherText); $i += 2) {
//                $c = $cipherText[$i];
//                $byte = (ord($c) - ord('a')) << 4;
//
//                $c = $cipherText[$i + 1];
//                $byte += (ord($c) - ord('a'));
//
//                $bytes .= chr($byte);
//            }
//
//            return openssl_decrypt(
//                $bytes,
//                'AES-128-CBC',
//                $this->AES_KEY,
//                OPENSSL_RAW_DATA,
//                $this->AES_IV
//            );
//        } catch (\Exception $e) {
//            throw new \RuntimeException(
//                sprintf('AES decryption failure, cipherText=%s. errorMessage=%s',
//                    $cipherText, $e->getMessage()),
//                0,
//                $e
//            );
//        }
//    }


    /***
     *
     */
    public function aa()
    {
        $a = $this->decrypt('<KEY>', $this->AES_KEY, $this->AES_IV);
    }

    public function CreatePreOrder1()
    {
        // 沙箱密钥配置
        $config = [
            'accountId' => '9436dc899b9345',
            'signKey' => 'bfab73a4a27421cb13385ac1c74278',
            'aesKey' => '296bbe3270ce0f',
            'aesIv' => '70cd11aa0281d11',
        ];

        // 获取携程POST推送的全部json参数
        $pushData = $this->request->post();
        $header = $pushData['header'];
        $encryptBody = $pushData['body'];

        // iv 使用携程给你的,不要写成16个0!
        $plainBody = self::decrypt($encryptBody, $config['aesKey'], $config['aesIv']);

        // 验签拼接顺序严格不能改动
        $signRaw = $header['accountId']
            . $header['serviceName']
            . $header['requestTime']
            . $plainBody
            . $header['version']
            . $config['signKey'];

        $localSign = strtolower(md5($signRaw));

        dump('本地签名:' . $localSign);
        dump('携程推送签名:' . $header['sign']);

        if ($localSign !== $header['sign']) {
            exit("验签失败");
        }

        // 验签成功之后再解析json
        $orderInfo = json_decode($plainBody, true);
        dump($orderInfo);
    }


    /**
     * 和Java源码完全一致 解密
     */
    public static function decrypt(string $cipherText, string $secretKey, string $iv): ?string
    {
        $rawBytes = self::decodeBytes($cipherText);
        $res = openssl_decrypt(
            $rawBytes,
            'AES-128-CBC',
            $secretKey,
            OPENSSL_RAW_DATA,
            $iv
        );
        return $res === false ? null : $res;
    }

    protected static function decodeBytes(string $str): string
    {
        $bytes = '';
        $len = strlen($str);
        for ($i = 0; $i < $len; $i += 2) {
            $c1 = ord($str[$i]) - ord('a');
            $c2 = ord($str[$i + 1]) - ord('a');
            $bytes .= chr(($c1 << 4) | $c2);
        }
        return $bytes;
    }

    public function CreatePreOrder()
    {
        $datetime = date('Y-m-d H:i:s');
        $filename = 'log/' . date('Ymd') . '.txt';
        $pushData = $this->request->post();
        $header = $pushData['header'];
        $encryptBody = $pushData['body'];
        $a = $this->decrypt($encryptBody, $this->AES_KEY, $this->AES_IV);
        //转成数组
        $bodyArr = json_decode($a, true);
//        dump($bodyArr);
        //存入携程订单表
        $xcorder = [
            'otaOrderId' => $bodyArr['otaOrderId'],
            'supplierOrderId' => 'xc' . time() . rand(100000, 999999),
            'PLU' => $bodyArr['items'][0]['PLU'],
            'quantity' => $bodyArr['items'][0]['quantity'],
            'useDate' => date('Y-m-d'),
            'createtime' => time(),
            'status' => 1,
        ];
        $xcorderres = Xcorder::create($xcorder);
        @file_put_contents($filename, $datetime . '-接收数据$bodyArr:' . json_encode($bodyArr, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);
        $res = [
            'header' => [
                'resultCode' => '0000',
                'resultMessage' => '预下单创建成功',
            ],
            'body' => [
                'otaOrderId' => $xcorder['otaOrderId'],
                'supplierOrderId' => $xcorder['supplierOrderId'],
                'items' => [
                    [
                        'PLU' => $xcorder['PLU'],
                        'inventorys' => [
                            'useDate' => date('Y-m-d'),
                            'quantity' => $xcorder['quantity']
                        ]
                    ]
                ]
            ]
        ];
        //1、body转json字符串
        $bodyJson = json_encode($res['body'], JSON_UNESCAPED_UNICODE);
        //2、AES加密
        $encryptBody = $this->encrypt($bodyJson, $this->AES_KEY, $this->AES_IV);
//        {"requestTime":"2026-08-08 10:07:21","accountId":"9436dc17899b9345","sign":"da921cc33e0930f7b8045803c89f962b","serviceName":"CreatePreOrder","version":"1.0"}
        //3、头部参数
        $serviceName = $header['serviceName'];
        $requestTime = $header['requestTime'];
        $version = $header['version'];

        //4、签名字符串拼接规则:accountId+serviceName+requestTime+加密后的body+version+signKey
        $signSource = $this->ACCOUNT_ID . $serviceName . $requestTime . $encryptBody . $version . $this->SIGN_KEY;
        $sign = strtolower(md5($signSource));

        //5、最终推送完整报文
        $pushDatares = [
            "header" => [
                'resultCode' => '0000',
                'resultMessage' => '预下单创建成功',
            ],
            "body" => $encryptBody
        ];

//        echo json_encode($pushData);
        $res = json_encode($pushDatares, JSON_UNESCAPED_UNICODE);
        return $res;
    }

    public function PayPreOrder()
    {
        $datetime = date('Y-m-d H:i:s');
        $filename = 'log/' . date('Ymd') . '.txt';
        $pushData = $this->request->post();
        $header = $pushData['header'];
        $encryptBody = $pushData['body'];
        $a = $this->decrypt($encryptBody, $this->AES_KEY, $this->AES_IV);
        //转成数组
        $bodyArr = json_decode($a, true);
//        dump($bodyArr);exit;
        @file_put_contents($filename, $datetime . '-接收数据$bodyArr:' . json_encode($bodyArr, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);
        $res = [
            'header' => [
                'resultCode' => '0000',
                'resultMessage' => '预下单支付成功',
            ],
            'body' => [
                'otaOrderId' => $bodyArr['otaOrderId'],
                'supplierOrderId' => $bodyArr['supplierOrderId'],
                'supplierConfirmType' => 1,
                'voucherSender' => 1,
                'items' => [
                    [
                        'itemId' => $bodyArr['items'][0]['itemId'],
                        'isCredentialVouchers' => 0
                    ]
                ]
            ]
        ];
        //1、body转json字符串
        $bodyJson = json_encode($res['body'], JSON_UNESCAPED_UNICODE);
        //2、AES加密
        $encryptBody = $this->encrypt($bodyJson, $this->AES_KEY, $this->AES_IV);
//        {"requestTime":"2026-08-08 10:07:21","accountId":"9436dc17899b9345","sign":"da921cc33e0930f7b8045803c89f962b","serviceName":"CreatePreOrder","version":"1.0"}
        //3、头部参数
        $serviceName = $header['serviceName'];
        $requestTime = $header['requestTime'];
        $version = $header['version'];

        //4、签名字符串拼接规则:accountId+serviceName+requestTime+加密后的body+version+signKey
        $signSource = $this->ACCOUNT_ID . $serviceName . $requestTime . $encryptBody . $version . $this->SIGN_KEY;
        $sign = strtolower(md5($signSource));

        //5、最终推送完整报文
        $pushDatares = [
            "header" => [
                'resultCode' => '0000',
                'resultMessage' => '预下单支付成功',
            ],
            "body" => $encryptBody
        ];

//        echo json_encode($pushData);
        $res = json_encode($pushDatares, JSON_UNESCAPED_UNICODE);
        return $res;
    }

    public function CancelOrder()
    {
        $datetime = date('Y-m-d H:i:s');
        $filename = 'log/' . date('Ymd') . '.txt';
        $pushData = $this->request->post();
        $header = $pushData['header'];
        $encryptBody = $pushData['body'];
        $a = $this->decrypt($encryptBody, $this->AES_KEY, $this->AES_IV);
        //转成数组
        $bodyArr = json_decode($a, true);
        // dump($bodyArr);exit;
        @file_put_contents($filename, $datetime . '-接收数据$bodyArr:' . json_encode($bodyArr, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);
        $res = [
            'header' => [
                'resultCode' => '0000',
                'resultMessage' => '订单取消',
            ],
            'body' => [
                'supplierConfirmType' => 1,
                'items' => [
                    'itemId' => $bodyArr['items'][0]['itemId'],
                    'vouchers' => [
                        'voucherId' => $bodyArr['items'][0]['itemId']
                    ]
                ]
            ]
        ];
        //1、body转json字符串
        $bodyJson = json_encode($res['body'], JSON_UNESCAPED_UNICODE);
        //2、AES加密
        $encryptBody = $this->encrypt($bodyJson, $this->AES_KEY, $this->AES_IV);
//        {"requestTime":"2026-08-08 10:07:21","accountId":"9436dc17899b9345","sign":"da921cc33e0930f7b8045803c89f962b","serviceName":"CreatePreOrder","version":"1.0"}
        //3、头部参数
        $serviceName = $header['serviceName'];
        $requestTime = $header['requestTime'];
        $version = $header['version'];

        //4、签名字符串拼接规则:accountId+serviceName+requestTime+加密后的body+version+signKey
        $signSource = $this->ACCOUNT_ID . $serviceName . $requestTime . $encryptBody . $version . $this->SIGN_KEY;
        $sign = strtolower(md5($signSource));

        //5、最终推送完整报文
        $pushDatares = [
            "header" => [
                'resultCode' => '0000',
                'resultMessage' => '订单取消',
            ],
            "body" => $encryptBody
        ];

        // echo json_encode($pushData);
        $res = json_encode($pushDatares, JSON_UNESCAPED_UNICODE);
        return $res;
    }

    /***
     * 订单核销
     * @return false|string
     */
    public function OrderConsumedNotice()
    {
//        $datetime = date('Y-m-d H:i:s');
//        $filename = 'log/' . date('Ymd') . '.txt';
//        $pushData = $this->request->post();
//        $header = $pushData['header'];
//        $encryptBody = $pushData['body'];
//        $a = $this->aes128_cbc_decrypt($encryptBody);
//        //转成数组
//        $bodyArr = json_decode($a, true);

//         dump($header);
//         dump($bodyArr);exit;
        $supplierOrderId = $this->request->post('supplierOrderId');
        $order_info = Xcorder::where('supplierOrderId', $supplierOrderId)->find();
        if (!$order_info) {
            return json_encode([
                'header' => [
                    'resultCode' => '0001',
                    'resultMessage' => '订单不存在',
                ]
            ], JSON_UNESCAPED_UNICODE);
        }

        $requestTime = date('Y-m-d H:i:s');
        $res = [
            'header' => [
                'accountId' => $this->ACCOUNT_ID,
                'serviceName' => 'OrderConsumedNotice',
                'requestTime' => $requestTime,
                'version' => '1.0'
            ],
            'body' => [
                'sequenceId' => $order_info['sequenceId'],
                'otaOrderId' => $order_info['otaOrderId'],
                'supplierOrderId' => $order_info['supplierOrderId'],
                'items' => [
                    [
                        'itemId' => $order_info['itemId'],
                        'quantity' => $order_info['quantity'],
                        'useQuantity' => 0
                    ]
                ]
            ]
        ];
//        echo "[明文完整报文] = \n\n" . json_encode($res, JSON_UNESCAPED_UNICODE) . "\n\n\n";
        //1、body转json字符串
        $bodyJson = json_encode($res['body'], JSON_UNESCAPED_UNICODE);
//        echo "[明文body] = \n\n" . $bodyJson . "\n\n\n";
        //2、AES加密
        $encryptBody = $this->aes128_cbc_encrypt($bodyJson);
//        echo "[加密后的body] = \n\n" . $encryptBody . "\n\n\n";
//        {"requestTime":"2026-08-08 10:07:21","accountId":"9436dc17899b9345","sign":"da921cc33e0930f7b8045803c89f962b","serviceName":"CreatePreOrder","version":"1.0"}
        //3、头部参数
        $serviceName = $res['header']['serviceName'];
        $requestTime = $res['header']['requestTime'];
        $version = $res['header']['version'];

        //4、签名字符串拼接规则:accountId+serviceName+requestTime+加密后的body+version+signKey
        $signSource = $this->ACCOUNT_ID . $serviceName . $requestTime . $encryptBody . $version . $this->SIGN_KEY;
//        echo "[signSource] = \n\n" . $signSource . "\n\n\n";
        $sign = strtolower(md5($signSource));
//        echo "[签名sign] = \n\n" . $sign . "\n\n\n";

        //5、最终推送完整报文
        $pushDatares = [
            "header" => [
                'accountId' => $this->ACCOUNT_ID,
                'serviceName' => 'OrderConsumedNotice',
                'requestTime' => $requestTime,
                'version' => '1.0',
                'sign' => $sign
            ],
            "body" => $encryptBody
        ];

//        echo json_encode($pushData);
        $res = json_encode($pushDatares, JSON_UNESCAPED_UNICODE);
//        echo "[密文完整报文] = \n\n" . $res . "\n\n\n";
//        $result = json_decode(\fast\Http::post('https://ttdopen.ctrip.com/api/order/notice.do', $res), true);
        $result = json_decode($this->httpPost('https://ttdopen.ctrip.com/api/order/notice.do', $res), true);
//        dump($result);exit;
        if ($result['header']['resultCode'] == '0000') {
            $order_info->status = 8;
            $order_info->useQuantity = 1;
            $order_info->save();
            $this->success('订单核销成功');
        } else {
            $this->error('订单核销失败');
        }
//        return $result;
    }

    public function httpPost($url, $data, $headers = [])
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        $defaultHeaders = [
            'Content-Type: application/json',
            'Content-Length: ' . strlen($data)
        ];
        $headers = array_merge($defaultHeaders, $headers);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        $response = curl_exec($ch);
        $error = curl_error($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($error) {
            throw new \Exception('CURL错误:' . $error);
        }

        if ($httpCode != 200) {
            throw new \Exception('HTTP错误:' . $httpCode);
        }

        return $response;
    }

    // public function __construct($key, $iv)
    // {
    //     $this->key = '2966ebbe3270ce0f';
    //     $this->iv = '70cd11aaa0281d11';
    // }

    /**
     * AES-128-CBC 加密(兼容 mcrypt 实现)
     * @param string $data 明文
     * @return string 加密后的 a-p 编码字符串
     */
    public function aes128_cbc_encrypt($data)
    {
        $key = '2966ebbe3270ce0f';
        $iv = '70cd11aaa0281d11';

        // 如果密钥长度不是16字节,使用MD5哈希(与 mcrypt 一致)
        if (strlen($key) !== 16) {
            $key = md5($key, true);
        }
        if (strlen($iv) !== 16) {
            $iv = md5($iv, true);
        }

        // PKCS7 填充(与 mcrypt 的 PKCS7 兼容)
        $blockSize = 16;
        $padding = $blockSize - (strlen($data) % $blockSize);
        $data .= str_repeat(chr($padding), $padding);

        // 使用 OpenSSL 加密
        $encrypted = openssl_encrypt(
            $data,
            'AES-128-CBC',
            $key,
            OPENSSL_RAW_DATA | OPENSSL_NO_PADDING,  // 手动处理填充,与 mcrypt 一致
            $iv
        );

        if ($encrypted === false) {
            throw new \Exception('加密失败:' . openssl_error_string());
        }

        // 编码为 a-p 字符串
        return $this->encode_bytes($encrypted);
    }

    /**
     * AES-128-CBC 解密(兼容 mcrypt 实现)
     * @param string $data a-p 编码的密文
     * @return string 解密后的明文
     */
    public function aes128_cbc_decrypt($data)
    {
        $key = '2966ebbe3270ce0f';
        $iv = '70cd11aaa0281d11';

        // 如果密钥长度不是16字节,使用MD5哈希
        if (strlen($key) !== 16) {
            $key = md5($key, true);
        }
        if (strlen($iv) !== 16) {
            $iv = md5($iv, true);
        }

        // 解码 a-p 字符串为二进制
        $encrypted = $this->decode_bytes($data);

        // 使用 OpenSSL 解密
        $decrypted = openssl_decrypt(
            $encrypted,
            'AES-128-CBC',
            $key,
            OPENSSL_RAW_DATA | OPENSSL_NO_PADDING,
            $iv
        );

        if ($decrypted === false) {
            throw new \Exception('解密失败:' . openssl_error_string());
        }

        // 去除 PKCS7 填充
        $padding = ord($decrypted[strlen($decrypted) - 1]);
        if ($padding < 1 || $padding > 16) {
            // 如果填充无效,返回原始数据(兼容旧数据)
            return $decrypted;
        }
        return substr($decrypted, 0, -$padding);
    }

    /**
     * 编码二进制为 a-p 字符串(Java 兼容)
     */
    private function encode_bytes($bytes)
    {
        $result = '';
        $len = strlen($bytes);
        for ($i = 0; $i < $len; $i++) {
            $byte = ord($bytes[$i]);
            $high = ($byte >> 4) & 0xF;
            $low = $byte & 0xF;
            $result .= chr($high + ord('a'));
            $result .= chr($low + ord('a'));
        }
        return $result;
    }

    /**
     * 解码 a-p 字符串为二进制(Java 兼容)
     */
    private function decode_bytes($str)
    {
        $len = strlen($str);
        if ($len % 2 != 0) {
            return false;
        }

        $bytes = '';
        $a = ord('a');
        for ($i = 0; $i < $len; $i += 2) {
            $high = ord($str[$i]) - $a;
            $low = ord($str[$i + 1]) - $a;
            if ($high < 0 || $high > 15 || $low < 0 || $low > 15) {
                return false;
            }
            $bytes .= chr(($high << 4) | $low);
        }
        return $bytes;
    }

    public function OrderConsumedNotice1()
    {
//        $datetime = date('Y-m-d H:i:s');
//        $filename = 'log/' . date('Ymd') . '.txt';
//        $pushData = $this->request->post();
//        $header = $pushData['header'];
//        $encryptBody = $pushData['body'];
//        $a = $this->aes128_cbc_decrypt($encryptBody);
//        //转成数组
//        $bodyArr = json_decode($a, true);
//        // dump($bodyArr);exit;
//        @file_put_contents($filename, $datetime . '-接收数据$bodyArr:' . json_encode($bodyArr, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);
        $res = [
            'header' => [
                'accountId' => "9436dc17899b9345",
                'serviceName' => 'OrderConsumedNotice',
                'requestTime' => '2026-08-08 15:10:55',
                'version' => '1.0'
            ],
            'body' => [
                'sequenceId' => 'fbdd7812-fbb5-4777-94d4-7b976b436b12',
                'otaOrderId' => 'trip-test-1786171255450',
                'supplierOrderId' => '1786171255849238',
                'items' => [
                    [
                        'itemId' => '1003696'
                    ]
                ]
            ]
        ];
        echo "[明文完整报文] = \n\n" . json_encode($res, JSON_UNESCAPED_UNICODE) . "\n\n\n";
        //1、body转json字符串
        $bodyJson = json_encode($res['body'], JSON_UNESCAPED_UNICODE);
        echo "[明文body] = \n\n" . $bodyJson . "\n\n\n";
        //2、AES加密
        $encryptBody = $this->aesEncrypt($bodyJson);
        echo "[加密后的body] = \n\n" . $encryptBody . "\n\n\n";
//        {"requestTime":"2026-08-08 10:07:21","accountId":"9436dc17899b9345","sign":"da921cc33e0930f7b8045803c89f962b","serviceName":"CreatePreOrder","version":"1.0"}
        //3、头部参数
        $serviceName = $res['header']['serviceName'];
        $requestTime = $res['header']['requestTime'];
        $version = $res['header']['version'];

        //4、签名字符串拼接规则:accountId+serviceName+requestTime+加密后的body+version+signKey
        $signSource = "9436dc17899b9345" . $serviceName . $requestTime . $encryptBody . $version . "283fbbd87d77d29d915d47714c33b4bc";
        echo "[signSource] = \n\n" . $signSource . "\n\n\n";
        $sign = strtolower(md5($signSource));
        echo "[签名sign] = \n\n" . $sign . "\n\n\n";

        //5、最终推送完整报文
        $pushDatares = [
            "header" => [
                'accountId' => "9436dc17899b9345",
                'serviceName' => 'OrderConsumedNotice',
                'requestTime' => date('Y-m-d H:i:s'),
                'version' => '1.0',
                'sign' => $sign
            ],
            "body" => $encryptBody
        ];

//        echo json_encode($pushData);
        $res = json_encode($pushDatares, JSON_UNESCAPED_UNICODE);
        echo "[密文完整报文] = \n\n" . $res . "\n\n\n";
//        $result = json_decode(\fast\Http::post('https://ttdopen.ctrip.com/api/order/notice.do', $res), true);
        $result = json_decode($this->httpPost('https://ttdopen.ctrip.com/api/order/notice.do', $res), true);
        dump($result);
//        return $res;
    }

    //AES‑128‑CBC加密
    protected function aesEncrypt($plainText)
    {
        return openssl_encrypt($plainText, 'AES-128-CBC', "2966ebbe3270ce0f", OPENSSL_RAW_DATA, "70cd11aaa0281d11");
    }

    //生成签名
    protected function getSign($jsonStr)
    {
        return md5($jsonStr . "283fbbd87d77d29d915d47714c33b4bc");
    }

    /***
     * 订单取消
     * @return false|string|void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function XcCancelOrder()
    {
        $supplierOrderId = $this->request->post('supplierOrderId');
        $order_info = Xcorder::where('supplierOrderId', $supplierOrderId)->find();
        if (!$order_info) {
            return json_encode([
                'header' => [
                    'resultCode' => '0001',
                    'resultMessage' => '订单不存在',
                ]
            ], JSON_UNESCAPED_UNICODE);
        }

        $requestTime = date('Y-m-d H:i:s');
        $res = [
            'header' => [
                'accountId' => $this->ACCOUNT_ID,
                'serviceName' => 'CancelOrder',
                'requestTime' => $requestTime,
                'version' => '1.0'
            ],
            'body' => [
                'sequenceId' => $order_info['sequenceId'],
                'otaOrderId' => $order_info['otaOrderId'],
                'supplierOrderId' => $order_info['supplierOrderId'],
                'confirmType' => 1,
                'items' => [
                    [
                        'itemId' => $order_info['itemId'],
                        'PLU' => $order_info['PLU'],
                        'cancelType' => 0,
                        'quantity' => $order_info['quantity'],
                        'passengers' => [
                            [
                                'passengerId' => $order_info['itemId']
                            ]
                        ],
                        'lastConfirmTime' => $requestTime,
                        'amount' => 0.1,
                        'amountCurrency' => 'CNY'
                    ]
                ]
            ]
        ];
//        echo "[明文完整报文] = \n\n" . json_encode($res, JSON_UNESCAPED_UNICODE) . "\n\n\n";
        //1、body转json字符串
        $bodyJson = json_encode($res['body'], JSON_UNESCAPED_UNICODE);
//        echo "[明文body] = \n\n" . $bodyJson . "\n\n\n";
        //2、AES加密
        $encryptBody = $this->aes128_cbc_encrypt($bodyJson);
//        echo "[加密后的body] = \n\n" . $encryptBody . "\n\n\n";
//        {"requestTime":"2026-08-08 10:07:21","accountId":"9436dc17899b9345","sign":"da921cc33e0930f7b8045803c89f962b","serviceName":"CreatePreOrder","version":"1.0"}
        //3、头部参数
        $serviceName = $res['header']['serviceName'];
        $requestTime = $res['header']['requestTime'];
        $version = $res['header']['version'];

        //4、签名字符串拼接规则:accountId+serviceName+requestTime+加密后的body+version+signKey
        $signSource = $this->ACCOUNT_ID . $serviceName . $requestTime . $encryptBody . $version . $this->SIGN_KEY;
//        echo "[signSource] = \n\n" . $signSource . "\n\n\n";
        $sign = strtolower(md5($signSource));
//        echo "[签名sign] = \n\n" . $sign . "\n\n\n";

        //5、最终推送完整报文
        $pushDatares = [
            "header" => [
                'accountId' => $this->ACCOUNT_ID,
                'serviceName' => 'CancelOrder',
                'requestTime' => $requestTime,
                'version' => '1.0',
                'sign' => $sign
            ],
            "body" => $encryptBody
        ];

//        echo json_encode($pushData);
        $res = json_encode($pushDatares, JSON_UNESCAPED_UNICODE);
//        echo "[密文完整报文] = \n\n" . $res . "\n\n\n";
//        $result = json_decode(\fast\Http::post('https://ttdopen.ctrip.com/api/order/notice.do', $res), true);
        $result = json_decode($this->httpPost('https://ttdopen.ctrip.com/api/order/notice.do', $res), true);
        dump($result);
        exit;
//        if ($result['header']['resultCode'] == '0000') {
//            $order_info->status = 8;
//            $order_info->useQuantity = 1;
//            $order_info->save();
//            $this->success('订单核销成功');
//        } else {
//            $this->error('订单核销失败');
//        }
//        return $result;
    }

    /***
     * 查询订单
     * @return false|string|void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function XcQueryOrder()
    {
        $supplierOrderId = $this->request->post('supplierOrderId');
        //截取订单号的前两位
        $supplierOrderId = substr($supplierOrderId, 0, 2);
        if ($supplierOrderId == 'xc') {
            $order_info = Xcorder::where(['supplierOrderId' => $supplierOrderId, 'sttaus' => 2])->find();
        }


    }


}
相关推荐
weixin_4038101310 小时前
AI智能体写安卓自动化脚本教程:Cursor/Trae+CLI 实战,自然语言生成代码
android·人工智能·自动化·跨境电商·安卓自动化脚本·多账户运营
呆呆小孩12 小时前
零基础学 MySQL(上):从建库建表到增删改查,一篇搭好 SQL 基础
android·sql·mysql
catchadmin12 小时前
NativePHP v4 让 Blade 构建原生 iOS 与 Android 界面
android·ios·ai·php
FfHUCisI13 小时前
Golang 数据库连接池深度调优
android·数据库·golang
Sagittarius_A*14 小时前
Burst Lab | PHP 审计 13|反序列化(三):POP 链构造与 Gadget Chain 分析
开发语言·web安全·php·代码审计·反序列化
蓝速科技15 小时前
蓝速科技丨新旧楼宇混杂场景下会议室预约门牌屏一体化改造方案
开发语言·科技·php
古法安卓16 小时前
Android-epoll原理详解
android·java·android studio
Sagittarius_A*17 小时前
Burst Lab | PHP 审计 14|反序列化(四):字符串逃逸与绕过技巧
开发语言·安全·php·web·反序列化
字节暗面18 小时前
四款 APP 加固强度测评:让 AI 拆了四个包,结果有点出乎意料
android·逆向工程·加固