如何使用Stripe和Syncano建立每日确认短信服务

本文由Syncano赞助。 感谢您支持使SitePoint成为可能的赞助商。

Syncano为实时应用程序提供了基于云的平台。 它存储数据,微服务代码,自动执行代码的时间表,用户帐户,通过HTTP访问这些功能的网络钩子等等。 他们甚至拥有代码段的开源社区,并支持各种运行时环境,包括Node,Python,Go和Ruby。

从开发人员的角度来看,Syncano通过提供许多您可能需要自己拼凑的后端基础架构,使入门变得更简单。 在本文中,我们将研究使用Syncano设置网络应用并将其链接到第三方服务所涉及的内容。

您需要什么

为了能够按照本教程进行操作,您将很容易掌握HTML,CSS和JavaScript的基础知识。

在演示应用程序中,我们使用jQuery组合了一些简单的原型屏幕和动作。 我想强调一点–在正确的应用程序中,您确实应该使用一种更加可靠和简洁的方法来构建Web应用程序。 我会推荐一个JavaScript框架,例如React,Angular,Meteor…等。在此演示中,我们有目的地避免使用类似JavaScript的框架来使事情保持简单并集中精力关注Syncano。 阅读我们的Syncano功能片段,并使前端JavaScript适应您自己喜欢的框架!

我们的演示应用

为了从初学者的角度探讨Syncano的功能,我们将构建一个Web应用程序,它将以每月1美元的低价每天向注册用户发送肯定确认书! 我们将探讨用户注册,安排事件,通过Twilio发送SMS消息以及设置付款方式。

编码

此演示的代码都可以在GitHub找到

Syncano入门

如果您没有Syncano帐户,则可以在Syncano.com上免费登录 。 您会在右上方找到“注册”按钮:

右上方的Syncano注册按钮

填写您的电子邮件地址和首选密码,然后单击“创建我的帐户”:

填写帐户详细信息

注册后,您将可以访问Syncano仪表板。 您可以随时通过转到dashboard.syncano.io进行访问 。 登录后,您将拥有一个“实例”,我们将用它来演示应用程序。 如果您已经在使用Syncano并想要创建一个新的,请单击右下角的“ +”图标(请注意,除非使用实例的API资源管理器 ,否则您无法为该实例指定自定义名称,但这超出了范围这篇文章!):

注册后的初始仪表板

生成Syncano API密钥

单击该实例将其打开。 开始时看起来很空白,左边有很多选择。 您要做的第一件事是单击“ API密钥”菜单选项以获取您的API密钥:

转到“获取API密钥”屏幕

然后通过单击“生成API密钥”为该实例生成API密钥:

生成API密钥

Syncano将为您提供一个弹出窗口以提供API密钥设置。 您可以更新三个设置:

  • 说明– API密钥的说明。 我们称其为“肯定”。
  • 忽略ACL –这将忽略在我们的应用程序中为资源设置的任何权限,我们将不需要此权限。
  • 用户注册–这使人们可以使用此API密钥进行注册,我们希望将其打勾!

输入所有这些设置后,单击“确认”:

输入API密钥设置

现在,您应该看到列出了您的API密钥,并将该密钥复制到某个地方,以备您在代码中使用它时使用。 如果您丢失了它,只需回到仪表板中的“ API密钥”页面即可:

复制该API密钥

查找您的Syncano帐户密钥

为了在Syncano中进行一些调用,您将需要生成一个API密钥。 我们可以通过“帐户”屏幕来做到这一点。 要到达那里,我们将单击右上角的个人资料图片,然后单击包含我们电子邮件的区域以转到“帐户”屏幕:

帐户图标

在此处,我们单击左侧菜单中的“身份验证”项,然后单击“复制”以复制显示的帐户密钥。 暂时将其存储在安全的地方!

帐户键屏幕

我们将尽可能尝试使用API​​密钥,尤其是在Syncano生态系统之外的任何地方。

Syncano JavaScript入门

Syncano提供了多种方法可以将其JavaScript库包含到您的应用程序中:

  • 从GitHub直接下载JavaScript文件–您可以在其GitHub上找到最新的JavaScript库( 从此链接下载zip文件 )。 您将在dist/syncano.min.js下找到所需的JavaScript文件。
  • 包括他们的npm模块-如果您更喜欢使用npm(通过Node,Browserify…等),则可以通过npm install syncano --save安装他们的模块。
    • 然后,您可以通过var Syncano = require('syncano');将其包含在您的项目中var Syncano = require('syncano');
  • 包括他们的Bower模块–如果您更喜欢Bower,则可以通过bower install syncano安装他们的模块
    • 通过<script src="path/to/bower_components/syncano/dist/syncano.min.js">
      </script>
      <script src="path/to/bower_components/syncano/dist/syncano.min.js">
      </script>

