使用Laravel和Recurly创建基于订阅的网站,第1部分

tech2023-12-16  35

Scheduling and processing payments is easy, but don’t think recurring payments are trivial. Things can get complicated very quickly. You need to decide how to handle failures (how many failed payment attempts does someone get?), billing details must be kept up to date, and upgrading and downgrading plans can introduce all sorts of issues. Then there’s perhaps the most significant issue with recurring payments – you need to keep your visitors’ payment details on file. This introduces security, compliance, and legal issues.

安排和处理付款很容易,但是不要认为定期付款是微不足道的。 事情很快就会变得复杂。 您需要确定如何处理失败(某人会发生多少次失败的支付尝试?),必须保持账单详细信息最新,并且升级和降级计划会带来各种问题。 然后,循环付款可能是最重要的问题–您需要将访客的付款详细信息存档。 这引入了安全性,合规性和法律问题。

Luckily, Recurly is a service that handles most of the issues around taking payments, as well as processing recurring payments from there on out. Using its JavaScript libraries, you can create secure forms for submitting and updating billing information with Recurly – including the all-important credit card details – which submit the information securely, independent from your application.

幸运的是,Recurly是一项服务,可以处理围绕付款和付款的大部分问题。 使用其JavaScript库,您可以使用Recurly创建安全的表单来提交和更新帐单信息(包括所有重要的信用卡详细信息),这些表单可以独立于您的应用程序安全地提交信息。

Once you’ve set up the amount and frequency of payments, the service takes care of scheduling and taking payments at regular intervals until the customer decides to cancel. Recurly also handles plan changes, calculating and making additional charges or refunds.

设置付款金额和付款频率后,该服务会安排并定期进行付款,直到客户决定取消为止。 Recurly还可以处理计划变更,计算并收取额外费用或退款。

In this two-part series I’ll show you step-by-step how to create a paid subscription-based membership website using Laravel, a PHP5-based framework, and the Recurly payment processing service. First we’ll start by creating a simple site with basic registration, authentication, and user roles and permissions. Then we’ll add payment processing and tie it into the registration process, allowing people to purchase different membership tiers.

在这个由两部分组成的系列文章中,我将逐步向您展示如何使用Laravel,基于PHP5的框架和Recurly付款处理服务来创建基于付费订阅的会员网站。 首先,我们将从创建一个具有基本注册,身份验证以及用户角色和权限的简单站点开始。 然后,我们将添加付款处理并将其绑定到注册过程中,从而使人们可以购买不同的会员级别。

设置应用 (Setting Up the Application)

Start by creating a new project folder and run the following command:

首先创建一个新的项目文件夹,然后运行以下命令:

composer create-project laravel/laravel recurly --prefer-dist

This creates a new Laravel project using Composer, which downloads the framework and its dependencies.

这将使用Composer创建一个新的Laravel项目,该项目将下载框架及其依赖项。

We also need some additional libraries for later, so add the following in the require section of composer.json and run composer.phar update.

我们还需要其他一些库供以后使用,因此请在composer.json的require部分添加以下内容,然后运行composer.phar update 。

"machuga/authority": "dev-develop", "machuga/authority-l4" : "dev-master", "recurly/recurly-client": "2.1.*@dev"

This downloads the Authority library, which we’ll use for user roles and permissions, and the Recurly client library.

这将下载用于用户角色和权限的授权库和递归客户端库。

Next, configure the database connection by specifying the appropriate schema name, username, password and hostname/address in app/config/database.php. Laravel works out-of-the-box with a number of databases, such as MySQL, Postgres, SQLite, and SQL Server.

接下来,通过在app/config/database.php指定适当的模式名称,用户名,密码和主机名/地址来app/config/database.php 。 Laravel开箱即用地处理许多数据库,例如MySQL,Postgres,SQLite和SQL Server。

We also need a users table. Rather than set that up by hand, Laravel provides migrations, a means to create and modify database tables programmatically. Run the following command:

我们还需要一个用户表。 Laravel无需手工设置,而是提供了迁移,这是一种以编程方式创建和修改数据库表的方法。 运行以下命令:

php artisan migrate:make create_users_table

This creates the migration file in the app/database/migrations folder. The file is created with a basic outline, but let’s flesh it out with our table definition:

