6
0
Fork 0
jiqu-library-server/app/Services/WeChatPayService.php

173 lines
4.9 KiB
PHP

<?php
namespace App\Services;
use App\Exceptions\WeChatPayException;
use Closure;
use EasyWeChat\Factory;
use EasyWeChat\Payment\Application;
use Illuminate\Support\Arr;
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 \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)
{
if (! isset($params['notify_url'])) {
$params['notify_url'] = url(route('wxpay.paid_notify', [], false), [], true);
}
// 如果交易类型不存在,则使用 App 支付
if (! isset($params['trade_type'])) {
$params['trade_type'] = static::TRADE_TYPE_APP;
}
$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
);
}
return match ($params['trade_type']) {
static::TRADE_TYPE_APP => $this->app->jssdk->appConfig($result['prepay_id']),
static::TRADE_TYPE_H5 => Arr::only($result, ['mweb_url']),
default => $this->app->jssdk->bridgeConfig($result['prepay_id'], 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);
}
}