Syncano中的用户帐户

Syncano已准备好提供用户帐户功能,供您直接使用。 如果我们通过单击左侧的菜单项转到“类”页面,则可以看到我们的user_profile类已准备就绪,正在等待存储用户详细信息:

用户个人资料已准备就绪,正在等待

在系统中找到用户后,我们还将能够在“用户”页面上看到我们的用户。 “用户”页面将显示其电子邮件地址以及是否将其分配给任何组(在此演示中,我们将不会分配组),带有“ user_profile ”类的“类”页面将向我们显示更多详细信息,包括我们将特别为我们的应用添加自定义字段。

添加自定义Syncano类

为了存储我们的确认,我们将在Syncano中创建一个新类来存储它们。 为此,请转到“班级”页面,然后单击加号图标以创建一个新班级:

新增班级

在此屏幕中,我们将类命名为“确认”并对其进行描述。 在“模式”下,我们为类设置了单个字段,我们也将其称为“确认”。 我们将其设置为文本字段,然后单击“添加”。 然后我们单击“确认”以保存新类。 确保同时单击“添加”和“确认”以保存所有内容!

设置确认班

现在,我们的affirmation班级将在“班级”页面上可见。 单击它进入一个屏幕,您可以在其中添加一些确认:

确认书已添加到“课程”页面

添加了很多内容后,屏幕应如下所示:

确认清单

整合短信

我们应用程序的主要功能是,它将以肯定和愉快的态度向用户发送每日SMS。 我们将通过Twilio发送这些SMS消息,Twilio是一项提供语音和SMS服务的服务。

设置Twilio号码

前往Twilio ,然后单击右上角的“注册”按钮以注册免费试用版。

Twilio主页

按照提示创建您的帐户。 完成此操作后,您可能会在屏幕上看到有关设置语音的信息,请不要进行设置! 我们不需要语音功能。 我们正在寻找消息传递。 这是您不想要的屏幕:

Twilio语音屏幕

而是转到Twilio的“入门”屏幕以进行消息传递 。 单击屏幕上显示“获取您的第一个Twilio号码”的红色按钮:

Twilio入门屏幕

如果下一个屏幕显示带有SMS作为其功能之一的号码,请继续并单击“选择此号码”。

但是,如果您不小心单击以在“语音”屏幕上获取号码(或由于其他未知原因),您可能会发现Twilio建议使用一个未提及SMS功能的号码。 如果仅显示“语音”,请单击“不喜欢这个? 搜索其他号码”:

Twilio获取号码屏幕

在下一个屏幕上,勾选“ SMS”,然后单击“搜索”:

搜索短信号码

然后选择任何具有SMS功能的号码(由于我们先前的选择,它们应具有此功能):

选择短信号码

Twilio现在将向您显示您的Twilio号码! 将该数字复制到安全的地方,因为我们很快就会使用它。

成功选择短信号码

查找您的Twilio API凭据

Twilio消息传递的“入门”屏幕上 ,我们的应用程序需要我们提供的最后一条信息– Twilio API凭据。 要找到这些,请单击右上角的“显示API凭据”链接。 然后,您会看到“帐户SID”和“验证令牌”。 将这些文件复制到安全的地方(最好与您复制电话号码的位置相同)。 我们也将很快在我们的应用程序中使用它们。

您的Twilio API凭证

Syncano解决方案

Syncano的真正不错的功能之一是其解决方案的开源存储库,您只需单击几下即可将其添加到您的项目中。 解决方案甚至不需要使用与应用程序其余部分相同的语言编写! 它们将添加功能正常运行所需的一切,您只需要提供应用程序需求的详细信息即可。 使用Twilio发送SMS消息非常容易,因为已经有准备就绪的Syncano解决方案,称为“发送SMS”。

要安装“发送SMS”解决方案,请单击右上方的“解决方案”链接,然后在左侧找到“ SMS”标签以对其进行过滤。 用这种方法找到“发送短信”解决方案要容易得多! 安装完成后,请单击其框右下角的箭头图标进行安装。

安装发送短信解决方案

将会出现一个弹出窗口,询问我们要保存在哪个实例中(到目前为止,只有一个实例,这很简单!),以及我们要保存哪个版本的解决方案。 保持原样,然后单击“确认”:

安装发送短信解决方案

Syncano CodeBoxes

我们可以在Syncano托管应用程序中运行的每个代码段都称为“ CodeBox”。 现成的CodeBoxes将作为解决方案的一部分出现,您也可以自己制作。 我们将在本指南中同时做这两项!