这将在app/database/migrations文件夹中创建app/database/migrations文件。 该文件是用基本轮廓创建的,但让我们通过表定义来充实它:

public function up() { Schema::create('users', function($table) { $table->increments('id'); $table->string('email')->unique(); $table->string('name'); $table->string('password'); $table->timestamps(); }); } public function down() { Schema::drop('users'); }

Go back to the command line and run:

返回命令行并运行:

php artisan migrate

Look in the database and you should find that Laravel has created the users table for you.

查看数据库,您应该发现Laravel为您创建了users表。

设置角色和权限的权限 (Setting up Authority for Roles and Permissions)

To determine the type of account a user has and privileges it grants them, we’ll assign users to a role. We’ve already downloaded Authority via Composer to help with this; we just need to carry out a few more steps to configure it fully.

为了确定用户拥有的帐户类型及其授予的特权,我们将为用户分配一个角色。 我们已经通过Composer下载了Authority来解决这个问题。 我们只需要执行一些步骤即可对其进行完整配置。

In app/config/app.php, add the following line to the providers:

在app/config/app.php , app/config/app.php下行添加到提供程序:

'Authority\AuthorityL4\AuthorityL4ServiceProvider',

Add the following to the aliases:

将以下内容添加到别名:

'Authority' => 'Authority\AuthorityL4\Facades\Authority',

And publish the Authority configuration file:

并发布Authority配置文件:

php artisan config:publish machuga/authority-l4

We’ll return to the configuration file later. For now, we need to create some additional database tables. Fortunately, the package contains its own migrations for this. Run them with the following command:

稍后我们将返回配置文件。 现在,我们需要创建一些其他数据库表。 幸运的是,该软件包为此包含了自己的迁移。 使用以下命令运行它们:

php artisan migrate --package="machuga/authority-l4"

You’ll find you have three additional tables: permissions, roles and role_user.

你会发现你有另外三个表: permissions , roles和role_user 。

We also need to create models to represent roles and permissions. We’ll keep them simple for now. In app/models/Role.php:

我们还需要创建模型来表示角色和权限。 我们暂时将它们保持简单。 在app/models/Role.php :

<?php class Role extends Eloquent { }

And in app/models/Permission.php:

并在app / models / Permission.php中:

<?php class Permission extends Eloquent { }

Now we need to modify the User model class – which has already been created – to associate a user with roles and permissions. Add the following lines to app/models/User.php:

现在,我们需要修改已经创建的User模型类,以将用户与角色和权限相关联。 app/models/User.php添加到app/models/User.php :

public function roles() { return $this->belongsToMany('Role'); } public function permissions() { return $this->hasMany('Permission'); } public function hasRole($key) { foreach($this->roles as $role){ if ($role->name === $key) { return true; } } return false; }

Now let’s pre-populate the database with some data. Open app/database/seeds/DatabaseSeeder.php and paste in the following:

现在,让我们用一些数据预填充数据库。 打开app/database/seeds/DatabaseSeeder.php并粘贴以下内容:

<?php class DatabaseSeeder extends Seeder { public function run() { Eloquent::unguard(); $this->call('UserTableSeeder'); $this->command->info('User table seeded!'); $this->call('RoleTableSeeder'); $this->command->info('Role table seeded!'); } } class UserTableSeeder extends Seeder { public function run() { DB::table('users')->delete(); User::create(array( 'email' => 'joe.bloggs@example.com', 'name' => 'Joe Bloggs', 'password' => Hash::make('password') )); } } class RoleTableSeeder extends Seeder { public function run() { DB::table('roles')->delete(); Role::create(array('name' => 'admin')); Role::create(array('name' => 'pending')); Role::create(array('name' => 'member')); Role::create(array('name' => 'bronze')); Role::create(array('name' => 'silver')); Role::create(array('name' => 'gold')); } }

Then seed the database by running:

然后运行以下命令来播种数据库:

php artisan db:seed

创建布局 (Creating a Layout )

Now we’ll create the overall page layout. Download Twitter Bootstrap and put the source files in the public folder – moving the js files to public/js/libs.

现在,我们将创建整体页面布局。 下载Twitter Bootstrap并将源文件放在public文件夹中-将js文件移动到public/js/libs 。

Create the file app/views/layouts/default.blade.php with the following contents:

