簡單易用且優雅的跨境支付 PHP SDK 擴充套件包

削個椰子皮_給個梨發表於2021-10-10

支援國際版支付的 PHP SDK,目前只支援支付寶國際版。因目前支付寶跨境線上支付服務只支援 app、wap、web 和報關這四種,本 SDK 提供了 app、wap、web 這三種跨境支付,詳見國際支付寶官方文件

安裝

composer require pudongping/global-pay -vvv

特點

  • 命名規範
  • 隱藏開發者不需要關注的細枝末節
  • 符合 PSR 規範,可以方便的與各種 PHP 框架整合
  • 有良好的文件,包含各種示例方法以及官方返回結果。文件地址pudongping.github.io/global-pay-do...

執行環境

  • PHP >= 7.1.3
  • Composer

支援的支付方法

支付寶

  • 電腦支付
  • 手機網站支付
  • APP 支付
method 描述
web 電腦支付
wap 手機網站支付
app APP 支付

支援的方法

所有閘道器均支援以下方法

  • find(array|string $order)
    說明: 查詢訂單介面
    引數: $orderstring 型別時,請傳入系統訂單號,對應跨境支付寶中的 out_trade_no 引數; array 型別時,引數請參考支付寶境外訂單單筆查詢文件
    返回: 查詢成功,返回 Illuminate\Support\Collection 例項,可以通過 $collection->toArray() 或者 $collection->all() 或者 $collection->get('field') 訪問伺服器返回的資料。

  • refund(array $order)
    說明: 退款介面
    引數: $order 陣列格式,退款引數請參考支付寶境外退款介面文件
    返回: 退款成功,返回 Illuminate\Support\Collection 例項,可以通過 $collection->toArray() 或者 $collection->all() 或者 $collection->get('field') 訪問伺服器返回的資料。

  • verify()
    說明: 驗證伺服器返回資料是否合法
    返回: 驗證成功,返回 Illuminate\Support\Collection 例項,可以通過 $collection->toArray() 或者 $collection->all() 或者 $collection->get('field') 訪問伺服器返回的資料。

其他通用方法

  • getExchangeRate()
    說明: 獲取匯率。詳見支付寶境外匯率查詢介面
    返回: 獲取成功,返回 Illuminate\Support\Collection 例項,可以通過 $collection->toArray() 或者 $collection->all() 或者 $collection->get('field') 訪問伺服器返回的資料。
    注意: 1、貨幣間的匯率會在北京時間每日 9:00 到 11:00 間變動一次; 2、匯率每日獲取上限為 100 次。 (可能需要考慮通過快取儲存匯率,防止介面出現異常,因為本 SDK 沒有做快取處理)

  • getHbFqCost(float $totalAmount, bool $isShowAll = false, bool $isSellerPercent = false)
    說明: 獲取花唄分期計費情況
    引數: $totalAmount 為分期的本金,$isShowAll 為是否顯示每一期的還款數,$isSellerPercenttrue 表示商家承擔全部手續費,為 false 表示使用者承擔全部手續費。
    返回: 獲取成功,返回 Illuminate\Support\Collection 例項,可以通過 $collection->toArray() 或者 $collection->all() 或者 $collection->get('field') 訪問伺服器返回的資料。

返回引數說明

引數 含義
nper 期數
total_amount 本金
total_charge 總手續費
rate 利率
per_charge 每期手續費
per_amount 每期本金
per_total_amount 每期總費用
refund_list 還款列表
refund_list.nper 第幾期
refund_list.charge 當前期數所需要支付的手續費
refund_list.amount 當前期數所需要支付的本金數
refund_list.current_total_amount 當前期數所需要支付的總費用

使用說明

非花唄分期支付


<?php

declare(strict_types=1);

namespace App\Controller;

use Pudongping\GlobalPay\GlobalPay;
use Pudongping\GlobalPay\Log;

class PayController
{