如果单击“ CodeBoxes”菜单链接,则会发现“发送SMS”解决方案为我们创建了一个名为“ sendsms”的CodeBox。 它旁边的图标告诉我们CodeBox是用Python编写的。 幸运的是,正如我之前提到的,我们可以使使用不同语言编写的组件协同工作。 这是一种非常有趣的方法,可以共享功能!

出现发送短信代码框

如果单击该CodeBox项,Syncano将为其打开代码编辑器。 这将使我们能够在其中编辑一些变量以匹配我们的Twilio凭据和设置。 我们需要更新以下内容:

  • SYNCANO_API_KEY –将其更新为我们先前复制的Syncano API密钥。
  • ENTER_INSTANCE_NAME_HERE –将其更新为您的Syncano实例名称(例如,粗体雨–1234)。
  • ENTER_YOUR_ACCOUNT_SID_HERE –将其更新为您的Twilio帐户SID。
  • ENTER_YOUR_AUTH_TOKEN_HERE –将其更新为您的Twilio身份验证令牌。
  • from_number –此变量必须等于您先前选择的Twilio电话号码。

自定义发送SMS CodeBox

查看CodeBox,我们可以看到它需要三个参数才能运行。 这些由ARGS.get('argument_name', None)None是其初始值):

message_body = ARGS.get('body', None)  # Arg 'body' is passed to CodeBox
media_url = ARGS.get('media_url', None)  # Arg 'media_url' -- gif, jpeg, or png
to_number = ARGS.get('to_number', None)  # Arg 'to_number' is receiving number, ie; "+13475555717"

我们的预定确认书CodeBox

为了为我们的每个用户运行此代码,我们将创建自己的CodeBox,该sendsms将使用我们的用户详细信息和消息正文的确认来触发sendsms CodeBox。

要创建一个新的CodeBox,请单击“ CodeBoxes”页面右下方的加号图标:

添加新的代码框按钮

在出现的屏幕上,我们将新的CodeBox命名为“ Schedled Affirmation”,如果愿意,可以给它一个描述,为运行时环境选择“ nodejs”,然后单击“ Confirm”:

添加新的计划确认代码框

我们的自定义CodeBox代码如下所示:

var Syncano = require('syncano');
var _ = require('lodash');
var account = new Syncano({accountKey: 'YOURKEYHERE'});

account.instance('bold-rain-5584').class('affirmation').dataobject().list()
.then(function(res){
  var randomId = _.random(0, res.objects.length - 1),
      messageToSend = res.objects[randomId].affirmation;

  console.log('Sending message of ', messageToSend);

  var filter = {
    "query": {"subscribed":{"_eq":true}}
  };

  account.instance('bold-rain-5584').class('user_profile').dataobject().list(filter, function(err, res) {
    if (err) {
      console.log('Error!');
      console.log(err); return;
    }
    _.each(res.objects, function(user) {
      var payload = {"payload":{'body': messageToSend, 'to_number': user.phone}};

      console.log({"body": messageToSend, "to_number": user.phone});

      account.instance('bold-rain-5584').codebox(2).run(payload, function(err, res) {
        console.log('Just sent that SMS out.');
      });
    });
  });
})
.catch(function(err) {
  console.log('Error!');
  console.log(err); return;
});

我将解释这段代码的每个部分在做什么。 这与其他Node.js代码段完全一样,仅在Syncano的云中运行。 (注意:我们尚未为此在Syncano中设置所有其余部分,因此,如果您尝试立即运行它,则此代码将无法工作!)

就像任何其他Node应用程序一样,我们require()我们的依赖项。 我们将使用lodash一些实用程序功能,因此我们将其包括在内(在撰写本文时,Syncano没有Underscore模块可用,只有lodash可用):

var _ = require('lodash');

由于Syncano CodeBox使用隔离的Docker映像来运行,因此我们需要包括Syncano模块以使用诸如查找类和用户之类的功能。 为此,我们必须使用我们先前找到的帐户密钥初始化Syncano:

var Syncano = require('syncano');
var account = new Syncano({accountKey: 'YOURKEYHERE'});

然后,我们将使用account.instance('bold-rain-5584').class('affirmation').dataobject().list()函数account.instance('bold-rain-5584').class('affirmation').dataobject().list()我们的affirmation类中的所有确认。 确认列表加载后,我们将在JavaScript中使用promise, then通过res.objects返回的变量访问这些确认。

