admin 发表于 2026-5-21 14:31:51

fastadmin支付插件中使用v3支付的方法

当前微信支付宝整合插件中微信支付v3配置仍需要配置v2证书,否则v3支付失败,这可能是个bug,等官方后续更新。

v3微信支付需要配置的参数包括:

我们在需要调用V3支付的地方执行:
set_addon_config('epay', ['version'=>'v3'], false);将支付版本改为使用V3。
1、需要使用到的支付类:
use addons\epay\library\Service;
use Yansongda\Pay\Exceptions\BusinessException;
use Yansongda\Pay\Exceptions\GatewayException;
use Yansongda\Pay\Exceptions\InvalidSignException;
use addons\epay\library\Collection;
use GuzzleHttp\Psr7\Response;2、构造支付参数发起支付:
// 支付参数
                $pay_params = [
                  'amount'    => $order->payfee,
                  'orderid'   => $order->ordersn,
                  'type'      => 'wechat',
                  'title'   => '商城购买商品消费',
                  'returnurl' => null,
                  'method'    => 'miniapp',
                  'openid'    => $third->openid
                ];
                // 回调通知地址
                $pay_params['notifyurl'] = $this->request->root(true) . "/addons/eshop/api.goods/notify";
                \think\Log::record($pay_params);
                // 调用支付
                try {
                  $response = Service::submitOrder($pay_params);
                  \think\Log::record($response);
                  $this->success('请求成功', $response);
                } catch (BusinessException|GatewayException|InvalidSignException|Collection $e) {
                  \think\Log::record($e);
                  $this->error($e->getMessage());
                }3、支付回调通知:
public function notify()
    {
      $params = $this->request->param();
      \think\Log::record($params);
      $pay = Service::checkNotify('wechat');
      if (!$pay) {
            echo '签名错误';
            return;
      }
      \think\Log::record(Service::isVersionV3());
      $data = Service::isVersionV3() ? $pay->callback() : $pay->verify();
      \think\Log::record($data);
      $notifydata = json_decode($data, true);
      try {
            // 订单表单
            $orderdata = [
                'paytype' => 2,
                'paytime' => time(),
                'status' => 1
            ];
            if (Service::isVersionV3()) {
                $out_trade_no = $notifydata['resource']['ciphertext']['out_trade_no'];
                $orderdata['transid'] = $notifydata['resource']['ciphertext']['transaction_id'];
                $orderdata['cash'] = $notifydata['resource']['ciphertext']['amount']['payer_total'] / 100;
                $orderdata['realpayfee'] = $notifydata['resource']['ciphertext']['amount']['payer_total'] / 100;
            } else {
                $out_trade_no = $data->out_trade_no;
                $orderdata['cash'] = $data->total_fee / 100;
                $orderdata['transid'] = $data->transaction_id;
                $orderdata['realpayfee'] = $data->total_fee / 100;
            }
            // 查询订单
            $order = Order::where(['ordersn'=>$out_trade_no])->find();
            // 待付款的才可以执行
            if ($order->status == 0) {
                // 更新订单
                $result = Order::update($orderdata, ['id'=>$order->id]);
                if ($result) {
                  // 处理订单商品状态
                  $ordergoods = Ordergoods::where(['order_id'=>$order->id])->find();
                  if ($ordergoods) {
                        $ordergoods->allowField(true)->save(['status'=>1]);
                  }
                  // 积分兑换处理积分
                  if ($order->paystyle == 1) {
                        User::score(-$order->score, $order->user_id, '商城购买商品消费');
                  }
                  // 商品/规格信息
                  if ($ordergoods->option_id) {
                        // 规格
                        $option = Option::get($ordergoods->option_id);
                        if (!empty($option)) {
                            // 更新库存
                            $stock = $option->stock - $ordergoods->total;
                            $option->allowField(true)->save(['stock'=>$stock]);
                        }
                  } else {
                        // 商品
                        $goods = Goods::get($ordergoods->goods_id);
                        if (!empty($goods)) {
                            // 更新库存
                            $stock = $goods->stock - $ordergoods-total;
                            $goods->allowField(true)->save(['stock'=>$stock]);
                        }
                  }
                }
            }
      } catch (Exception $e) {
            $this->error($e->getMessage());
      }
      //下面这句必须要执行,且在此之前不能有任何输出
      if (Service::isVersionV3()) {
            return $pay->success()->getBody()->getContents();
      } else {
            return $pay->success()->send();
      }
    }4、退款:
