<?php

use mallbook\MallbookApi;
use think\Controller;
use think\Db;

class Mall 
{
    /**
     * demo只包含了担保交易多次异步分账的代码
     * 1.微信支付(app/公众号)
     * 2.支付宝支付(app)
     * 3.回调
     */

    /**
     * wechat : Hush_LLL
     * email : m870rusha@163.com
     * qq : 1193038523
     */


    /**
     * 准备工作
     *
     * 1.mallbook商户信息,mallbook客服会帮你处理好 (配置信息 extend/mallbook/MallbookApi __construct)
     * 1.1 apiUrl 环境配置 支付宝可以使用测试环境,微信无法使用测试环境(微信支付只可采用正式环境)强烈建议直接使用生产环境
     * 1.2 merchantNo 商户号
     * 1.3 channelType HF 一般都是HF
     * 1.4 version 1.0.0 写死
     * 1.5 pkcs8私钥 extend/mallbook/Mallbook/getSign 换成你的文件路径
     * 1.6 mallbook_key_file mallbook plus公钥  extend/mallbook/Mallbook/verify 换成你的文件路径
     */


    /**
     * 注意事项
     *
     * 1 app微信支付使用mallbook 只能通过拉起小程序进而拉起支付,对应的小程序内部建议放上假的商城页面(单支付页面小程序因微信方面原因无法上线)且需要将appid发给mallbook
     * 2 公众号微信支付 需要将对应的公众号域名发给mallbook
     * 3 支付宝支付使用C扫B
     * 4 mallbook 所有的支付金额都是分,没有小数
     */

    const domin = 'https://123456.com/';//这个写自己的域名

    /**
     * 支付
     */
    public function payOrder()
    {
        /**
         * 1.接收参数
         */
        $params = [
            'order_id' => input('order_id'),
            'payment_type' => input('payment_type'), //wechat/alipay
            'pay_type' => input('pay_type'),//WX_MINI=小程序,WX_JSAPI=公众号
        ];
        /**
         * 2.验证参数部分 根据业务逻辑补充即可
         */


        /**
         * 3.业务逻辑
         */
        $orderInfo = \app\common\model\Order::find(1);
        $type = 1;//1=直接支付同步分账2=担保交易同步分账3=担保交易单次异步分账4=担保交易多次异步分账
        if ($params['payment_type'] == 'alipay') {
            $response = $this->alipayOrder($orderInfo,$type);
        } else {
            $response = $this->wxPayOrder($orderInfo, $params['pay_type']);
        }


        /**
         * 4.返回结果
         */
        if ($response) {
            $this->success('支付成功', ['response' => $response, 'order_num' => $orderInfo->order_num]);
        } else {
            $this->error('支付失败');
        }

        //正确的返回结果格式如下 为保证隐私性部分数据使用*代替
        //"result": "{\"amount\":\"12\",\"merOrderId\":\"23090809595725444737\",\"payCode\":\"{\\\"timeStamp\\\":\\\"1694142233\\\",\\\"package\\\":\\\"prepay_id=wx0811***156****9078175640000\\\",\\\"paySign\\\":\\\"ftTczXoOXlmM1Tz9PJlA****o125dWqa7k3LCUlPVTsasFQs70n/mWyBxNT+UYEpu35wf1cbnqts8eBus****hOtOtg7r94O7wXBzSRE3d/9melal/ZKxVhL4Fc8Q28iiuutMrlvh8lVJyKn1Ww5b9f8y6+Aa4K+zxedPyXkOkMQopuTt9xsuNL0kPcjrkHzt59BJrnOZwsga9iBiU2vWHfg2zG9eoONO/6gpLQr/d9yrDHX6ddbTQKZ5pIjjGYyjzJIKxhaMLy6ydEcWOQ==\\\",\\\"appId\\\":\\\"wxb038ca25944802ab\\\",\\\"signType\\\":\\\"RSA\\\",\\\"nonceStr\\\":\\\"8Ie5DKw*evjTITiH0\\\"}\",\"status\":\"0\"}",
        //        "sign": "lI+******+gMmlGcEh****1Fr9YjiQOI+/******/MUbJ03jGek6kCESLqu0PCxbL7***WsaKqZ6qdadn1TIDBjohx+YP941kdZDH8Y=",
        //        "code": "0000",
        //        "msg": "操作成功",
        //        "date": "1694142232961",
        //        "version": "1.0.0"


    }