account.instance('bold-rain-5584').class('affirmation').dataobject().list()
.then(function(res){
  // In here we will look at res.objects

我们要做的第一件事是使用lodash获得一个随机数,该随机数在零和我们拥有的肯定数之间(减去1,因为我们从零开始)。 这就是我们选择随机确认的方式。 然后,我们通过将该随机ID处的确认对象分配给变量messageToSend来选择该确认。

var randomId = _.random(0, res.objects.length - 1),
    messageToSend = res.objects[randomId].affirmation;

console.log('Sending message of ', messageToSend);

为了向我们的用户发送随机确认,我们需要首先列出所有用户。 请记住,我们只想将此发送给通过Stripe订阅了我们的确认服务的用户。 我们还没有设置Stripe服务,但是跟踪用户是否已订阅的方法是通过在user_profile类中切换一个称为subscribed的自定义值(我们也将很快进行设置)。

Syncano允许我们过滤查询,以便仅使subscribed等于true 。 我们像对affirmation类所做的那样列出了user_profile类,但是通过传递JSON对象作为第一个参数来使用此过滤,如下所示:

var filter = {
  "query": {"subscribed":{"_eq":true}}
};

account.instance('bold-rain-5584').class('user_profile').dataobject().list(filter, function(err, res) {
// We will look into our users in the res.objects variable here next!

user_profile类列表中,我们首先检查是否有错误。 如果您想透彻一点,也可以在affirmation类列表中添加同样的错误检查。 始终发现错误是一种好习惯!

if (err) {
  console.log('Error!');
  console.log(err); return;
}

如果没有错误,则使用lodash遍历每个用户,并将JSON与messageToSend (我们的确认书)以及在此循环中通过user.phone为用户找到的电话号码放在一起。 我们也将尽快设置该自定义phone字段。

_.each(res.objects, function(user) {
  var payload = {"payload":{'body': messageToSend, 'to_number': user.phone}};

最后,我们通过codebox(2).run()函数运行sendsms代码codebox(2).run()2是我们之前记下的CodeBox的ID。 一旦完成运行,它将在控制台中记录一条消息,让我们知道它已成功运行。

account.instance('bold-rain-5584').codebox(2).run(payload, function(err, res) {
        console.log('Just sent that SMS out.');
      });
    });
  });
})

最后,在最初承诺的最后,我们发现了所有错误:

.catch(function(err) {
  console.log('Error!');
  console.log(err); return;
});

为SMS准备用户帐户

现在,我们需要将这些自定义字段添加到我们的应用程序的用户详细信息中,以便能够获取向用户发送SMS消息所需的所有信息。

回到我们之前在“类”页面中查看的仪表板的user_profile区域,单击三个点图标,然后选择“编辑类”:

编辑user_profile类

在出现的屏幕中,我们能够将自定义字段添加到我们的user_profile类中。 在“架构”下的区域中,我们添加需要的任何自己的字段。 对于我们的SMS功能,我们需要两个字段:

  • subscribed -布尔值,用于跟踪用户是否对我们的服务进行了付费订阅(我们将很快整合到付费位中)。 我们只想向我们的付费订户发送确认书!
  • phone –一个字符串,用于存储每个用户的电话号码。 我们需要它来知道在何处发送短信。

我们将通过输入名称,设置适当的类型,然后单击“添加”来完成该字段的添加。 一旦添加了两个字段(确保单击“添加”!),然后单击屏幕底部的“确认”以保存这些更新。

更新我们的SMS的user_profile

我们的HTML

为了使HTML中的内容简单,我们将使用Foundation的框架模板。 您可以从Foundation下载页面下载该文件 。 如果您不是Foundation的粉丝或偏爱其他框架,那完全可以。 我们仅将框架用作起点,并使用表单的简单模板。 如果需要,您可以在首选模板中执行相同操作(或从头开始!)。 这只是为了避免我们的原型看起来像是90年代默认HTML样式构建的。 在HTML代码示例中,我将避免使用Foundation标记,但是请注意,这就是使事情看起来比默认情况更好的原因!

我们的登录/注册表格

对于登录和注册表单,我们都有一个非常简单的HTML表单,还有一个ID为#message的div,其中显示了一些基本说明。 为了简化起见,这是我们注册表单中基本HTML的样本,该表单中除去了Foundation框架元素:

<h1>Register</h1>
<div id="message">To register, please enter your email and password.</div>

<form id="register">
  <label>E-mail
    <input id="email" type="email" placeholder="Your email address">
  </label>
  <label>Password
    <input id="password" type="password" placeholder="Your password">
  </label>
  <button type="submit" class="button">Sign Up!</button>
</form>

如果您想查看Foundation框架版本,请随时浏览我们的演示的GitHub。

我们授权我们的app.js前端代码可以通过我们之前保存的Syncano API密钥访问Syncano实例:

instance = new Syncano({
  instance: 'bold-rain-5584',
  apiKey: '10133b1f19bbd71a11a8055a8357ffd3b233697d'
});

然后,只要需要访问它,便可以通过instance变量引用该实例。

