Project Icon

multipay

PHP支付网关集成包 支持多种驱动

multipay是一个PHP支付网关集成包,支持多种主流支付驱动。它提供统一API处理支付流程,包括创建发票、购买、支付和验证。支持PHP 7.2+,可与Laravel框架集成。开发者可创建自定义驱动扩展支持范围。multipay简化了支付集成,为开发提供了灵活可扩展的解决方案。

PHP支付网关

软件许可证 Packagist 最新版本 Packagist 总下载量 StyleCI 可维护性 代码质量评分

这是一个用于支付网关集成的PHP包。该包支持PHP 7.2+

如果您喜欢这个包,可以捐赠给我 :sunglasses: :bowtie:

对于Laravel集成,您可以使用shetabit/payment包。

此包可以使用多个驱动程序,如果在当前可用驱动程序列表中找不到所需的驱动程序,您可以创建自定义驱动程序。

目录

可用驱动程序列表

通过创建pull requests来帮助我添加以下网关

  • stripe
  • authorize
  • 2checkout
  • braintree
  • skrill
  • payU
  • amazon payments
  • wepay
  • payoneer
  • paysimple

如果列表中不存在,您可以创建自己的自定义驱动程序,请阅读创建自定义驱动程序部分。

安装

通过Composer安装

$ composer require shetabit/multipay

配置

a. 将config/payment.php复制到项目中的某个位置。(您也可以在vendor/shetabit/multipay/config/payment.php路径中找到它)。

b. 在配置文件中,您可以设置用于所有支付的默认驱动程序,也可以在运行时更改驱动程序。

选择您想在应用程序中使用的网关。然后将其设为默认驱动程序,这样您就不必在每个地方都指定它。但是,您也可以在一个项目中使用多个网关。

// 例如,如果您想使用zarinpal。
'default' => 'zarinpal',

然后在驱动程序数组中填写该网关的凭据。

'drivers' => [
    'zarinpal' => [
        // 在此处填写凭据。
        'apiPurchaseUrl' => 'https://www.zarinpal.com/pg/rest/WebGate/PaymentRequest.json',
        'apiPaymentUrl' => 'https://www.zarinpal.com/pg/StartPay/',
        'apiVerificationUrl' => 'https://www.zarinpal.com/pg/rest/WebGate/PaymentVerification.json',
        'merchantId' => '',
        'callbackUrl' => 'http://yoursite.com/path/to',
        'description' => 'payment in '.config('app.name'),
    ],
    ...
]

c. 实例化Payment类并将配置传递给它,如下所示:

    use Shetabit\Multipay\Payment;

    // 从项目中加载配置文件
    $paymentConfig = require('path/to/payment.php');

    $payment = new Payment($paymentConfig);

如何使用

您的Invoice保存了支付详情,所以我们首先讨论Invoice类。

处理发票

在做任何事情之前,您需要使用Invoice类来创建发票。

在代码中,像这样使用它:

// 在文件顶部。
use Shetabit\Multipay\Invoice;
...

// 创建新发票。
$invoice = new Invoice;

// 设置发票金额。
$invoice->amount(1000);

// 添加发票详情:有4种可用语法。
// 1
$invoice->detail(['detailName' => 'your detail goes here']);
// 2 
$invoice->detail('detailName','your detail goes here');
// 3
$invoice->detail(['name1' => 'detail1','name2' => 'detail2']);
// 4
$invoice->detail('detailName1','your detail1 goes here')
        ->detail('detailName2','your detail2 goes here');

可用方法:

  • uuid: 设置发票的唯一ID
  • getUuid: 获取发票当前的唯一ID
  • detail: 在发票中附加一些自定义详情
  • getDetails: 获取所有自定义详情
  • amount: 设置发票金额
  • getAmount: 获取发票金额
  • transactionId: 设置发票支付交易ID
  • getTransactionId: 获取支付交易ID
  • via: 设置我们用来支付发票的驱动程序
  • getDriver: 获取驱动程序

购买发票

为了支付发票,我们需要支付交易ID。 我们购买发票以获取交易ID:

// 在文件顶部。
use Shetabit\Multipay\Invoice;
use Shetabit\Multipay\Payment;
...

// 从项目中加载配置文件
$paymentConfig = require('path/to/payment.php');

$payment = new Payment($paymentConfig);


