You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
328 lines
11 KiB
328 lines
11 KiB
<?php
|
|
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';
|
|
}
|
|
} |