123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- <?php
- namespace App\Handlers;
- use App\Models\EcommerceBillW;
- use Illuminate\Console\Command;
- use Illuminate\Support\Facades\Log;
- class EcommerceBillHandler extends Command
- {
- //获取二级商户资金账单
- public function getecommercebill($bill_date,$account_type,$algorithm){
- $url='https://api.mch.weixin.qq.com/v3/ecommerce/bill/fundflowbill?bill_date='.$bill_date.'&account_type='.$account_type.'&algorithm='.$algorithm;
- $merchant_id=config('wechat.payment.default.mch_id');//商户号
- $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号
- $handle=new SignHandler();
- $mch_private_key=$handle->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文
- $timestamp=time();//时间戳
- $nonce=$handle->nonce_str();//随机字符串
- $body="";
- $sign=$handle->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名
- $header=[
- 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign,
- 'Accept:application/json',
- 'User-Agent:' . $merchant_id,
- 'Content-Type:application/json',
- 'Wechatpay-Serial:' . $handle->getzhengshu()//获取平台证书序列号
- ];
- $result=$handle->curl($url,'',$header,'GET');
- $res=json_decode($result,true);
- if(!array_key_exists('download_bill_list', $res)){
- Log::info($res);
- return $res;
- }
- Log::info($bill_date.'下载资金账单,页数为'.count($res['download_bill_list']));
- foreach($res['download_bill_list'] as $key=>$val){
- $ciphertext= $this->down($val['download_url']);
- $key=$this->getDecrypt($val['encrypt_key'],'',$val['nonce']);
- $result_str=$this->decryptToString('',$val['nonce'],base64_encode($ciphertext),$key);
- $res_arr=$this->deal_ecommerce_bill($result_str);
- $bill_day = $res_arr['bill'][0]['bill_date'];
- $trade_info = EcommerceBillW::where('bill_date',$bill_day)->first();
- if(!$trade_info){
- if(count($res_arr['bill']) > 1000){
- $arr = array_chunk($res_arr['bill'],1000);
- foreach($arr as $k=>$v){
- EcommerceBillW::insert($v);
- }
- }else{
- EcommerceBillW::insert($res_arr['bill']);
- }
- }
- }
- return $res;
- }
- public function down($url){
- $merchant_id=config('wechat.payment.default.mch_id');//商户号
- $serial_no=config('wechat.payment.default.serial_no');//不是平台证书序列号
- $handle=new SignHandler();
- $mch_private_key=$handle->getPublicKey();//读取商户api证书公钥 getPublicKey()获取方法 见下文
- $timestamp=time();//时间戳
- $nonce=$handle->nonce_str();//随机字符串
- $body="";
- $sign=$handle->sign($url,'GET',$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no);//签名
- $header=[
- 'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $sign,
- 'Accept:application/json',
- 'User-Agent:' . $merchant_id,
- 'Content-Type:application/json',
- 'Wechatpay-Serial:' . $handle->getzhengshu()//获取平台证书序列号
- ];
- $result=$handle->curl($url,'',$header,'GET');
- return $result;
- }
- //解密数据
- public function getDecrypt($ciphertext, $associatedData, $nonceStr){
- $mch_private_key= file_get_contents(config('wechat.payment.default.key_path'));
- // Log::info($mch_private_key);
- $str = base64_decode($ciphertext);
- openssl_private_decrypt($str,$encrypted,$mch_private_key,OPENSSL_PKCS1_OAEP_PADDING);
- return $encrypted;
- }
- //解密返回的信息
- public function decryptToString($associatedData,$nonceStr,$ciphertext,$aesKey){
- if (strlen($aesKey) != 32) {
- throw new InvalidArgumentException('无效的ApiV3Key,长度应为32个字节');
- }
- $ciphertext=\base64_decode($ciphertext);
- if (strlen($ciphertext) <= 16) {
- return false;
- }
- if (function_exists('\sodium_crypto_aead_aes256gcm_is_available') &&
- \sodium_crypto_aead_aes256gcm_is_available()) {
- return \sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $aesKey);
- }
- // ext-libsodium (need install libsodium-php 1.x via pecl)
- if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') &&
- \Sodium\crypto_aead_aes256gcm_is_available()) {
- return \Sodium\crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $aesKey);
- }
- // if(function_exists('\sodium_crypto_aead_aes256gcm_is_available')&& \sodium_crypto_aead_aes256gcm_is_available()){
- // return \sodium_crypto_aead_aes256gcm_decrypt($ciphertext,$associatedData,$nonceStr,$aesKey);
- // }
- if(PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())){
- $ctext=substr($ciphertext,0,-16);
- $authTag=substr($ciphertext,-16);
- return \openssl_decrypt(
- $ctext,
- 'aes-256-gcm',
- $aesKey,
- \OPENSSL_RAW_DATA,
- $nonceStr,
- $authTag,
- $associatedData
- );
- }
- throw new \RuntimeException('php7.1');
- }
- public function deal_ecommerce_bill($response){
- $result = array();
- $response = str_replace(","," ",$response);
- $response = explode(PHP_EOL, $response);
- foreach ($response as $key=>$val){
- if(strpos($val, '`') !== false){
- $data = explode('`', $val);
- array_shift($data); // 删除第一个元素并下标从0开始
- if(count($data) == 13){ // 处理账单数据
- $result['bill'][] = array(
- 'bill_time' => $data[0], // 记账时间
- 'wx_order_no' => $data[1], // 微信支付业务单号
- 'fee_order_no' => $data[2], // 资金流水单号
- 'bill_name' => $data[3], // 业务名称
- 'bill_type' => $data[4], // 业务类型
- 'fee_type' => $data[5], // 收支类型
- 'amount' => $data[6], // 收支金额(元)
- 'account_fee' => $data[7], // 账户结余(元)
- 'apply_name' => $data[8], // 资金变更提交申请人
- 'remark' => $data[9], // 备注
- 'bill_cre_no' => $data[10], // 业务凭证号
- 'sub_mch_id' => $data[11], // 电商二级商户号
- 'account_type' => $data[12], // 账户类型
- 'bill_date' => date("Y-m-d", strtotime($data[0]))
- );
- }
- if(count($data) == 1){ // 统计数据
- $result['summary'] = array(
- 'order_num' => $data[0], // 资金流水总笔数
- );
- }
- }
- }
- return $result;
- }
- }
|