    /**
     * 担保交易多次异步分账
     */
    protected function alipayOrder($orderInfo,$type)
    {
        if ($type == 4) {
            if (empty($params)) {
                $params = [
                    'orderName' => '支付订单',//订单描述
                    'payType' => 'ALI_CB',//ALI_CB:支付宝C扫B
                    'transferType' => '1',//支付时上传对应收款方子商户编号(payeeUserId)和分账方列表(splitList),支付完成后资金直接同步分账到各子商户可结算资金。
                    'asynSplitFlag' => '0',//是否异步(重点是异步)分账 如果transferType传的是1无法进行异步分账
                    'terminalIp' => '127.0.0.1',//写死就行
                    'frontUrl' => self::domin . 'api/Mall/callback',//前端回调地址,可以写个假的
                    'notifyUrl' => self::domin . 'api/Mall/callback',//回调地址
                    'goodsDetail' => [['goodsId' => $orderInfo->id, 'goodsName' => '订单']],
                    //'appSchema' => 'Mallbook://',
                    'bizOrderId' => $orderInfo->order_num,//请求单号(业务系统唯一单号)
                    'amount' => bcmul($orderInfo->m_total_amount, 100)//金额 单位是分
                ];
            }
            $mallbookApi = new MallbookApi();
            return $mallbookApi->paymentOrder($orderInfo->order_num, $params);
        }
        if (empty($params)) {
            $params = [
                'orderName' => '支付订单',//订单描述
                'payType' => 'ALI_CB',//ALI_CB:支付宝C扫B
                'transferType' => '0',//0=担保交易,需要调用确认收货接口,资金才会划转到对方账户1=直接支付,支付成功后,资金直接划转到对方账户中
                'asynSplitFlag' => '1',//是否异步(重点是异步)分账 如果transferType传的是1无法进行异步分账
                'terminalIp' => '127.0.0.1',//写死就行
                'frontUrl' => self::domin . 'api/Mall/callback',//前端回调地址,可以写个假的
                'notifyUrl' => self::domin . 'api/Mall/callback',//回调地址
                'goodsDetail' => [['goodsId' => $orderInfo->id, 'goodsName' => '订单']],
                //'appSchema' => 'Mallbook://',
                'bizOrderId' => $orderInfo->order_num,//请求单号(业务系统唯一单号)
                'amount' => bcmul($orderInfo->m_total_amount, 100)//金额 单位是分
            ];
        }
        $mallbookApi = new MallbookApi();
        return $mallbookApi->paymentOrder($orderInfo->order_num, $params);
    }
    protected function wxPayOrder($orderInfo, $payType)
    {
        if ($payType == 'WX_MINI') {
            $openid = \app\common\model\User::where('id', '=', $orderInfo->user_id)->value('mini_openid');//对应的小程序用户的openid
            $appid = '这里换上你的小程序appid';
        } else {
            $openid = \app\common\model\User::where('id', '=', $orderInfo->user_id)->value('gzh_openid');//对应的公众号的用户openid
            $appid = '这里换上你的公众号appid';
        }
        $params = [
            'appid' => $appid,
            'openid' => $openid,//小程序openid,如果是app支付那么appid必传
            'frontUrl' => self::domin . 'api/Mall/callback',
            'notifyUrl' => self::domin . 'api/Mall/callback',
            'orderName' => '订单',//订单描述
            'payType' => $payType,//微信小程序或者公众号
            'transferType' => '0',//0=担保交易,需要调用确认收货接口,资金才会划转到对方账户1=直接支付,支付成功后,资金直接划转到对方账户中
            'asynSplitFlag' => '1',
            'terminalIp' => '127.0.0.1',
            'payeeUserId' => '',
            'goodsDetail' => [['goodsId' => $orderInfo->id, 'goodsName' => '订单']],
            'bizOrderId' => $orderInfo->order_num,//自己生成的订单号
            'amount' => bcmul($orderInfo->m_total_amount, 100)//金额 单位是分
        ];
        $mallbookApi = new MallbookApi();
        return $mallbookApi->paymentOrder($orderInfo->order_num, $params);
    }

