Bootstrap

微信服务商分账

一、前言

这里我们还是用微信服务商V3版本做分账接口,上篇文章已经说了怎么安装微信v3版本的sdk。
废话不多说直接上代码

二、服务商分账demo

	//添加分账接收方
   public function add()
    {
        /*判断请求类型(GET、POST、PUT、DELETE)*/
        switch (strtolower($this->request->method())){
			/*
			*接口参数请查看微信文档
			*微信文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_8.shtml
			*/
            case "post":
                /*接收接口请求参数*/
                $account =   input('param.account')   ?   input('param.account')  : '';
                $type =   input('param.type')   ?   input('param.type')  : '';
                $name =   input('param.name')   ?   input('param.name')  : '';
                $sub_mchid =   input('param.sub_mchid')   ?   input('param.sub_mchid')  : '';

                if($account){
                    $this->initialization();
                    $platformCertificateFilePath = './cert/cert.pem';
                    // 加载平台证书
                    $platformCertificateInstance = PemUtil::loadCertificate($platformCertificateFilePath);
                    // 解析平台证书序列号
                    $platformCertificateSerial = PemUtil::parseCertificateSerialNo($platformCertificateInstance);
                    $encryptor = function($msg) use ($platformCertificateInstance) { return Rsa::encrypt($msg, $platformCertificateInstance); };
                    try {
                        $resp = $this->instance->v3->profitsharing->receivers->add->post(['json' => [
                            'sub_mchid'=>'子商户号',
                            'appid'=>'微信分配的公众账号ID',
                            //'sub_appid' => '',
                            'type' => 'MERCHANT_ID',
                            'account' => $account,//分账接收方账号
                            'relation_type' => 'SERVICE_PROVIDER',//与分账方的关系类型
                            'name'=>$encryptor($name)
                            //'custom_relation'=>'代理商'
                        ],
                            'headers' => [
                                // $platformCertificateSerial 见初始化章节
                                'Wechatpay-Serial' => $platformCertificateSerial,
                            ]
                        ]);

                        if($resp->getStatusCode() == 200 && $resp->getReasonPhrase() == 'OK'){
                            $this->code = 0;
                            $this->msg = '成功';
                            $this->ret_data = json_decode($resp->getBody()->getContents(),true);
                        }
                        /*echo $resp->getStatusCode() . ' ' . $resp->getReasonPhrase(), PHP_EOL;
                        echo $resp->getBody(), PHP_EOL;*/
                    } catch (\Exception $e) {
                        // 进行错误处理
                        //echo $e->getMessage(), PHP_EOL;
                        $this->msg = '接口异常,请稍后重试';
                        if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
                            $r = $e->getResponse();
                            //echo $r->getStatusCode() . ' ' . $r->getReasonPhrase(), PHP_EOL;
                            //$this->msg = json_decode($r->getBody()->getContents(),true)['message'];
                            $this->msg = json_decode($r->getBody()->getContents(),true)['message'];
                        }
                    }

                }else {
                    $this->msg  = "参数有误!";
                }
                break;

            default:
                $this->msg  = "请求方式错误";
                break;

        }
        /*定义接口返回数据*/
        $this->success($this->msg,$this->ret_data,$this->code,$this->total);
    }


	   /**
     * 服务商支付 删除分账接收方
     **/
    public function delete()
    {
        /*判断请求类型(GET、POST、PUT、DELETE)*/
        switch (strtolower($this->request->method())){
			/*
			*接口参数请查看微信文档
			*微信文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_9.shtml
			*/
            case "post":
                /*接收接口请求参数*/
                $account =   input('param.account')   ?   input('param.account')  : '';
                $type =   input('param.type')   ?   input('param.type')  : '';
                $sub_mchid =   input('param.sub_mchid')   ?   input('param.sub_mchid')  : '';

                if($account){
                    $this->initialization();
                    try {
                        $resp = $this->instance->v3->profitsharing->receivers->delete->post(['json' => [
                            'sub_mchid'=>'子商户号',
                            'appid'=>'微信分配的公众账号ID',
                            //'sub_appid' => 'wx4974463e06ab0355',
                            'type' => 'MERCHANT_ID',
                            'account' => $account,//分账接收方账号
                        ]
                        ]);

                        if($resp->getStatusCode() == 200 && $resp->getReasonPhrase() == 'OK'){
                            $this->code = 0;
                            $this->msg = '成功';
                            $this->ret_data = json_decode($resp->getBody()->getContents(),true);
                        }
                        /*echo $resp->getStatusCode() . ' ' . $resp->getReasonPhrase(), PHP_EOL;
                        echo $resp->getBody(), PHP_EOL;*/
                    } catch (\Exception $e) {
                        // 进行错误处理
                        //echo $e->getMessage(), PHP_EOL;
                        $this->msg = '接口异常,请稍后重试';
                        if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
                            $r = $e->getResponse();
                            //echo $r->getStatusCode() . ' ' . $r->getReasonPhrase(), PHP_EOL;
                            //$this->msg = json_decode($r->getBody()->getContents(),true)['message'];
                            $this->msg = json_decode($r->getBody()->getContents(),true)['message'];
                        }
                    }

                }else {
                    $this->msg  = "参数错误!";
                }
                break;

            default:
                $this->msg  = "请求方式错误";
                break;

        }
        /*定义接口返回数据*/
        $this->success($this->msg,$this->ret_data,$this->code,$this->total);
    }
	
	        /**
     * 服务商支付 请求分账
     **/
    public function split()
    {
        /*判断请求类型(GET、POST、PUT、DELETE)*/
        switch (strtolower($this->request->method())){
			/*
			*接口参数请查看微信文档
			*微信文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_1.shtml
			*/
            case "post":
                /*接收接口请求参数*/
                $account =   input('param.account')   ?   input('param.account')  : '';
                $amount =   input('param.amount')   ?   input('param.amount')  : '';
                $type =   input('param.type')   ?   input('param.type')  : '';
                $sub_mchid =   input('param.sub_mchid')   ?   input('param.sub_mchid')  : '';
                $transaction_id =   input('param.transaction_id')   ?   input('param.transaction_id')  : '';
                $out_order_no =   input('param.out_order_no')   ?   input('param.out_order_no')  : '';

                if($account){
                    $this->initialization();
                    try {
                        $resp = $this->instance->v3->profitsharing->orders->post(['json' => [
                            'sub_mchid'=>'子商户号',
                            'transaction_id' => $transaction_id,//微信订单号
                            'appid'=>'微信分配的服务商appid',
                            'sub_appid' => '子商户应用ID',
                            'out_order_no' => $out_order_no,
                            'receivers' => [[
                                'type' => 'MERCHANT_ID',
                                'account' => $account,
                                'amount' => $amount*100,
                                'description'=>'测试'
                            ]],
                            'unfreeze_unsplit'=> true,
                        ]]);

                        if($resp->getStatusCode() == 200 && $resp->getReasonPhrase() == 'OK'){
                            $this->code = 0;
                            $this->msg = '成功';
                            $this->ret_data = json_decode($resp->getBody()->getContents(),true);
                        }

                        /*echo $resp->getStatusCode() . ' ' . $resp->getReasonPhrase(), PHP_EOL;
                        echo $resp->getBody(), PHP_EOL;*/
                    } catch (\Exception $e) {
                        // 进行错误处理
                        //echo $e->getMessage(), PHP_EOL;
                        $this->msg = '接口异常,请稍后重试';
                        if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
                            $r = $e->getResponse();
                            //echo $r->getStatusCode() . ' ' . $r->getReasonPhrase(), PHP_EOL;
                            //$this->msg = json_decode($r->getBody()->getContents(),true)['message'];
                            $this->msg = json_decode($r->getBody()->getContents(),true)['message'];
                        }
                    }

                }else {
                    $this->msg  = "参数错误!";
                }
                break;

            default:
                $this->msg  = "请求方式错误";
                break;

        }
        /*定义接口返回数据*/
        $this->success($this->msg,$this->ret_data,$this->code,$this->total);
    }
    
 	/**
     * 服务商支付 查询分账结果
     **/
    public function splitQuery()
    {
        /*判断请求类型(GET、POST、PUT、DELETE)*/
        switch (strtolower($this->request->method())){
			/*
			*接口参数请查看微信文档
			*微信文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_2.shtml
			*/
            case "post":
                /*接收接口请求参数*/
                $transaction_id =   input('param.transaction_id')   ?   input('param.transaction_id')  : ''; //微信订单号
                $out_trade_no =   input('param.out_trade_no')   ?   input('param.out_trade_no')  : ''; //商户分账单号
                $sub_mchid =   input('param.sub_mchid')   ?   input('param.sub_mchid')  : ''; //子商户号

                if($transaction_id){
                    $this->initialization();
                    $res = $this->instance->v3->profitsharing->orders->{'{out_order_no}'}
                        ->getAsync([
                            // 查询参数结构
                            'query' => ['transaction_id'=>$transaction_id, 'sub_mchid'=>$sub_mchid],
                            // uri_template 字面量参数
                            'out_order_no' => $out_trade_no,

                        ])
                        ->then(static function($response) {
                            // 正常逻辑回调处理
                            /*echo $response->getStatusCode(),PHP_EOL;
                            echo $response->getReasonPhrase();
                            echo $response->getBody()->getContents(), PHP_EOL;*/
                            $data = [];
                            if($response->getStatusCode() == 200 && $response->getReasonPhrase() == 'OK'){

                                $data['code'] = 0;
                                $data['msg'] = '成功';
                                $data['list'] = json_decode($response->getBody()->getContents(),true);
                                return $data;
                            }

                        }) ->otherwise(static function($e) {
                            // 异常错误处理
                            //echo $e->getMessage();
                            $data = [];
                            $data['msg'] = '接口异常,请稍后重试';
                            if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
                                $r = $e->getResponse();
                                //echo $r->getStatusCode() . ' ' . $r->getReasonPhrase(), PHP_EOL;
                                //$this->msg = json_decode($r->getBody()->getContents(),true)['message'];
                                $data['msg'] = json_decode($r->getBody()->getContents(),true)['message'];
                                return $data;
                            }
                        })->wait();

                    if(!empty($res) && isset($res['list'])){
                        $this->code = $res['code'];
                        $this->msg = $res['msg'];
                        $this->ret_data = $res['list'];
                    }else{
                        $this->msg = $res['msg'];
                    }

                }else {
                    $this->msg  = "参数错误!";
                }
                break;

            default:
                $this->msg  = "请求方式错误";
                break;

        }
        /*定义接口返回数据*/
        $this->success($this->msg,$this->ret_data,$this->code,$this->total);
    }

	/**
     * 服务商支付 分账动账通知
     **/
    public function splitBack()
    {
        /*判断请求类型(GET、POST、PUT、DELETE)*/
        switch (strtolower($this->request->method())){
			/*
			*接口参数请查看微信文档
			*微信文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_10.shtml
			*/
            case "post":

                $statuscode = 500;
                $platformCertificateFilePath = '平台证书路径';
                // 加载平台证书
                $platformCertificateInstance = PemUtil::loadCertificate($platformCertificateFilePath);
                // 解析平台证书序列号
                $platformCertificateSerial = PemUtil::parseCertificateSerialNo($platformCertificateInstance);

                /*接收接口请求参数*/
                $response = file_get_contents('php://input');
                $data = json_decode(file_get_contents('php://input'),true);
                $signature = $this->request->header('Wechatpay-Signature');
                $timestamp = $this->request->header('Wechatpay-Timestamp');
                $nonce = $this->request->header('Wechatpay-Nonce');
                $serial = $this->request->header('Wechatpay-Serial');
                file_put_contents('./cert/back.log', "params_data:".$response."\n\r",FILE_APPEND);
                file_put_contents('./cert/back.log', "serial:".$serial."\n\r",FILE_APPEND);

                //平台证书序列号验证
                if ($serial == $platformCertificateSerial) {
                    //签名验证
                    if (Crypto\Rsa::verify(Formatter::response($timestamp, $nonce, $response), $signature, $platformCertificateInstance)) {
                        file_put_contents('./cert/back.log', "Rsa:".'签名验证成功'."\n\r",FILE_APPEND);
                        if(!empty($data) && $data['event_type'] == 'TRANSACTION.SUCCESS'){
                            $associated_data = $data['resource']['associated_data'];
                            $nonce = $data['resource']['nonce'];
                            $ciphertext = $data['resource']['ciphertext'];
                            $apiv3Key = 'JeO9MgDcxUOLOD1ZpvVXIwQaGVWyTPvu';
                            //var_dump($apiv3Key);die;
                            $list = AesGcm::decrypt($ciphertext, $apiv3Key, $nonce, $associated_data);
                            $list = json_decode($list,true);
                            if(!empty($list)){
                                //解密成功做业务逻辑代码
                                $statuscode = 200;
                                //var_dump($list);die;
                                $this->code = 'SUCCESS';
                                $this->msg = '成功';
                                file_put_contents('./cert/back.log', "msg:".'SUCCESS'."\n\r",FILE_APPEND);
                            }

                        }
                    }
                }

                break;

            default:
                $statuscode = 500;
                $this->msg  = "请求方式错误";
                break;

        }
        /*定义接口返回数据*/
        $this->success($this->msg,$this->ret_data,$this->code,$this->total,'',array('statuscode'=>$statuscode));
    }
	
	/**
     * 服务商支付 请求分账回退
     **/
    public function splitRefund()
    {
        /*判断请求类型(GET、POST、PUT、DELETE)*/
        switch (strtolower($this->request->method())){
			/*
			*接口参数请查看微信文档
			*微信文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_3.shtml
			*/
            case "post":
                /*接收接口请求参数*/
                $amount =   input('param.amount')   ?   input('param.amount')  : ''; //回退金额
                $out_order_no =   input('param.out_order_no')   ?   input('param.out_order_no')  : ''; //商户分账单号
                $sub_mchid =   input('param.sub_mchid')   ?   input('param.sub_mchid')  : ''; //子商户号
                $out_return_no =   input('param.out_return_no')   ?   input('param.out_return_no')  : '';//商户回退单号
                $return_mchid =   input('param.return_mchid')   ?   input('param.return_mchid')  : ''; //回退商户号

                if($amount){
                    $this->initialization();
                    try {
                        $resp = $this->instance->v3->profitsharing->returnOrders->post(['json' => [
                            'sub_mchid'=>$sub_mchid,//'1603045425',
                            'out_order_no' => $out_order_no,
                            'out_return_no' => $out_return_no,
                            'return_mchid' => $return_mchid,
                            'amount'=>$amount*100,
                            'description' => '测试',
                        ]
                        ]);

                        if($resp->getStatusCode() == 200 && $resp->getReasonPhrase() == 'OK'){
                            $this->code = 0;
                            $this->msg = '成功';
                            $this->ret_data = json_decode($resp->getBody()->getContents(),true);
                        }
                        /*echo $resp->getStatusCode() . ' ' . $resp->getReasonPhrase(), PHP_EOL;
                        echo $resp->getBody(), PHP_EOL;*/
                    } catch (\Exception $e) {
                        // 进行错误处理
                        //echo $e->getMessage(), PHP_EOL;
                        $this->msg = '接口异常,请稍后重试';
                        if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
                            $r = $e->getResponse();
                            //echo $r->getStatusCode() . ' ' . $r->getReasonPhrase(), PHP_EOL;
                            //$this->msg = json_decode($r->getBody()->getContents(),true)['message'];
                            $this->msg = json_decode($r->getBody()->getContents(),true)['message'];
                        }
                    }

                }else {
                    $this->msg  = "参数错误!";
                }
                break;

            default:
                $this->msg  = "请求方式错误";
                break;

        }
        /*定义接口返回数据*/
        $this->success($this->msg,$this->ret_data,$this->code,$this->total);
    }
	

大致就是这些方法吧。

;