API文档>QStack>插件>公共部分 > 支付通道插件开发说明

支付通道插件开发说明

发布时间:2022-03-30 15:33

一、概述

通过支付插件,你可以将您所需要的支付通道集成到QStack系统当中,该插件类型属于钩子类型的插件。

二、根据插件开发说明文档创建好插件的基本结构

三、实现支付钩子 PaymentChannelHook 接口

    public function hookPaymentChannel(): PaymentChannelConfig
    {
        $dir = __DIR__ . DIRECTORY_SEPARATOR;
        $html_snippet = file_get_contents("{$dir}html_snippet.html");
        $logo = "data:image/jpg;base64," . base64_encode(file_get_contents("{$dir}logo.jpg"));

        return new PaymentChannelConfig(
            '样例支付渠道', // 渠道名称
            $logo, // 渠道图标
            $html_snippet, // html 片段
            'demo_payment', // 渠道唯一标识 (建议与插件名称一致,需要全局唯一)
            self::class, // PaymentProcessor 实例(也可以单独创建一个类实现 PaymentProcessor 接口)
            'demo_payment_handler', // js_handler 脚本处理
            '手续费=充值金额 * 手续费(1%)<br>到账金额=充值金额 - 手续费' // 手续费规则(支持富文本)
        );
    }

四、实现支付处理钩子 PaymentProcessor 接口

    /**
     * 以下方法中,如果需要用到用户的自定义配置,需要参考"插件开发说明"文档中“参数配置”的内容
     */

    public function calcHandlingFee(float $float): float
    {
        // 计算充值手续费
        return $float * 0.01;
    }

    public function amountValidate(float $amount)
    {
        // 检查充值金额是否合法,如果不合法,需要抛出异常以终止订单流程
    }

    public function isInclusiveTax(): bool
    {
        // 充值是否含税
        return true;
    }

    public function createOrder(string $out_trade_no, float $amount, array $extra_params): array
    {
        /**
         * 创建充值订单
         * 在这里,您需要调用上游 API 创建充值订单
         * extra_params 中包含您在 js_handler 中添加的额外的参数,以及其它可能会用到的额外的参数
         * 这个方法的返回值会原样传递给 js_handler
         */
        return ['payment_url' => 'https://www.alipay.com/'];
    }

五、编写 html_snippet 文件


<!--
    本文件中的内容会被渲染到 用户中心->财务管理->充值中心 页面的固定区域

    本文件支持 thinkPHP 模板语法

    本文件中可以获取到本插件的配置信息,变量名为 [插件标识]_config

    本文件必须加载一个可以全局引用的 js_handler
-->

<div>
    <h1>{$demo_payment_config['description']}</h1>
</div>

<script>
    /**
     * 实现 js_handler
     * handler 的名称必须与 hookPaymentChannel 返回值中的 js_handler 字段一致
     * handler 必须可以全局访问
     */
    var demo_payment_handler = {
        // 当支付渠道被选中时,该方法会被调用
        on_selected: function () {
            console.log('选中demo_payment')
        },
        // 当支付金额变动时,该方法会被调用
        after_amount_change: function (value) {
            console.log('金额变动:', value);
        },
        // 当用户确认充值后,该方法会被调用,返回值作为额外参数传递给 createOrder 方法
        before_submit: function () {
            console.log('提交前')
            return { extra_param: '额外参数' }
        },
        // 订单创建成功后,该方法会被调用,createOrder 方法的返回值作为参数传入
        after_submit: function (res) {
            console.log('提交后', res)
            window.open(res.payment_url)
        }
    }
</script>

六、实现支付回调API

<?php

declare(strict_types=1);

namespace app\apinotify\controller;

use app\common\controller\ApiNotifyController;
use app\common\service\UnifiedPaymentService;

class DemoPaymentController extends ApiNotifyController
{
    public function index(UnifiedPaymentService $unified_payment_service)
    {
        /**
         * 这个接口作为支付成功的回调接口
         * 您需要检验回调信息的签名是否合法
         * 校验通过后,调用 UnifiedPaymentService->unifiedPaymentConfirm 进行订单确认
         */

        if ($unified_payment_service->unifiedPaymentConfirm(
            'demo_payment', // 渠道唯一标识
            '202105182939', // 交易单号(由 QStack 生成)
            '20210518293923131', // 支付单号 (由支付平台生成)
            100.00, // 充值金额
            10, // 用户ID(可空)
            'xxxxx' // 付款人信息(可空)
        )) {
            return 'success';
        } else {
            return 'failed';
        }
    }
}

完整的插件主类代码示例

<?php

declare(strict_types=1);

namespace demo_payment;

use app\common\contracts\addon\PaymentChannelConfig;
use app\common\contracts\addon\PaymentChannelHook;
use app\common\contracts\PaymentProcessor;

class DemoPayment implements PaymentChannelHook, PaymentProcessor
{
    public function hookPaymentChannel(): PaymentChannelConfig
    {
        $dir = __DIR__ . DIRECTORY_SEPARATOR;
        $html_snippet = file_get_contents("{$dir}html_snippet.html");
        $logo = "data:image/jpg;base64," . base64_encode(file_get_contents("{$dir}logo.jpg"));

        return new PaymentChannelConfig(
            '样例支付渠道', // 渠道名称
            $logo, // 渠道图标
            $html_snippet, // html 片段
            'demo_payment', // 渠道唯一标识 (建议与插件名称一直,需要全局唯一)
            self::class, // PaymentProcessor 示例,可以单独创建一个类
            'demo_payment_handler', // js_handler
            '手续费=充值金额 * 手续费(1%)<br>到账金额=充值金额 - 手续费' // 手续费规则
        );
    }


    /**
     * 以下方法中,如果需要用到用户的自定义配置,需要参考"插件开发说明"文档中“参数配置”的内容
     */

    public function calcHandlingFee(float $float): float
    {
        // 计算充值手续费
        return $float * 0.01;
    }

    public function amountValidate(float $amount)
    {
        // 检查充值金额是否合法,如果不合法,需要抛出异常以终止订单流程
    }

    public function isInclusiveTax(): bool
    {
        // 充值是否含税
        return true;
    }

    public function createOrder(string $out_trade_no, float $amount, array $extra_params): array
    {
        /**
         * 创建充值订单
         * 在这里,您可以调用上游创建充值订单
         * extra_params 中包含您在 js_handler 中添加的额外的参数,以及其它可能会用到的额外的参数
         * 这个方法的返回值会原样传递给 js_handler
         */
        return ['payment_url' => 'https://www.alipay.com/'];
    }
}
本文导读