    /**
     * 回调
     */
    public function callback()
    {
        $params = file_get_contents('php://input');
        $logInfo = $params;
        //把加密的函数处理下
        $res = [];
        parse_str($params, $res);//获取所有的返回结果

        /**
         * 返回的所有数据
         *
         *  'date' => '1694143252472',
         * 'msg' => '操作成功',
         * 'result' => '{"amount":"12","channelOrderId":"ZF16999****781026816","merOrderId":"230908****43002","openid":"oX4jC5B5*****bqFM","outTransId":"4200001896****8582078","partyOrderId":"02212309*****86401","splitList":[],"status":"1"}',
         * 'sign' => 'OJvBKeT/vBgx******QmNUOfET/MwpQjJCYvJuzEj9WP1ZNgufj72R28Q3A****ZC/j8IhA5wZ/wwR****PXSpQBjLRnZEexesragjCMiF*****I9htkCJJe65sd2/Y3fhFcqKiyIgGbUu4=',
         * 'code' => '0000',
         * 'version' => '1.0.0',
         *
         */


        $sign = $res['sign'];//获取签名值
        $result = json_decode($res['result'], true);//获取返回结果
        $filePath = ROOT_PATH . 'public' . DS . 'log';
        if (!file_exists($filePath)) {
            mkdir($filePath, 0777);
        }
        //验签
        if (!\mallbook\Mallbook::verify($res, $sign)) {
            $logInfo = '返回值验签失败';
        }
        file_put_contents($filePath . DS . 'log.txt', $logInfo);
        $order = Order::get(['order_num' => $result['merOrderId']]) ?: [];
        if ($order) {
            if ($order->status == 1 && $result['status'] == 1) {
                try {
                    /**
                     * 业务逻辑代码
                     */
                    Db::commit();
                } catch (\Throwable $e) {
                    Db::rollback();
                    halt($e->getMessage());
                }
            }
            return json(['code' => 200, 'msg' => 'success']);
        }
        return json(['code' => 0, 'msg' => 'failed']);
    }


    /**
     *分账
     */
    public function asynSub()
    {
        //假设本次订单支付100元分账100元
        $asynMerOrderId = '123456,自己生成一个订单号';//分账订单号,这个订单号需要保存下来,在确认收货的时候要用到,存起来存到哪里都行。自己把数据库设计好就行

        $orderInfo = Order::find(1);
        $data = [];
        $data[] = [
            'splitUserId' => '422****84',//分账接收方A的子商户号
            'splitAmount' => '1***4',//分账接收方的本次接收的分账金额
            'splitType' => '2',//非担保交易多次异步分账必传 实际测试过程中传2和1都行
            'feeFlag' => 0,//是否为手续费承担方式0=否1=是
        ];
        $data[] = [
            'splitUserId' => '236***2128286',//注册审核通过返回userId
            'splitAmount' => '4***0',
            'splitType' => '2',
            'feeFlag' => 0,
        ];
        $data[] = [
            'splitUserId' => '9**50816286',
            'splitAmount' => '6****0',
            'splitType' => '2',
            'feeFlag' => 0,
        ];

        if (empty($params)) {
            $params = [
                'originalMerOrderId' => $orderInfo->order_num,//订单的支付单号!
                'splitList' => json_encode($data),//必须是json样式
                'notifyUrl' => self::domin . 'api/Mall/asynSubCallback',//异步分账回调地址
            ];
        }
        $mallbookApi = new MallbookApi();
        //$asynMerOrderId 这个分账订单号存起来!!!
        $result = $mallbookApi->complete($asynMerOrderId, $params);
        halt($result);
    }