我们用于注册或登录用户的代码的最后一行(这两个代码段非常相似)是操作实际开始的地方。 下面的注册代码可查找用户并通过Syncano登录。 如果Syncano没有返回任何错误,则它将运行我们的callback()函数,该函数告诉前端一切正常。

在注册表格中,我们还读取了一个名为phone的自定义字段,以存储用户注册时的电话号码。 成功注册用户后,我们的JavaScript会通过AJAX执行基本的POST请求。 该请求是针对一个Syncano Webhook的,该Webhook接受用户的ID和他们的电话号码,并将电话号码保存到该帐户。

$('#main').on('submit', '#register', function(e) {
  var $form = $(this),
      username = $('#email').val(),
      password = $('#password').val(),
      phone = $('#phone').val(),
      data = 'username=' + username + '&password=' + password + '&phone=' + phone;

  function callback(resp) {
    $.ajax({
      type: "POST",
      url: "https://api.syncano.io/v1/instances/bold-rain-5584/webhooks/p/f5bb236b40f560a44dbc930a7bebaf87ea18e6d1/savephonenumber/",
      data: {"phone": phone, "user_id": resp.profile.id}
    })
    .done(function(msg) {
      console.log(msg);
        console.log('Phone number saved ', resp);
      userLoggedIn(resp);
    });
  }
  function error(resp) {
      console.log('Register failure... ', resp);
  }

  instance.user().add({"username": username, "password": password})
    .then(callback).catch(error);

  e.preventDefault();
});

创建Syncano Webhooks

作为如何制作基本Webhook的示例,我们将创建上面提到的Webhook,将用户的电话号码保存到他们的帐户中。 Syncano中的Webhook是通过HTTP请求运行CodeBox的一种方式。 它可以是公共请求,也可以是首先需要身份验证的请求。 我们的Webhooks将通过POST请求公开访问。

我们的CodeBox(我们称为“保存电话号码”)接受两个参数phoneuser_id 。 然后,它为该ID更新user_profile数据对象:

var Syncano = require('syncano');
var account = new Syncano({accountKey: 'YOURACCOUNTKEY'});

var phone = ARGS.POST.phone;
var userId = ARGS.POST.user_id;

var details = {
  "phone": phone
};

account.instance('bold-rain-5584').class('user_profile').dataobject(userId).update(details, function(err, res) {
    console.log("Phone number " + phone + "added to " + userId + "!");
});

我们使用帐户密钥而不是API密钥的原因是API密钥无法更改user_profile数据。 我们也不应该在公共JavaScript中清楚地看到帐户密钥,因此我们选择仅在Syncano CodeBox中使用它们。

要在Syncano仪表板上为此CodeBox创建一个Webhook,请转到“ Webhooks”菜单项。 在“ Webhooks”页面上,单击右下角的箭头图标以打开“添加Webhook”窗口。 在这里,为您的Webhook命名一个URL友好名称,如果需要,请给它一个描述,然后选择要运行的CodeBox。 确保选中“将此Webhook公开?”。 这样您就可以通过POST请求访问Webhook。

在Syncano的仪表板中创建Webhook

整合付款

我们已经设置了用户帐户,确认列表和代码准备就绪,可以通过SMS发送这些确认。 现在,我们只需要这些用户订阅并付费的方式即可获得这些每日确认! 为简单起见,我们将使用在线支付提供商Stripe。

要注册,我们转到Stripe网站 ,然后单击“登录”:

Stripe主页登录按钮

然后点击底部的“注册”链接:

条纹注册链接

按照他们的提示进行操作,直到成功设置了帐户,并且我们自己的仪表板出现在我们眼前:

新条纹仪表板

从这里,我们需要找到并复制我们的Stripe API密钥。 可以在您的帐户设置中找到。 单击右上角的“您的帐户”,然后单击“帐户设置”。

条带帐户设置

然后单击“ API密钥”选项卡,然后复制“ Test Secret Key”旁边的密钥。 这是我们访问Stripe测试环境所需要的。 将其复制到安全的地方,准备在CodeBox中立即使用。

查找您的API密钥

订阅新客户

Syncano当前在其“解决方案”集合中确实有一个Stripe解决方案,但是它仅适用于单个事务。 我们可以将其与计划任务一起使用,但这可能会变得混乱,因为我们需要同时为每个人运行该任务。 如果有人在我们的下一次预定跑步之前加入,该怎么办? 我们只在任务完成后才向他们收费吗?

相反,我们以一种更好的方式消除了所有这些情况。 Stripe已经有基于订阅的支付服务。 Syncano可以订阅用户,然后Stripe为我们处理每月的付款。 我们在Syncano中需要管理的所有系统都是它们是否已订阅。 容易得多!