使用以下内容创建文件app/views/layouts/default.blade.php :

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Subscription Site Tutorial</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description" content=""> <meta name="author" content=""> <!-- Le styles --> <link href="/css/bootstrap.css" rel="stylesheet"> <link href="/css/style.css" rel="stylesheet"> </head> <body> <div class="navbar navbar-inverse navbar-fixed-top"> <div class="navbar-inner"> <div class="container"> <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="brand" href="#">Subscription Site Tutorial</a> <div class="nav-collapse collapse"> <ul class="nav"> <li class="active"><a href="#">Home</a></li> <li><a href="#about">About</a></li> <li><a href="#contact">Contact</a></li> </ul> </div><!--/.nav-collapse --> </div> </div> </div> <div class="container"> @if(Session::has('success')) <div class="alert alert-success"> <button type="button" class="close" data-dismiss="alert">&times;</button> {{ Session::get('success') }} </div> @endif @if(Session::has('error')) <div class="alert alert-error"> <button type="button" class="close" data-dismiss="alert">&times;</button> {{ Session::get('error') }} </div> @endif @yield('content') </div> <!-- /container --> <!-- Le javascript ================================================== --> <!-- Placed at the end of the document so the pages load faster --> <script src="https://code.jquery.com/jquery-1.10.2.min.js"></script> <script src="/js/libs/bootstrap.min.js"></script> </body> </html>

It’s pretty basic stuff – our page content is outputted in the line that reads @yield('content').

这是非常基本的东西–我们的页面内容在读取@yield('content')的行中输出。

Next, create the file public/css/style.css:

接下来,创建文件public/css/style.css :

body { padding-top: 50px; } p.logged-in { color: white; margin-top: 0.5em; }

And finally, let’s create a basic home page for the application. Create the file app/views/home/index.blade.php:

最后,让我们为应用程序创建一个基本主页。 创建文件app/views/home/index.blade.php :

@extends('layouts.default') @section('content') <h1>Subscription Site Tutorial</h1> @stop

The @extends declaration tells Laravel to use the default layout we just created with the content we’re injecting into the content area via the @yield command wrapped in the @section declaration.

@extends声明告诉Laravel使用我们刚创建的默认布局,并通过包装在@section声明中的@yield命令将内容注入内容区域。

Don’t forget to change the default route accordingly in app/routes.php:

不要忘记在app/routes.php相应地更改默认路由:

Route::get('/', function() { return View::make('home/index'); });

建立登录机制 (Building the Login Mechanism)

We’ve got our users – and an account to start off with – so now we need the ability to log in. In app/routes.php, add a route to the login page:

我们已有用户-一个帐户开始,因此现在我们需要能够登录。在app/routes.php ,向登录页面添加路由:

Route::get('/auth/login', function() { return View::make('auth/login'); });

Now create the view, app/views/auth/login.blade.php. The .blade.php extension indicates that we’re going to use the Blade templating library which ships with Laravel, which is cleaner than straight PHP. Behind the scenes, these template files are compiled into PHP as required.

现在创建视图app/views/auth/login.blade.php 。 .blade.php扩展名指示我们将使用Laravel附带的Blade模板库,它比纯PHP更干净。 在后台,这些模板文件将根据需要编译为PHP。

@extends('layouts.default') @section('content') <h1>Please Log in</h1> {{ Form::open(array('url' => 'auth/login')) }} {{ Form::label('email', 'E-Mail Address') }} {{ Form::text('email') }} {{ Form::label('password', 'Password') }} {{ Form::password('password') }} <div class="form-actions"> {{ Form::submit('Login', array('class' => 'btn btn-primary')) }} </div> {{ Form::close() }} <p>Not a member? <a href="/user/register">Register here</a>.</p> @stop

If you browse to /auth/login in your browser you should see a simple login form.

如果您在浏览器中浏览到/ auth / login ,应该会看到一个简单的登录表单。

To process the login, we’ll need to build a POST route. Authentication in Laravel is a breeze; we simply do this:

要处理登录,我们需要构建一个POST路由。 Laravel中的身份验证非常容易。 我们只是这样做:

Route::post('/auth/login', function() { $email = Input::get('email'); $password = Input::get('password'); if (Auth::attempt(array('email' => $email, 'password' => $password))) { return Redirect::to('/')->with('success', 'You have been logged in'); } else { return Redirect::to('auth/login')->with('error', 'Login Failed'); } return View::make('auth/login'); });

