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

214 lines
6.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace App\Services\Payment;
use App\Enums\WxpayTradeType;
use App\Exceptions\WeChatPayException;
use EasyWeChat\Factory;
use EasyWeChat\Payment\Application;
use Illuminate\Support\Arr;
class WxpayService
{
/**
* @var array<string, \EasyWeChat\Payment\Application>
*/
protected $payments = [];
/**
* 支付
*
* @param array $params
* @param string|null $payment
* @return array
*/
public function pay(array $params, ?string $payment = null): array
{
if (! isset($params['notify_url'])) {
$path = route('wxpay.paid_notify', ['payment' => $payment ?: 'default'], false);
$params['notify_url'] = url($path, [], true);
}
if (! isset($params['trade_type'])) {
$params['trade_type'] = WxpayTradeType::App->value;
}
$app = $this->payment($payment);
// 服务商模式 (子商户)
$appId = config('wechat.payment.sub.app_id');
$mchId = config('wechat.payment.sub.mch_id');
if ($appId && $mchId) {
$params['sub_openid'] = Arr::pull($params, 'openid');
}
$result = $app->order->unify($params);
$this->validateResult($result, $params);
return match ($params['trade_type']) {
WxpayTradeType::App->value => $app->jssdk->appConfig($result['prepay_id']),
WxpayTradeType::H5->value => Arr::only($result, ['mweb_url']),
default => $app->jssdk->bridgeConfig($result['prepay_id'], false),
};
}
/**
* 微信企业付款到零钱
*
* @param array $params
* @return array
* @throws WeChatPayException
*/
public function transfer(array $params)
{
$config = config('wechat.payment.transfer');
$debug = config('app.debug');
if (!isset($params['openid']) && $debug) {
$params['openid'] = 'oU7xS5UspzVvpPEBqKZuW6N9WXDg';
}
if ($debug) {
$params['amount'] = 100;
}
$app = Factory::payment($config);
/*
'partner_trade_no' => '1233455', // 商户订单号,需保持唯一性(只能是字母或者数字,不能包含有符号)
'openid' => 'oxTWIuGaIt6gTKsQRLau2M0yL16E',
'check_name' => 'FORCE_CHECK', // NO_CHECK不校验真实姓名, FORCE_CHECK强校验真实姓名
're_user_name' => '王小帅', // 如果 check_name 设置为FORCE_CHECK则必填用户真实姓名
'amount' => 10000, // 企业付款金额,单位为分
'desc' => '理赔', // 企业付款操作说明信息。必填
*/
$result = $app->transfer->toBalance($params);
$this->validateResult($result);
return $result;
}
/**
* 查询 微信企业付款到零钱 的订单
*
* @param string $no 商户订单号
* @return array
*/
public function queryTransfer($no)
{
$config = config('wechat.payment.transfer');
$app = Factory::payment($config);
$result = $app->transfer->queryBalanceOrder($no);
$this->validateResult($result);
return $result;
}
/**
* 根据商户订单号退款
*
* @param string $number
* @param string $refundNumber
* @param int $totalFee
* @param int $refundFee
* @param array $optional
* @return array
*/
public function refundByOutTradeNumber(array $params, ?string $payment = null)
{
$optional = Arr::get($params, 'optional', []);
if (! is_array($optional)) {
$optional = [];
}
if (! isset($optional['notify_url'])) {
$path = route('wxpay.order_refund_notify', [
'payment' => $payment ?: 'default',
], false);
$optional['notify_url'] = url($path, [], true);
}
$result = $this->payment($payment)->refund->byOutTradeNumber(
$params['number'],
$params['refund_number'],
$params['total_fee'],
$params['refund_fee'],
$optional,
);
$this->validateResult($result, $params);
return $result;
}
/**
* @param string|null $name
* @return \EasyWeChat\Payment\Application
*/
public function payment(?string $name = null): Application
{
$name = $name ?: 'default';
return $this->payments[$name] = $this->get($name);
}
/**
* @param string $name
* @return \EasyWeChat\Payment\Application
*/
protected function get(string $name): Application
{
return $this->payments[$name] ?? $this->resolve($name);
}
/**
* @param string $name
* @return \EasyWeChat\Payment\Application
*
* @throws \App\Exceptions\WeChatPayException
*/
protected function resolve(string $name): Application
{
$config = config("wechat.payment.{$name}");
if (empty($config)) {
throw new WeChatPayException("支付 [{$name}] 配置未找到");
}
$app = Factory::payment($config);
// 服务商模式 (子商户)
$appId = config('wechat.payment.sub.app_id');
$mchId = config('wechat.payment.sub.mch_id');
if ($appId && $mchId) {
$app->setSubMerchant($mchId, $appId);
}
return $app;
}
/**
* 校验响应结果
*
* @param array $result
* @param array $raw
* @return void
*
* @throws \App\Exceptions\WeChatPayException
*/
protected function validateResult(array $result, array $raw = [])
{
if (Arr::get($result, 'return_code') !== 'SUCCESS') {
throw new WeChatPayException(Arr::get($result, 'return_msg', '请求失败'), $raw);
}
if (Arr::get($result, 'result_code') !== 'SUCCESS') {
throw new WeChatPayException(sprintf(
'[%s] %s',
Arr::get($result, 'err_code', '-1'),
Arr::get($result, 'err_code_des', '交易失败')
), $raw);
}
}
}