条纹订阅

为此,我们需要首先在Stripe中定义订阅类型。 我们将返回Stripe仪表板,然后单击“订阅”下方左侧的“计划”菜单项。 在此处,单击“创建您的第一个计划”:

在Stripe中添加新的订阅计划

在出现的屏幕上,我们将输入以下内容:

  • ID –确认订阅(在我们的代码中用于引用我们的订阅的ID)
  • 名称 –肯定(仅在Stripe的仪表板中使用)
  • 货币 –我将其留作澳元,但您可能希望以您的本国货币!
  • 金额 -$ 1美元(如果您认为自己的主张更有价值,可以免费收取更多)
  • 间隔 –每月一次(您可以根据需要更改结算频率)
  • 试用期 –我们不提供免费试用期,但是如果您愿意,您可以在这里提供。
  • 声明说明 -“生活是美好的”(这是用户银行对帐单上显示的内容)

条纹计划设置

然后我们点击“创建计划”。 这样,我们在Stripe端的设置就完成了。

我们的订阅代码箱

为了在Syncano端设置我们的订阅管理,我们将创建一个名为“ Stripe Subscribe New Customer”的新CodeBox。 我们的CodeBox如下所示:

var Syncano = require('syncano');
var account = new Syncano({accountKey: 'YOURACCOUNTKEY'});
var _ = require('lodash');

var stripe = require("stripe")("sk_test_YOURSTRIPEKEY");
var stripeToken = ARGS.POST.stripe_token;
var email = ARGS.POST.email;

stripe.customers.create({
  source: stripeToken,
  plan: "affirmationsubscription",
  email: email
}, function(err, customer) {
  account.instance('bold-rain-5584').user().list()
    .then(function(res){
        console.log(res);

        _.each(res.objects, function(user) {
            if (user.username == email) {
                console.log("USER:");
                console.log(user);

                var details = {
                  "subscribed": true,
                  "stripe_id": customer.id,
                  "subscription_id": customer.subscriptions.data[0].id
                };

                account.instance('bold-rain-5584').class('user_profile').dataobject(user.profile.id).update(details, function(err, res) {
                    console.log(customer.id + ',' + customer.subscriptions.data[0].id);
                });
            }
        });
    })
    .catch(function(err) {
        console.log("Error! ", err);
    });
});

我们将遍历每个部分以解释每个部分的作用:

开始与我们以前的CodeBox非常相似,使用帐户密钥并要求使用lodash

var Syncano = require('syncano');
var account = new Syncano({accountKey: 'YOURACCOUNTKEY'});
var _ = require('lodash');

然后,我们需要Stripe的npm模块,进行stripe并将其传递给我们之前从Stripe复制的密钥:

var stripe = require("stripe")("sk_test_YOURTESTKEY");

我们为要查找的CodeBox设置了两个参数,分别是Stripe令牌和用户的电子邮件。 Stripe令牌是一种令牌,一旦用户将其付款详细信息放入Stripe中,Stripe将为我们提供令牌。 这将发生在JavaScript的前端。 然后,我们将获取这些详细信息,并使用它们使用stripe.customers.create()将其订阅我们的“确认订阅”计划:

var stripeToken = ARGS.POST.stripe_token;
var email = ARGS.POST.email;

stripe.customers.create({
  source: stripeToken,
  plan: "affirmationsubscription",
  email: email
}, function(err, customer) {
  // Our callback function will be here!
}

在回调函数中,我们列出用户并在数据库中使用相同的电子邮件更新用户的字段。 我们保存他们的Stripe ID(Stripe中的每个用户都有一个唯一的ID,以后我们可以使用该ID来对其进行管理)和他们的订阅ID(Stripe还为每个订阅提供了自己的ID,因此我们也可以对其进行管理)。 我们还为他们设置了true subscribed ,因此我们知道他们应该收到确认短信。 我发现在回调中包含console.log很有用。 这会在测试时记录两个Stripe ID,以确保正确的ID通过。

account.instance('bold-rain-5584').user().list()
    .then(function(res){
        console.log(res);

        _.each(res.objects, function(user) {
            if (user.username == email) {
                console.log("USER:");
                console.log(user);

                var details = {
                  "subscribed": true,
                  "stripe_id": customer.id,
                  "subscription_id": customer.subscriptions.data[0].id
                };

                account.instance('bold-rain-5584').class('user_profile').dataobject(user.profile.id).update(details, function(err, res) {
                    console.log(customer.id + ',' + customer.subscriptions.data[0].id);
                });
            }
        });
    })

最后,我们捕获并记录在此过程中发生的所有错误:

.catch(function(err) {
        console.log("Error! ", err);
    });
});

