SDK de Pago (V3)

Dirección del proyecto

https://github.com/yansongda/pay

Instalación

composer require yansongda/pay ~3.0

Uso

Nota: La siguiente documentación está escrita asumiendo el entorno de sandbox de Alipay. Si hay algún problema, ¡haznoslo saber!

Archivo de configuración

Supongamos que hay el siguiente archivo de configuración config/payment.php

<?php
/**
 * @desc Archivo de configuración de pago
 * @author Tinywan(ShaoBo Wan)
 * @date 2022/03/11 20:15
 */
return [
    '_force' => true, // Nota: esto debe ser true
    'alipay' => [
        'default' => [
            // Requerido - app_id asignado por Alipay
            'app_id' => '20160909004708941',
            // Requerido - clave privada de la aplicación como cadena o ruta
            'app_secret_cert' => 'MIIEpAIBAAKCxxxxxxxxxxxxxxP4r3m4OUmD/+XDgCg==',
            // Requerido - ruta del certificado público de la aplicación
            'app_public_cert_path' => base_path().'/payment/appCertPublicKey_2016090900470841.crt',
            // Requerido - ruta del certificado público de Alipay
            'alipay_public_cert_path' => base_path().'/payment/alipayCertPublicKey_RSA2.crt',
            // Requerido - ruta del certificado raíz de Alipay
            'alipay_root_cert_path' => base_path().'/payment/alipayRootCert.crt',
            // Opcional - dirección de retorno síncrono
            'return_url' => 'https://webman.tinywan.cn/payment/alipay-return',
            // Opcional - dirección de retorno asíncrono
            'notify_url' => 'https://webman.tinywan.cn/payment/alipay-notify',
            // Opcional - ID del proveedor del servicio en modo proveedor de servicios, cuando el modo sea Pay::MODE_SERVICE
            'service_provider_id' => '',
            // Opcional - por defecto es el modo normal. Opciones: MODE_NORMAL, MODE_SANDBOX, MODE_SERVICE
            'mode' => \Yansongda\Pay\Pay::MODE_SANDBOX,
        ]
    ],
    'wechat' => [
        'default' => [
            // Requerido - número de comerciante, en modo proveedor de servicios es el número de comerciante del proveedor
            'mch_id' => '',
            // Requerido - clave secreta del comerciante
            'mch_secret_key' => '',
            // Requerido - clave privada del comerciante como cadena o ruta
            'mch_secret_cert' => '',
            // Requerido - ruta del certificado público del comerciante
            'mch_public_cert_path' => '',
            // Requerido
            'notify_url' => 'https://yansongda.cn/wechat/notify',
            // Opcional - app_id del mini programa
            'mp_app_id' => '2016082000291234',
            // Opcional - app_id del mini programa
            'mini_app_id' => '',
            // Opcional - app_id de la aplicación
            'app_id' => '',
            // Opcional - app_id del pedido combinado
            'combine_app_id' => '',
            // Opcional - número de comerciante del pedido combinado
            'combine_mch_id' => '',
            // Opcional - app_id del sub-publico en modo proveedor de servicios
            'sub_mp_app_id' => '',
            // Opcional - app_id del sub-app en modo proveedor de servicios
            'sub_app_id' => '',
            // Opcional - app_id del sub-mini programa en modo proveedor de servicios
            'sub_mini_app_id' => '',
            // Opcional - id del sub-comerciante en modo proveedor de servicios
            'sub_mch_id' => '',
            // Opcional - ruta del certificado público de WeChat, opcional, se recomienda configurar este parámetro en modo php-fpm
            'wechat_public_cert_path' => [
                '45F59D4DABF31918AFCEC556D5D2C6E376675D57' => __DIR__.'/Cert/wechatPublicKey.crt',
            ],
            // Opcional - por defecto es el modo normal. Opciones: MODE_NORMAL, MODE_SERVICE
            'mode' => \Yansongda\Pay\Pay::MODE_SANDBOX,
        ]
    ],
    'logger' => [
        'enable' => false,
        'file' => runtime_path().'/logs/alipay.log',
        'level' => 'debug', // Se sugiere cambiar el nivel a info en producción, y a debug en desarrollo
        'type' => 'single', // opcional, puede ser daily.
        'max_file' => 30, // opcional, válido cuando el tipo es daily, predeterminado a 30 días
    ],
    'http' => [ // opcional
        'timeout' => 5.0,
        'connect_timeout' => 5.0,
        // Para más opciones de configuración, consulta [Guzzle](https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html)
    ]
];

Nota: No se ha especificado un directorio de certificados; el ejemplo anterior se coloca en el directorio payment del marco.

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

Inicialización

Llama directamente al método config para inicializar

// Obtener el archivo de configuración config/payment.php
$config = config('payment');
Pay::config($config);

Nota: Si estás en modo sandbox de Alipay, asegúrate de activar la opción en el archivo de configuración 'mode' => \Yansongda\Pay\Pay::MODE_SANDBOX, ya que esta opción por defecto está en modo normal.

Pago (web)

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

/**
 * @param Request $request
 * @return string
 */
public function payment(Request $request)
{
    // 1. Inicializar la configuración
    Pay::config(config('payment'));

    // 2. Pago web
    $order = [
        'out_trade_no' => time(),
        'total_amount' => '8888.88',
        'subject' => 'pago webman',
        '_method' => 'get' // Usa el método get para redirigir
    ];
    return Pay::alipay()->web($order)->getBody()->getContents();
}

Retorno asíncrono

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

/**
 * @desc: Notificación asíncrona de『Alipay』
 * @param Request $request
 * @return Response
 */
public function alipayNotify(Request $request): Response
{
    // 1. Inicializar la configuración
    Pay::config(config('payment'));

    // 2. Procesar la notificación de Alipay
    $result = Pay::alipay()->callback($request->post());

    // ===================================================================================================
    // Debes determinar el trade_status y otras lógicas; sólo se considerará que el comprador ha pagado exitosamente cuando el estado de la notificación de la transacción sea TRADE_SUCCESS o TRADE_FINISHED.
    // 1. El comerciante debe verificar si el out_trade_no en los datos de notificación corresponde al número de pedido creado en su sistema;
    // 2. Verificar si el total_amount coincide con el monto real de dicho pedido (es decir, el monto al crear el pedido del comerciante);
    // 3. Validar seller_id (o seller_email) en la notificación corresponde a la parte operativa del out_trade_no;
    // 4. Verificar si el app_id corresponde al comerciante.
    // 5. Otras lógicas de negocio
    // ===================================================================================================

    // 5. Procesar la notificación de Alipay
    return new Response(200, [], 'success');
}

Nota: No debes usar la respuesta del plugin mismo return Pay::alipay()->success(); para responder a la notificación de Alipay. Si usas middleware podría haber problemas con él. Por lo tanto, se debe usar la clase de respuesta de webman support\Response; para responder a Alipay.

Retorno síncrono

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

/**
 * @desc: Notificación síncrona de『Alipay』
 * @param Request $request
 * @author Tinywan(ShaoBo Wan)
 */
public function alipayReturn(Request $request)
{
    Log::info('Notificación síncrona de『Alipay』'.json_encode($request->get()));
    return 'success';
}

Más contenido

Consulta la documentación oficial en https://pay.yansongda.cn/docs/v3/