182 lines
5.0 KiB
PHP
182 lines
5.0 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Exceptions\WeChatPayException;
|
|
use Closure;
|
|
use EasyWeChat\Factory;
|
|
use EasyWeChat\Payment\Application;
|
|
|
|
class WeChatPayService
|
|
{
|
|
/**
|
|
* 小程序交易类型
|
|
* https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_2
|
|
*/
|
|
public const TRADE_TYPE_JSAPI = 'JSAPI'; // JSAPI支付
|
|
public const TRADE_TYPE_APP = 'APP'; // App支付
|
|
public const TRADE_TYPE_NATIVE = 'NATIVE'; // Native支付
|
|
public const TRADE_TYPE_H5 = 'MWEB'; // H5支付
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
public static $allowTradeTypes = [
|
|
self::TRADE_TYPE_JSAPI,
|
|
self::TRADE_TYPE_APP,
|
|
];
|
|
|
|
/**
|
|
* @var \EasyWeChat\Payment\Application
|
|
*/
|
|
protected $app;
|
|
|
|
/**
|
|
* @param \EasyWeChat\Payment\Application|null $app
|
|
*/
|
|
public function __construct(?Application $app = null)
|
|
{
|
|
if ($app === null) {
|
|
$app = Factory::payment(config('wechat.payment.default'));
|
|
}
|
|
|
|
$this->app = $app;
|
|
}
|
|
|
|
/**
|
|
* 支付
|
|
*
|
|
* @param array $params
|
|
* @return array
|
|
*
|
|
* @throws \App\Exceptions\WeChatPayException
|
|
*/
|
|
public function pay(array $params)
|
|
{
|
|
// 如果交易类型不存在,则使用 App 支付
|
|
if (! isset($params['trade_type'])) {
|
|
$params['trade_type'] = static::TRADE_TYPE_APP;
|
|
}
|
|
|
|
if (! in_array($params['trade_type'], static::$allowTradeTypes)) {
|
|
throw new WeChatPayException(sprintf('交易类型 [%s] 暂不支持', $params['trade_type']), $params);
|
|
}
|
|
|
|
$result = $this->app->order->unify($params);
|
|
|
|
if (data_get($result, 'return_code') !== 'SUCCESS') {
|
|
throw new WeChatPayException(
|
|
data_get($result, 'return_msg', '请求失败'),
|
|
$params
|
|
);
|
|
}
|
|
|
|
if (data_get($result, 'result_code') !== 'SUCCESS') {
|
|
throw new WeChatPayException(
|
|
sprintf(
|
|
'[%s] %s',
|
|
data_get($result, 'err_code', '-1'),
|
|
data_get($result, 'err_code_des', '交易失败')
|
|
),
|
|
$params
|
|
);
|
|
}
|
|
|
|
$prepayId = $result['prepay_id'];
|
|
|
|
if ($params['trade_type'] === static::TRADE_TYPE_APP) {
|
|
return $this->app->jssdk->appConfig($prepayId);
|
|
}
|
|
|
|
return $this->app->jssdk->bridgeConfig($prepayId, false);
|
|
}
|
|
|
|
/**
|
|
* 支付结果通知
|
|
*
|
|
* @param \Closure $closure
|
|
* @return \Symfony\Component\HttpFoundation\Response
|
|
*/
|
|
public function handlePaidNotify(Closure $closure)
|
|
{
|
|
return $this->app->handlePaidNotify($closure);
|
|
}
|
|
|
|
/**
|
|
* 根据微信订单号退款
|
|
*
|
|
* @param string $transactionId
|
|
* @param string $refundNumber
|
|
* @param int $totalFee
|
|
* @param int $refundFee
|
|
* @param array $optional
|
|
* @return array
|
|
*/
|
|
public function refundByTransactionId(string $transactionId, string $refundNumber, int $totalFee, int $refundFee, array $optional = [])
|
|
{
|
|
$result = $this->app->refund->byTransactionId($transactionId, $refundNumber, $totalFee, $refundFee, $optional);
|
|
|
|
if (data_get($result, 'return_code') !== 'SUCCESS') {
|
|
throw new WeChatPayException(
|
|
data_get($result, 'return_msg', '请求失败')
|
|
);
|
|
}
|
|
|
|
if (data_get($result, 'result_code') !== 'SUCCESS') {
|
|
throw new WeChatPayException(
|
|
sprintf(
|
|
'[%s] %s',
|
|
data_get($result, 'err_code', '-1'),
|
|
data_get($result, 'err_code_des', '退款失败')
|
|
)
|
|
);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* 根据商户订单号退款
|
|
*
|
|
* @param string $number
|
|
* @param string $refundNumber
|
|
* @param int $totalFee
|
|
* @param int $refundFee
|
|
* @param array $optional
|
|
* @return array
|
|
*/
|
|
public function refundByOutTradeNumber(string $number, string $refundNumber, int $totalFee, int $refundFee, array $optional = [])
|
|
{
|
|
$result = $this->app->refund->byOutTradeNumber($number, $refundNumber, $totalFee, $refundFee, $optional);
|
|
|
|
if (data_get($result, 'return_code') !== 'SUCCESS') {
|
|
throw new WeChatPayException(
|
|
data_get($result, 'return_msg', '请求失败')
|
|
);
|
|
}
|
|
|
|
if (data_get($result, 'result_code') !== 'SUCCESS') {
|
|
throw new WeChatPayException(
|
|
sprintf(
|
|
'[%s] %s',
|
|
data_get($result, 'err_code', '-1'),
|
|
data_get($result, 'err_code_des', '退款失败')
|
|
)
|
|
);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* 退款结果通知
|
|
*
|
|
* @param \Closure $closure
|
|
* @return \Symfony\Component\HttpFoundation\Response
|
|
*/
|
|
public function handleRefundedNotify(Closure $closure)
|
|
{
|
|
return $this->app->handleRefundedNotify($closure);
|
|
}
|
|
}
|