主题
支付功能
专业版基于 yansongda/pay 包装一份非常易用的支付工厂类。只需要在后台保存支付配置之后,使用下面的调用即可
php
// 公众号支付
\Modules\Pay\Support\PayFactory::make(\Modules\Pay\Enums\Pay::WECHAT_PAY)
->mp([
'subject' => '公众号支付测试',
'total_amount' => 1,
]);
WARNING
支付功能提供的是最基础的支付功能,不包含任何业务。功能代码需要根据实际业务编写
支付接口
提供三个支付接口,如下
php
use Modules\Pay\Support\NotifyData\NotifyData;
interface PayInterface
{
// 退款接口
public function refund(array $params): mixed;
// 退款回调
public function refundNotify(NotifyData $notify): mixed;
// 支付回调
public function payNotify(NotifyData $notify): mixed;
}
支付基础类
专业版在基础类实现了创建订单号逻辑,这个订单号只是默认填充的,需要根据自己的实际业务来实现
php
abstract class Pay implements PayInterface
{
/**
* 创建订单号
*
* @throws RandomException
*/
protected function createOrderNo(): string
{
$prefix = $this->orderNoPrefix();
return $prefix.date('YmdHis').random_int(1000000, 9999999).Str::random(10);
}
/**
* 创建退款订单号,退款订单号加个 R 字符
*
* @throws RandomException
*/
public function createRefundOrderNo(): string
{
return 'R'.$this->createOrderNo();
}
/**
* @return array|string[]
*
* @throws RandomException
*/
protected function createTradeData(array $param): array
{
return array_merge([
'out_trade_no' => $this->createOrderNo(),
], $param);
}
/**
* @return array|string[]
*
* @throws RandomException
*/
protected function createRefundData(array $params): array
{
return array_merge([
'out_trade_no' => $this->createRefundOrderNo(),
], $params);
}
}
具体实现的支付
以支付宝为例,如下代码
php
/**
* @method ResponseInterface|Rocket web(array $order) 网页支付
* @method ResponseInterface|Rocket h5(array $order) H5 支付
* @method ResponseInterface|Rocket app(array $order) APP 支付
* @method Rocket|Collection mini(array $order) 小程序支付
* @method Rocket|Collection pos(array $order) 刷卡支付
* @method Rocket|Collection scan(array $order) 扫码支付
* @method Rocket|Collection transfer(array $order) 账户转账
*/
class AliPay extends Pay
{
public function refund(array $params): mixed
{
$refundData = $this->createRefundData([
'refund_amount' => $params['amount'],
]);
}
/**
* @return \Yansongda\Pay\Provider\Alipay
*
* @throws \Yansongda\Artful\Exception\ContainerException
*/
protected function instance(): mixed
{
PayProvider::config(config('pay.alipay'));
return PayProvider::alipay();
}
/**
* 退款回调
*
* @param NotifyData $notify
* @return mixed
* @throws ContainerException
*/
public function refundNotify(NotifyData $notify): mixed
{
try {
} catch (ContainerException $e) {
} finally {
return $this->instance()->success();
}
}
/**
* 支付回调
*
* @param NotifyData $notify
* @return mixed
* @throws ContainerException
*/
public function payNotify(NotifyData $notify): mixed
{
try {
} catch (ContainerException $e) {
} finally {
return $this->instance()->success();
}
}
/**
* 包装回调数据
*/
protected function getNotifyData(array $data): NotifyData
{
return new AliPayNotifyData($data);
}
protected function orderNoPrefix(): string
{
return 'A';
}
}
这里为了隐藏支付回调业务处理的细节,对回调数据进行了一次包装。
回调数据接口
php
// 回调数据接口
interface NotifyDataInterface
{
/**
* 是否支付成功
*
* @return bool
*/
public function isPaySuccess(): bool;
/**
* 是否退款成功
*
* @return bool
*/
public function isRefundSuccess(): bool;
/**
* 是否是退款
*
* @return bool
*/
public function isRefund(): bool;
/**
* 获取支付平台的订单号
*
* @return string
*/
public function getOutTradeNo(): string;
/**
* 获取本地订单号
*
* @return string
*/
public function getTradeNo(): string;
}
例如支付宝的回调数据处理,必须实现接口的几个方法,这样在回调数据处理的时候就不需要关心具体实现了。
php
/**
* 微信回调数据
*/
class AliPayNotifyData implements NotifyDataInterface
{
/**
* 是否支付成功
*/
public function isPaySuccess(): bool
{
return $this->getTradeState() == 'trade_success';
}
/**
* 是否退款成功
*/
public function isRefundSuccess(): bool
{
return $this->getRefundStatus() == 'success';
}
/**
* 获取退款状态
*/
public function getRefundStatus(): string
{
return strtolower($this->data['resource']['refund_status']);
}
/**
* 交易是否完成
*
* @return bool
*/
public function isTradeFinished(): bool
{
return $this->getTradeState() == 'trade_finished';
}
/**
* 交易是否等待付款
*
* @return bool
*/
public function isWaitBuyerPay(): bool
{
return $this->getTradeState() == 'wait_buyer_pay';
}
/**
* 交易是否关闭
*
* @return bool
*/
public function isTradeClose(): bool
{
return $this->getTradeState() == 'trade_closed';
}
/**
* 获取交易状态
*
* @return string
*/
public function getTradeState(): string
{
return strtolower($this->data['trade_status']);
}
/**
* 是否是退款回调
*/
public function isRefund(): bool
{
return $this->data['resource']['original_type'] == 'refund';
}
/**
* 获取平台交易订单号
*
* @return string
*/
public function getOutTradeNo(): string
{
return $this->data['trade_no'];
}
/**
* 获取本地交易订单号
*
* @return string
*/
public function getTradeNo(): string
{
return $this->data['out_trade_no'];
}
}
这是整个支付的框架,当然具体业务实现还需要根据实际业务功能添加。但是这已经在很大程度上屏蔽了支付功能的实际复杂度。只需要关注业务实现即可