    protected $config = [
        'partner' => '2088000000000000',  // 合作身份者 id,以 2088 開頭的 16 位純數字
        'notify_url' => 'http://a90b-8-37-43-168.demo.io/index/notify_url',  // 非同步回撥地址
        'return_url' => 'http://a90b-8-37-43-168.demo.io/index/return_url',  // 同步回撥地址
        'refer_url' => 'https://www.demo.net',  // 二級商戶網站地址
        'seller_email' => 'xxxx@gmail.com',  // 簽約支付寶賬號或賣家支付寶帳戶
        'key' => 'xxxx',  // 安全檢驗碼,以數字和字母組成的 32 位字元
        'sign_type' => 'RSA',  // 不需要修改
        'input_charset' => 'UTF-8',  // 商戶網站使用的編碼格式,建議不需要修改
        'transport' => 'http',  // 訪問模式,根據自己的伺服器是否支援 ssl 訪問,若支援請選擇 https;若不支援請選擇 http
        'split_fund' => '2088000000000000:0.10',  // 接受分賬資金的支付寶賬戶 ID 和比例,用逗號分隔其他帳號資訊。ID 是以 2088 開頭的純 16 位數字。
        'private_key' => '/Users/pudongping/glory/key/alipay_private_key.pem',  // 私鑰路徑
        'public_key' => '/Users/pudongping/glory/key/alipay_public_key.pem',  // 公鑰路徑

        'log' => [ // optional
            'file' => 'alipay.log',  // 當前目錄下
            'level' => 'debug', // 建議生產環境等級調整為 info,開發環境為 debug
            'type' => 'single', // optional, 可選 daily.
            'max_file' => 30, // optional, 當 type 為 daily 時有效,預設 30 天
        ],
        'http' => [ // optional
            'timeout' => 5.0,
            'connect_timeout' => 5.0,
            // 更多配置項請參考 [Guzzle](https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html)
        ],
        'mode' => 'dev', // optional,設定此引數,將進入沙箱模式
    ];

    /**
     * document link: https://global.alipay.com/docs/ac/web_cn/about
     *
     * @return mixed
     */
    public function web()
    {
        $order = [
            'out_trade_no' => time(),
            'subject' => '交易 alex ',
            'currency' => 'JPY',
            'rmb_fee' => '0.20',
            'trade_information' => json_encode([
                'business_type' => 4,
                'goods_info' => '変身ベ...^1',
                'total_quantity' => 1
            ], 256),
            // '_only_args' => true  // 只需要返回引數模式時增加
        ];

        $globalPay = GlobalPay::alipay($this->config)->web($order);

        return $globalPay->send();

        // 如果設定了 `_only_args` 為 true,則使用以下方法獲取所有的引數
        // var_dump($globalPay->getContent());

    }

    /**
     * document link:  https://global.alipay.com/docs/ac/wap_cn/start
     *
     * @return mixed
     */
    public function wap()
    {

        $order = [
            'out_trade_no' => time(),
            'subject' => '交易 alex ',
            'currency' => 'JPY',
            'rmb_fee' => '0.10',
            'trade_information' => json_encode([
                'business_type' => 4,
                'goods_info' => '変身ベ...^1',
                'total_quantity' => 1
            ], 256),
            // '_only_args' => true  // 只需要返回引數模式時增加
        ];

        $globalPay = GlobalPay::alipay($this->config)->wap($order);

        return $globalPay->send();

        // 如果設定了 `_only_args` 為 true,則使用以下方法獲取所有的引數
        // var_dump($globalPay->getContent());

    }

    /**
     * document link: https://global.alipay.com/docs/ac/app_cn/about
     */
    public function app()
    {
        $order = [
            'out_trade_no' => 'alex_' . time(),
            'subject' => '交易 5200',
            'currency' => 'JPY',
            'rmb_fee' => '1.01',
            'trade_information' => json_encode([
                'business_type' => 4,
                'goods_info' => '大海にて^1',
                'total_quantity' => 1
            ], 256),
        ];

        $globalPay = GlobalPay::alipay($this->config)->app($order);

        $content = $globalPay->getContent();

        var_dump($content);

    }

    /**
     * 單筆查詢介面 document link: https://global.alipay.com/docs/ac/global/single_trade_query_cn
     */
    public function find()
    {
        // out_trade_no 和 trade_no 引數可以同時含有,也可以二選一
        $order = [
            'out_trade_no' => 'alex_1629950066',
            // 'trade_no' => '2021082622001364941434754996',
        ];

        $globalPay = GlobalPay::alipay($this->config)->find($order);

        var_dump($globalPay->toArray());

    }

    /**
     * 退款介面 document link: https://global.alipay.com/docs/ac/global/forex_refund_cn
     */
    public function refund()
    {
        $order = [
            'out_return_no' => 'alex_refund_' . time(),
            'out_trade_no' => 'alex_1629950066',
            'return_rmb_amount' => '1.01',
            'currency' => 'JPY',
            'reason' => '退款測試',
            // 'is_sync' => 'N',  // 如果 is_sync => N 則開啟非同步通知,否則不開啟非同步通知,不開啟非同步通知 notify_url 引數將會失效(不需要開啟時,則不需要設定)
            // 'notify_url' => 'http://api.demo.com:8016/v2/alipay/forexNotify',  // $order['notify_url'] 設定了,則使用 $order['notify_url'] 的值,否則使用配置檔案中的 notify_url 引數
            // 'type' => 'pc',  // 如果是網站支付,則需要設定 type 引數為 pc,手機瀏覽器或支付寶錢包支付時,不需要設定
        ];

        $globalPay = GlobalPay::alipay($this->config)->refund($order);

        var_dump($globalPay->toArray());

    }