要访问该CodeBox,创建一个名为网络挂接subscribecustomer在Syncano是运行它(以同样的方式,我们在上面创建的网络挂接创建它)。 我们将尽快使用它。

触发订阅

Stripe知道我们的订阅服务,Syncano知道如何通过Stripe订阅我们。 剩下的一个难题是用户单击按钮,该按钮将启动整个订阅过程。

我们通过Stripe的Checkout服务开始该过程。 我们将创建一个自定义的Stripe Checkout按钮。 该按钮实际上并不进行订阅。 它可以用于付款,但是我们仅将其用于获取用户的信用卡详细信息并最初通过电子邮件发送到Stripe。 它需要这些,然后我们才能使他们订阅我们的计划。

要为此访问Stripe的API,我们在index.html文件的底部包括其JavaScript:

<script src="https://checkout.stripe.com/checkout.js"></script>

app.js ,我们使用StripeCheckout.configure()函数准备订阅:

var handler = StripeCheckout.configure({
  key: 'pk_test_YOURSTRIPEKEY',
  locale: 'auto',
  panelLabel: 'Subscribe',
  email: username,
  token: function(token) {
    stripeToken = token;

    console.log("Stripe token is " + JSON.stringify(token));

    $.ajax({
      type: "POST",
      url: "https://api.syncano.io/v1/instances/bold-rain-5584/webhooks/p/1254a339e4544e4c36ae4c5fcf67f4249413b3f2/subscribecustomer/",
      data: {"stripe_token": stripeToken.id, "email": username}
    })
    .done(function(msg) {
      paid = true;
      ids = msg.result.stdout.split(',');
      stripeId = ids[0];
      subscriptionId = ids[1];

      goToPage('myaccount');
    });
  }
});

此功能的开头包含我们之前使用的Stripe键, locale设置为以用户的本地语言弹出(很好的触摸), panelLabel更改了付款按钮将在其信用卡详细信息表格下显示的内容(我们希望它说“订阅”),我们通过在我们已经从通过其Syncano帐户知道的电子邮件地址email ,以便它预先填充:

var handler = StripeCheckout.configure({
  key: 'pk_test_YOURSTRIPEKEY',
  locale: 'auto',
  panelLabel: 'Subscribe',
  email: username,

当条纹有用户的详细信息,该token功能运行和我们发送的令牌和电子邮件给我们Syncano网络挂接称为subscribecustomer 。 这会将它们传递到我们的CodeBox上,以在我们的实际订阅过程中使用。

token: function(token) {
    stripeToken = token;

    $.ajax({
      type: "POST",
      url: "https://api.syncano.io/v1/instances/bold-rain-5584/webhooks/p/1254a339e4544e4c36ae4c5fcf67f4249413b3f2/subscribecustomer/",
      data: {"stripe_token": stripeToken.id, "email": username}
    })

完成该POST请求后,我们将设置本地JavaScript变量,以使我们知道当前用户已付款,并知道其Syncano用户ID,数据条ID和订阅ID。 然后,我们运行一个功能,将用户带到应用程序的“我的帐户”页面,该页面将检查详细信息,现在告诉他们已订阅。 请记住,您可以(并且应该)使用自己选择的框架来做得更好。

.done(function(msg) {
      paid = true;
      ids = msg.result.stdout.split(',');
      stripeId = ids[0];
      subscriptionId = ids[1];

      goToPage('myaccount');
    });
  }
});

要实际启动该Stripe Checkout处理程序,我们有一个简单的handler.open()函数,该函数触发Stripe弹出窗口以请求付款详细信息:

$('#main').on('click', '#paymentButton', function(e) {
  handler.open({
    name: "Life is Good Affirmations",
    description: "A monthly subscription to daily affirmations!",
    currency: "aud"
  });
  e.preventDefault();
});

如果他们单击导致Stripe触发popstate事件的弹出窗口部分,则弹出窗口关闭:

$(window).on('popstate', function() {
  handler.close();
});

退订客户

要取消订阅客户,我们会简化订阅过程。 我们不需要Stripe即可最初获取客户的详细信息或类似信息,因为我们已经获得了他们的Stripe ID和Stripe订阅ID。 相反,我们需要的是一个CodeBox,它可以使用这些详细信息并告诉Stripe取消订阅此用户。 我们将创建一个名为“ Stripe Unsubscribe Customer”的代码框。

在“ Stripe取消订阅客户”代码框中,我们具有与“ Stripe订阅客户”代码框相同类型的require语句。 我们接受当前用户的Syncano ID以及其Stripe ID,以便我们也可以更改其最终subscribed的列表,以将subscribed设置为false并从数据库中删除其subscribed ID。

