Платежный SDK (V3)

Адрес проекта

https://github.com/yansongda/pay

Установка

composer require yansongda/pay ~3.0

Использование

Примечание: далее документация написана с использованием песочницы Alipay. Если у вас возникнут вопросы, пожалуйста, сообщите об этом!

Конфигурационный файл

Предположим, что есть следующий конфигурационный файл config/payment.php

<?php
/**
 * @desc Конфигурационный файл платежа
 * @author Tinywan(ShaoBo Wan)
 * @date 2022/03/11 20:15
 */
return [
    '_force' => true, // Примечание: это должно быть true
    'alipay' => [
        'default' => [
            // Обязательный параметр - app_id, выделенный Alipay
            'app_id' => '20160909004708941',
            // Обязательный параметр - закрытый ключ приложения, строка или путь
            'app_secret_cert' => 'MIIEpAIBAAKCxxxxxxxxxxxxxxP4r3m4OUmD/+XDgCg==',
            // Обязательный параметр - путь к сертификату открытого ключа приложения
            'app_public_cert_path' => base_path().'/payment/appCertPublicKey_2016090900470841.crt',
            // Обязательный параметр - путь к сертификату открытого ключа Alipay
            'alipay_public_cert_path' => base_path().'/payment/alipayCertPublicKey_RSA2.crt',
            // Обязательный параметр - путь к корневому сертификату Alipay
            'alipay_root_cert_path' => base_path().'/payment/alipayRootCert.crt',
            // Необязательный параметр - URL для синхронного обратного вызова
            'return_url' => 'https://webman.tinywan.cn/payment/alipay-return',
            // Необязательный параметр - URL для асинхронного обратного вызова
            'notify_url' => 'https://webman.tinywan.cn/payment/alipay-notify',
            // Необязательный параметр - идентификатор провайдера услуг в режиме службы, используется при mode равном Pay::MODE_SERVICE
            'service_provider_id' => '',
            // Необязательный параметр - по умолчанию нормальный режим. Возможные значения: MODE_NORMAL, MODE_SANDBOX, MODE_SERVICE
            'mode' => \Yansongda\Pay\Pay::MODE_SANDBOX,
        ]
    ],
    'wechat' => [
        'default' => [
            // Обязательный параметр - идентификатор торговца, в режиме службы - это идентификатор торговца провайдера услуг
            'mch_id' => '',
            // Обязательный параметр - секретный ключ торговца
            'mch_secret_key' => '',
            // Обязательный параметр - закрытый ключ торговца, строка или путь
            'mch_secret_cert' => '',
            // Обязательный параметр - путь к сертификату открытого ключа торговца
            'mch_public_cert_path' => '',
            // Обязательный параметр
            'notify_url' => 'https://yansongda.cn/wechat/notify',
            // Необязательный параметр - app_id мини-программы
            'mp_app_id' => '2016082000291234',
            // Необязательный параметр - app_id мини-программы
            'mini_app_id' => '',
            // Необязательный параметр - app_id приложения
            'app_id' => '',
            // Необязательный параметр - app_id объединенного заказа
            'combine_app_id' => '',
            // Необязательный параметр - идентификатор объединенного торговца
            'combine_mch_id' => '',
            // Необязательный параметр - app_id дочернего публичного аккаунта в режиме службы
            'sub_mp_app_id' => '',
            // Необязательный параметр - app_id дочернего приложения в режиме службы
            'sub_app_id' => '',
            // Необязательный параметр - app_id дочерней мини-программы в режиме службы
            'sub_mini_app_id' => '',
            // Необязательный параметр - ID дочернего торговца в режиме службы
            'sub_mch_id' => '',
            // Необязательный параметр - путь к сертификату открытого ключа WeChat, рекомендуется настраивать этот параметр в режиме php-fpm
            'wechat_public_cert_path' => [
                '45F59D4DABF31918AFCEC556D5D2C6E376675D57' => __DIR__.'/Cert/wechatPublicKey.crt',
            ],
            // Необязательный параметр - по умолчанию нормальный режим. Возможные значения: MODE_NORMAL, MODE_SERVICE
            'mode' => \Yansongda\Pay\Pay::MODE_SANDBOX,
        ]
    ],
    'logger' => [
        'enable' => false,
        'file' => runtime_path().'/logs/alipay.log',
        'level' => 'debug', // Рекомендуется устанавливать уровень на info в производственной среде и на debug в среде разработки
        'type' => 'single', // необязательный параметр, возможен daily.
        'max_file' => 30, // необязательный параметр, актуален при type равном daily, по умолчанию 30 дней
    ],
    'http' => [ // необязательный параметр
        'timeout' => 5.0,
        'connect_timeout' => 5.0,
        // Для получения дополнительных конфигурационных параметров обратитесь к [Guzzle](https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html)
    ]
];