    /**
     * 同步驗籤
     */
    public function return()
    {
        $data = GlobalPay::alipay($this->config)->verify();
    }

    /**
     * 非同步驗籤
     *
     * @return mixed
     */
    public function notify()
    {
        $globalPay = GlobalPay::alipay($this->config);

        try {

            $data = $globalPay->verify();  // 驗籤

            // 建議必須對以下幾個引數進行業務邏輯驗證
            $outTradeNo = $data->get('out_trade_no');  // 商戶需要驗證該通知資料中的 out_trade_no 是否為商戶系統中建立的訂單號。
            $tradeStatus = $data->get('trade_status');  // 在支付寶的業務通知中,只有交易通知狀態為 TRADE_FINISHED 時,支付寶才會認定為買家付款成功。
            $totalFee = $data->get('total_fee');  // 該筆訂單的總金額。請求時對應的引數,原樣通知回來。(外幣金額)

            Log::debug('GlobalPay Notify ===> ', $data->all());

        } catch (\Exception $exception) {
            Log::error('非同步通知異常 ===> ' . $exception->getMessage());
            return $globalPay->fail()->send();  // 其他框架
            // return $globalPay->fail();  // Laravel 框架可以直接這樣
        }

        return $globalPay->success()->send();  // 其他框架
        // return $globalPay->success();  //  Laravel 框架可以直接這樣
    }

    /**
     * 獲取匯率
     */
    public function getExchangeRate()
    {
        $globalPay = GlobalPay::alipay($this->config)->getExchangeRate();

        var_dump($globalPay->toArray());
    }

}

花唄分期支付


<?php

declare(strict_types=1);

namespace App\Controller;

use Pudongping\GlobalPay\GlobalPay;
use Pudongping\GlobalPay\Log;

class HbfqPayController
{

    public function web()
    {
        $order = [
            'out_trade_no' => time(),
            'subject' => '交易 alex',
            'currency' => 'JPY',
            'rmb_fee' => 5.45,
            'trade_information' => json_encode([
                'business_type' => 4,
                'goods_info' => '交易費用^1',
                'total_quantity' => 1
            ], 256),
            'hb_fq_param' => [
                'num' => 3,  // 花唄分期分期數,只支援 3、6、12 期
                // 只有 is_has_household 為 true, is_seller_percent 才能設定為 true
                'is_has_household' => false,  // 是否擁有出資戶,只有擁有出資戶,商家才能貼息,否則只能使用者貼息
                'is_seller_percent' => false,  // 是否商家貼息
                // 花唄分期開啟訂單傳參貼息活動(不支援 PC 支付,無論是國際還是國內的交易都不支援)
                // 因此相比 app 支付,不能傳遞 is_order_subsidy 引數
            ],
            // '_only_args' => true  // 只需要返回引數模式時增加
        ];

        $globalPay = GlobalPay::alipay($this->config)->web($order);

        return $globalPay->send();

        // 如果設定了 `_only_args` 為 true,則使用以下方法獲取所有的引數
        // var_dump($globalPay->getContent());
    }

    public function wap()
    {
        $order = [
            'out_trade_no' => time(),
            'subject' => '交易 alex',
            'currency' => 'JPY',
            'rmb_fee' => 5.45,
            'trade_information' => json_encode([
                'business_type' => 4,
                'goods_info' => '交易費用^1',
                'total_quantity' => 1
            ], 256),
            'hb_fq_param' => [
                'num' => 3,  // 花唄分期分期數,只支援 3、6、12 期
                // 只有 is_has_household 為 true, is_seller_percent 才能設定為 true
                'is_has_household' => false,  // 是否擁有出資戶,只有擁有出資戶,商家才能貼息,否則只能使用者貼息
                'is_seller_percent' => false,  // 是否商家貼息
                // 花唄分期開啟訂單傳參貼息活動(不支援 PC 支付,無論是國際還是國內的交易都不支援)
                // 因此相比 app 支付,不能傳遞 is_order_subsidy 引數
            ],
            // '_only_args' => true  // 只需要返回引數模式時增加
        ];

        $globalPay = GlobalPay::alipay($this->config)->wap($order);

        return $globalPay->send();

        // 如果設定了 `_only_args` 為 true,則使用以下方法獲取所有的引數
        // var_dump($globalPay->getContent());
    }