此CodeBox中唯一看起来可能与我们已经完成的工作不同的地方是stripe.customers.cancelSubscription() ,这是我们对Stripe的调用,以取消该用户的订阅。 我们传入Stripe ID和Stripe订阅ID,然后在成功回调中,对自己的数据库进行更改。

var Syncano = require('syncano');
var account = new Syncano({accountKey: 'YOURACCOUNTKEY'});
var _ = require('lodash');

var stripe = require("stripe")("sk_test_YOURSTRIPEKEY");

var userId = ARGS.POST.user_id;
var stripeId = ARGS.POST.stripe_id;
var subscriptionId = ARGS.POST.subscription_id;

stripe.customers.cancelSubscription(
  stripeId,
  subscriptionId,
  function(err, confirmation) {
    var details = {
      "subscribed": false,
      "subscription_id": ""
    };

    account.instance('bold-rain-5584').class('user_profile').dataobject(userId).update(details, function(err, res) {
        console.log("User set to unsubscribed");
    });
  }
);

创建一个名为“ unsubscribecustomer”的Webhook,并通过与我们的“ subscribecustomer” Webhook相同的方法触发它,您的订阅设置就完成了!

计划任务

现在我们可以接受客户了,我们要开始运营的最后一件事就是预定的确认。 我们准备好了名为“计划确认”的CodeBox,我们只需要将其设置为计时器即可。

转到“任务”页面,单击带有图标的圆形按钮,该图标看起来有点像右下角的计时器。 在出现的弹出窗口中,为您的日程安排选择一个名称,选择“ Schedled Affirmation”作为我们要安排的代码框,并选择您希望其运行的频率(目前,每天半夜出现一次唯一的选择–尚无一种设置时区的方法,因此这对每个人来说都不是午夜! 点击“确认”,您的日程安排将自动运行!

创建Syncano时​​间表

一些注意事项

在我们的演示前端JavaScript中,我们通过一个相当粗糙的goToPage()函数来管理页面,就像您在上面偶尔看到的那样。 我们将避免详细解释所有工作原理,因为您应该代替自己实现自己喜欢的适当框架!

最后一个重要的注意事项,在我们观看演示之前:

在一个实时站点上,当您收集非常敏感的信息时,您将希望通过HTTPS运行该应用程序!

行动中

现在尝试一下! 您可以在任何简单的Web服务器上运行前端HTML。 在我的个人Web服务器上,我通过http://localhost/lab/syncano/public/运行它。 为了运行我们的粗略JavaScript,请避免在URL中包含index.html

我们的应用首页

我们单击注册,然后输入我们的详细信息(请确保您输入了自己的有效电话号码,否则此测试不会太令人兴奋!):

注册页面

如预期的那样,我们将提示您注册该服务的订阅:

订阅请求页面

当我们单击“订阅”时,出现“条纹结帐”弹出窗口,要求您提供付款详细信息。 Stripe的测试信用卡号之一是4242 4242 4242 4242 ,这是我在下面使用的。 您可以在此处找到更多Stripe测试编号列表

订阅弹出

订阅成功后,页面将更改为显示该页面并提供一个取消订阅选项(以及一个简单的注销选项,该选项仅清除存储在JavaScript中的用户ID并返回首页):

订阅成功

如果我们转到Stripe仪表板,单击“计划”,然后单击“确认计划”,我们将看到有关该计划的详细信息。 特别是,我们可以看到我们的新订户!

订阅服务器在条带中可见

无需等待计划的确认运行,我们可以打开“计划的确认”代码框,然后单击右侧的播放按钮立即运行它:

运行我们的CodeBox

在很短的时间内,您应该从您的应用收到一条短信:

短信确认成功

如果我们随后决定退订,则单击退订,并返回到上一个屏幕:

订阅请求页面

回顾Stripe,如果刷新页面,我们将发现该订阅不再有任何订阅者:

订阅者已删除

我们的应用程序运行良好!

查看日志

如果由于某种原因您的应用无法正常运行,并且您想查看日志,则可以通过打开CodeBox并单击“跟踪”选项卡从CodeBox中找到日志。 然后单击您要从中查看日志的记录:

查看跟踪日志

对于通过Webhooks运行的CodeBox,您可以通过转到Webhooks页面并单击要查看以下日志的Webhook来查找其日志:

查看Webhook日志

结论

Syncano是一个平台,可以使将应用程序集成在一起的任务更加快捷,易于管理。 它的代码框和解决方案的概念还鼓励将任务分成较小的块,这可以使事情保持整洁和可重复使用。 如果您有正在考虑构建的原型应用程序,为什么不尝试将其扔到Syncano中并试一下呢?

From: https://www.sitepoint.com/how-to-build-a-daily-affirmations-sms-service-with-stripe-syncano/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值