use Yansongda\Pay\Pay;
use addons\epay\library\Service;
use Yansongda\Pay\Exceptions\BusinessException;
use fast\Random;public function refund($ids = null)
    {
      $row = $this->model->get($ids);
      if (!$row) {
            $this->error(__('No Results were found'));
      }
      $adminIds = $this->getDataLimitAdminIds();
      if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
            $this->error(__('You have no permission'));
      }
      if (false === $this->request->isPost()) {
            $this->view->assign('row', $row);
            return $this->view->fetch();
      }
      $params = $this->request->post('row/a');
      if (empty($params)) {
            $this->error(__('Parameter %s can not be empty', ''));
      }
      $params = $this->preExcludeFields($params);
      // \think\Log::record($params);
      if ($row->status < 1 || $row->status > 3) {
            $this->error('当前订单状态不允许退款');
      }
      // 判断退款金额
      if (bccomp($params['refundfee'], $row->realpayfee, 2) > 0) {
            // \think\Log::record('退款金额不得高于支付金额');
            $this->error('退款金额不得高于支付金额');
      }
      if (bccomp($params['refundfee'], '0.00', 2) <= 0) {
            // \think\Log::record('退款金额不合法');
            $this->error('退款金额不合法');
      }
      // 积分+现金支付
      if ($row->paystyle == 1) {
            if (bccomp($params['refundscore'], $row->score, 0) > 0) {
                // \think\Log::record('退款金额不得高于支付金额');
                $this->error('退款积分不得高于支付积分');
            }
            if (bccomp($params['refundscore'], '0', 0) <= 0) {
                // \think\Log::record('退款金额不合法');
                $this->error('退款积分不合法');
            }
      }
      
      // 退款单号
      $params['refundsn'] = 'T'.date('YmdHis').Random::numeric();
      // 退款时间
      $params['refundtime'] = time();
      // 退款状态
      $params['status'] = 5;
      // 支付方式
      if ($row->paytype == 1) {
            // \think\Log::record($params);
            // 余额支付
            User::money($params['refundfee'], $row->user_id, '商城购物订单退款');
            // 退回积分
            if ($params['refundscore'] > 0) {
                User::score($params['refundscore'], $row->user_id, '商城购物订单退款');
            }
            // 更新订单状态
            $result = $row->allowField(true)->save($params);
            // \think\Log::record($result);
            if ($result) {
                $this->success('退款成功');
            }
            $this->error('退款失败,请核实用户余额和积分记录');
      } elseif ($row->paytype == 2) {
            $result = false;
            Db::startTrans();
            // 退款参数
            $order = [
                '_action' => 'mini',
                'out_trade_no' => $row->ordersn,
                'out_refund_no' => $params['refundsn'],
                'amount' => [
                  'refund' => $params['refundfee'] * 100,
                  'total' => $row->realpayfee * 100,
                  'currency' => 'CNY',
                ],
                'reason' => $params['reason']
            ];
            $config = Service::getConfig('wechat');
            // \think\Log::record($config);
            $result = false;
            $erromsg = '退款成功';
            // 微信支付
            try {
                // 调用支付接口
                $ret = Pay::wechat($config)->refund($order);
                \think\Log::record($ret);
                $response = json_decode($ret, true);
                \think\Log::record($response);
                if ($response['status'] == 'SUCCESS' || $response['status'] == 'PROCESSING') {
                  // 支付平台退款单号
                  $params['refund_id'] = $response['refund_id'];
                  $result = $row->allowField(true)->save($params);
                  if ($result) {
                        // 退回积分
                        if ($params['refundscore'] > 0) {
                            User::score($params['refundscore'], $row->user_id, '商城购物订单退款');
                        }
                        Db::commit();
                  } else {
                        $erromsg = '退款成功,但订单状态更新失败,请核实用户积分记录!';
                  }
                } else {
                  $erromsg = '退款失败,请稍后重试!';
                }
            } catch (Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
            if (false === $result) {
                $this->error($erromsg);
            }
            $this->success($erromsg);
      }
    }

页: [1]
查看完整版本: fastadmin支付插件中使用v3支付的方法