yansongda/pay PHP Payment SDK

repository·master·Indexed 26 days ago

https://github.com/yansongda/pay

A highly abstracted PHP payment SDK featuring a plugin-based architecture and multi-tenant support. It simplifies integration with payment gateways including Alipay, WeChat Pay, Douyin, UnionPay, Jiangsu Bank (e-Rong Pay), and Airwallex. The SDK is compatible with modern PHP standards (PSR) and provides dedicated extension packages for Hyperf, Laravel, and Yii.

Tokens
57.3K
Snippets
181
Records
373
Agent score
90%

What's inside yansongda/pay

  1. Overview of yansongda/pay v3

    master
    yansongda/pay v3 is a PHP payment SDK designed to be highly extensible and easy to use. It features a redesigned architecture compared to v2.x, focusing on multi-tenant support, Swoole compatibility, and a flexible plugin mechanism. It abstracts complex JSON and XML manipulations and follows major PSR standards (PSR2, PSR3, PSR4, PSR7, PSR11, PSR14, PSR18) for easy integration with existing frameworks.
  2. Understand the return formats of yansongda/pay

    master

    The yansongda/pay library returns one of three types depending on the method called. These formats are consistent with yansongda/artful:

    1. \Psr\Http\Message\MessageInterface (specifically \GuzzleHttp\Psr7\Response): Used for methods that generate a direct HTTP response.
    2. \Yansongda\Supports\Collection: The default return type for most API calls (e.g., refunds, transfers, mini-program payments).
    3. \Yansongda\Artful\Rocket: A specialized return type available via custom configuration.
  3. Check PHP version compatibility and version support

    master

    Before installing, ensure your PHP environment meets the requirements for the version you intend to use.

    • v3.7 (Current Active Development): Requires PHP >= 8.0. This is the recommended version for new projects.
    • v3.4~v3.x: Requires PHP >= 8.0 (End of Life, no longer maintained).
    • v3.0~v3.3: Requires PHP >= 7.3 (End of Life, no longer maintained).
    • v2.x: Requires PHP >= 7.0. Provides security support only; no new features are being developed.
    • v1.x: Requires PHP >= 5.6 (End of Life, no longer maintained).
  4. Quickstart WeChat (v2) Integration

    master

    To integrate WeChat using version 2 of the library, configure your credentials including appid (App), app_id (Official Account), miniapp_id (Mini Program), mch_id, and key. You can optionally provide cert_client and cert_key for refund operations. Use Pay::wechat($config) to initialize the driver.

    Mini Program (MP) Payment Flow

    1. Create Order: Define an order array with out_trade_no, total_fee (in cents/fen), body, and openid. Use ->mp($order) to get the payment parameters.
    2. Handle Notify: Use Pay::wechat($config)->verify() within a try-catch block to validate the signature. After processing, return a success response using ->success()->send().
    <?php
    
    namespace App\Http\Controllers;
    
    use Yansongda\Pay\Pay;
    use Yansongda\Pay\Log;
    
    class PayController
    {
        protected $config = [
            'appid' => 'wxb3fxxxxxxxxxxx',
            'app_id' => 'wxb3fxxxxxxxxxxx',
            'miniapp_id' => 'wxb3fxxxxxxxxxxx',
            'mch_id' => '14577xxxx',
            'key' => 'mF2suE9sU6Mk1Cxxxxxxxxxxx',
            'notify_url' => 'http://yanda.net.cn/notify.php',
            'cert_client' => './cert/apiclient_cert.pem',
            'cert_key' => './cert/apiclient_key.pem',
            'log' => [
                'file' => './logs/wechat.log',
                'level' => 'info',
                'type' => 'single',
                'max_file' => 30,
            ],
            'http' => [
                'timeout' => 5.0,
                'connect_timeout' => 5.0,
            ],
            'mode' => 'dev',
        ];
    
        public function index()
        {
            $order = [
                'out_trade_no' => time(),
                'total_fee' => '1',
                'body' => 'test body - 测试',
                'openid' => 'onkVf1FjWS5SBIixxxxxxx',
            ];
    
            $pay = Pay::wechat($this->config)->mp($order);
    
            // $pay->appId
            // $pay->timeStamp
            // $pay->nonceStr
            // $pay->package
            // $pay->signType
        }
    
        public function notify()
        {
            $pay = Pay::wechat($this->config);
    
            try{
                $data = $pay->verify();
                Log::debug('Wechat notify', $data->all());
            } catch (\Exception $e) {
                // handle error
            }
            
            return $pay->success()->send();
        }
    }
  5. Quickstart Alipay (v2) Integration

    master

    To integrate Alipay using version 2 of the library, configure your credentials including app_id, notify_url, return_url, ali_public_key, and private_key (using RSA2 encryption). You can also configure logging and HTTP timeouts. Use Pay::alipay($config) to initialize the driver.

    Web Payment Flow

    1. Create Order: Define an order array with out_trade_no, total_amount, and subject. Use ->web($order)->send() to generate the payment redirect.
    2. Handle Return: Use Pay::alipay($config)->verify() to validate the signature on the return URL. The returned object contains out_trade_no, trade_no, and total_amount.
    3. Handle Notify: Use Pay::alipay($config)->verify() within a try-catch block to validate asynchronous notifications. After processing business logic, return a success response using ->success()->send().
    <?php
    
    namespace App\
    Http\\Controllers;
    
    use Yansongda\Pay\Pay;
    use Yansongda\Pay\Log;
    
    class PayController
    {
        protected $config = [
            'app_id' => '2016082000295641',
            'notify_url' => 'http://yansongda.cn/notify.php',
            'return_url' => 'http://yansongda.cn/return.php',
            'ali_public_key' => 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuWJKrQ6SWvS6niI+4vEVZiYfjkCfLQfoFI2nCp9ZLDS42QtiL4Ccyx8scgc3nhVwmVRte8f57TFvGhvJD0upT4O5O/lRxmTjechXAorirVdAODpOu0mFfQV9y/T9o9hHnU+VmO5spoVb3umqpq6D/Pt8p25Yk852/w01VTIczrXC4QlrbOEe3sr1E9auoC7rgYjjCO6lZUIDjX/oBmNXZxhRDrYx4Yf5X7y8FRBFvygIE2FgxV4Yw+SL3QAa2m5MLcbusJpxOml9YVQfP8iSurx41PvvXUMo49JG3BDVernaCYXQCoUJv9fJwbnfZd7J5YByC+5KM4sblJTq7bXZWQIDAQAB',
            'private_key' => 'MIIEpAIBAAKCAQEAs6+F2leOgOrvj9jTeDhb5q46GewOjqLBlGSs/bVL4Z3fMr3p+Q1Tux/6uogeVi/eHd84xvQdfpZ87A1SfoWnEGH5z15yorccxSOwWUI+q8gz51IWqjgZxhWKe31BxNZ+prnQpyeMBtE25fXp5nQZ/pftgePyUUvUZRcAUisswntobDQKbwx28VCXw5XB2A+lvYEvxmMv/QexYjwKK4M54j435TuC3UctZbnuynSPpOmCu45ZhEYXd4YMsGMdZE5/077ZU1aU7wx/gk07PiHImEOCDkzqsFo0Buc/knGcdOiUDvm2hn2y1XvwjyFOThsqCsQYi4JmwZdRa8kvOf57nwIDAQABAoIBAQCw5QCqln4VTrTvcW+msB1ReX57nJgsNfDLbV2dG8mLYQemBa9833DqDK6iynTLNq69y88ylose33o2TVtEccGp8Dqluv6yUAED14G6LexS43KtrXPgugAtsXE253ZDGUNwUggnN1i0MW2RcMqHdQ9ORDWvJUCeZj/AEafgPN8AyiLrZeL07jJz/uaRfAuNqkImCVIarKUX3HBCjl9TpuoMjcMhz/MsOmQ0agtCatO1eoH1sqv5Odvxb1i59c8Hvq/mGEXyRuoiDo05SE6IyXYXr84/Nf2xvVNHNQA6kTckj8shSi+HGM4mO1Y4Pbb7XcnxNkT0Inn6oJMSiy56P+CpAoGBAO1O+5FE1ZuVGuLb48cY+lHCD+nhSBd66B5FrxgPYCkFOQWR7pWyfNDBlmO3SSooQ8TQXA25blrkDxzOAEGX57EPiipXr/hy5e+WNoukpy09rsO1TMsvC+v0FXLvZ+TIAkqfnYBgaT56ku7yZ8aFGMwdCPL7WJYAwUIcZX8wZ3dAoGBAMHWplAqhe4bfkGOEEpfs6VvEQxCqYMYVyR65K0rI1LiDZn6Ij8fdVtwMjGKFSZZTspmsqnbbuCE/VTyDzF4NpAxdm3cBtZACv1Lpu2Om+aTzhK2PI6WTDVTKAJBYegXaahBCqVbSxieR62IWtmOMjggTtAKWZ1P5LQcRwdkaB2rAoGAWnAPT318Kp7YcDx8whOzMGnxqtCc24jvk2iSUZgb2Dqv+3zCOTF6JUsV0Guxu5bISoZ8GdfSFKf5gBAo97sGFeuUBMsHYPkcLehM1FmLZk1Q+ljcx3P1A/ds3kWXLolTXCrlpvNMBSN5NwOKAyhdPK/qkvnUrfX8sJ5XK2H4J8ECgYAGIZ0HIiE0Y+g9eJnpUFelXvsCEUW9YNK4065SD/BBGedmPHRC3OLgbo8X5A9BNEf6vP7fwpIiRfKhcjqqzOuk6fueA/yvYD04v+Da2MzzoS8+hkcqF3T3pta4I4tORRdRfCUzD80zTSZlRc/h286Y2eTETd+By1onnFFe2X01mwKBgQDaxo4PBcLL2OyVT5DoXiIdTCJ8KNZL9+kV1aiBuOWxnRgkDjPngslzNa1bK+klGgJNYDbQqohKNn1HeFX3mYNfCUpuSnD2Yag53Dd/1DLO+NxzwvTu4D6DCUnMMMBVaF42ig31Bs0jI3JQZVqeeFzSET8fkoFopJf3G6UXlrIEAQ==',
            'log' => [
                'file' => './logs/alipay.log',
                'level' => 'info',
                'type' => 'single',
                'max_file' => 30,
            ],
            'http' => [
                'timeout' => 5.0,
                'connect_timeout' => 5.0,
            ],
            'mode' => 'dev',
        ];
    
        public function index()
        {
            $order = [
                'out_trade_no' => time(),
                'total_amount' => '1',
                'subject' => 'test subject - 测试',
            ];
    
            $alipay = Pay::alipay($this->config)->web($order);
    
            return $alipay->send();
        }
    
        public function return()
        {
            $data = Pay::alipay($this->config)->verify();
        }
    
        public function notify()
        {
            $alipay = Pay::alipay($this->config);
        
            try{
                $data = $alipay->verify();
                Log::debug('Alipay notify', $data->all());
            } catch (\Exception $e) {
                // handle error
            }
    
            return $alipay->success()->send();
        }
    }
  6. Handle Alipay success callback

    master

    To notify Alipay that the callback was received successfully, use the success() method on your Alipay instance. This method requires no parameters and returns a Response object.

    In a standard PHP environment, use $alipay->success()->send() to output the response. If you are using the Laravel framework, you can simply return the response object directly.

  7. Handle Jiangsu Bank (e-Rong) callback

    master

    To process a callback from Jiangsu Bank (e-Rong) payment, use the callback() method on the jsb() driver. This method returns a Collection instance containing the processed parameters.

    Important Note for Swoole Users: If you are running in a Swoole environment, do not pass null. Instead, pass a ServerRequestInterface object to ensure the request is correctly handled.

    Pay::config($this->config);
    
    // Process the callback
    $result = Pay::jsb()->callback();
  8. Switch configurations for multi-tenancy

    master

    In v3.x, the library supports multi-tenancy. To switch to a different configuration set during a specific operation, include the '_config' key in your request parameters, setting it to the name of the configuration you wish to use.

    Pay::config($this->config);
    
    $order = [
        'out_trade_no' => '1514027114',
        '_config' => 'default', // Specifies the configuration to use
    ];
    
    $result = Pay::alipay()->find($order);
  9. Refund via Alipay

    master

    Use the refund method on an Alipay instance to process a refund. The method accepts an array of order parameters and returns a Collection object containing the server response.

    Note: This documentation is for version 2 (v2) of the library. The configuration parameters are identical to the official Alipay API; refer to the official Alipay documentation for the full list of available request parameters.

    $order = [
        'out_trade_no' => '1514027114',
        'refund_amount' => '0.01',
    ];
    
    $result = $alipay->refund($order);
  10. Handle UnionPay (Unipay) callbacks

    master

    To process a callback from UnionPay, use the callback() method on the unipay() driver. This method returns a Collection instance containing the processed parameters.

    Important Environment Note:

    • If running in a standard php-fpm environment, you can call the method without arguments.
    • If running in a swoole environment, it is highly recommended to pass a ServerRequestInterface object as the first argument to ensure correct request handling.
    Pay::config($this->config);
    
    // Simple usage for php-fpm
    $result = Pay::unipay()->callback();