All the magic happens in Auth::attempt(); if the login is successful, a session is created and a populated instance of the User object is accessible via the static method Auth::user().

所有的魔术都发生在Auth::attempt() ; 如果登录成功,则会创建一个会话,并可以通过静态方法Auth::user()访问User对象的填充实例。

The logout method is equally straightforward:

注销方法同样简单明了:

Route::get('/auth/logout', function() { Auth::logout(); return Redirect::to('/')->with('success', 'You have successfully logged out'); });

基本注册 (Basic Registration)

Our last task in this part is to set up a basic registration process. Create a registration route in app/routes.php:

这部分的最后一个任务是建立基本的注册过程。 在app/routes.php创建注册路线:

Route::get('/user/register', function() { return View::make('user/register/index'); });

Now create the view app/views/user/register/index.blade.php:

现在创建视图app/views/user/register/index.blade.php :

@extends('layouts.default') @section('content') {{ Form::open(array('url' => 'user/register')) }} {{ Form::label('email', 'E-Mail Address') }} {{ Form::text('email') }} {{ $errors->first('email') }} {{ Form::label('name', 'Your name') }} {{ Form::text('name') }} {{ $errors->first('name') }} {{ Form::label('password', 'Password') }} {{ Form::password('password') }} {{ $errors->first('password') }} {{ Form::label('password_confirmation', 'Repeat') }} {{ Form::password('password_confirmation') }} <div class="form-actions"> {{ Form::submit('Register', array('class' => 'btn btn-primary')) }} </div> {{ Form::close() }} @stop

There are a couple of things to note here:

这里有几件事要注意:

The $errors object is automatically passed to the view, regardless of whether there are any errors in the submission. If the field’s okay, it’ll just print nothing.

不管提交中是否有错误, $errors对象都会自动传递给视图。 如果该字段没有问题,则仅打印任何内容。

By appending _confirmation to the name of a field, it’s simple to validate the two fields together; i.e. confirm that the user has re-entered the chosen password correctly.

通过将_confirmation附加到字段名称,可以很容易地将两个字段一起验证。 即确认用户已正确重新输入所选密码。

Now let’s implement the POST action:

现在让我们实现POST操作:

Route::post('/user/register', function() { $validator = Validator::make( Input::all(), array( 'name' => array('required', 'min:5'), 'email' => array('required', 'email', 'unique:users'), 'password' => array('required', 'confirmed') ) ); if ($validator->passes()) { $user = new User(); $user->name = Input::get('name'); $user->email = Input::get('email'); $user->password = Hash::make(Input::get('password')); $user->save(); $role_pending = Role::where('name', '=', 'pending')->first(); $user->roles()->attach($role_pending); Auth::login($user); return Redirect::to('/')->with( 'success', 'Welcome to the site, . Auth::user()->name . '!' ); } else { return Redirect::to('user/register')->with( 'error', 'Please correct the following errors:' )->withErrors($validator); } });

This is all fairly basic stuff – we create a validator, passing it the POST variables with Input::all() and a set of validation rules. If validation passes, we create a new user, assign them to the pending role, log them in, and then redirect them to the front page.

这都是相当基本的东西–我们创建一个验证器,并通过Input::all()和一组验证规则将POST变量传递给它。 如果验证通过,我们将创建一个新用户,将其分配给待处理的角色,登录他们,然后将其重定向到首页。

If validation fails, we redirect back to the form, create an error flash message, and pass the error messages from the validator – they’ll then be available in the view in the $errors variable.

如果验证失败,我们将重定向回表单,创建一条错误Flash消息,然后传递来自验证程序的错误消息–然后,这些错误消息将在$errors变量的视图中可用。

结论 (Conclusion)

In this part we’ve gone step-by-step through building the bare bones of a subscription site. It has the ability to register a basic account, login, and logout. In the next part we’ll integrate Recurly for paid subscription plans.

在这一部分中,我们将逐步构建订阅站点的基础。 它具有注册基本帐户,登录和注销的功能。 在下一部分中,我们将为付费订阅计划集成Recurly。

翻译自: https://www.sitepoint.com/creating-subscription-based-website-laravel-recurly-1/

相关资源:Laravel开发-recurly-client-laravel
最新回复(0)