// 创建新发票。
$invoice = (new Invoice)->amount(1000);

// 购买给定的发票。
$payment->purchase($invoice,function($driver, $transactionId) {
	// 我们可以将$transactionId存储在数据库中。
});

// purchase方法接受一个回调函数。
$payment->purchase($invoice, function($driver, $transactionId) {
    // 我们可以将$transactionId存储在数据库中。
});

// 您可以指定callbackUrl
$payment->callbackUrl('http://yoursite.com/verify')->purchase(
    $invoice,
    function($driver, $transactionId) {
    	// 我们可以将$transactionId存储在数据库中。
	}
);

支付发票

购买发票后,我们可以将用户重定向到银行支付页面:

// 在文件顶部。
use Shetabit\Multipay\Invoice;
use Shetabit\Multipay\Payment;
...

// 从项目中加载配置文件
$paymentConfig = require('path/to/payment.php');

$payment = new Payment($paymentConfig);
// 创建新发票。
$invoice = (new Invoice)->amount(1000);

// 购买并支付给定发票。
// 你应该使用return语句将用户重定向到银行页面。
return $payment->purchase($invoice, function($driver, $transactionId) {
    // 将transactionId存储在数据库中,因为我们将来需要它来验证支付。
})->pay()->render();

// 在一行中完成所有操作。
return $payment->purchase(
    (new Invoice)->amount(1000), 
    function($driver, $transactionId) {
    	// 将transactionId存储在数据库中。
        // 我们需要transactionId来验证未来的支付。
	}
)->pay()->render();

// 获取重定向的JSON格式(在这种情况下你可以处理重定向到银行网关)
return $payment->purchase(
    (new Invoice)->amount(1000), 
    function($driver, $transactionId) {
    	// 将transactionId存储在数据库中。
        // 我们需要transactionId来验证未来的支付。
	}
)->pay()->toJson();

验证支付

当用户完成支付后,银行会将他们重定向到你的网站,然后你需要验证你的支付以确保invoice已经支付

// 在文件顶部。
use Shetabit\Multipay\Payment;
use Shetabit\Multipay\Exceptions\InvalidPaymentException;
...

// 从你的项目加载配置文件
$paymentConfig = require('path/to/payment.php');

$payment = new Payment($paymentConfig);


// 你需要验证支付以确保发票已成功支付。
// 我们使用交易ID来验证支付
// 同时添加发票金额是个好做法。
try {
	$receipt = $payment->amount(1000)->transactionId($transaction_id)->verify();

    // 你可以向用户显示支付参考ID。
    echo $receipt->getReferenceId();

    ...
} catch (InvalidPaymentException $exception) {
    /**
    	当支付未验证时,它会抛出一个异常。
    	我们可以捕获异常来处理无效的支付。
    	getMessage方法返回一个适合在用户界面使用的消息。
    **/
    echo $exception->getMessage();
}

