diff --git a/app/admin/controller/Goods.php b/app/admin/controller/Goods.php index bb117812..8b412ceb 100644 --- a/app/admin/controller/Goods.php +++ b/app/admin/controller/Goods.php @@ -511,9 +511,9 @@ class Goods extends Controller */ public function collector(string $sku): Json{ $res = getJdGoodsBySku([$sku]); - // $collector = new \app\job\service\goods\Collector; - // $url = "https://item.jd.com/{$sku}.html"; - // $res1 = $collector->collector($url, 10048); + if (!$res) { + return $this->renderError('数据抓取失败'); + } return $this->renderSuccess($res[$sku] ?? []); } diff --git a/app/api/controller/Goods.php b/app/api/controller/Goods.php index fdd0dd4d..da291bc0 100644 --- a/app/api/controller/Goods.php +++ b/app/api/controller/Goods.php @@ -26,148 +26,6 @@ use EasyWeChat\Factory; class Goods extends Controller { - public function pay(){ - // $merchantCode = '123456789900081'; - // $terminalCode = '00810001'; - // $originalOrderId = '20190306113204000017183219'; - // $data = array( - // 'merchantCode'=>$merchantCode, - // 'terminalCode'=>$terminalCode, - // 'originalOrderId'=>$originalOrderId - // ); - - //$ret = $this->unify(date("YmdHis").mt_rand(1000,9999), "1"); - $ret = $this->tradeQuery(date("YmdHis").mt_rand(1000,9999)); - return $this->renderSuccess([ 'ret' => $ret]); - } - /** - * 支付成功后的异步通知 - * @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 - { - $tradeQuery_url = "https://test-api-open.chinaums.com/v1/netpay/refund"; - //$order_url = "https://api-mop.chinaums.com/v1/netpay/refund"; - $mid = "898340149000005"; - $tid = "88880001"; - $subAppId = "wxa3127ed5c3542a28"; - $subOpenId = "oxeW66xXaOt4ErNCFTIDn90Zu_FI"; - $params = [ - "requestTimestamp" => date("Y-m-d H:i:s"), - "merOrderId" => $outTradeNo,//date("YmdHis").mt_rand(1000,9999), - "mid" => $mid, - "tid" => $tid, - "targetOrderId" => $tid, - "refundAmount" => $tid, - "refundOrderId" => $tid, - "platformAmount" => $tid, - "refundDesc" => $tid, - ]; - $authorization = $this->getAuthorization($params); - $headers = ["Authorization:".$authorization]; - - $ret = httpRequest($order_url, "POST", json_encode($params), $headers, true); - return $ret; - } - /** - * 交易查询 (主动查询订单支付状态) - * @param string $outTradeNo 交易订单号 - * @return array|null - * @throws BaseException - */ - public function tradeQuery(string $outTradeNo): ?array - { - $tradeQuery_url = "https://test-api-open.chinaums.com/v1/netpay/query"; - //$order_url = "https://api-mop.chinaums.com/v1/netpay/query"; - $mid = "898340149000005"; - $tid = "88880001"; - $subAppId = "wxa3127ed5c3542a28"; - $subOpenId = "oxeW66xXaOt4ErNCFTIDn90Zu_FI"; - $params = [ - "requestTimestamp" => date("Y-m-d H:i:s"), - "merOrderId" => $outTradeNo,//date("YmdHis").mt_rand(1000,9999), - "mid" => $mid, - "tid" => $tid, - ]; - $authorization = $this->getAuthorization($params); - $headers = ["Authorization:".$authorization]; - - $ret = httpRequest($order_url, "POST", json_encode($params), $headers, true); - return $ret; - } - /** - * 统一下单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{ - $order_url = "https://test-api-open.chinaums.com/v1/netpay/wx/unified-order"; - //$order_url = "https://api-mop.chinaums.com/v1/netpay/wx/unified-order"; - $mid = "898340149000005"; - $tid = "88880001"; - $subAppId = "wxa3127ed5c3542a28"; - $subOpenId = "oxeW66xXaOt4ErNCFTIDn90Zu_FI"; - $params = [ - "requestTimestamp" => date("Y-m-d H:i:s"), - "merOrderId" => $outTradeNo,//date("YmdHis").mt_rand(1000,9999), - "mid" => $mid, - "tid" => $tid, - "subAppId" => $subAppId, - "subOpenId" => $subOpenId, - "tradeType" => "MINI", - "notifyUrl" => "回调地址", - "orderDesc" => "账单描述", - "totalAmount" => $totalFee, - "divisionFlag" => true,//分账标记 - "platformAmount" => true,//平台商户分 账金额 - "subOrders" => [ - [ - "mid" => "111", - "totalAmount" => 1, - ] - - ], - ]; - $authorization = $this->getAuthorization($params); - $headers = ["Authorization:".$authorization]; - - $ret = httpRequest($order_url, "POST", json_encode($params), $headers, true); - return $ret; - } - public function getAuthorization($data){ - $appid = 'f0ec96ad2c3848b5b810e7aadf369e2f'; - $appkey = '775481e2556e4564985f5439a5e6a277'; - - $timestamp = date("YmdHis",time()); - $nonce = md5(uniqid((string)microtime(true),true)); - $body = json_encode($data); - //echo $body; - $str = bin2hex(hash('sha256', $body, true)); - $signature = base64_encode(hash_hmac('sha256', "$appid$timestamp$nonce$str", $appkey, true)); - $authorization = "OPEN-BODY-SIG AppId=$appid, Timestamp=$timestamp, Nonce=$nonce, =$signature"; - - return $authorization; - } /** * 商品列表 * @return Json diff --git a/app/api/controller/Notify.php b/app/api/controller/Notify.php index 69c91cf3..5ff1b4aa 100644 --- a/app/api/controller/Notify.php +++ b/app/api/controller/Notify.php @@ -59,4 +59,14 @@ class Notify extends BaseController $NotifyService = new NotifyService; return $NotifyService->alipay(); } + + /** + * 支付成功异步通知 (支付宝) + * @return string + */ + public function huifu(): string + { + $NotifyService = new NotifyService; + return $NotifyService->huifu(); + } } diff --git a/app/api/service/Notify.php b/app/api/service/Notify.php index adce058c..0c67e55c 100644 --- a/app/api/service/Notify.php +++ b/app/api/service/Notify.php @@ -123,7 +123,29 @@ class Notify } return isset($Payment) ? $Payment->getNotifyResponse() : 'FAIL'; } - + /** + * 支付成功异步通知 (银联) + * @return string + */ + public function huifu(): string + { + try { + // 获取第三方交易记录 + $tradeInfo = $this->getTradeInfo(PaymentMethodEnum::HUIFU); + // 构建支付模块 + $Payment = $this->getPayment($tradeInfo); + // 验证异步通知参数是否合法 + if (!$Payment->notify()) { + throwError($Payment->getError() ?: '异步通知验证未通过'); + } + // 订单支付成功事件 + $this->orderPaySucces($tradeInfo, $Payment->getNotifyParams()); + } catch (\Throwable $e) { + // 记录错误日志 + Log::append('Notify-银联', ['errMessage' => $e->getMessage()]); + } + return isset($Payment) ? $Payment->getNotifyResponse() : 'FAIL'; + } /** * 订单支付成功事件 * @param PaymentTradeModel $tradeInfo @@ -218,6 +240,9 @@ class Notify if ($method === PaymentMethodEnum::ALIPAY) { return \request()->post('out_trade_no'); } + if ($method === PaymentMethodEnum::HUIFU) { + return \request()->post('merOrderId'); + } return null; } diff --git a/app/api/service/Retail/PaySuccess.php b/app/api/service/Retail/PaySuccess.php index 5a14727b..e402558b 100644 --- a/app/api/service/Retail/PaySuccess.php +++ b/app/api/service/Retail/PaySuccess.php @@ -229,7 +229,7 @@ class PaySuccess extends BaseService ], ['order_no' => $orderInfo['order_no']]); } // 将第三方交易记录更新为已支付状态 - if (in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY])) { + if (in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY, PaymentMethodEnum::HUIFU])) { $this->updateTradeRecord(); } } diff --git a/app/api/service/Retail/Payment.php b/app/api/service/Retail/Payment.php index 23f78af5..f53548d9 100644 --- a/app/api/service/Retail/Payment.php +++ b/app/api/service/Retail/Payment.php @@ -247,7 +247,7 @@ class Payment extends BaseService private function unifiedorder(array $extra = []): array { // 判断支付方式是否合法 - if (!in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY])) { + if (!in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY, PaymentMethodEnum::HUIFU])) { return []; } // 生成第三方交易订单号 (并非主订单号) @@ -290,7 +290,7 @@ class Payment extends BaseService private function extraAsUnify(array $extra = []): array { // 微信支付时需要的附加数据 - if ($this->method === PaymentMethodEnum::WECHAT) { + if ($this->method === PaymentMethodEnum::WECHAT || $this->method === PaymentMethodEnum::HUIFU) { // 微信小程序端和微信公众号端需要openid if (in_array($this->client, [ClientEnum::WXOFFICIAL, ClientEnum::MP_WEIXIN])) { $extra['openid'] = $this->getWechatOpenid(); diff --git a/app/api/service/Server/PaySuccess.php b/app/api/service/Server/PaySuccess.php index 4e8c8ace..6467536c 100644 --- a/app/api/service/Server/PaySuccess.php +++ b/app/api/service/Server/PaySuccess.php @@ -187,7 +187,7 @@ class PaySuccess extends BaseService ], ['order_no' => $orderInfo['order_no']]); } // 将第三方交易记录更新为已支付状态 - if (in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY])) { + if (in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY, PaymentMethodEnum::HUIFU])) { $this->updateTradeRecord(); } } diff --git a/app/api/service/Server/ServerPayment.php b/app/api/service/Server/ServerPayment.php index b060ae4b..66104de0 100644 --- a/app/api/service/Server/ServerPayment.php +++ b/app/api/service/Server/ServerPayment.php @@ -185,7 +185,7 @@ class ServerPayment extends BaseService private function extraAsUnify(array $extra = []): array { // 微信支付时需要的附加数据 - if ($this->method === PaymentMethodEnum::WECHAT) { + if ($this->method === PaymentMethodEnum::WECHAT || $this->method === PaymentMethodEnum::HUIFU) { // 微信小程序端和微信公众号端需要openid if (in_array($this->client, [ClientEnum::WXOFFICIAL, ClientEnum::MP_WEIXIN])) { $extra['openid'] = $this->getWechatOpenid(); @@ -234,7 +234,7 @@ class ServerPayment extends BaseService public function tradeQuery(string $outTradeNo): bool { // 判断支付方式是否合法 - if (!in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY])) { + if (!in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY, PaymentMethodEnum::HUIFU])) { return false; } // 获取支付方式的配置信息 @@ -267,7 +267,7 @@ class ServerPayment extends BaseService private function unifiedorder(array $extra = []): array { // 判断支付方式是否合法 - if (!in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY])) { + if (!in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY, PaymentMethodEnum::HUIFU])) { return []; } // 生成第三方交易订单号 (并非主订单号) diff --git a/app/api/service/cashier/Payment.php b/app/api/service/cashier/Payment.php index de3cfff2..ddec3b7e 100644 --- a/app/api/service/cashier/Payment.php +++ b/app/api/service/cashier/Payment.php @@ -154,7 +154,7 @@ class Payment extends BaseService public function tradeQuery(string $outTradeNo): bool { // 判断支付方式是否合法 - if (!in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY])) { + if (!in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY, PaymentMethodEnum::HUIFU])) { return false; } //新增获取商户的支付配置问题 @@ -286,7 +286,7 @@ class Payment extends BaseService private function extraAsUnify(array $extra = []): array { // 微信支付时需要的附加数据 - if ($this->method === PaymentMethodEnum::WECHAT) { + if ($this->method === PaymentMethodEnum::WECHAT || $this->method === PaymentMethodEnum::HUIFU) { // 微信小程序端和微信公众号端需要openid if (in_array($this->client, [ClientEnum::WXOFFICIAL, ClientEnum::MP_WEIXIN])) { $extra['openid'] = $this->getWechatOpenid(); @@ -299,12 +299,6 @@ 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/api/service/identity/PaySuccess.php b/app/api/service/identity/PaySuccess.php index 76cd928f..337e1002 100644 --- a/app/api/service/identity/PaySuccess.php +++ b/app/api/service/identity/PaySuccess.php @@ -221,7 +221,7 @@ class PaySuccess extends BaseService ], ['order_no' => $orderInfo['order_no']]); } // 将第三方交易记录更新为已支付状态 - if (in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY])) { + if (in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY, PaymentMethodEnum::HUIFU])) { $this->updateTradeRecord(); } } diff --git a/app/api/service/identity/Payment.php b/app/api/service/identity/Payment.php index 15746759..bdb0849c 100644 --- a/app/api/service/identity/Payment.php +++ b/app/api/service/identity/Payment.php @@ -243,7 +243,7 @@ class Payment extends BaseService private function unifiedorder(array $extra = []): array { // 判断支付方式是否合法 - if (!in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY])) { + if (!in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY, PaymentMethodEnum::HUIFU])) { return []; } // 生成第三方交易订单号 (并非主订单号) @@ -286,7 +286,7 @@ class Payment extends BaseService private function extraAsUnify(array $extra = []): array { // 微信支付时需要的附加数据 - if ($this->method === PaymentMethodEnum::WECHAT) { + if ($this->method === PaymentMethodEnum::WECHAT || $this->method === PaymentMethodEnum::HUIFU) { // 微信小程序端和微信公众号端需要openid if (in_array($this->client, [ClientEnum::WXOFFICIAL, ClientEnum::MP_WEIXIN])) { $extra['openid'] = $this->getWechatOpenid(); diff --git a/app/api/service/order/PaySuccess.php b/app/api/service/order/PaySuccess.php index 3e1dbf9b..a4d57d9f 100644 --- a/app/api/service/order/PaySuccess.php +++ b/app/api/service/order/PaySuccess.php @@ -367,7 +367,7 @@ class PaySuccess extends BaseService // merchantModel::setIncTotal($orderInfo['merchant_id'], $precentPrice); } // 将第三方交易记录更新为已支付状态 - if (in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY])) { + if (in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY, PaymentMethodEnum::HUIFU])) { $this->updateTradeRecord(); } } diff --git a/app/api/service/recharge/PaySuccess.php b/app/api/service/recharge/PaySuccess.php index 43430e57..8b3997df 100644 --- a/app/api/service/recharge/PaySuccess.php +++ b/app/api/service/recharge/PaySuccess.php @@ -195,7 +195,7 @@ class PaySuccess extends BaseService 'store_id' => empty($orderInfo['store_id'])?$this->getStoreId():$orderInfo['store_id'], ], ['order_no' => $orderInfo['order_no']],$orderInfo['store_id']); // 将第三方交易记录更新为已支付状态 - if (in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY])) { + if (in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY, PaymentMethodEnum::HUIFU])) { $this->updateTradeRecord(); } // 提交事务处理 diff --git a/app/api/service/recharge/Payment.php b/app/api/service/recharge/Payment.php index e5002114..6eeb0658 100644 --- a/app/api/service/recharge/Payment.php +++ b/app/api/service/recharge/Payment.php @@ -121,7 +121,7 @@ class Payment extends BaseService public function tradeQuery(string $outTradeNo): bool { // 判断支付方式是否合法 - if (!in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY])) { + if (!in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY, PaymentMethodEnum::HUIFU])) { return false; } // 获取支付方式的配置信息 @@ -183,7 +183,7 @@ class Payment extends BaseService private function unifiedorder(array $extra = []): array { // 判断支付方式是否合法 - if (!in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY])) { + if (!in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY,PaymentMethodEnum::HUIFU])) { return []; } // 生成第三方交易订单号 (并非主订单号) @@ -226,7 +226,7 @@ class Payment extends BaseService private function extraAsUnify(array $extra = []): array { // 微信支付时需要的附加数据 - if ($this->method === PaymentMethodEnum::WECHAT) { + if ($this->method === PaymentMethodEnum::WECHAT || $this->method === PaymentMethodEnum::HUIFU) { // 微信小程序端和微信公众号端需要openid if (in_array($this->client, [ClientEnum::WXOFFICIAL, ClientEnum::MP_WEIXIN])) { $extra['openid'] = $this->getWechatOpenid(); diff --git a/app/api/service/wholesaler/PaySuccess.php b/app/api/service/wholesaler/PaySuccess.php index dad24075..9818b057 100644 --- a/app/api/service/wholesaler/PaySuccess.php +++ b/app/api/service/wholesaler/PaySuccess.php @@ -167,7 +167,7 @@ class PaySuccess extends BaseService ], ['order_no' => $orderInfo['order_no']]); } // 将第三方交易记录更新为已支付状态 - if (in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY])) { + if (in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY, PaymentMethodEnum::HUIFU])) { $this->updateTradeRecord(); } } diff --git a/app/api/service/wholesaler/Payment.php b/app/api/service/wholesaler/Payment.php index 932744ad..927ea359 100644 --- a/app/api/service/wholesaler/Payment.php +++ b/app/api/service/wholesaler/Payment.php @@ -134,7 +134,7 @@ class Payment extends BaseService private function unifiedorder(array $extra = []): array { // 判断支付方式是否合法 - if (!in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY])) { + if (!in_array($this->method, [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY, PaymentMethodEnum::HUIFU])) { return []; } // 生成第三方交易订单号 (并非主订单号) @@ -162,7 +162,7 @@ class Payment extends BaseService private function extraAsUnify(array $extra = []): array { // 微信支付时需要的附加数据 - if ($this->method === PaymentMethodEnum::WECHAT) { + if ($this->method === PaymentMethodEnum::WECHAT || $this->method === PaymentMethodEnum::HUIFU) { // 微信小程序端和微信公众号端需要openid if (in_array($this->client, [ClientEnum::WXOFFICIAL, ClientEnum::MP_WEIXIN])) { $extra['openid'] = $this->getWechatOpenid(); diff --git a/app/common.php b/app/common.php index 3512702d..ddac0530 100644 --- a/app/common.php +++ b/app/common.php @@ -628,8 +628,8 @@ function getJdGoodsBySku($skus){ $url = "http://8.130.98.31:8811/api/skus/info?skus=".$sku; $data = httpRequest($url, "GET", null, [], false, 30); - if ($data['code'] != 0 || !$data['data']) { - return []; + if (!isset($data['code']) || $data['code'] != 0 || !$data['data']) { + return false; } $data = $data['data']; foreach ($data as &$item) { diff --git a/app/common/enum/payment/Method.php b/app/common/enum/payment/Method.php index f28368c3..392be4c5 100644 --- a/app/common/enum/payment/Method.php +++ b/app/common/enum/payment/Method.php @@ -47,8 +47,8 @@ class Method extends EnumBasics 'name' => '支付宝', 'value' => self::ALIPAY, ], - self::ALIPAY => [ - 'name' => '汇支付', + self::HUIFU => [ + 'name' => '银联支付', 'value' => self::HUIFU, ], self::BALANCE => [ diff --git a/app/common/library/payment/gateway/driver/Huifu.php b/app/common/library/payment/gateway/driver/Huifu.php index 7f94e506..5cf3db8d 100644 --- a/app/common/library/payment/gateway/driver/Huifu.php +++ b/app/common/library/payment/gateway/driver/Huifu.php @@ -5,28 +5,18 @@ 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 { - /** + private $domain = "https://api-mop.chinaums.com"; + private $result; + /** * 设置支付宝配置信息(全局只需设置一次) * @param array $options 支付宝配置信息 * @param string $client 下单客户端 @@ -35,25 +25,28 @@ class Huifu extends Driver 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'], + 'appid' => $options['provider']['appid'], + 'appkey' => $options['provider']['appkey'], + 'msgSrcId' => $options['provider']['msgSrcId'], + 'msgSrc' => $options['provider']['msgSrc'], + 'md5Secret' => $options['provider']['md5Secret'], + 'mid' => $options['provider']['mid'], + 'tid' => $options['provider']['tid'], ]; } 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'], + 'appid' => $options['normal']['appid'], + 'appkey' => $options['normal']['appkey'], + 'msgSrcId' => $options['normal']['msgSrcId'], + 'msgSrc' => $options['normal']['msgSrc'], + 'md5Secret' => $options['normal']['md5Secret'], + 'mid' => $options['normal']['mid'], + 'tid' => $options['normal']['tid'], ]; } - $this->merChantKey = $options['normal']['sys_id'].$options['normal']['product_id']; - BsPay::init($config, true, $this->merChantKey); - + $this->config = $config; return $this; } @@ -99,47 +92,87 @@ class Huifu extends Driver // 发起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()) { + //$outTradeNo = date("YmdHis").mt_rand(1000,9999); + $order_url = $this->domain . "/v1/netpay/wx/mini-pre-order"; + //$order_url = $this->domain . "/v1/netpay/wx/unified-order"; + $params = [ + "requestTimestamp" => date("Y-m-d H:i:s"), + "merOrderId" => $this->config['msgSrcId'].$outTradeNo, + "mid" => $this->config['mid'], + "tid" => $this->config['tid'], + "subAppId" => $this->config['appid'], + "subOpenId" => $extra['openid'], + "tradeType" => "MINI", + "notifyUrl" => $this->notifyUrl(), + "orderDesc" => "商品支付", + "totalAmount" => bcmul($totalFee, "100"), + "divisionFlag" => false,//分账标记 + //"platformAmount" => false,//平台商户分 账金额 + // "subOrders" => [ + // [ + // "mid" => "111", + // "totalAmount" => 1, + // ] + + // ], + ]; + $authorization = $this->getAuthorization($params); + $headers = ["Authorization:".$authorization]; + + $data = httpRequest($order_url, "POST", json_encode($params), $headers, false); + if ($data['errCode'] != "SUCCESS") { + Log::append('银联-unify', ['client' => $this->client, 'result' => $data]); return false; } - $data = $result->getRspDatas()['data']; - if (isset($data['resp_code']) && $data['resp_code'] == "00000100") { - return $data; - } + $this->result = $data; + return true; + } + } catch (\Throwable $e) { + $this->throwError('银联API下单失败:' . $e->getMessage(), true, 'unify'); + } + return false; + } + /** + * 交易查询 (主动查询订单支付状态) + * @param string $outTradeNo 交易订单号 + * @return array|null + * @throws BaseException + */ + public function tradeQuery(string $outTradeNo): ?array + { + try { + $tradeQuery_url = $this->domain . "/v1/netpay/wx/mini-pre-query"; + $params = [ + "requestTimestamp" => date("Y-m-d H:i:s"), + "merOrderId" => $outTradeNo,//date("YmdHis").mt_rand(1000,9999), + "mid" => $this->config['mid'], + "tid" => $this->config['tid'], + ]; + $authorization = $this->getAuthorization($params); + $headers = ["Authorization:".$authorization]; + + $data = httpRequest($tradeQuery_url, "POST", json_encode($params), $headers, false); + // echo "
"; + // print_r($data); + // exit(); + if ($data['errCode'] != "SUCCESS") { + Log::append('huifu-tradeQuery', ['client' => $this->client, 'result' => $data]); return false; } + return [ + // 支付状态: true成功 false失败 + 'paySuccess' => isset($data['status']) && $data['status'] === 'TRADE_SUCCESS', + // 第三方交易流水号 + 'tradeNo' => $data['targetOrderId'] ?? "" + ]; + return $data; } catch (\Throwable $e) { - $this->throwError('支付宝API下单失败:' . $e->getMessage(), true, 'unify'); + $this->throwError('银联API交易查询失败:' . $e->getMessage(), true, 'tradeQuery'); } return false; + } + /** * 输出错误信息 * @param string $errMessage 错误信息 @@ -150,95 +183,11 @@ class Huifu extends Driver private function throwError(string $errMessage, bool $isLog = false, string $action = '') { $this->error = $errMessage; - $isLog && Log::append("Alipay-{$action}", ['errMessage' => $errMessage]); + $isLog && Log::append("银联-{$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); - } + + /** * 支付成功后的异步通知 @@ -247,11 +196,30 @@ class Huifu extends Driver */ public function notify(): bool { - if (!$this->getApp()->notify()) { - $this->setError($this->getApp()->getError()); - return false; + // 接收表单数据 + $this->notifyParams = request()->filter([])->post(); + + $notifyParams = $this->notifyParams; + $sign = $notifyParams['sign']; + unset($notifyParams['sign']); + ksort($notifyParams); + $str = http_build_query($notifyParams); + $verifyNotify = false; + if ($sign != md5($str)) { + $verifyNotify = true; } - return true; + + // 判断交易单状态必须是支付成功 + $this->notifyResult = $verifyNotify && $this->notifyParams['status'] === 'TRADE_SUCCESS'; + // 记录日志 + Log::append('银联-notify', [ + 'params' => $this->notifyParams, + 'verifyNotify' => $verifyNotify, + 'response' => $this->getNotifyResponse(), + 'result' => $this->notifyResult, + 'message' => '银联异步回调验证' . ($this->notifyResult ? '成功' : '失败') + ]); + return $this->notifyResult; } /** @@ -264,11 +232,32 @@ class Huifu extends Driver */ public function refund(string $outTradeNo, string $refundAmount, array $extra = []): bool { - if (!$this->getApp()->refund($outTradeNo, $refundAmount, $extra)) { - $this->setError($this->getApp()->getError()); - return false; + + try { + $refund_url = $this->domain . "/v1/netpay/refund"; + $params = [ + "requestTimestamp" => date("Y-m-d H:i:s"), + "merOrderId" => $outTradeNo, + "mid" => $this->config['mid'], + "tid" => $this->config['tid'], + "targetOrderId" => $extra['trade_no'], + "refundAmount" => bcmul($refundAmount, "100"), + "refundOrderId" => $this->config['msgSrcId'].date("YmdHis").mt_rand(1000, 9999), + "refundDesc" => "订单退款", + ]; + $authorization = $this->getAuthorization($params); + $headers = ["Authorization:".$authorization]; + + $data = httpRequest($refund_url, "POST", json_encode($params), $headers, false); + if ($data['errCode'] != "SUCCESS") { + $this->throwError($data['errMsg']); + } + // 请求成功 + return true; + } catch (\Throwable $e) { + $this->throwError('银联API退款请求:' . $e->getMessage(), true, 'refund'); } - return true; + return false; } /** @@ -294,17 +283,19 @@ class Huifu extends Driver */ public function getNotifyParams(): array { - return $this->getApp()->getNotifyParams(); + return [ + // 第三方交易流水号 + 'tradeNo' => $this->notifyParams['targetOrderId'] + ]; } /** * 返回异步通知结果的输出内容 * @return string - * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException */ public function getNotifyResponse(): string { - return $this->getApp()->getNotifyResponse(); + return $this->notifyResult ? 'SUCCESS' : 'FAILED'; } /** @@ -314,7 +305,31 @@ class Huifu extends Driver */ public function getUnifyResult(): array { - return $this->getApp()->getUnifyResult(); + if (empty($this->result)) { + $this->throwError('当前没有unify结果', true, 'getUnifyResult'); + } + $this->result['out_trade_no'] = $this->result['merOrderId'];//str_replace($this->config['msgSrcId'], "", $this->result['merOrderId']); + return $this->result; + } + /** + * 生成授权码 + * [getAuthorization description] + * @param [type] $data [description] + * @return [type] [description] + */ + private function getAuthorization($data){ + $appid = $this->config['appid']; + $appkey = $this->config['appkey']; + + $timestamp = date("YmdHis",time()); + $nonce = md5(uniqid((string)microtime(true),true)); + $body = json_encode($data); + //echo $body; + $str = bin2hex(hash('sha256', $body, true)); + $signature = base64_encode(hash_hmac('sha256', "$appid$timestamp$nonce$str", $appkey, true)); + $authorization = 'OPEN-BODY-SIG AppId="'.$appid.'", Timestamp="'.$timestamp.'", Nonce="'.$nonce.'", Signature="'.$signature.'"'; + + return $authorization; } /** * 异步回调地址 @@ -323,6 +338,6 @@ class Huifu extends Driver private function notifyUrl(): string { // 例如:https://www.xxxx.com/alipayNotice.php - return base_url() . 'alipayNotice.php'; + return base_url() . 'huifuNotice.php'; } -} \ No newline at end of file +} diff --git a/app/common/library/payment/gateway/driver/Qmf.php b/app/common/library/payment/gateway/driver/Qmf.php index 6be8e579..74d520a3 100644 --- a/app/common/library/payment/gateway/driver/Qmf.php +++ b/app/common/library/payment/gateway/driver/Qmf.php @@ -20,7 +20,7 @@ use app\common\library\Log; use app\common\enum\Client as ClientEnum; /** - * 全民付移动支付驱动 + * 微信支付驱动 * Class Wechat * @package app\common\library\payment\gateway\driver */ diff --git a/app/common/model/Payment.php b/app/common/model/Payment.php index fb86f391..79fe95ca 100644 --- a/app/common/model/Payment.php +++ b/app/common/model/Payment.php @@ -193,8 +193,8 @@ class Payment extends BaseModel { $data = [ ClientEnum::MP_WEIXIN => $this->defaultGroup(ClientEnum::MP_WEIXIN, [ - PaymentMethodEnum::WECHAT, PaymentMethodEnum::HUIFU, + PaymentMethodEnum::WECHAT, PaymentMethodEnum::BALANCE, ]), diff --git a/app/common/service/order/Refund.php b/app/common/service/order/Refund.php index a8727a01..cf794364 100644 --- a/app/common/service/order/Refund.php +++ b/app/common/service/order/Refund.php @@ -1,13 +1,5 @@ -// +---------------------------------------------------------------------- + declare (strict_types=1); namespace app\common\service\order; @@ -51,7 +43,7 @@ class Refund extends BaseService return $this->balance($order, $money); } // 第三方支付退款 - if (in_array($order['pay_method'], [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY])) { + if (in_array($order['pay_method'], [PaymentMethodEnum::WECHAT, PaymentMethodEnum::ALIPAY, PaymentMethodEnum::HUIFU])) { return $this->payment($order, $money); } return false; @@ -94,7 +86,7 @@ class Refund extends BaseService // 构建支付模块 $Payment = PaymentFacade::store($order['pay_method'])->setOptions($options, $order['platform']); // 执行第三方支付下单API - if (!$Payment->refund($tradeInfo['out_trade_no'], $money, ['totalFee' => (string)$order['pay_price']])) { + if (!$Payment->refund($tradeInfo['out_trade_no'], $money, ['totalFee' => (string)$order['pay_price'], 'trade_no' => $tradeInfo['trade_no']])) { throwError($Payment->getError() ?: '第三方支付退款API调用失败'); } // 将第三方交易记录更新为已退款状态 diff --git a/app/store/controller/Goods.php b/app/store/controller/Goods.php index 5322a0f0..80c38775 100644 --- a/app/store/controller/Goods.php +++ b/app/store/controller/Goods.php @@ -371,6 +371,9 @@ class Goods extends Controller */ public function collector(string $sku): Json{ $res = getJdGoodsBySku([$sku]); + if (!$res) { + return $this->renderError('数据抓取失败'); + } // $collector = new \app\job\service\goods\Collector; // $url = "https://item.jd.com/{$sku}.html"; // $res1 = $collector->collector($url, 10048); diff --git a/public/huifuNotice.php b/public/huifuNotice.php new file mode 100644 index 00000000..59047172 --- /dev/null +++ b/public/huifuNotice.php @@ -0,0 +1,23 @@ + 7.1.0 !'); + +// 加载核心文件 +require __DIR__ . '/../vendor/autoload.php'; + +// 执行HTTP应用并响应 +$http = (new App())->http; + +// 手动指定设置路由 +$_SERVER['PATH_INFO'] = '/notify/huifu'; + +// $http->name()用于设置当前入口文件绑定的应用 +$response = $http->name('api')->run(); + +$response->send(); + +$http->end($response);