    /**
     * 分账回调
     */
    public function asynSubCallback()
    {
        $params = file_get_contents('php://input');
        $logInfo = $params;
        //把加密的函数处理下
        $res = [];//这个res就是返回回来的参数的数组样式
        parse_str($params, $res);
        $sign = $res['sign'];
        $result = json_decode($res['result'], true);
        $filePath = ROOT_PATH . 'public' . DS . 'log';
        if (!file_exists($filePath)) {
            mkdir($filePath, 0777);
        }
        if (!\mallbook\Mallbook::verify($res, $sign)) {
            $logInfo = '返回值验签失败';
        }
        file_put_contents($filePath . DS . 'log.txt', $logInfo);
        if ($result['status'] == 1) {
            //业务逻辑部分
            //返回值里包含请求分账的订单号(是分账接口的请求单号),不是支付的订单号。把分账请求的订单号存起来

            return json(['code' => 200, 'msg' => 'success']);
        }
        return json(['code' => 0, 'msg' => 'failed']);
    }

    /**
     * 确认收货 没有回调
     */
    public function receive()
    {
        $receiveMerOrderId = '自己生成一个订单号,确保唯一性';
        $orderInfo = Order::get(1);
        $orderNum = $orderInfo->order_num;
        $asynOrderNum = $orderInfo->asyn_order_num;//假设我把分账订单号存进了订单表,但实际不建议这样操作,因为实际生产时很麻烦


        $data = [];
        $data[] = [
            'splitUserId' => '4**6*8*84', //注册审核通过返回userId
            'rcvSplitAmount' => '1**14',
        ];
        $data[] = [
            'splitUserId' => '236**2*8*286',
            'rcvSplitAmount' => '43**0',
        ];
        $data[] = [
            'splitUserId' => '92**2*8**86',
            'rcvSplitAmount' => '6**0',
        ];
        if (empty($params)) {
            $params = [
                'originalMerOrderId' => $orderNum,//原来的订单支付的订单号!支付订单号!
                'asynMerOrderId' => $asynOrderNum,//多次异步确认订单进行确认收货时必传,这个订单号是异步分账订单号,就是存起来的分账请求单号!
                'rcvAmount' => bcmul($orderInfo->real_money, 100),//确认收货总额==该分账单号对应的分账总额(上文已经说是100元),分账的时候分了多少钱这个地方就写多少钱,单位是分
                'splitList' => json_encode($data),
            ];
        }
        $mallbookApi = new MallbookApi();
        $result = $mallbookApi->receive($receiveMerOrderId, $params);
    }

    /**
     * 结算 就是经常说的提现,逻辑:今日提现明日十点到下午16点之间到账,周五周六周日的 统一在周一十点到下午16点到账
     */
    public function withdraw()
    {
        $mallbookApi = new MallbookApi();
        $params = [
            'userId' => '12345****',//就是子商户号
            'amount' => bcmul(43.80, 100),//分给这个商户号多少钱就是多少钱
            'notifyUrl' => self::domin . 'api/Mall/withdrawCallback',
        ];
        $withdrawMerOrderId = '自己生成一个订单号';//结算请求单号
        $result = $mallbookApi->withdraw($withdrawMerOrderId, $params);
        halt($result);
    }

    public function withdrawCallback()
    {
        $params = file_get_contents('php://input');
        $logInfo = $params;
        //把加密的函数处理下
        $res = [];//这个res就是返回回来的参数的数组样式
        parse_str($params, $res);
        $sign = $res['sign'];
        $result = json_decode($res['result'], true);
        $filePath = ROOT_PATH . 'public' . DS . 'log';
        if (!file_exists($filePath)) {
            mkdir($filePath, 0777);
        }
        if (!\mallbook\Mallbook::verify($res, $sign)) {
            $logInfo = '返回值验签失败';
        }
        file_put_contents($filePath . DS . 'log.txt', $logInfo);
        if ($result['status'] == 1) {
            //业务逻辑部分
            //返回值里包含结算请求的订单号(是结算接口的请求单号),不是支付的订单号。存起来

            return json(['code' => 200, 'msg' => 'success']);
        }
        return json(['code' => 0, 'msg' => 'failed']);
    }