有用的方法

  • callbackUrl: 可以用于在运行时更改回调URL。
    // 在文件顶部。
    use Shetabit\Multipay\Invoice;
    use Shetabit\Multipay\Payment;
    ...
    
    // 从你的项目加载配置文件
    $paymentConfig = require('path/to/payment.php');
    
    $payment = new Payment($paymentConfig);
    
    
    // 创建新发票。
    $invoice = (new Invoice)->amount(1000);
    
    // 购买给定发票。
    $payment->callbackUrl($url)->purchase(
        $invoice, 
        function($driver, $transactionId) {
        // 我们可以将$transactionId存储在数据库中。
    	}
    );
    
  • amount: 你可以直接设置发票金额
    // 在文件顶部。
    use Shetabit\Multipay\Invoice;
    use Shetabit\Multipay\Payment;
    ...
    
    // 从你的项目加载配置文件
    $paymentConfig = require('path/to/payment.php');
    
    $payment = new Payment($paymentConfig);
    
    
    // 购买(我们将发票设置为null)。
    $payment->callbackUrl($url)->amount(1000)->purchase(
        null,
        function($driver, $transactionId) {
        // 我们可以将$transactionId存储在数据库中。
    	}
    );
    
  • via: 动态更改驱动
    // 在文件顶部。
    use Shetabit\Multipay\Invoice;
    use Shetabit\Multipay\Payment;
    ...
    
    // 从你的项目加载配置文件
    $paymentConfig = require('path/to/payment.php');
    
    $payment = new Payment($paymentConfig);
    
    
    // 创建新发票。
    $invoice = (new Invoice)->amount(1000);
    
    // 购买给定发票。
    $payment->via('driverName')->purchase(
        $invoice, 
        function($driver, $transactionId) {
        // 我们可以将$transactionId存储在数据库中。
    	}
    );
    
  • config: 动态设置驱动配置
    // 在文件顶部。
    use Shetabit\Multipay\Invoice;
    use Shetabit\Multipay\Payment;
    ...
    
    // 从你的项目加载配置文件
    $paymentConfig = require('path/to/payment.php');
    
    $payment = new Payment($paymentConfig);
    
    
    // 创建新发票。
    $invoice = (new Invoice)->amount(1000);
    
    // 使用自定义驱动配置购买给定发票。
    $payment->config('mechandId', 'your mechand id')->purchase(
        $invoice,
        function($driver, $transactionId) {
        // 我们可以将$transactionId存储在数据库中。
    	}
    );
    
    // 我们也可以同时更改多个配置。
    $payment->config(['key1' => 'value1', 'key2' => 'value2'])->purchase(
        $invoice,
        function($driver, $transactionId) {
        // 我们可以将$transactionId存储在数据库中。
    	}
    );
    
  • 自定义字段: 使用网关的自定义字段(并非所有网关都支持此功能) SEP网关最多支持4个自定义字段,你可以将值设置为最多50个字符的字符串。 这些自定义字段只在用户面板查看报告时显示。

    // 在文件顶部。
    use Shetabit\Multipay\Invoice;
    ...
    
    
    // 创建新发票。
    $invoice = (new Invoice)->amount(1000);
    
    // 使用发票包来存储自定义字段值。
    $invoice->detail([
                'ResNum1' => $order->orderId,
                'ResNum2' => $customer->verifiedCode,
                'ResNum3' => $someValue,
                'ResNum4' => $someOtherValue,
                ]);
    

创建自定义驱动:

首先,你必须在drivers数组中添加你的驱动名称,同时也可以指定任何你想要的配置参数。

'drivers' => [
    'zarinpal' => [...],
    'my_driver' => [
        ... // 你的配置参数在这里。
    ]
]

现在你必须创建一个Driver Map Class,用于支付发票。 在你的驱动中,你只需要继承Shetabit\Multipay\Abstracts\Driver

例如,你创建了一个类:App\Packages\Multipay\Driver\MyDriver

namespace App\Packages\Multipay\Driver;

use Shetabit\Multipay\Abstracts\Driver;
use Shetabit\Multipay\Exceptions\InvalidPaymentException;
use Shetabit\Multipay\{Contracts\ReceiptInterface, Invoice, RedirectionForm, Receipt};

class MyDriver extends Driver
{
    protected $invoice; // 发票。

    protected $settings; // 驱动设置。

    public function __construct(Invoice $invoice, $settings)
    {
        $this->invoice($invoice); // 设置发票。
        $this->settings = (object) $settings; // 设置设置。
    }

    // 购买发票,保存其交易ID并最终返回。
    public function purchase() {
        // 请求支付交易ID。
        ...

        $this->invoice->transactionId($transId);

        return $transId;
    }

    // 使用交易ID重定向到银行,完成支付。
    public function pay() : RedirectionForm {
        // 最好在config/payment.php中设置bankApiUrl并在此处检索:
        $bankUrl = $this->settings->bankApiUrl; // bankApiUrl是配置名称。

        // 准备支付URL。
        $payUrl = $bankUrl.$this->invoice->getTransactionId();

        // 重定向到银行。
        $url = $payUrl;
        $inputs = [];
        $method = 'GET';

        return $this->redirectWithForm($url, $inputs, $method);
    }
  
    // 验证支付(我们必须验证以确保用户已支付发票)。
    public function verify(): ReceiptInterface {
        $verifyPayment = $this->settings->verifyApiUrl;
  
        $verifyUrl = $verifyPayment.$this->invoice->getTransactionId();
  
        ...
  
        /**
			然后我们向$verifyUrl发送请求,如果支付无效,我们会抛出一个带有适当消息的InvalidPaymentException。
        **/
        throw new InvalidPaymentException('一个适当的消息');
  
        /**
        	如果一切正常,我们为这次支付创建一个收据。
        **/
        return new Receipt('driverName', 'payment_receipt_number');
    }
}

