此软件包已被废弃,不再维护。未建议替代软件包。

Laravel 的 Flow SDK 集成

v3.0.0 2019-05-28 17:41 UTC

This package is auto-updated.

Last update: 2022-04-29 01:21:25 UTC


README

Laraflow

Latest Stable Version License Build Status Coverage Status Maintainability Test Coverage

Laraflow

此软件包允许您使用非官方的 Flow SDK 与 Laravel 配合使用。

此软件包与 Laravel Cashier 兼容,因此您可以使用两者。

要求

  • PHP >= 7.1.3
  • Laravel 5.8

检查旧版本以获取旧 Laravel 版本的版本。

安装

只需启动 Composer 并将要求包含到您的项目中。

composer require darkghosthunter/laraflow

数据库准备

如果您想使用 Billable 特性向客户收费,以及使用 SubscribableMultisubscribable 特性进行 Flow 订阅,您将需要运行这些数据库迁移

<?php

// To enable Billable trait methods
Schema::table('users', function (Blueprint $table) {
    $table->string('flow_customer_id')->nullable();
    $table->string('flow_card_brand')->nullable();
    $table->string('flow_card_last_four')->nullable();
});

// To enable Subscriptable/Multisubscribable traits method
Schema::create('subscriptions', function (Blueprint $table) {
    $table->increments('id');
    $table->unsignedInteger('flow_customer_id');
    $table->string('subscription_id');
    $table->string('plan_id');
    $table->string('coupon_id')->nullable();
    $table->date('trial_starts_at')->nullable();
    $table->date('trial_ends_at')->nullable();
    $table->date('starts_at')->nullable();
    $table->date('ends_at')->nullable();
    $table->timestamps();
});

这些迁移位于 database/migrations 中。 默认情况下这些迁移是停用的,但您可以通过 发布配置文件 来激活它们

<?php 

return [
    
    // ...
    
    'migrations' => true,
];

这些迁移的目的是同步客户 ID、订阅 ID 和本地数据。

如果您不打算使用这些特性,则不需要运行它们,因此您可以保留此配置为 false,这是默认值。

配置

要开始使用此软件包中的 Flow,只需在您的 .env 文件中设置三个密钥:环境、API 密钥和密钥。

APP_NAME=Laravel
APP_ENV=local

#...

FLOW_ENV=sandbox
FLOW_API_KEY=1F90971E-8276-4713-97FF-2BLF5091EE3B
FLOW_SECRET=f8b45f9b8bcdb5702dc86a1b894492303741c405

此外,如果您想设置默认值或其他高级设置,还可以发布配置文件 flow.php

php artisan vendor:publish --provider="DarkGhostHunter\Laraflow\FlowHelpersServiceProvider"

禁用 CSRF

由于 Flow 使用用户的浏览器向您的站点发送 POST 请求,因此必须在这些路由中禁用 CSRF

  • payment.urlReturn
  • card.url_return

这些 POST 请求有一个由 40 个随机字符组成的 token,用于标识交易。请考虑使用 ThrottleRequests 中间件来防止 暴力攻击

<?php

Route::post('flow/return/payment')
    ->uses('PaymentController@status')
    ->middleware('throttle:20,1'); // 20 attempts every 1 minute.

包含内容

许多好东西

外观

您将获得所有 Flow 服务的外观

服务 外观
Coupon FlowCoupon
Customer FlowCustomer
Invoice FlowInvoice
Payment FlowPayment
计划 FlowPlan
退款 FlowRefund
结算 FlowSettlement
订阅 FlowSubscription

所有服务都从服务容器接收主Flow实例。因此,您可以轻松地做这样的事情

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use FlowPayment;

class PaymentController extends Controller
{
    /**
     * Make a Payment.
     *
     * @param Request $request
     * @return \Illuminate\Http\RedirectResponse
     */
    public function pay(Request $request)
    {
        // Validate, check items, ...
        
        // Finally, create the Payment
        $response = FlowPayment::commit([
            'commerceOrder' => 'MyOrder1',
            'subject' => 'Game Console',
            'email' => 'johndoe@email.com',
            'amount' => 9900,
            'urlConfirmation' => 'https://myapp.com/webhooks/payment',
            'urlReturn' => 'https://myapp.com/payment/return',
        ]);

        return redirect($response->getUrl());
    }
    
}

请参阅Flow SDK Wiki了解如何使用每个服务。只需将$flow->{service}()替换为您选择的门面。

可收费

