# Kylin Payment 支付通知

## 1. 支付通知概述

Kylin Payment 提供了完善的支付通知功能，用于处理支付平台的异步通知，确保支付结果的及时处理。

## 2. 通知类型

### 2.1 支付通知

当用户完成支付后，支付平台会发送支付通知，通知系统支付结果。

### 2.2 退款通知

当退款处理完成后，支付平台会发送退款通知，通知系统退款结果。

### 2.3 其他通知

支付平台可能会发送其他类型的通知，如订单关闭通知、风险提示通知等。

## 3. 通知处理

### 3.1 处理支付通知

使用 `Payment::handleNotification()` 方法处理支付通知：

```php
use Kylin\Payment\Facades\Payment;

$notification = Payment::handleNotification(function ($data) {
    // 处理支付通知
    $orderNo = $data['order_no'];
    $status = $data['status'];
    $amount = $data['amount'];
    $transactionId = $data['transaction_id'];
    
    // 更新订单状态
    // 处理业务逻辑
    
    return true; // 返回true表示处理成功
});
```

### 3.2 处理退款通知

使用 `Payment::handleRefundNotification()` 方法处理退款通知：

```php
use Kylin\Payment\Facades\Payment;

$notification = Payment::handleRefundNotification(function ($data) {
    // 处理退款通知
    $refundNo = $data['refund_no'];
    $orderNo = $data['order_no'];
    $status = $data['status'];
    $amount = $data['amount'];
    $refundTransactionId = $data['refund_transaction_id'];
    
    // 更新退款状态
    // 处理业务逻辑
    
    return true; // 返回true表示处理成功
});
```

## 4. 通知验证

### 4.1 签名验证

支付平台发送的通知会包含签名，需要验证签名的真实性：

```php
use Kylin\Payment\Facades\Payment;

$notification = Payment::handleNotification(function ($data) {
    // 验证签名
    $signature = $data['sign'];
    $valid = Payment::verifySignature($data, $signature);
    
    if (!$valid) {
        return false; // 签名验证失败
    }
    
    // 处理支付通知
    return true;
});
```

### 4.2 数据验证

验证通知数据的完整性和合法性：

```php
use Kylin\Payment\Facades\Payment;

$notification = Payment::handleNotification(function ($data) {
    // 验证数据完整性
    if (!isset($data['order_no']) || !isset($data['status']) || !isset($data['amount'])) {
        return false; // 数据不完整
    }
    
    // 验证数据合法性
    $order = Payment::query($data['order_no']);
    if (!$order) {
        return false; // 订单不存在
    }
    
    if (abs($order['amount'] - $data['amount']) > 0.01) {
        return false; // 金额不匹配
    }
    
    // 处理支付通知
    return true;
});
```

## 5. 通知响应

### 5.1 微信支付通知响应

微信支付要求返回特定格式的响应：

```php
// 成功响应
return [
    'return_code' => 'SUCCESS',
    'return_msg' => 'OK',
];

// 失败响应
return [
    'return_code' => 'FAIL',
    'return_msg' => '处理失败',
];
```

### 5.2 支付宝支付通知响应

支付宝支付要求返回特定格式的响应：

```php
// 成功响应
echo 'success';

// 失败响应
echo 'fail';
```

### 5.3 银联支付通知响应

银联支付要求返回特定格式的响应：

```php
// 成功响应
echo 'ok';

// 失败响应
echo 'fail';
```

## 6. 通知路由

### 6.1 配置通知路由

在 `routes/web.php` 文件中配置通知路由：

```php
Route::post('/payment/wechat/notify', 'PaymentController@wechatNotify');
Route::post('/payment/alipay/notify', 'PaymentController@alipayNotify');
Route::post('/payment/unionpay/notify', 'PaymentController@unionpayNotify');
Route::post('/payment/wechat/refund-notify', 'PaymentController@wechatRefundNotify');
```

### 6.2 控制器方法

在 `PaymentController` 中实现通知处理方法：

```php
<?php

namespace App\Http\Controllers;

use Kylin\Payment\Facades\Payment;
use Illuminate\Http\Request;

class PaymentController extends Controller
{
    /**
     * 处理微信支付通知
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function wechatNotify(Request $request)
    {
        $notification = Payment::handleNotification(function ($data) {
            // 处理支付通知
            return true;
        });
        
        return response()->json($notification);
    }

    /**
     * 处理支付宝支付通知
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function alipayNotify(Request $request)
    {
        $notification = Payment::handleNotification(function ($data) {
            // 处理支付通知
            return true;
        });
        
        return response($notification);
    }

    /**
     * 处理银联支付通知
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function unionpayNotify(Request $request)
    {
        $notification = Payment::handleNotification(function ($data) {
            // 处理支付通知
            return true;
        });
        
        return response($notification);
    }

    /**
     * 处理微信退款通知
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function wechatRefundNotify(Request $request)
    {
        $notification = Payment::handleRefundNotification(function ($data) {
            // 处理退款通知
            return true;
        });
        
        return response()->json($notification);
    }
}
```

## 7. 通知重试

### 7.1 微信支付通知重试

微信支付会在通知失败后进行重试，重试规则如下：
- 通知频率：15s, 15s, 30s, 3m, 10m, 20m, 30m, 1h, 2h, 6h, 15h
- 最多重试10次

### 7.2 支付宝支付通知重试

支付宝支付会在通知失败后进行重试，重试规则如下：
- 通知频率：2m, 10m, 10m, 1h, 2h, 6h, 15h
- 最多重试7次

### 7.3 银联支付通知重试

银联支付会在通知失败后进行重试，重试规则如下：
- 通知频率：5m, 10m, 30m, 1h, 2h, 6h, 12h
- 最多重试7次

## 8. 常见问题

### 8.1 通知未收到

**问题**：支付通知未收到
**解决方案**：
1. 检查通知地址是否正确
2. 检查服务器是否可以被访问
3. 检查通知处理逻辑是否正确
4. 检查支付平台是否发送了通知

### 8.2 通知验证失败

**问题**：通知验证失败
**解决方案**：
1. 检查签名验证逻辑是否正确
2. 检查支付方式配置是否正确
3. 检查通知数据是否完整

### 8.3 通知处理失败

**问题**：通知处理失败
**解决方案**：
1. 检查业务逻辑是否正确
2. 检查数据库操作是否成功
3. 检查错误处理是否完善

### 8.4 通知重复处理

**问题**：通知重复处理
**解决方案**：
1. 实现幂等性处理
2. 记录已处理的通知
3. 检查通知的唯一性

### 8.5 通知超时

**问题**：通知超时
**解决方案**：
1. 优化通知处理逻辑
2. 减少处理时间
3. 异步处理通知

## 9. 最佳实践

1. **通知地址配置**：确保通知地址可以被支付平台访问
2. **签名验证**：必须验证通知的签名，确保通知的真实性
3. **数据验证**：验证通知数据的完整性和合法性
4. **幂等性处理**：实现通知的幂等性处理，避免重复处理
5. **错误处理**：完善错误处理，确保通知处理的稳定性
6. **日志记录**：记录通知的详细信息，便于排查问题
7. **异步处理**：对于复杂的业务逻辑，使用异步处理
8. **监控**：监控通知的处理状态，及时发现问题

## 10. 总结

Kylin Payment 提供了完善的支付通知功能，用于处理支付平台的异步通知，确保支付结果的及时处理。通过合理的通知处理，可以提高支付的可靠性和安全性，确保交易的顺利完成。