Примечание: директория сертификатов не установлена; приведённый выше пример размещен в директории payment фреймворка.

├── payment
│   ├── alipayCertPublicKey_RSA2.crt
│   ├── alipayRootCert.crt
│   └── appCertPublicKey_2016090900470841.crt

Инициализация

Просто вызовите метод config для инициализации.

// Получить конфигурационный файл config/payment.php
$config = config('payment');
Pay::config($config);

Примечание: если вы используете песочницу Alipay, обязательно установите в конфигурационном файле 'mode' => \Yansongda\Pay\Pay::MODE_SANDBOX,; этот параметр по умолчанию установлен в нормальный режим.

Оплата (веб)

use support\Request;
use Yansongda\Pay\Pay;

/**
 * @param Request $request
 * @return string
 */
public function payment(Request $request)
{
    // 1. Инициализация конфигурации
    Pay::config(config('payment'));

    // 2. Веб-оплата
    $order = [
        'out_trade_no' => time(),
        'total_amount' => '8888.88',
        'subject' => 'webman payment',
        '_method' => 'get' // Использовать метод get для перенаправления
    ];
    return Pay::alipay()->web($order)->getBody()->getContents();
}

Асинхронный обратный вызов

use support\Request;
use Yansongda\Pay\Pay;

/**
 * @desc: Асинхронное уведомление от Alipay
 * @param Request $request
 * @return Response
 */
public function alipayNotify(Request $request): Response
{
    // 1. Инициализация конфигурации
    Pay::config(config('payment'));

    // 2. Обработка обратного вызова от Alipay
    $result = Pay::alipay()->callback($request->post());

    // ===================================================================================================
    // Пожалуйста, проверьте trade_status и другую логику самостоятельно; только если статус уведомления о сделке TRADE_SUCCESS или TRADE_FINISHED, Alipay считает, что покупатель произвел оплату успешно.
    // 1. Торговец должен проверить, соответствует ли out_trade_no заказу, созданному в системе торговца;
    // 2. Проверьте, действительно ли total_amount соответствует фактической сумме данного заказа (то есть сумме, созданной при создании заказа торговцем);
    // 3. Проверьте, соответствует ли seller_id (или seller_email) идентификатору оператора для данного out_trade_no;
    // 4. Проверьте, соответствует ли app_id данному торговцу.
    // 5. Другие бизнес-логические случаи
    // ===================================================================================================

    // 5. Обработка обратного вызова от Alipay
    return new Response(200, [], 'success');
}

Примечание: нельзя использовать метод return Pay::alipay()->success(); для ответа на обратный вызов Alipay; если вы используете промежуточное программное обеспечение, могут возникнуть проблемы с ним. Поэтому для ответа на Alipay необходимо использовать класс ответа webman support\Response;

Синхронный обратный вызов

use support\Request;
use Yansongda\Pay\Pay;

/**
 * @desc: Синхронное уведомление от Alipay
 * @param Request $request
 * @author Tinywan(ShaoBo Wan)
 */
public function alipayReturn(Request $request)
{
    Log::info('Синхронное уведомление от Alipay'.json_encode($request->get()));
    return 'success';
}

Дополнительные материалы

Посетите официальную документацию https://pay.yansongda.cn/docs/v3/