    /**
     * 退款
     */
    public function refund()
    {
        $orderInfo = Order::get(1);
        $merOrderId = '自己生成一个订单号保证唯一性';
        $refundMoney = bcmul($orderInfo->real_money, 100);//想退多少退多少,不能超过原支付金额
        if (empty($params)) {
            $params = [
                'originalMerOrderId' => $orderInfo->order_num,//原支付请求订单号,就是自己生成的订单号
                'refundAmount' => $refundMoney,//退款总金额=总退款分账金额
                'notifyUrl' => self::domin . 'api/Mallbook/refundCallback',//回调
                //'asynMerOrderId' => ''//异步分账订单号,如果进行了异步分账就把异步分账订单号传进来,没有就不传,这里没有就不传,确认收货之后就不能再退款了
            ];
        }
        $mallbookApi = new MallbookApi();
        $result = $mallbookApi->refund($merOrderId, $params);
        //退款操作一般以回调通知为准,非常不建议使用调用结果来进行业务逻辑
        $res = json_decode($result['result'], true);
    }

    public function refundCallback()
    {
        $params = file_get_contents('php://input');
        $logInfo = $params;
        //把加密的函数处理下
        $res = [];//这个res就是返回回来的参数的数组样式
        parse_str($params, $res);
        $sign = $res['sign'];
        $result = json_decode($res['result'], true);
        $filePath = ROOT_PATH . 'public' . DS . 'log';
        if (!file_exists($filePath)) {
            mkdir($filePath, 0777);
        }
        if (!\mallbook\Mallbook::verify($res, $sign)) {
            $logInfo = '返回值验签失败';
        }
        file_put_contents($filePath . DS . 'log.txt', $logInfo);
        if ($result['status'] == 1) {
            //业务逻辑部分

            return json(['code' => 200, 'msg' => 'success']);
        }
        return json(['code' => 0, 'msg' => 'failed']);
    }

    /**
     * 子商户注册
     */
    public function sonRegister()
    {
        $params = [
            'phone' => input('phone'),
            'user_name' => input('user_name'),
            'cert_id' => input('cert_id'),
        ];

        $data = [
            'merUserId' => '自己写一个唯一的',
            'phone' => $params['phone'],
            'userType' => 0,//0 小微 1个体工商户  2 企业
            'userName' => $params['user_name'],//真实姓名
            'certId' => $params['cert_id'],
            'notifyUrl' => self::domin.'api/Mall/sonRegistercallback',//小微商户不走回调同步返回数据,但是这个参数不传会报错,所以传上
        ];

        $mallbook = new MallbookApi();
        $userId = 1;//用户主键
        $result = $mallbook->register($data,$userId);
        if (!$result) {
            $this->error('信息有误,请重新绑定');
        }
        $res = json_decode($result['result'], true);
        if ($result['code'] == '0000') {
           //业务逻辑 把返回的数据 merUserId存起来 对应的用户存对应的 $res包含对应的数据
            //用不用回调数据都行,实际操作小微商户没用回调数据也可以,如果需要回调操作,回调格式与其他回调格式一样,请自行处理
            //把split_user_id(子商户编号,也叫子商户号)/cert_id身份证号码 存起来
        }
        $this->error('绑定失败,请检查您的信息');
    }

    /**
     * 绑定结算信息
     */
    public function bindCard()
    {
        $params = [
            'card_name' => input('card_name'),
            'card_no' => input('card_no'),
            'phone' => input('phone'),
            'bank_name' => input('bank_name'),
        ];
        $userId = 1;
        $userInfo = \app\common\model\User::get($userId);
        $data = [
            'userId' => $userInfo->split_user_id,//子商户编号
            'certId' => $userInfo->cert_id,//个人身份证号码
            'cardName' => $params['card_name'],//银行卡号对应的户名 人名
            'cardNo' => $params['card_no'],//银行卡号
            'bankAcctType' => 2,//1-对公;2-对私
            'phone' => $params['phone'],
        ];
        $mallbook = new MallbookApi();
        $result = $mallbook->bindAccount($data, $userId);
        if (!$result) {
            $this->error('信息有误,请重新绑定');
        }
        if ($result['code'] == '0000') {
          //业务逻辑
        }
        $this->error('信息错误,请重新申请');
    }

