<?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