您可以通过Billable特质将费用与用户的信用卡或电子邮件(如果没有注册)关联。

在您完成了update_users_table迁移之后,您将能够

  • 在Flow中注册为顾客
  • 在Flow中删除顾客
  • 注册和注销信用卡
  • 被收费(信用卡,或者如果没有信用卡则通过电子邮件)。
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use DarkGhostHunter\Laraflow\Billable;

class User extends Model
{
    use Billable;
    
    // ...
    
}

默认情况下,Billable在创建用户时不会注册用户,这样您就可以避免在Flow账户中添加不会使用计费或订阅的用户。您可以通过将syncOnCreate设置为true来同步模型创建与Flow中的顾客创建。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use DarkGhostHunter\Laraflow\Billable;

class User extends Model
{
    use Billable;
    
    /**
     * Should create a Customer in Flow when created
     *
     * @return bool
     */
    protected $syncOnCreate = true;
}
方法 描述
hasCustomer() 如果模型有Flow顾客
hasCard() 如果模型在Flow中注册了信用卡
getCustomer() 返回Flow顾客
createCustomer() 在Flow中创建顾客
updateCustomer() 使用本地数据在Flow中更新顾客
deleteCustomer() 在Flow中删除顾客
registerCard() 向Flow中注册信用卡创建请愿书
syncCard() 从Flow同步本地卡片数据
removeCard() 从Flow中移除信用卡
charge() 向顾客收费
chargeToCard() 仅当顾客已注册信用卡时向顾客收费

您始终可以查看源代码以获取更多方便的方法。

可订阅

为了优雅地允许您的用户由Flow管理订阅,添加Subscribable特质。这将把一对一的订阅链接到顾客和用户。

在您运行了create_flow_subscriptions迁移后,结合此特质,您将能够

  • 订阅和取消订阅顾客
  • 仅当已注册信用卡时订阅
  • 将优惠券附加到或从订阅中分离
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use DarkGhostHunter\Laraflow\Billable;
use DarkGhostHunter\Laraflow\Subscribable;

class User extends Model
{
    use Billable, Subscribable;
    
    // ...
}
方法 描述
flowSubscription() 本地Flow订阅关系
hasSubscription() 如果模型有本地订阅
subscription() 返回Flow订阅
subscribe() 将顾客订阅到计划
subscribeWithCard() 仅当顾客已注册信用卡时将顾客订阅到计划
updateSubscription() 更新订阅试用期(如果可能)
unsubscribe() 在周期结束时取消顾客的订阅
unsubscribeNow() 立即取消顾客的订阅
attachCoupon() 将优惠券附加到Flow订阅
attachOrReplaceCoupon() 在Flow订阅中附加或替换优惠券
detachCoupon() 从Flow订阅中分离任何优惠券

您始终可以查看源代码以获取更多方便的方法。

多订阅

此特质与Subscribable特质的主要区别是它允许用户有多个订阅 - 甚至在同一个计划上。

由于此特质使用相同的方法名,不要在同一个模型中使用SubscribableMultisubscribable特质

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use DarkGhostHunter\Laraflow\Billable;
use DarkGhostHunter\Laraflow\Multisubscribable;

class User extends Model
{
    use Billable, Multisubscribable;
    
    // ...
}

由于用户可能拥有多个订阅,对于大多数操作,您需要包含要操作的 subscriptionId

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class SubscriptionController extends Controller
{
    /**
     * Unsubscribe.
     *
     * @param Request $request
     * @return \Illuminate\View\View
     */
    public function unsubscribe(Request $request)
    {
        // Validate, etc, ...
        
        // Unsubscribe the user immediately
        $subscription = Auth::user()->unsubscribeNow(
            $request->subscription_id
        );
        
        if ($subscription->status === 4) {
            return view('user.unsubscribed')
                ->with('subscription', $subscription);            
        }

        return view('user.unsubscribe-fail')
                ->with('subscription', $subscription); 
    }
}

方法表

方法 描述
flowSubscriptions() 本地流订阅关系
hasSubscriptions() 如果用户至少有一个匹配的订阅
isSubscribedTo() 如果用户订阅了计划
subscription() 返回Flow订阅
subscriptions() 返回所有用户的流订阅
subscriptionsForPlanId() 返回特定计划ID的流订阅
subscribe() 将顾客订阅到计划
subscribeWithCard() 仅当顾客已注册信用卡时将顾客订阅到计划
updateSubscription() 更新订阅试用期(如果可能)
unsubscribe() 在周期结束时取消顾客的订阅
unsubscribeNow() 立即取消顾客的订阅
attachCoupon() 将优惠券附加到Flow订阅
attachOrReplaceCoupon() 在Flow订阅中附加或替换优惠券
detachCoupon() 从Flow订阅中分离任何优惠券