一旦你创建了这个类,你必须在payment.php配置文件的map部分指定它。

'map' => [
    ...
    'my_driver' => App\Packages\Multipay\Driver\MyDriver::class,
]

注意: 你必须确保map数组的键与drivers数组的键相同。

事件:

注意1: 事件监听器将全局注册所有支付。

注意2: 如果你希望你的监听器正常工作,你必须在目标事件分发之前订阅它们。

最好在你的应用程序的入口点或主服务提供者中订阅事件,这样事件就会在任何事件分发之前被订阅。


你可以监听3个事件:

  1. purchase
  2. pay
  3. verify
  • purchase: 发生在发票被购买时(成功购买发票后)。
// 添加购买事件监听器
Payment::addPurchaseListener(function($driver, $invoice) {
    echo $driver;
    echo $invoice;
});
  • pay: 发生在准备支付发票时。
// 添加支付事件监听器
Payment::addPayListener(function($driver, $invoice) {
    echo '第一个监听器';
});

// 我们可以添加多个监听器
Payment::addPayListener(function($driver, $invoice) {
    echo '第二个监听器';
});
  • verify: 发生在发票成功验证时。
// 我们可以添加多个监听器,也可以删除它们!!!

$firstListener = function($driver, $invoice) {
    echo '第一个监听器';
};

$secondListener = function($driver, $invoice) {
    echo '第二个监听器';
};

Payment::addVerifyListener($firstListener);
Payment::addVerifyListener($secondListener);

// 删除第一个监听器
Payment::removeVerifyListener($firstListener);

// 如果我们调用removeListener时不带任何参数,它将删除所有监听器
Payment::removeVerifyListener(); // 删除所有验证监听器 :D

本地驱动

Local驱动可以模拟真实网关的支付流程,用于开发目的。

可以像任何其他驱动一样发起支付

$invoice = (new Invoice)->amount(10000);
$payment->via('local')->purchase($invoice, function($driver, $transactionId) {
    // 生成并返回一个虚假的交易ID。
})->pay()->render();

调用render()方法将渲染一个带有接受取消按钮的HTML表单,模拟真实支付网关的相应操作,并重定向到指定的回调URL。 transactionId参数将始终在返回的查询URL中可用。

收到回调请求后可以验证支付。

$receipt = $payment->via('local')->verify();

如果支付成功,$receipt将包含以下参数:

[
'orderId' => // 虚假订单号
'traceNo' => // 虚假跟踪号(应存储在数据库中)
'referenceNo' => // 在`purchase`方法回调中生成的交易ID
'cardNo' => // 虚假的卡号后四位
]

如果支付被取消,将抛出PurchaseFailedException异常以模拟网关验证失败。

可以通过Invoice详情包配置驱动功能。

  • 可用参数
$invoice->detail([
    // 设置此值将导致`purchase`方法抛出`PurchaseFailedException`异常
    // 以模拟网关无法初始化支付的情况。
        'failedPurchase' => '描述错误的自定义消息',

    // 设置此参数将在支付表单中显示。
        'orderId' => 4444,
]);
  • 外观

支付表单的外观可以通过payment.php文件中local驱动的配置参数进行自定义。

'local' => [
    // 驱动的默认回调URL
    'callbackUrl' => '/callback',

    // 表单的主标题
    'title' => '测试网关',
  
    // 在标题下显示的更多说明
    'description' => '此网关仅用于开发环境。',
  
    // 显示为订单号的自定义标签
    'orderLabel' => '订单号',
  
    // 显示为应付金额的自定义标签
    'amountLabel' => '应付金额',
  
    // 成功支付按钮的自定义标签
    'payButton' => '成功支付',
  
    // 取消支付按钮的自定义标签
    'cancelButton' => '取消支付',
],

更新日志

请查看CHANGELOG了解最近的更改。

贡献

请查看CONTRIBUTINGCONDUCT了解详情。

安全

如果您发现任何与安全相关的问题,请发送邮件至khanzadimahdi@gmail.com,而不是使用问题跟踪器。

致谢

许可证

MIT许可证(MIT)。请查看许可证文件了解更多信息。

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号