diff --git a/app/admin/controller/Goods.php b/app/admin/controller/Goods.php index 7d2e55e4..2494cbfd 100644 --- a/app/admin/controller/Goods.php +++ b/app/admin/controller/Goods.php @@ -176,6 +176,8 @@ class Goods extends Controller 'delivery_time' => $goods_sku->delivery_time, 'is_use_jd_stock' => $goods_sku->is_use_jd_stock, 'is_jd_remove' => $goods_sku->is_jd_remove, + 'goods_no_other' => $goods_sku->goods_no_other, + 'link_other' => $goods_sku->link_other, // 'is_pool' => $goods_sku->is_pool, // 'is_sale' => $goods_sku->is_sale, 'update_time' => time(), diff --git a/app/api/controller/StoreKeeper.php b/app/api/controller/StoreKeeper.php index aa68e2d2..c7177a38 100644 --- a/app/api/controller/StoreKeeper.php +++ b/app/api/controller/StoreKeeper.php @@ -186,16 +186,29 @@ class StoreKeeper extends Controller { $params = $this->request->param(); $params['searchType'] = 'all'; + $goodsModel = new GoodsModel; // 订单列表 if (!empty($params['dataType']) && $params['dataType'] == 'refund') { $model = new OrderRefundModel; $list = $model->getNewList($params); + if (!empty($list['data'])) { + foreach ($list['data'] as $key => &$value) { + $goods_images = $goodsModel->storeUsePlatformGoodsImage(array_column($value['goods'], 'origin_goods_id')); + foreach ($value['goods'] as &$good) { + //使用总后台的商品图片 + if ($good['origin_goods_id'] && $value['store_id'] > 0) { + $good['goods_image'] = $goods_images[$good['origin_goods_id']][0]['file']['preview_url'] ?? ""; + } + } + } + } return $this->renderSuccess(compact('list')); } else { $model = new OrderModel; $list = $model->getNewList($params); + if (!empty($list['data'])) { - foreach ($list['data'] as $key => $value) { + foreach ($list['data'] as $key => &$value) { if (!empty($value['transfer']) && !empty($value['transfer']['chat_image_id'])) { $chat_image_ids = UploadFile::whereIn('file_id', explode(",", $value['transfer']['chat_image_id']))->field('file_id,file_path,file_type,storage,domain')->select(); foreach ($chat_image_ids as &$chat_image_id) { @@ -212,7 +225,14 @@ class StoreKeeper extends Controller } //复制信息 $copy_text = "订单号:{$value['order_no']}\n"; - foreach ($value['goods'] as $good) { + $goods_images = $goodsModel->storeUsePlatformGoodsImage(array_column($value['goods'], 'origin_goods_id')); + + foreach ($value['goods'] as &$good) { + //使用总后台的商品图片 + if ($good['origin_goods_id'] && $value['store_id'] > 0) { + $good['goods_image'] = $goods_images[$good['origin_goods_id']][0]['file']['preview_url'] ?? ""; + } + $copy_text .= "商品名称:{$good['goods_name']}\n"; if (!empty($good['goods_no'])) { $copy_text .= "商品编码:{$good['goods_no']}\n"; @@ -222,6 +242,7 @@ class StoreKeeper extends Controller $copy_text .= "总价:{$good['total_price']}\n"; $copy_text .= "\n"; } + if (!empty($value['address'])) { $copy_text .= "\n"; $copy_text .= "收件人:{$value['address']['name']}\n"; diff --git a/app/api/service/cashier/Payment.php b/app/api/service/cashier/Payment.php index 61edc504..de3cfff2 100644 --- a/app/api/service/cashier/Payment.php +++ b/app/api/service/cashier/Payment.php @@ -240,7 +240,7 @@ class Payment extends BaseService private function unifiedorder(array $extra = [], int $merchantId = null): array { // 判断支付方式是否合法 - if (!in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY])) { + if (!in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY, PaymentMethodEnum::HUIFU])) { return []; } // 生成第三方交易订单号 (并非主订单号) @@ -299,6 +299,12 @@ class Payment extends BaseService $extra['buyerId'] = $this->getAlipayBuyerId(); } } + if ($this->method === PaymentMethodEnum::HUIFU) { + // 微信小程序端和微信公众号端需要openid + if (in_array($this->client, [ClientEnum::WXOFFICIAL, ClientEnum::MP_WEIXIN])) { + $extra['openid'] = $this->getWechatOpenid(); + } + } return $extra; } diff --git a/app/common/enum/payment/Method.php b/app/common/enum/payment/Method.php index 0b1a1b02..f28368c3 100644 --- a/app/common/enum/payment/Method.php +++ b/app/common/enum/payment/Method.php @@ -30,6 +30,8 @@ class Method extends EnumBasics // 余额支付 const BALANCE = 'balance'; + const HUIFU = 'huifu'; + /** * 获取类型值 * @return array @@ -45,6 +47,10 @@ class Method extends EnumBasics 'name' => '支付宝', 'value' => self::ALIPAY, ], + self::ALIPAY => [ + 'name' => '汇支付', + 'value' => self::HUIFU, + ], self::BALANCE => [ 'name' => '余额支付', 'value' => self::BALANCE, diff --git a/app/common/library/payment/gateway/driver/Huifu.php b/app/common/library/payment/gateway/driver/Huifu.php new file mode 100644 index 00000000..cc3397fe --- /dev/null +++ b/app/common/library/payment/gateway/driver/Huifu.php @@ -0,0 +1,337 @@ + +// +---------------------------------------------------------------------- +declare (strict_types=1); + +namespace app\common\library\payment\gateway\driver; + +use app\common\library\payment\gateway\Driver; +use cores\exception\BaseException; + +# 加载 SDK 初始化文件 +require_once root_path() . "/vendor/huifurepo/dg-php-sdk/BsPaySdk/init.php"; +require_once root_path() . "/vendor/huifurepo/dg-php-sdk/BsPaySdk/request/V2TradePaymentJspayRequest.php"; +require_once root_path() . "/vendor/huifurepo/dg-php-sdk/BsPaySdk/request/V2MerchantBusiOpenRequest.php"; + +use BsPaySdk\core\BsPay; +use BsPaySdk\core\BsPayClient; +use BsPaySdk\request\V2TradePaymentJspayRequest; +use BsPaySdk\request\V2MerchantBusiOpenRequest; +use BsPaySdk\config\MerConfig; +use app\common\library\Log; +use app\common\enum\Client as ClientEnum; + +/** + * 微信支付驱动 + * Class Wechat + * @package app\common\library\payment\gateway\driver + */ +class Huifu extends Driver +{ + /** + * 设置支付宝配置信息(全局只需设置一次) + * @param array $options 支付宝配置信息 + * @param string $client 下单客户端 + * @return Driver|null + */ + public function setOptions(array $options, string $client): ?Driver + { + $this->client = $client ?: null; + $this->options = $options; + if ($options['mchType'] === 'provider') { + $config = [ + 'sys_id' => $options['provider']['sys_id'], + 'product_id' => $options['provider']['product_id'], + 'rsa_merch_private_key' => $options['provider']['rsa_merch_private_key'], + 'rsa_huifu_public_key' => $options['provider']['rsa_huifu_public_key'], + ]; + } else { + $config = [ + 'sys_id' => $options['normal']['sys_id'], + 'product_id' => $options['normal']['product_id'], + 'rsa_merch_private_key' => $options['normal']['rsa_merch_private_key'], + 'rsa_huifu_public_key' => $options['normal']['rsa_huifu_public_key'], + ]; + } + $this->merChantKey = $options['normal']['sys_id'].$options['normal']['product_id']; + BsPay::init($config, true, $this->merChantKey); + + return $this; + } + + /* 统一下单API + * @param string $outTradeNo 交易订单号 + * @param string $totalFee 实际付款金额 + * @param array $extra 附加的数据 (需要携带openid) + * @return bool + * @throws BaseException + */ + public function addReceiver(string $type, string $account, string $name, string $relation_type = "HEADQUARTER", string $custom_relation = ""): bool + { + + return true; + } + /** + * 统一下单API + * @param string $outTradeNo 交易订单号 + * @param string $totalFee 实际付款金额 + * @param array $extra 附加的数据 (需要携带openid) + * @return bool + * @throws BaseException + */ + public function profitsharing(string $transaction_id, string $out_order_no, array $receivers): bool + { + return true; + } + public function profitsharingQuery(string $out_order_no, string $transaction_id): ?array{ + return []; + } + /** + * 统一下单API + * @param string $outTradeNo 交易订单号 + * @param string $totalFee 实际付款金额 + * @param array $extra 附加的数据 (需要携带openid) + * @return bool + * @throws BaseException + */ + public function unify(string $outTradeNo, string $totalFee, array $extra = []): bool + { + try { + $result = null; + // 发起API调用 微信小程序端 + if ($this->client === ClientEnum::MP_WEIXIN) { + + // 2.组装请求参数 + $request = new V2TradePaymentJspayRequest(); + // 请求日期 + $request->setReqDate(date("Ymd")); + // 请求流水号 + $request->setReqSeqId($outTradeNo); + + $merConfig = BsPay::getConfig($this->merChantKey); + // 商户号 + $request->setHuifuId($merConfig->sys_id); + // 交易类型 + $request->setTradeType("T_MINIAPP"); + // 交易金额 + $request->setTransAmt(sprintf("%.2f", $totalFee)); + // 商品描述 + $request->setGoodsDesc($extra['title'] ?? "商品支付"); + + // 设置非必填字段 + $extendInfoMap = $this->getExtendInfos($extra); + $request->setExtendInfo($extendInfoMap); + + // 3. 发起API调用 + $client = new BsPayClient($this->merChantKey); + $result = $client->postRequest($request); + var_dump($result); + exit(); + Log::append('Alipay-unify', ['client' => $this->client, 'result' => $result]); + if (!$result || $result->isError()) { + return false; + } + $data = $result->getRspDatas()['data']; + if (isset($data['resp_code']) && $data['resp_code'] == "00000100") { + return $data; + } + return false; + } + } catch (\Throwable $e) { + $this->throwError('支付宝API下单失败:' . $e->getMessage(), true, 'unify'); + } + return false; + } + /** + * 输出错误信息 + * @param string $errMessage 错误信息 + * @param bool $isLog 是否记录日志 + * @param string $action 当前的操作 + * @throws BaseException + */ + private function throwError(string $errMessage, bool $isLog = false, string $action = '') + { + $this->error = $errMessage; + $isLog && Log::append("Alipay-{$action}", ['errMessage' => $errMessage]); + throwError($errMessage); + } + public function getExtendInfos($params) { + // 设置非必填字段 + $extendInfoMap = array(); + // 交易有效期 + $extendInfoMap["time_expire"]= date("YmdHis", time() + 86400); + // 禁用信用卡标记 + $extendInfoMap["limit_pay_type"]= "NO_CREDIT"; + // 是否延迟交易 + $extendInfoMap["delay_acct_flag"]= "N"; + // 渠道号 + $extendInfoMap["channel_no"]= ""; + // 手续费扣款标志 + // $extendInfoMap["fee_flag"]= ""; + // 补贴支付信息 + // $extendInfoMap["combinedpay_data"]= $this->getCombinedpayData(); + // 场景类型 + $extendInfoMap["pay_scene"]= "02"; + // 安全信息 + //$extendInfoMap["risk_check_data"]= $this->getRiskCheckData(); + // 设备信息 + //$extendInfoMap["terminal_device_data"]= $this->getTerminalDeviceData(); + // 分账对象 + //$extendInfoMap["acct_split_bunch"]= $this->getAcctSplitBunch(); + // 传入分帐遇到优惠的处理规则 + $extendInfoMap["term_div_coupon_type"]= "0"; + // 聚合正扫微信拓展参数集合 + $extendInfoMap["wx_data"]= $this->getWxData($params); + // 支付宝扩展参数集合 + //$extendInfoMap["alipay_data"]= $this->getAlipayData(); + // 银联参数集合 + // $extendInfoMap["unionpay_data"]= getUnionpayData(); + // 数字人民币参数集合 + // $extendInfoMap["dc_data"]= getDcData(); + // 商户贴息标记 + $extendInfoMap["fq_mer_discount_flag"]= "N"; + // 异步通知地址 + $extendInfoMap["notify_url"]= $this->notifyUrl(); + // 备注 + $extendInfoMap["remark"] = $params['title'] ?? "商品支付"; + // 账户号 + // $extendInfoMap["acct_id"]= ""; + return $extendInfoMap; + } + public function getWxData($params) { + $dto = array(); + // 子商户公众账号id + $dto["sub_appid"] = "wxa3127ed5c3542a28"; + // 用户标识 + $dto["openid"] = $params['openid']; + // 子商户用户标识 + $dto["sub_openid"] = ""; + // 附加数据 + // $dto["attach"] = ""; + // 商品描述 + // $dto["body"] = ""; + // 商品详情 + // $dto["detail"] = getDetail(); + // 设备号 + // $dto["device_info"] = ""; + // 订单优惠标记 + // $dto["goods_tag"] = ""; + // 实名支付 + // $dto["identity"] = ""; + // 开发票入口开放标识 + // $dto["receipt"] = ""; + // 场景信息 + // $dto["scene_info"] = getSceneInfo(); + // 终端ip + // $dto["spbill_create_ip"] = ""; + // 单品优惠标识 + // $dto["promotion_flag"] = ""; + // 新增商品ID + // $dto["product_id"] = ""; + + return json_encode($dto,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES); + } + /** + * 交易查询 (主动查询订单支付状态) + * @param string $outTradeNo 交易订单号 + * @return array|null + * @throws BaseException + */ + public function tradeQuery(string $outTradeNo): ?array + { + return $this->getApp()->tradeQuery($outTradeNo); + } + + /** + * 支付成功后的异步通知 + * @return bool + * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException + */ + public function notify(): bool + { + if (!$this->getApp()->notify()) { + $this->setError($this->getApp()->getError()); + return false; + } + return true; + } + + /** + * 微信支付退款API + * @param string $outTradeNo 第三方交易单号 + * @param string $refundAmount 退款金额 + * @param array $extra 附加数据 (需要携带订单付款总金额) + * @return bool + * @throws BaseException + */ + public function refund(string $outTradeNo, string $refundAmount, array $extra = []): bool + { + if (!$this->getApp()->refund($outTradeNo, $refundAmount, $extra)) { + $this->setError($this->getApp()->getError()); + return false; + } + return true; + } + + /** + * 商家转账到零钱API + * @param string $outTradeNo 交易订单号 + * @param string $totalFee 实际付款金额 + * @param array $extra 附加的数据 (需要携带openid、desc) + * @return bool + * @throws BaseException + */ + public function transfers(string $outTradeNo, string $totalFee, array $extra = []): bool + { + if (!$this->getApp()->transfers($outTradeNo, $totalFee, $extra)) { + $this->setError($this->getApp()->getError()); + return false; + } + return true; + } + + /** + * 获取异步回调的请求参数 + * @return array + */ + public function getNotifyParams(): array + { + return $this->getApp()->getNotifyParams(); + } + + /** + * 返回异步通知结果的输出内容 + * @return string + * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException + */ + public function getNotifyResponse(): string + { + return $this->getApp()->getNotifyResponse(); + } + + /** + * 返回统一下单API的结果 (用于前端) + * @return array + * @throws BaseException + */ + public function getUnifyResult(): array + { + return $this->getApp()->getUnifyResult(); + } + /** + * 异步回调地址 + * @return string + */ + private function notifyUrl(): string + { + // 例如:https://www.xxxx.com/alipayNotice.php + return base_url() . 'alipayNotice.php'; + } +} \ No newline at end of file diff --git a/app/common/model/Payment.php b/app/common/model/Payment.php index 9d2a3080..fb86f391 100644 --- a/app/common/model/Payment.php +++ b/app/common/model/Payment.php @@ -194,7 +194,9 @@ class Payment extends BaseModel $data = [ ClientEnum::MP_WEIXIN => $this->defaultGroup(ClientEnum::MP_WEIXIN, [ PaymentMethodEnum::WECHAT, + PaymentMethodEnum::HUIFU, PaymentMethodEnum::BALANCE, + ]), // ClientEnum::H5 => $this->defaultGroup(ClientEnum::H5, [ // PaymentMethodEnum::WECHAT,