账单分账支付

<?php
/**
 *  _______  _______  _______
 * |       ||       ||       |
 * |  _____||_     _||   _   |
 * | |_____   |   |  |  | |  |
 * |_____  |  |   |  |  |_|  |
 *  _____| |  |   |  |       |
 * |_______|  |___|  |_______|
 */

namespace apimodulesv1dispatchessys
eturn_order;

use commonmodelsAccount;
use Yii;
use apiaseBaseDispatch;
use commonwx_serverAuthAPI;
use commonmodelsSalesmanBill;
use commonmodelsReturnOrder;
use commonmodelsPostProvince;
use commonmodelsAccountBudget;
use commonmodelsChannelCustomer;
use commonmodelsAccountBankaccount;
use commonmodelsPayLogMoneys;

/**
 * @category 系统
 *
 * @dispatch salesman.rebill.pay
 *
 * @desc 业务员退货账单微信支付
 *
 * @package apimodulesv1dispatchessys
eturn_order
 *
 * @name ReorderBillWxPaymentDispatch
 *
 * 请求参数
 * 格式:  参数名称 | 类型    | 必须 | 示例值 | 描述
 * @requestParam  id | int | true | 12356789 | 业务员退货账单id
 *
 *
 * 响应参数
 * 格式:  参数名称 | 类型 | 示例值 | 描述
 * @responseParam appId | string | iu455452e2ed4 | appId
 * @responseParam timeStamp | string | 1575882074 | timeStamp
 * @responseParam nonceStr | string | 11904757b7724df992c5096dd | nonceStr
 * @responseParam package | string | prepay_id=wx0917011467575811 | package
 * @responseParam signType | string | RSA | signType
 * @responseParam paySign | string | IHEoW/sH | paySign
 *
 * 错误代码
 * 格式: 编号 | 描述
 * @errorCode 1000 | 未查询到账单
 * @errorCode 1001 | 账单未出账
 * @errorCode 1002 | 账单已支付
 * @errorCode 1003 | 账单已作废
 * @errorCode 1004 | 账单已取消
 * @errorCode 1005 | 未查询到账单相关订单
 * @errorCode 1006 | 订单价格异常,请核实后再支付
 * @errorCode 1007 | 所得分账金额异常,请核实后再支付
 * @errorCode 1008 | 业务员账单生成失败
 * @errorCode 1009 | 业务员所得分账金额异常,请核实后再支付
 * @errorCode 1010 | 系统错误 {errors}
 * @errorCode 1011 | 订单已取消
 * @errorCode 1012 | 分账总金额与实际付款金额
 * @errorCode 1013 | 运费低于4元,不允许支付
 * @errorCode 100000 | {errors}
 *
 * 是否要token 有 @token 就是需要,没有不要加@token
 * @token
 *
 * 是否可用
 * @usable
 */