您始终可以查看源代码以获取更多方便的方法。

通知事件

此包包含Webhook路由和事件,当流触发了这些路由并支付、退款和付费计划时,这些事件将触发。

  • DarkGhostHunter\Laraflow\Events\PaymentResolvedEvent
  • DarkGhostHunter\Laraflow\Events\RefundResolvedEvent
  • DarkGhostHunter\Laraflow\Events\PlanPaidEvent

将触发一个事件,其中包含支付或退款,具体取决于流发送的内容。

虽然这旨在节省您的时间,但您可以禁用这些路由并使用自己的逻辑使用自己的路由,无论是否触发事件,在发布的 flow.php 中。

<?php

return [
    
    // ...
    
    'webhooks-defaults' => false,
];

如果将 webhooks-defaults 设置为 true,您可以覆盖每个默认设置

<?php

return [
    
    // ...
    
    'webhooks' => [
        'payment.urlConfirmation'   => 'https://app.com/my-payment-webhook',
        'refund.urlCallBack'        => null,
        'plan.urlCallback'          => 'https://app.com/my-plan-webhook'
    ],

];

默认Webhook路由由 VerifyWebhookMiddleware 保护,如果设置了,将验证密钥。

Webhook保护

由于禁用CSRF将解除端点保护,建议添加一个静态Webhook密钥字符串,以便只有流才能访问您的应用程序。此字符串永远不会对最终用户可见。

您可以方便地生成一个随机字符串并将其保存为Webhook密钥以保护您的公开端点。

php artisan webhook-secret:generate

这将自动将密钥追加到您的 .env 文件中,或者如果它已存在,则替换它。

#...

FLOW_ENV=sandbox
FLOW_API_KEY=1F90971E-8276-4713-97FF-2BLF5091EE3B
FLOW_SECRET=f8b45f9b8bcdb5702dc86a1b894492303741c405

FLOW_WEBHOOK_SECRET=f9b8bcdb5702dc86a1b8944922d8s8w7

之后,将 VerifyWebhookMiddleware 添加到Webhook端点。此中间件确保POST请求具有40个字符的 token 并与配置的密钥相同。如果不一致,它将终止请求并返回404 Not Found。

<?php

Route::post('my-route/payment','MyFlowController@payment')
    ->middleware('flow-webhook');

如果您已加载中间件但未设置Webhook密钥,请不要担心。中间件不会执行任何操作,因为它会首先检查Webhook密钥是否存在。

日志记录

无需麻烦!此包将Flow优雅地集成到Laravel的默认日志系统中,因此无需更改任何内容。

自定义适配器

虽然Flow SDK使用Guzzle作为默认的HTTP客户端,但您可以创建自己的适配器,实现 AdapterInterface 并在 Service Container 中注册。

然后,将您的注册适配器的名称放在发布的 flow.php 配置文件中的 adapter 部分。适配器将在创建Flow SDK实例时解决。

<?

return [
    
    // ...
    
    'adapter' => 'App\Http\Flow\MyCurlAdapter',
];

这将允许您在测试中创建一个假适配器并捕获所有请求。

服务提供商

此包将Flow SDK添加到您的应用程序中作为服务提供商。您可以像通常那样从服务容器中获取Flow对象,例如使用依赖注入或使用 resolve() 助手等。

<?php

namespace App;

use DarkGhostHunter\FlowSdk\Flow;
use Illuminate\Http\Request;
use App\Http\Controller;

class ExampleController extends Controller
{
    public function pay(Request $request, Flow $flow)
    {
        if ($flow->isProduction()) {
            // ...
        }
    }
    
    public function customPay()
    {
        $flow = app(Flow::class);
        
        echo $flow->isProduction(); // false..
    }
}

在后台,此包注册了两个服务提供商

  • FlowHelpersServiceProvider 加载配置、中间件和其他辅助工具。
  • FlowServiceProvider 在服务容器中注册一个 Flow 的单例实例,作为延迟服务提供者,以及其他服务。

这确保了配置始终被加载,而 Flow SDK 仅在您的代码中调用时才会加载。

许可证

此软件包由MIT 许可证授权。

此软件包与在此软件包中引用的任何服务、公司、产品和服务没有直接或间接的关系。