    //直接交易同步分账
    public function directPay()
    {
        //支付多少分多少,例如:支付100元必须在本次分完100元
        $orderInfo = Order::where('id','=',1)->find();
        $data[] = [
            'splitUserId' => '983443968300',//分账接收方A的子商户号
            'splitAmount' => '70',//分账接收方的本次接收的分账金额
            'splitType' => '0',//直接支付同步分账 payeeUserId如果是该用户,splitType需要上传字段0
            'feeFlag' => 0,//是否为手续费承担方式0=否1=是
        ];
        $data[] = [
            'splitUserId' => '915051008180',//注册审核通过返回userId
            'splitAmount' => '30',
            'splitType' => '2',
            'feeFlag' => 0,
        ];
        if (empty($params)) {
            $params = [
                'orderName' => '支付订单',//订单描述
                'payType' => 'ALI_CB',//ALI_CB:支付宝C扫B
                'transferType' => '1',//支付时上传对应收款方子商户编号(payeeUserId)和分账方列表(splitList),支付完成后资金直接同步分账到各子商户可结算资金。
                'asynSplitFlag' => '0',//是否异步(重点是异步)分账 如果transferType传的是1无法进行异步分账
                'terminalIp' => '127.0.0.1',//写死就行
                'frontUrl' => self::domin . 'api/Mall/callback',//前端回调地址,可以写个假的
                'notifyUrl' => self::domin . 'api/Mall/callback',//回调地址
                'goodsDetail' => [['goodsId' => $orderInfo->id, 'goodsName' => '订单']],
                //'appSchema' => 'Mallbook://',
                'bizOrderId' => $orderInfo->order_num,//请求单号(业务系统唯一单号)
                'amount' => bcmul($orderInfo->m_total_amount, 100),//金额 单位是分
                'splitList' => $data,
                'payeeUserId' => '983443968300',//只写一个,一般是门店
            ];
        }
        $mallbookApi = new MallbookApi();
        $result = $mallbookApi->paymentOrder($orderInfo->order_num, $params);
        $this->success('成功',$result);

        //"code": 1,
        //  "msg": "成功",
        //  "time": "1694509431",
        //  "data": {
        //     "result": "{\"amount\":\"100\",\"merOrderId\":\"23082***86637\",\"payCode\":\"https://qr.alipay.com/bax096390un41wfyqsko00f7\",\"splitList\":[{\"feeFlag\":\"0\",\"splitAmount\":\"70\",\"splitUserId\":\"983***68300\",\"splitType\":\"0\"},{\"feeFlag\":\"0\",\"splitAmount\":\"30\",\"splitUserId\":\"915***80\",\"splitType\":\"2\"}],\"status\":\"0\"}",
        //     "sign": "UBNVZfZFoFm****DB+XB5Z/hA0LjOFhLYnmUdrYXbxP****gQQ0bzK3KTF8***voUW9hasTVhjFhFGRTHJNYa***q2LAxLHORFx1E4kzz6s=",
        //     "code": "0000",
        //     "msg": "操作成功",
        //     "date": "1694509432488",
        //     "version": "1.0.0"
        //  }

    }
    //担保交易同步分账
    public function directPay1()
    {
        //支付多少分多少,例如:支付100元必须在本次分完100元
        $orderInfo = Order::where('id','=',1)->find();
        $data[] = [
            'splitUserId' => '983443968300',//分账接收方A的子商户号
            'splitAmount' => '70',//分账接收方的本次接收的分账金额
            'splitType' => '0',//同步分账 payeeUserId如果是该用户,splitType需要上传字段0
            'feeFlag' => 0,//是否为手续费承担方式0=否1=是
        ];
        $data[] = [
            'splitUserId' => '915051008180',//注册审核通过返回userId
            'splitAmount' => '30',
            'splitType' => '2',
            'feeFlag' => 0,
        ];
        if (empty($params)) {
            $params = [
                'orderName' => '支付订单',//订单描述
                'payType' => 'ALI_CB',//ALI_CB:支付宝C扫B
                'transferType' => '0',//支付时上传对应收款方子商户编号(payeeUserId)和分账方列表(splitList),支付完成后资金直接同步分账到各子商户可结算资金。
                'asynSplitFlag' => '0',//是否异步(重点是异步)分账 如果transferType传的是1无法进行异步分账
                'terminalIp' => '127.0.0.1',//写死就行
                'frontUrl' => self::domin . 'api/Mall/callback',//前端回调地址,可以写个假的
                'notifyUrl' => self::domin . 'api/Mall/callback',//回调地址
                'goodsDetail' => [['goodsId' => $orderInfo->id, 'goodsName' => '订单']],
                //'appSchema' => 'Mallbook://',
                'bizOrderId' => $orderInfo->order_num,//请求单号(业务系统唯一单号)
                'amount' => bcmul($orderInfo->m_total_amount, 100),//金额 单位是分
                'splitList' => $data,
                'payeeUserId' => '983443968300',//只写一个,一般是门店
            ];
        }
        $mallbookApi = new MallbookApi();
        $result = $mallbookApi->paymentOrder($orderInfo->order_num, $params);
        $this->success('成功',$result);

        //"code": 1,
        //  "msg": "成功",
        //  "time": "1694508913",
        //  "data": {
        //     "result": "{\"amount\":\"100\",\"merOrderId\":\"230***186634\",\"payCode\":\"https://qr.alipay.com/bax09179k2wpkpb9cy7d0053\",\"splitList\":[{\"feeFlag\":\"0\",\"splitAmount\":\"70\",\"splitUserId\":\"983****300\",\"splitType\":\"0\"},{\"feeFlag\":\"0\",\"splitAmount\":\"30\",\"splitUserId\":\"9****8180\",\"splitType\":\"2\"}],\"status\":\"0\"}",
        //     "sign": "g3DduT7YP****1/hNyZm97ZSpKPchuXE6h***yBb/RhSvrgseq3BnjEeO0ls6MT7WSEVuHMmd/TsJPsP***ODyWdZ3NeLYVkWGi4wTFFbVJTu2nGXpSkzw9J7WXQ=",
        //     "code": "0000",
        //     "msg": "操作成功",
        //     "date": "1694508914122",
        //     "version": "1.0.0"
        //  }

    }
    //担保交易单次异步分账
    public function directPay2()
    {
        //支付多少分多少,例如:支付100元必须在本次分完100元
        $orderInfo = Order::where('id','=',1)->find();
        $data[] = [
            'splitUserId' => '98****68300',//分账接收方A的子商户号
            'splitAmount' => '70',//分账接收方的本次接收的分账金额
            'splitType' => '0',//同步分账 payeeUserId如果是该用户,splitType需要上传字段0
            'feeFlag' => 0,//是否为手续费承担方式0=否1=是
        ];
        $data[] = [
            'splitUserId' => '91****180',//注册审核通过返回userId
            'splitAmount' => '30',
            'splitType' => '2',
            'feeFlag' => 0,
        ];
        if (empty($params)) {
            $params = [
                'orderName' => '支付订单',//订单描述
                'payType' => 'ALI_CB',//ALI_CB:支付宝C扫B
                'transferType' => '0',//支付时上传对应收款方子商户编号(payeeUserId)和分账方列表(splitList),支付完成后资金直接同步分账到各子商户可结算资金。
                'asynSplitFlag' => '0',//是否异步(重点是异步)分账 如果transferType传的是1无法进行异步分账
                'terminalIp' => '127.0.0.1',//写死就行
                'frontUrl' => self::domin . 'api/Mall/callback',//前端回调地址,可以写个假的
                'notifyUrl' => self::domin . 'api/Mall/callback',//回调地址
                'goodsDetail' => [['goodsId' => $orderInfo->id, 'goodsName' => '订单']],
                //'appSchema' => 'Mallbook://',
                'bizOrderId' => $orderInfo->order_num,//请求单号(业务系统唯一单号)
                'amount' => bcmul($orderInfo->m_total_amount, 100),//金额 单位是分
                'splitList' => $data,
                'payeeUserId' => '98****00',//只写一个,一般是门店
            ];
        }
        $mallbookApi = new MallbookApi();
        $result = $mallbookApi->paymentOrder($orderInfo->order_num, $params);
        $this->success('成功',$result);

        //  "code": 1,
        //  "msg": "成功",
        //  "time": "1694509105",
        //  "data": {
        //     "result": "{\"amount\":\"100\",\"merOrderId\":\"230****50186636\",\"payCode\":\"https://qr.alipay.com/bax08914fkimokg9nliz006c\",\"splitList\":[{\"feeFlag\":\"0\",\"splitAmount\":\"70\",\"splitUserId\":\"983****300\",\"splitType\":\"0\"},{\"feeFlag\":\"0\",\"splitAmount\":\"30\",\"splitUserId\":\"915*****180\",\"splitType\":\"2\"}],\"status\":\"0\"}",
        //     "sign": "nLbz****a90ZgdJDcQuEIiwCZkg09wwLJxusQLpHf***
        //     "msg": "操作成功",
        //     "date": "1694509106434",
        //     "version": "1.0.0"
        //  }

    }
    //担保交易多次异步分账
    public function directPay3()
    {
        //支付多少分多少,例如:支付100元必须在本次分完100元
        $orderInfo = Order::where('id','=',1)->find();

        if (empty($params)) {
            $params = [
                'orderName' => '支付订单',//订单描述
                'payType' => 'ALI_CB',//ALI_CB:支付宝C扫B
                'transferType' => '0',//支付时上传对应收款方子商户编号(payeeUserId)和分账方列表(splitList),支付完成后资金直接同步分账到各子商户可结算资金。
                'asynSplitFlag' => '0',//是否异步(重点是异步)分账 如果transferType传的是1无法进行异步分账
                'terminalIp' => '127.0.0.1',//写死就行
                'frontUrl' => self::domin . 'api/Mall/callback',//前端回调地址,可以写个假的
                'notifyUrl' => self::domin . 'api/Mall/callback',//回调地址
                'goodsDetail' => [['goodsId' => $orderInfo->id, 'goodsName' => '订单']],
                //'appSchema' => 'Mallbook://',
                'bizOrderId' => $orderInfo->order_num,//请求单号(业务系统唯一单号)
                'amount' => bcmul($orderInfo->m_total_amount, 100),//金额 单位是分
                //'splitList' => $data, 多次异步分账可以不传这个参数
                //'payeeUserId' => '子商户id',
            ];
        }
        $mallbookApi = new MallbookApi();
        $result = $mallbookApi->paymentOrder($orderInfo->order_num, $params);
        $this->success('成功',$result);

        //  "code": 1,
        //  "msg": "成功",
        //  "time": "1694509105",
        //  "data": {
        //     "result": "{\"amount\":\"100\",\"merOrderId\":\"23082313305750186636\",\"payCode\":\"https://qr.alipay.com/bax08914fkimokg9nliz006c\",\"splitList\":[{\"feeFlag\":\"0\",\"splitAmount\":\"70\",\"splitUserId\":\"983******0\",\"splitType\":\"0\"},{\"feeFlag\":\"0\",\"splitAmount\":\"30\",\"splitUserId\":\"91*****80\",\"splitType\":\"2\"}],\"status\":\"0\"}",
        //     "sign": "nLbz****u+D++KEoilU*****gdJDcQuEIiwCZkg****5z0ykziyPhen3DPYSIjtTjk4x13*****6tALhDGaOmH***of7aIxc=",
        //     "code": "0000",
        //     "msg": "操作成功",
        //     "date": "1694509106434",
        //     "version": "1.0.0"
        //  }

    }
}

mallbook 扩展适配代码

最后检测日期 2023/10/09