123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471 |
- <?php
- namespace App\Http\Controllers\Api\Traits;
- use App\Jobs\System\CheckBatchCahceDataLossJob;
- use App\Models\Shop\WxShopOrder;
- use App\Models\User\WxUser;
- use App\Models\User\WxUserWithdrawal;
- use App\Models\WxOrder;
- use App\Wen\Utils\Settings;
- use App\Wen\Utils\UserUtils;
- use Yansongda\Pay\Pay;
- use App\Wen\Utils\Utils;
- use App\Lib\Pay\EPay;
- use Illuminate\Support\Facades\Cache;
- use SimpleSoftwareIO\QrCode\Facades\QrCode;
- use Yansongda\Pay\Plugin\Wechat\Fund\Transfer\QueryBatchIdPlugin;
- trait PayTrait{
- public function transferBatchQuery($provider, $batch_id, $need_query_detail = false){
- if($provider == 'wxpay'){
- $config = json_decode(Cache::get('app_pay_config'), true);
- if(_empty_($config)){
- CheckBatchCahceDataLossJob::dispatch();
- }
- $pay = Pay::wechat($config);
- $plugins = $pay->mergeCommonPlugins([QueryBatchIdPlugin::class]);
- // need_query_detail:【是否查询转账明细单】 true-是;false-否,默认否。商户可选择是否查询指定状态的转账明细单,当转账批次单状态为“FINISHED”(已完成)时,才会返回满足条件的转账明细单
- $result = $pay->pay($plugins ,['batch_id' => $batch_id, 'need_query_detail' => true, 'detail_status' => 'ALL']);
- $result_arr = $result->toArray();
- if(!_empty_(_array_key($result_arr, 'transfer_batch', ''))){
- // 查询成功
- return $result_arr;
- }else{
- if(_array_key($result_arr, 'code', '') == 'NOT_FOUND'){
- WxUserWithdrawal::whereIn('wx_batch_id', $batch_id)->where('state', 3)->update([
- 'state' => 2,
- 'refuse_tip' => '查询的转账批次单不存在',
- ]);
- }else{
- _logger_(__file__, __line__, '微信商家转账到零钱-查询批次单失败-批次号'.$batch_id.'-:'.json_encode($result_arr, JSON_UNESCAPED_UNICODE));
- UserUtils::assistant_notice('admin', '微信商家转账到零钱失败-查询批次单失败-批次号'.$batch_id.'-:'.json_encode($result_arr, JSON_UNESCAPED_UNICODE));
- }
- return null;
- }
- }else{
- throw new \Exception('暂时未实现');
- }
- }
- /**
- * @param $provider
- * @param $pay_type
- * @param $list
- * 'transfer_detail_list' => [
- [
- 'out_detail_no' => (string)(time() + 5), // 商家明细单号
- 'transfer_amount' => 0.1 * 100, // 转账金额
- 'transfer_remark' => '商家付款到零钱', // 单条转账备注(微信用户会收到该备注)
- 'openid' => 'ozxxxxxxxxxx', // 转账用户的 openid
- ],
- ],
- * @param $batch_name 余额提现
- * @param $batch_remark 平台转账到用户微信零钱
- * @throws \Exception
- */
- public function transferBatch($provider, $pay_type, $list, $batch_name = '余额提现', $batch_remark = '平台转账到用户微信零钱'){
- $total_amount = 0;
- if(!_empty_($list)){
- foreach ($list as $item){
- $total_amount += $item['transfer_amount'];
- }
- }
- if($provider == 'wxpay'){
- $config = json_decode(Cache::get('app_pay_config'), true);
- if(_empty_($config)){
- CheckBatchCahceDataLossJob::dispatch();
- }
- if($pay_type == 'app'){
- $appid = Settings::get('app_app_id', '');
- }else if($pay_type == 'mp'){
- $appid = Settings::get('mp_app_id', '');
- }else if($pay_type == 'mini'){
- $appid = Settings::get('app_id', '');
- }else{
- $appid = Settings::get('app_id', '');
- }
- $result = Pay::wechat($config)->transfer([
- 'appid' => $appid, // 微信小程序的app_id
- 'out_batch_no' => (string)time(), // 商家批次单号
- 'batch_name' => $batch_name, // 该笔批量转账的名称
- 'batch_remark' => $batch_remark, // 转账说明
- 'total_amount' => (int)$total_amount, // 转账金额,单位:分
- 'total_num' => count($list), // 转账总笔数
- 'transfer_detail_list' => $list,
- ]);
- $result_arr = $result->toArray();
- if(!_empty_(_array_key($result_arr, 'batch_id', ''))){
- // 转账成功
- return _array_key($result_arr, 'batch_id', '');
- }else{
- if(_array_key($result_arr, 'code', '') == 'NOT_ENOUGH'){
- throw new \Exception('资金不足');
- }
- _logger_(__file__, __line__, '微信商家转账到零钱(总'. ($total_amount/100) .'元)失败:'.json_encode($result_arr, JSON_UNESCAPED_UNICODE));
- UserUtils::assistant_notice('admin', '微信商家转账到零钱(总'. ($total_amount/100) .'元)失败:'.json_encode($result_arr, JSON_UNESCAPED_UNICODE));
- return null;
- }
- }else if($provider == 'alipay'){
- throw new \Exception('暂时未实现');
- $config = json_decode(Cache::get('app_pay_config'), true);
- if(_empty_($config)){
- CheckBatchCahceDataLossJob::dispatch();
- }
- if($pay_type == 'app'){
- }else if($pay_type == 'mp'){
- }else if($pay_type == 'mini'){
- }
- $order = [
- 'out_biz_no' => time(),
- 'trans_amount' => 0.1,
- 'product_code' => 'TRANS_ACCOUNT_NO_PWD',
- 'payee_info' => [
- 'identity' => 'ghdhjw7124@sandbox.com',
- 'name' => '张三',
- 'identity_type' => 'ALIPAY_LOGON_ID',
- ],
- 'remark'=>'赔付金'//相当于转账里面的备注
- ];
- $result = Pay::alipay($config)->transfer($order);
- }
- }
- /**
- * @param $uid
- * @param $provider
- * @param $pay_type
- * @param $total_fee
- * @param $body
- * @param $out_trade_no
- * @param int $order_type 1: 普通订单 2:商城订单
- * @return \Illuminate\Http\JsonResponse
- */
- public function payHandler($uid, $provider, $pay_type, $total_fee, $body, $out_trade_no, $order_type = 1){
- global $__MINI_GLOBAL_DEVICE__;
- if($__MINI_GLOBAL_DEVICE__ == 'h5'){
- if($provider == 'wxpay'){
- if($pay_type != 'mp' && $pay_type != 'h5'){
- $pay_type = 'h5';
- }
- }else{
- $pay_type = 'h5';
- }
- }
- if($provider == 'wxpay'){
- $config = json_decode(Cache::get('app_pay_config'), true);
-
- if(_empty_($config)){
- CheckBatchCahceDataLossJob::dispatch();
- }
- if($order_type == 1){
- $outTradeNoPre = Utils::outTradeNoPre($out_trade_no, 'wx_order_');
- }else{
- $outTradeNoPre = Utils::outTradeNoPre($out_trade_no, 'wx_shoporder_');
- }
- $config['wechat']['default']['return_url'] = route('pay.return', ['out_trade_no'=>$outTradeNoPre]);
- // 微信支付
- if($pay_type == 'app'){
- // $openid = WxUser::where('id', $uid)->value('weixin_app_openid');
- // 支付
- $order = [
- 'out_trade_no' => $out_trade_no,
- 'description' => $body,
- 'amount' => [
- 'total' => (int)($total_fee * 100),
- ],
- ];
- $pay_data = Pay::wechat($config)->app($order);
- $pay_data['query_state_no'] = $outTradeNoPre;
- if($order_type == 1){
- WxOrder::where('order_number', $out_trade_no)->update(['order_serial_platform_type'=>'app', 'order_serial_platform'=>0]);
- }else{
- WxShopOrder::where('order_id', $out_trade_no)->update(['serial_platform_type'=>'app', 'serial_platform'=>0]);
- }
- return $this->success($pay_data);
- }else if($pay_type == 'h5'){
- global $__MINI_GLOBAL_IP__;
- $order = [
- 'out_trade_no' => $out_trade_no,
- 'description' => $body,
- 'amount' => [
- 'total' => (int)($total_fee * 100),
- ],
- 'scene_info' => [
- 'payer_client_ip' => $__MINI_GLOBAL_IP__,
- 'h5_info' => [
- 'type' => 'Wap',
- ]
- ],
- ];
- $pay_data = Pay::wechat($config)->wap($order);
- $h5_url = $pay_data->h5_url;
- $cache_html = '<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="refresh" content="0;url='.$h5_url.'"> <title>Redirecting</title> </head> <body></body> </html>';
- $r = Cache::put($outTradeNoPre, $cache_html, $seconds = 300);
- if($r){
- if($order_type == 1){
- WxOrder::where('order_number', $out_trade_no)->update(['order_serial_platform_type'=>'h5', 'order_serial_platform'=>0]);
- }else{
- WxShopOrder::where('order_id', $out_trade_no)->update(['serial_platform_type'=>'h5', 'serial_platform'=>0]);
- }
- return $this->success(['direct'=>route('pay.direct', ['out_trade_no'=>$outTradeNoPre]), 'query_state_no'=>$outTradeNoPre]);
- }else{
- return $this->fail(200005, ['msg'=>'系统写入缓存时失败,请联系管理员']);
- }
- }else if($pay_type == 'yi') {
- $epay_config = json_decode(Cache::get('yi_pay_config'), true);
- if(_empty_($epay_config)){
- CheckBatchCahceDataLossJob::dispatch();
- }
- if($order_type == 1){
- $outTradeNoPre = Utils::outTradeNoPre($out_trade_no, 'yi_order_');
- }else{
- $outTradeNoPre = Utils::outTradeNoPre($out_trade_no, 'yi_shoporder_');
- }
- $return_url = route('pay.return', ['out_trade_no' => $outTradeNoPre]);
- $epay = new EPay();
- $epay->key($epay_config['app_secret']);
- // 发起订单
- try {
- $pay_data = $epay->pid($epay_config['app_id'])
- ->url($epay_config['provider_url'])
- ->outTradeNo($out_trade_no)
- ->type('wxpay')
- ->notifyUrl($epay_config['notify_url'])
- ->returnUrl($return_url)
- ->money($total_fee)
- ->name($body)
- ->sitename($epay_config['site'])
- ->submit()
- ->getHtmlForm();
- $r = Cache::put($outTradeNoPre, Utils::payDirectHtmlForApp('', $pay_data), $seconds = 300);
- if ($r) {
- if($order_type == 1){
- WxOrder::where('order_number', $out_trade_no)->update(['order_serial_platform_type'=>'yi', 'order_serial_platform'=>0]);
- }else{
- WxShopOrder::where('order_id', $out_trade_no)->update(['serial_platform_type'=>'yi', 'serial_platform'=>0]);
- }
- return $this->success(['direct' => route('pay.direct', ['out_trade_no' => $outTradeNoPre]), 'query_state_no' => $outTradeNoPre]);
- } else {
- return $this->fail(200005, ['msg' => '系统写入缓存时失败,请联系管理员']);
- }
- } catch (\Exception $e) {
- _logger_(__file__, __line__, $e->getMessage());
- return $this->fail(200006, ['msg' => '易支付生成订单出错']);
- }
- }else if($pay_type == 'code' || $pay_type == 'code_pc') {
- // native支付
- $order = [
- 'out_trade_no' => $out_trade_no,
- 'description' => $body,
- 'amount' => [
- 'total' => (int)($total_fee * 100),
- ],
- ];
- $pay_data = Pay::wechat($config)->scan($order);
- if($pay_data && $pay_data->code_url){
- if($order_type == 1){
- WxOrder::where('order_number', $out_trade_no)->update(['order_serial_platform_type'=>$pay_type, 'order_serial_platform'=>0]);
- }else{
- WxShopOrder::where('order_id', $out_trade_no)->update(['serial_platform_type'=>$pay_type, 'serial_platform'=>0]);
- }
- return $this->success(['url'=>$pay_data->code_url, 'code'=>QrCode::size(300)->generate($pay_data->code_url), 'query_state_no'=>$outTradeNoPre]);
- }
- return $this->fail(200006, $pay_data);
- }else if($pay_type == 'mp') {
- $order = [
- 'out_trade_no' => $out_trade_no,
- 'description' => $body,
- 'amount' => [
- 'total' => (int)($total_fee * 100),
- ],
- 'payer' => [
- 'openid' => WxUser::where('id', $uid)->value('weixin_mp_openid'),
- ],
- ];
- _logger_(__file__, __line__, '111111111111111111');
- try {
- $result = Pay::wechat($config)->mp($order);
- if($result && $result->paySign){
- if($order_type == 1){
- WxOrder::where('order_number', $out_trade_no)->update(['order_serial_platform_type'=>'mp', 'order_serial_platform'=>0]);
- }else{
- WxShopOrder::where('order_id', $out_trade_no)->update(['serial_platform_type'=>'mp', 'serial_platform'=>0]);
- }
- // todo优化: 返回二维码,以及url 微信文档:https://pay.weixin.qq.com/docs/merchant/apis/jsapi-payment/jsapi-transfer-payment.html
- _logger_(__file__, __line__, $result->toArray());
- return $this->success([
- 'appId' => $result->appId,
- 'timeStamp' => $result->timeStamp,
- 'nonceStr' => $result->nonceStr,
- 'package' => $result->package,
- 'signType' => $result->signType,
- 'paySign' => $result->paySign,
- 'prepayid' => $result->prepayid,
- 'query_state_no' => $outTradeNoPre
- ]);
- }
- }catch (\Exception $e){
- _logger_(__file__, __line__, $e->getMessage());
- return $this->fail(200006);
- }
- }else if($pay_type == 'mini') {
- $order = [
- 'out_trade_no' => $out_trade_no,
- 'description' => $body,
- 'amount' => [
- 'total' => (int)($total_fee * 100),
- 'currency' => 'CNY',
- ],
- 'payer' => [
- 'openid' => WxUser::where('id', $uid)->value('weixin_openid'),
- ],
- ];
- try {
- $result = Pay::wechat($config)->mini($order);
- if($result && $result->paySign){
- if($order_type == 1){
- WxOrder::where('order_number', $out_trade_no)->update(['order_serial_platform_type'=>'mini', 'order_serial_platform'=>0]);
- }else{
- WxShopOrder::where('order_id', $out_trade_no)->update(['serial_platform_type'=>'mini', 'serial_platform'=>0]);
- }
- // todo优化: 返回二维码,以及url 微信文档:https://pay.weixin.qq.com/docs/merchant/apis/jsapi-payment/jsapi-transfer-payment.html
- return $this->success([
- 'appId' => $result->appId,
- 'timeStamp' => $result->timeStamp,
- 'nonceStr' => $result->nonceStr,
- 'package' => $result->package,
- 'signType' => $result->signType,
- 'paySign' => $result->paySign,
- 'query_state_no' => $outTradeNoPre
- ]);
- }
- }catch (\Exception $e){
- _logger_(__file__, __line__, $e->getMessage());
- return $this->fail(200006);
- }
- }
- }else if($provider == 'alipay'){
- $config = json_decode(Cache::get('app_pay_config'), true);
- if(_empty_($config)){
- CheckBatchCahceDataLossJob::dispatch();
- }
- if($order_type == 1){
- $outTradeNoPre = Utils::outTradeNoPre($out_trade_no, 'ali_order_');
- }else{
- $outTradeNoPre = Utils::outTradeNoPre($out_trade_no, 'ali_shoporder_');
- }
- $config['alipay']['default']['return_url'] = route('pay.return', ['out_trade_no'=>$outTradeNoPre]);
- $config['alipay']['default']['notify_url'] = env('APP_URL'). '/api/v1/app/ali/notify/app';
- // 支付宝支付
- if($pay_type == 'app'){
- $order = [
- 'out_trade_no' => $out_trade_no,
- 'total_amount' => $total_fee,
- 'subject' => $body,
- ];
- if($order_type == 1){
- WxOrder::where('order_number', $out_trade_no)->update(['order_serial_platform_type'=>'app', 'order_serial_platform'=>1]);
- }else{
- WxShopOrder::where('order_id', $out_trade_no)->update(['serial_platform_type'=>'app', 'serial_platform'=>1]);
- }
- return Pay::alipay($config)->app($order);
- // $pay_data->query_state_no = $outTradeNoPre;
- }else if($pay_type == 'h5'){
- $config['alipay']['default']['notify_url'] = env('APP_URL'). '/api/v1/app/ali/notify/wap';
- $order = [
- 'out_trade_no' => $out_trade_no,
- 'total_amount' => $total_fee,
- 'subject' => $body,
- 'quit_url' => env('APP_URL'),
- ];
- $pay_data = Pay::alipay($config)->wap($order);
- $pay_data = $pay_data->getBody();
- $r = Cache::put($outTradeNoPre, Utils::payDirectHtmlForApp('', $pay_data), $seconds = 300);
- if($r){
- if($order_type == 1){
- WxOrder::where('order_number', $out_trade_no)->update(['order_serial_platform_type'=>'h5', 'order_serial_platform'=>1]);
- }else{
- WxShopOrder::where('order_id', $out_trade_no)->update(['serial_platform_type'=>'h5', 'serial_platform'=>1]);
- }
- return $this->success(['direct'=>route('pay.direct', ['out_trade_no'=>$outTradeNoPre]), 'query_state_no'=>$outTradeNoPre]);
- }else{
- return $this->fail(200005, ['msg'=>'系统写入缓存时失败,请联系管理员']);
- }
- }else if($pay_type == 'yi') {
- $epay_config = json_decode(Cache::get('yi_pay_config'), true);
- if(_empty_($epay_config)){
- CheckBatchCahceDataLossJob::dispatch();
- }
- if($order_type == 1){
- $outTradeNoPre = Utils::outTradeNoPre($out_trade_no, 'yi_order_');
- }else{
- $outTradeNoPre = Utils::outTradeNoPre($out_trade_no, 'yi_shoporder_');
- }
- $return_url = route('pay.return', ['out_trade_no' => $outTradeNoPre]);
- $epay = new EPay();
- $epay->key($epay_config['app_secret']);
- // 发起订单
- try {
- $pay_data = $epay->pid($epay_config['app_id'])
- ->url($epay_config['provider_url'])
- ->outTradeNo($out_trade_no)
- ->type('alipay')
- ->notifyUrl($epay_config['notify_url'])
- ->returnUrl($return_url)
- ->money($total_fee)
- ->name($body)
- ->sitename($epay_config['site'])
- ->submit()
- ->getHtmlForm();
- $r = Cache::put($outTradeNoPre, Utils::payDirectHtmlForApp('', $pay_data), $seconds = 300);
- if ($r) {
- if($order_type == 1){
- WxOrder::where('order_number', $out_trade_no)->update(['order_serial_platform_type'=>'yi', 'order_serial_platform'=>1]);
- }else{
- WxShopOrder::where('order_id', $out_trade_no)->update(['serial_platform_type'=>'yi', 'serial_platform'=>1]);
- }
- return $this->success(['direct' => route('pay.direct', ['out_trade_no' => $outTradeNoPre]), 'query_state_no' => $outTradeNoPre]);
- } else {
- return $this->fail(200005, ['msg' => '系统写入缓存时失败,请联系管理员']);
- }
- } catch (\Exception $e) {
- _logger_(__file__, __line__, $e->getMessage());
- return $this->fail(200006, ['msg' => '易支付生成订单出错']);
- }
- }else if($pay_type == 'code' || $pay_type == 'code_pc') {
- $order = [
- 'out_trade_no' => $out_trade_no,
- 'total_amount' => $total_fee,
- 'subject' => $body,
- ];
- $pay_data = Pay::alipay($config)->scan($order);
- if($pay_data && $pay_data->code_url){
- if($order_type == 1){
- WxOrder::where('order_number', $out_trade_no)->update(['order_serial_platform_type'=>$pay_type, 'order_serial_platform'=>1]);
- }else{
- WxShopOrder::where('order_id', $out_trade_no)->update(['serial_platform_type'=>$pay_type, 'serial_platform'=>1]);
- }
- return $this->success(['url'=>$pay_data->code_url, 'code'=>QrCode::size(300)->generate($pay_data->code_url), 'query_state_no'=>$outTradeNoPre]);
- }
- return $this->fail(200006, $pay_data);
- }
- }
- }
- }
|