class ReorderBillWxPaymentDispatch extends BaseDispatch
{
    public function run($params)
    {
        $transaction = Yii::$app->db->beginTransaction();
        try {
            $salesmanBill = SalesmanBill::find()->where(['id' => $params['id']])->asArray()->one();
            if(is_null($salesmanBill)){
                throw new Exception(null, 1000);
            }else if($salesmanBill['status'] == 0){
                throw new Exception(null, 1001);
            }else if($salesmanBill['status'] == 2){
                throw new Exception(null, 1002);
            }else if($salesmanBill['status'] == 3){
                throw new Exception(null, 1003);
            }else if($salesmanBill['status'] == 4){
                throw new Exception(null, 1004);
            }

            //获取账单中包含的退货订单
            $returnOrder = ReturnOrder::find()->select(['id', 'account_id', 'waybill', 'order_id', 'channel_customer_id', 'format_fee'])->with('channelCustomer')->where(['salesman_bill_id' => $params['id']])->asArray()->all();
            if(is_null($returnOrder)){
                return $this->errorReturn(1005);
            }

            $user_fee = 0;      #用户总分账金额
            $channel_fee = 0;   #渠道总分账金额
            $sto_fee = 0;       #申通总分账金额
            $div_details_list = [];  #分账信息列表
            $div_details_arr = [];  #分账信息
            foreach($returnOrder as $key=>$value){
                #服务模式(1:自助模式;2:半自助模式(有人员服务模式)) 不同分账方式不同
                if($value['service_mode'] == 1){
                    //根据不同的订单金额,对分账对象有不同的分账金额。
                    if(sprintf("%1$.2f", $value['format_fee']-1) == 7){
                        $user_fee += 2;
                        $channel_fee += 1;
                        $sto_fee += 4;

                        $budget_user = 2;       #用户分账
                        $budget_channel = 1;    #渠道分账
                    }else if(sprintf("%1$.2f", $value['format_fee']-1) == 11){
                        $user_fee += 4;
                        $channel_fee += 2;
                        $sto_fee += 5;

                        $budget_user = 4;       #用户分账
                        $budget_channel = 2;    #渠道分账
                    }else{
                        return $this->errorReturn(1006);
                    }
                }else if($value['service_mode'] == 2){
                    if(sprintf("%1$.2f", $value['format_fee']-1) == 7){
                        $user_fee += 7;

                        $budget_user = 7;       #用户分账(少1元的用户返利,待业务员账单支付完成后,生成一元账单)
                    }else if(sprintf("%1$.2f", $value['format_fee']-1) == 11){
                        $user_fee += 11;

                        $budget_user = 11;      #用户分账(少1元的用户返利,待业务员账单支付完成后,生成一元账单)
                    }else{
                        return $this->errorReturn(1006);
                    }
                }



                //订单用户账户信息
                $user_accountBankaccount = AccountBankaccount::find()->where(['account_id'=>$value['account_id']])->asArray()->one();
                if(!is_null($user_accountBankaccount)){
                    $user_divCustId = $user_accountBankaccount['user_cust_id'];       #用户分账用户客户号
                    $user_divAcctId = $user_accountBankaccount['acct_id'];            #用户分账子账号
                }else{
                    $user_divCustId = Yii::$app->params['bank_acco']['cashpool_divCustId'];     #资金池分账用户客户号
                    $user_divAcctId = Yii::$app->params['bank_acco']['cashpool_divAcctId'];     #资金池分账子账号
                }

                //订单渠道账户信息
                $channel_accountBankaccount = AccountBankaccount::find()->where(['account_id'=>$value['channelCustomer']['account_id']])->asArray()->one();
                if(!is_null($channel_accountBankaccount)){
                    $channel_divCustId = $channel_accountBankaccount['user_cust_id'];       #渠道分账用户客户号
                    $channel_divAcctId = $channel_accountBankaccount['acct_id'];            #渠道分账子账号
                }else{
                    $channel_divCustId = Yii::$app->params['bank_acco']['cashpool_divCustId'];     #资金池分账用户客户号
                    $channel_divAcctId = Yii::$app->params['bank_acco']['cashpool_divAcctId'];     #资金池分账子账号
                }

                //单个订单分账信息
                $user_div_details = [
                    'divCustId' => $user_divCustId,       #用户
                    'divAcctId' => $user_divAcctId,
                    'divAmt' => sprintf("%1$.2f", $budget_user),
                ];
                $channel_div_details = [
                    'divCustId' => $channel_divCustId,       #渠道
                    'divAcctId' => $channel_divAcctId,
                    'divAmt' => sprintf("%1$.2f", $budget_channel),
                ];

                array_push($div_details_list, $user_div_details, $channel_div_details);
            }

            //将相同账号的分账信息合并
            $merge_result = [];
            foreach($div_details_list as $key=>$val){
                $key = $val['divCustId'].$val['divAcctId'];
                if(!isset($merge_result[$key])){
                    $merge_result[$key] = $val;
                }else{
                    $merge_result[$key]['divAmt'] += $val['divAmt'];
                }

            }

            //生成账单信息
            foreach($merge_result as $k=>$v){
                $v['divAmt'] = sprintf("%1$.2f", $v['divAmt']);
                array_push($div_details_arr, $v);
            }
            //申通账户信息
            $sto_div_details = [
                'divCustId' => Yii::$app->params['bank_acco']['divCustId'],    #申通
                'divAcctId' => Yii::$app->params['bank_acco']['divAcctId'],
                'divAmt' => sprintf("%1$.2f", $sto_fee),
            ];
            array_push($div_details_arr, $sto_div_details);
            $div_details = json_encode($div_details_arr); #分账串数据格式;


            //未完,目前是最多只能分5个账号!!!!!!!!!!!

            $transaction->commit();
//            //支付接口所需参数
//            $bill['div_details'] = $div_details; #分账串数据格式
//            $bill['account_id'] = $params['account_id'];
//            $bill['openid'] = $params['openid'];
//            $bill['order_date'] = date('Ymd',strtotime($bill['verify_time']));
//            $bill['fee'] = sprintf("%1$.2f",$bill['amount']);
//            $bill['order_code'] = $bill['id'];
//            $bill['bg_ret_url'] = $bill['id'];
//
//            $result = AuthAPI::v_pay_bill($bill);
//
//            if(!isset($result['code'])){
//                $transaction->commit();
//                return $this->dataReturn($result);
//            }else{
//                throw new Exception($result['code'].$result['message'], 100000);
//            }

        } catch (Exception $e) {
            $transaction->rollBack();
            $errorCode = $e->getCode();
            if ($errorCode == 0) {
                $errorCode = 1010;
            }
            return $this->errorReturn($errorCode, null, ['{errors}' => $e->getMessage()]);
        }
    }

    //创建账单
    public function addAccountBudget($type_id, $order_code, $no, $type_source, $scene, $amount, $account_id)
    {
        $accountBudget = new AccountBudget;
        $accountBudget->loadDefaultValues();
        $accountBudget->type = 1;
        $accountBudget->type_id = $type_id;
        $accountBudget->order_code = $order_code;
        $accountBudget->no = $no;
        $accountBudget->type_source = $type_source;
        $accountBudget->scene = $scene;
        $accountBudget->describe = "系统计算分账";
        $accountBudget->amount = $amount;
        $accountBudget->account_id = $account_id;

        if (!$accountBudget->save()) {
            return false;
        }
        return true;
    }

    public function check_price($price, $fen_price)
    {
        //如果分账金额大于总金额的50%, 将大于部分分到$b_price
        //$price        总金额
        //$fen_price   分账金额
        //$price50  50%
        //$a_price  主要部分
        //$b_price  余下部分


        $price50 = round($price * 0.5, 2);
        if ($fen_price > $price50) {
            $a_price = $price50;
            $b_price = $fen_price - $price50;
            return ['a_price' => $a_price, 'b_price' => $b_price];
        } else {
            $a_price = $fen_price;
            $b_price = 0;
            return ['a_price' => $a_price];
        }
    }
}

  

原文地址:https://www.cnblogs.com/gaogaoxingxing/p/13685748.html