    public function app()
    {
        $order = [
            'out_trade_no' => time(),
            'subject' => '交易 alex',
            'currency' => 'JPY',
            'rmb_fee' => 3.45,
            'trade_information' => json_encode([
                'business_type' => 4,
                'goods_info' => '交易費用^1',
                'total_quantity' => 1
            ], 256),
            'hb_fq_param' => [
                'num' => 3,  // 花唄分期分期數,只支援 3、6、12 期
                // 只有 is_has_household 為 true, is_seller_percent 才能設定為 true,否則 is_seller_percent 只能設定為 false
                'is_has_household' => false,  // 是否擁有出資戶,只有擁有出資戶,商家才能貼息,否則只能使用者貼息
                'is_seller_percent' => false,  // 是否商家貼息, true 為商家貼息, false 為使用者貼息
                'is_order_subsidy' => false,  // 是否開啟訂單傳參貼息活動
                // 出資戶貼息和訂單傳參貼息只能允許一個為 true
            ],
        ];

        $globalPay = GlobalPay::alipay($this->config)->app($order);

        $content = $globalPay->getContent();

        var_dump($content);
    }

    public function find()
    {
        // out_trade_no 和 trade_no 引數可以同時含有,也可以二選一
        $order = [
            'out_trade_no' => 'alex_1629950066',
            // 'trade_no' => '2021082622001364941434754996',
            'is_hbfq' => true,  // 該筆訂單是否為花唄分期支付,訂單查詢出來的結果會含有 hb_fq_num 引數,不是花唄分期訂單則沒有這個引數
        ];

        $globalPay = GlobalPay::alipay($this->config)->find($order);

        var_dump($globalPay->toArray());
    }

    public function refund()
    {
        // 花唄分期退款和非花唄分期退款操作流程一致
        $order = [
            'out_return_no' => 'alex_refund_' . time(),
            'out_trade_no' => 'alex_1629950066',
            'return_rmb_amount' => 3.45,
            'currency' => 'JPY',
            'reason' => '退款測試',
            // 'is_sync' => 'N',  // 如果 is_sync => N 則開啟非同步通知,否則不開啟非同步通知,不開啟非同步通知 notify_url 引數將會失效(不需要開啟時,則不需要設定)
            // 'notify_url' => 'http://api.demo.com:8016/v2/alipay/forexNotify',  // $order['notify_url'] 設定了,則使用 $order['notify_url'] 的值,否則使用配置檔案中的 notify_url 引數
            // 'type' => 'pc',  // 如果是網站支付,則需要設定 type 引數為 pc,手機瀏覽器或支付寶錢包支付時,不需要設定
        ];

        $globalPay = GlobalPay::alipay($this->config)->refund($order);

        var_dump($globalPay->toArray());
    }

    public function return()
    {
        $data = GlobalPay::alipay($this->config)->verify();
    }

    public function notify()
    {
        $globalPay = GlobalPay::alipay($this->config);

        try {

            $data = $globalPay->verify();  // 驗籤

            // 建議必須對以下幾個引數進行業務邏輯驗證
            $outTradeNo = $data->get('out_trade_no');  // 商戶需要驗證該通知資料中的 out_trade_no 是否為商戶系統中建立的訂單號。
            $tradeStatus = $data->get('trade_status');  // 在支付寶的業務通知中,只有交易通知狀態為 TRADE_FINISHED 時,支付寶才會認定為買家付款成功。
            $totalFee = $data->get('total_fee');  // 該筆訂單的總金額。請求時對應的引數,原樣通知回來。(外幣金額)

            Log::debug('GlobalPay Notify ===> ', $data->all());

        } catch (\Exception $exception) {
            Log::error('非同步通知異常 ===> ' . $exception->getMessage());
            return $globalPay->fail()->send();  // 其他框架
            // return $globalPay->fail();  // Laravel 框架可以直接這樣
        }

        return $globalPay->success()->send();  // 其他框架
        // return $globalPay->success();  //  Laravel 框架可以直接這樣
    }

    /**
     * 獲取花唄分期計費情況
     */
    public function getHbFqCost()
    {
        $totalAmount = 100.88;

        // 只需要獲取 3 6 12 期相對應的還款數
        // $globalPay = GlobalPay::alipay($this->config)->getHbFqCost($totalAmount);

        // 獲取 3 6 12 期相對應到還款數且顯示出每一期的還款情況(使用者承擔所有的手續費)
        // $globalPay = GlobalPay::alipay($this->config)->getHbFqCost($totalAmount, true);

        // 獲取 3 6 12 期相對應到還款數且顯示出每一期的還款情況(商家承擔所有的手續費)
        $globalPay = GlobalPay::alipay($this->config)->getHbFqCost($totalAmount, true, true);

        var_dump($globalPay->toArray());
    }

}

LICENSE

MIT

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章