kristof202/cryptomus

Laravel 对 Cryptomus API 的封装

v1.0 2024-03-26 13:13 UTC

This package is not auto-updated.

Last update: 2024-09-25 14:29:23 UTC


README

安装

您可以通过 composer 安装此包

composer require kristof202/cryptomus

服务提供程序将自动注册自己。

您必须使用以下命令发布配置文件

php artisan vendor:publish --provider="Kristof\Cryptomus\CryptomusServiceProvider" --tag="config"

这是将发布到 config/cryptomus.php 的配置文件内容

return [
    'MerchantID' => env('CRYPTOMUS_MERCHANT_ID'),
    'PaymentKey' => env('CRYPTOMUS_PAYMENT_KEY'),
    'webhookJobs' => [
        // 'cancel' => \App\Jobs\CryptomusWebhook\HandleCancel::class,
        // 'paid' => \App\Jobs\CryptomusWebhook\HandlePaid::class,
        // 'wrong_amount' => \App\Jobs\CryptomusWebhook\HandleWrongAmount::class,
        // 'paid_over' => \App\Jobs\CryptomusWebhook\HandlePaidOver::class,
    ],
    'webhookModel' => Kristof\Cryptomus\Models\CryptomusWebhookCall::class,
];

在配置文件的 PaymentKey 键中,您应该添加一个有效的支付密钥。您可以在 [Cryptomus 商户仪表板] 找到密钥。

接下来,您必须使用以下命令发布迁移

php artisan vendor:publish --provider="Kristof\Cryptomus\CryptomusServiceProvider" --tag="migrations"

迁移发布后,您可以通过运行迁移来创建 cryptomus_webhook_calls

php artisan migrate

使用方法

创建发票

$payment = Cryptomus::createPayment([
            "amount"=> "15",
	        "currency"=> "USD",
            "order_id"=>"1",
        ]);

Webhooks

Cryptomus 将为几种事件类型发送 webhooks。请检查 Cryptomus API 文档。

Cryptomus 将为击中您的应用程序 webhook url 的所有请求签名。此包将自动验证签名是否有效。如果不是,则请求可能不是由 Cryptomus 发送的。

除非发生严重错误,否则此包将始终对 webhook 请求响应 200。所有具有有效签名的 webhook 请求都将记录在 cryptomus_webhook_calls 表中。该表有一个 payload 列,其中保存了传入 webhook 的整个有效负载。

如果签名无效,则请求将不会记录在 cryptomus_webhook_calls 表中,但会抛出 Kristof\Cryptomus\Exceptions\WebhookFailed 异常。如果在 webhook 请求过程中发生错误,则抛出的异常将保存在 exception 列中。在这种情况下,控制器将发送 500 而不是 200

此包有两种方式让您处理 webhook 请求:您可以选择排队作业或监听包将引发的事件。

使用作业处理 webhook 请求

如果您想在特定事件类型到来时执行某些操作,您可以定义一个执行工作的作业。以下是一个此类作业的示例

<?php

namespace App\Jobs\CryptomusWebhook;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Kristof\Cryptomus\Models\CryptomusWebhookCall;

class HandlePaid implements ShouldQueue
{
    use InteractsWithQueue, Queueable, SerializesModels;

    public function __construct(
        CryptomusWebhookCall $webhookCall,
    ) {}

    public function handle(): void
    {
        // do your work here
        
        // you can access the payload of the webhook call with `$this->webhookCall->payload`
    }
}

我们强烈建议您将此作业排队,因为这将最小化 webhook 请求的响应时间。这允许您处理更多的 Cryptomus webhook 请求并避免超时。

创建您的作业后,您必须在 cryptomus.php 配置文件中的 jobs 数组中注册它。键应该是 cryptomus 支付状态 的名称,但用 . 替换为 _。值应该是完全限定的类名。

// config/cryptomus.php

'jobs' => [
    'paid' =>  \App\Jobs\CryptomusWebhook\HandlePaid::class,
],

使用事件处理 webhook 请求

而不是在 webhook 请求到来时排队作业执行某些工作,您可以选择监听此包将引发的事件。每当有效的请求击中您的应用程序时,该包将引发一个 cryptomus::<payment-status-name>

事件的有效负载将是为传入请求创建的 CryptomusWebhookCall 实例。

让我们看看如何监听此类事件。在 EventServiceProvider 中,您可以注册监听器。

/**
 * The event listener mappings for the application.
 *
 * @var array
 */
protected $listen = [
    'cryptomus::paid' => [
        App\Listeners\PaymentPaidListener::class,
    ],
];

以下是一个此类监听器的示例

<?php

namespace App\Listeners;

use Illuminate\Contracts\Queue\ShouldQueue;
use Kristof\Cryptomus\Models\CryptomusWebhookCall;

class PaymentPaidListener implements ShouldQueue
{
    public function handle(CryptomusWebhookCall $webhookCall): void
    {
        // do your work here

        // you can access the payload of the webhook call with `$webhookCall->payload`
    }   
}

我们强烈建议您使事件监听器可排队,因为这将最小化 webhook 请求的响应时间。这允许您处理更多的 Cryptomus webhook 请求并避免超时。

上述示例只是处理Laravel事件的一种方式。要了解其他选项,请阅读Laravel处理事件的文档

高级用法

重试处理webhook

所有传入的webhook请求都写入数据库。当处理webhook调用时出现问题时,这一点非常有价值。在调查并修复了失败原因之后,您可以轻松地重试处理webhook调用,如下所示

use Kristof\Cryptomus\Models\CryptomusWebhookCall;

CryptomusWebhookCall::find($id)->process();

执行自定义逻辑

您可以通过使用自己的模型在队列作业调度之前和/或之后添加一些自定义逻辑。您可以通过在cryptomus配置文件的model键中指定自己的模型来实现这一点。该类应扩展Kristof\Cryptomus\Models\CryptomusWebhookCall

以下是一个示例

use Kristof\Cryptomus\Models\CryptomusWebhookCall;

class MyCustomWebhookCall extends CryptomusWebhookCall
{
    public function process(): void
    {
        // do some custom stuff beforehand
        
        parent::process();
        
        // do some custom stuff afterwards
    }
}