首先,要有点抱怨:)迟早,任何在线商店都存在建立废弃篮子的问题。 统计数据和失去金钱的感觉使人无法幸免。
2006年至2017年弃置篮子的百分比
来源2018年第一季度废弃篮子的百分比,按行业分类:
来源同时,尽管统计数据普遍可用,但大多数在线商店都不使用可用功能,也不连接废弃的购物篮。 EmailSoldiers最近进行的一项“家庭”研究清楚地表明,大多数商店根本不会理会它。
连接的废弃篮子的当前统计数据
来源同时,每个人(而且我们也不是圣人)赶上了流量,投放了广告和广告素材,但甚至没有试图返回在最后一刻破产的人。
但是在第一个迭代中,您可以使用不带动态内容的字母来增加订单数量,只需配置它即可。 只做一次努力,这样在后台就能赚钱-这不是童话吗?
自然地,带有动态内容的字母可以将篮子中的物品拉入其中,效果更好。 也许另一只眼睛悲伤的小猫会对听众产生更大的影响。 或者,您将推荐的商品拉到篮子里的商品上,然后发现从信件中购买的商品更多,从而增加了平均支票数量。 或者,您将亲身制作一系列字母,以使转换效果更大。
您可以改善和测试从废弃的篮子到无法达到的理想状态的字母,但是任何曾经配置的字母都比没有要好。
根据RetailRocket转换为废弃的篮子
来源因此,
Artem Aleksandrov同志
和我开始从两个侧面介绍篮子。
技术实施
集成的TOR
简要描述任务的本质。
任务:使用Mailchimp邮件服务将站点xxx.xx的废弃购物车连接起来
我们提供所有必要的材料。
API密钥:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-usXX
从哪里获得钥匙?

→
我们提供了指向文档的链接我们与商店连接的工作表的ID:XXXXXXXXXX
在哪里可以获取工作表ID?

邮件服务必须预先创建。 邮件服务一接收到API请求,就会自动生成消息,并将收件人添加到队列中进行发送。
对于我们的情况,我们选择了以下逻辑来发送废弃的篮子:
站点上的授权用户将商品添加到购物篮中,但未完成交易且未完成订单,购物篮在1小时内保持不变。 之后,将请求发送到Mailchimp,在该电子邮件中,将发送电子邮件,用户订单的构成,产品图像,商品价格以及到用户购物篮的链接。
布局模板
当为一个废弃的篮子创建自动化时,mailchim立即询问是否会有一个或几个字母,并建议选择连接的商店。

在基本模板中,mch提供了以下三种选择:

- 被遗弃的篮子与动态商品
- 被遗弃的购物篮,带有杂货店推荐(需要单独配置)
- 被遗弃的篮子,没有货物(只是文字字母)
按照最好的传统,如果有时间,您可以自己整理篮子。
没有样式的动态产品看起来像这样(忘了缩进,它们在这里很难看):
<table> <tbody> *|ABANDONED_CART:[$total=3]|* <table> <tbody> <tr> <td> <a href="*|CART:URL|*" title="*|PRODUCT:TITLE|*" target="_blank"> <img src="*|PRODUCT:IMAGE_URL|*"> </a> </td> <td> *|PRODUCT:TITLE|* — *|PRODUCT:PRICE|* </td> </tr> </tbody> </table> *|END:ABANDONED_CART|* </tbody> </table> *|END:ABANDONED_CART|* </tbody> </table>
看来,如果您更改变量
* | ABANDONED_CART:[$ total = 3] | *中的数字 ,则字母将显示不同数量的商品,但不,至少放置5,至少100的商品将不显示其他数量。
而且,这也有点奇怪,变量
* | PRODUCT:PRICE | *被替换为RUB288格式值,由于某种原因,也无法更改此值,但稍后会进行更多更改。
为了进行更改,我们尝试用通过api传输的游戏数量和订单总成本来代替变量,但此处的mailchimp拒绝了。 好吧,就这样吧。
给程序员一个字:)
有了mailchimp,他们就有与第三方服务mandrill集成的历史经验,那里的一切都很简单明了。 非常友好的文档(当然是英文),但是没有毛病,从一开始就有效。
此外,我们网站上还引入了通过特殊形式的订阅机制。 在这里,我们完全感觉到mailchimp文档的轻描淡写和含糊不清。 对于经验丰富的开发人员而言,英语不是问题,但默认情况下并不隐含对克林贡语的了解。
最初的数据是:php7语言和yii2框架,随着其生态系统的发展,它们已经以压倒性的速度增长。 即 我们已经有6个小型项目正在尝试在后端和前端使用通用组件。 因此,任何任务的执行都需要独立解决其项目,但这并不意味着框架独立,因为 您必须用人工来付钱,而这总是很短缺。
收到整合任务后,我们必须首先环顾四周。 给了我们什么? 首先,您需要与之交朋友的mailchimp服务。 我们转到github,看到有很多实现。 但是选择很简单-最受欢迎的1.5k星包装(
drewm / mailchimp-api )。
该软件包为与mailchimp的其余交互提供了一个简单的包装。 我们只能用我们的逻辑来获得这一点。
其次,我们得到了
文档 。 根据文档,我们具有带有嵌套资源的商店资源:购物车,客户,订单,产品,促销规则。 对于没有推荐产品的废弃购物篮,我们只需要产品,购物车和客户。 反过来,购物车由购物车行集组成,并且产品包含产品变体。
我们将任务分解如下:
- 将商店数据上传到商店
- 在产品上下载所有可购买的产品
- 安排用户安排购物篮的装载
好,走吧 首先,我们继承“商店”的本质。 我们决定立即使用商店的测试和战斗版本,并且根据负责处女/生产模式的环境变量,我们在一家商店或另一家商店工作。
要下载商店数据,我们使用以下参数在/ ecommerce / stores上发布请求:
[ 'id' => 'dev.***.ru', 'list_id' => '****', 'name' => '*** - test', 'domain' => 'dev.***.ru', 'email_address' => 'admin@***.ru', 'currency_code' => 'RUB', 'primary_locale' => 'ru', 'money_format' => '₽', ]
还有其他几种选择,但这都取决于需求。 因为 我们不会以字母形式使用商店的联系方式,也没有填写电话,地址,时区等字段。
但是一个小惊喜在等待着我们。 money_format字段似乎是专门为能够以对我们方便的格式显示价格的能力而创建的。 但是,在构建废弃的购物篮模板时,邮件芯片顽固地用RUB代替号码。 Mailchimp,别说了!
下载后,我们可以使用地址/ ecommerce / stores上的get-request查看数据,以查看所有已加载的商店,或/ ecommerce / stores / {id}以获得特定商店上的数据。
现在,您可以添加所有其他数据,因为存储是我们数据树中的根点,因为 我们会将所有其他数据上传到特定的商店。
因此,为了使妇幼保健中心可以用废弃的篮子代替货物,他需要喂食这些货物。 为此,我们有地址/电子商务/商店/ {store_id} /产品,我们在其中发送在系统中创建产品的后期请求。
[ 'id' => '742', 'title' => '', 'handle' => 'kastrulya', 'url' => 'http://***.ru/catalog/kastrulya/', 'description' => ' — . , . , ! !', 'type' => '', 'vendor' => ' ', 'image_url' => 'http://***.ru/images/742/product.png', 'variants' => [ [ 'id' => '742', 'title' => '', 'url' => 'http://***.ru/catalog/kastrulya/', 'price' => 890, 'sku' => 'KA453', 'inventory_quantity' => 1000, 'image_url' => 'http://***.ru/images/742/product.png', 'visibility' => 'visible', ], ], ]
有什么特别之处? 好吧,首先,每个产品必须包含至少一个产品报价。 本质上,产品是用于加载产品报价的容器。 此外,产品的ID和产品提供的ID可能会相交,因为它们是MCH API中的不同资源。
在这里,MCH文档的轻描淡写开始了。 我不得不猜测,即使这并不困难,但您可以正常进行,而不是一如既往。
手柄字段已被描述为“产品的手柄”。 好的,在咨询之后,我们决定这是与产品本身(cnc)相关的URL的一部分。 但这仅在测试期间得到确认。
您也可以将一系列图片附加到产品上,但是我们认为这对我们没有用,因此,只有主图像同时加载到产品和每个产品报价中。
在这里,我们遇到了一个问题,由于某种原因,商品没有出现在邮件图表模板中。
我们开始深入研究产品码头。 他们发现了一个带有豪华描述的可见性字段:

好吧,输入字符串! 什么可以转移到那里? 为什么不可能描述所有可能的含义?! 我可以发送到那里,例如“给我看!”。
幸运的是有一个示例请求!

好吧,这并不能消除问题。 我不知道还有哪些其他有用的值。
每个人都应对! 现在,电子邮件营销人员可以通过在商品参与下构建模板来验证系统中商品的可用性,也可以通过使用控制台通过相同的获取请求来完成商品的可用性。
接下来,我们面临着将废弃的篮子装到妇幼保健中心的任务。 最初,我想到了两种选择:
- 每次您更改购物篮(添加/删除商品)时,我们都会在MCH中重复此操作。 在缺点中,对外部服务的大量请求立即表明了自己。
- 每n分钟一次,观察一个多小时前没有变化的篮子。 然后,我们将其发送给MCH。 只有一个问题-跟踪去MCH后恢复的篮子。
首先,我们在1小时至3的窗口中向数据库(以下称为DB)请求数据。为什么是3? 上次更改一个小时后,我们将购物篮发送到系统。 在MCH中,发送购物篮的最小可能间隔为1小时。 因此,理论上,在2小时±5分钟后,将发送一封信。 因此,即使有余量,3小时也是一个值。
从数据库接收到数据后,我们在地址/电子商务/商店/ {store_id} /购物车上请求获取。 因此,我们得到了位于电子商务系统中的所有购物篮,正在等待轮流发送(或已经发送)。 我们为什么需要这个? 与我们的数据同步是必要的。 我们将发送从数据库收到的所有购物篮,但是我们需要删除那些不在1-3小时范围内的购物篮。 3倍之后-已经不相关的数据。 最多一个小时-可以再次更新或下订单的篮子。
要删除,我们只需要找到篮子的两个阵列/集合之间的差异即可。
收到需要删除的购物篮后,我们发送删除请求/电子商务/商店/ {store_id} /购物车/ {cart_id}。
接下来,我们将这些篮子下载下来,并通过后期请求将它们周期性地发送到系统。
购物篮参数如下所示:
[ 'id' => '1207', 'customer' => [ 'id' => '25', 'email_address' => 'email@example.com', 'opt_in_status' => false, ], 'currency_code' => 'RUB', 'order_total' => 1597, 'checkout_url' => 'http://***.ru/cart/abandoned/?cart=eyJpdGVtcyI6eyI1OTgwIjoxLCIzNDA0IjoxLCI3NzMiOjEsIjkwNTgiOjEsIjkwOTEiOjEsIjE4ODciOjEsIjc4NCI6MSwiNTExMSI6MSwiODA1MyI6MSwiMTk0MSI6MSwiNTQ0NSI6MSwiNzk1NCI6MywiOTA2NyI6NCwiOTA2NSI6NCwiNzg0MyI6MSwiOTA2NiI6M30sInByb21vY29kZSI6bnVsbH0%253D', 'lines' => [ 0 => [ 'id' => '123', 'product_id' => '5980', 'product_variant_id' => '5980', 'quantity' => 1, 'price' => 841, ], 1 => [ 'id' => '124', 'product_id' => '3404', 'product_variant_id' => '3404', 'quantity' => 1, 'price' => 756, ], ], ]
?//***.ru/cart/abandoned/购物= eyJpdGVtcyI6eyI1OTgwIjoxLCIzNDA0IjoxLCI3NzMiOjEsIjkwNTgiOjEsIjkwOTEiOjEsIjE4ODciOjEsIjc4NCI6MSwiNTExMSI6MSwiODA1MyI6MSwiMTk0MSI6MSwiNTQ0NSI6MSwiNzk1NCI6MywiOTA2NyI6NCwiOTA2NSI6NCwiNzg0MyI6MSwiOTA2NiI6M30sInByb21vY29kZSI6bnVsbH0%253D', [ 'id' => '1207', 'customer' => [ 'id' => '25', 'email_address' => 'email@example.com', 'opt_in_status' => false, ], 'currency_code' => 'RUB', 'order_total' => 1597, 'checkout_url' => 'http://***.ru/cart/abandoned/?cart=eyJpdGVtcyI6eyI1OTgwIjoxLCIzNDA0IjoxLCI3NzMiOjEsIjkwNTgiOjEsIjkwOTEiOjEsIjE4ODciOjEsIjc4NCI6MSwiNTExMSI6MSwiODA1MyI6MSwiMTk0MSI6MSwiNTQ0NSI6MSwiNzk1NCI6MywiOTA2NyI6NCwiOTA2NSI6NCwiNzg0MyI6MSwiOTA2NiI6M30sInByb21vY29kZSI6bnVsbH0%253D', 'lines' => [ 0 => [ 'id' => '123', 'product_id' => '5980', 'product_variant_id' => '5980', 'quantity' => 1, 'price' => 841, ], 1 => [ 'id' => '124', 'product_id' => '3404', 'product_variant_id' => '3404', 'quantity' => 1, 'price' => 756, ], ], ]
再说一次,我们最喜欢的标题是“猜测这些字段的工作方式”。 例如,通过科学戳的方法,发现有可能不创建具有单独请求的买方。 有必要传输所需的最小字段集,如果它不在系统中,它将自动创建。 在我们的案例中,我们将自己限制为ID,电子邮件,opt_in_status。 最后一个参数负责工作表中的用户订阅状态。 如果为true,则表示状态已订阅,否则为事务性。
通过Cart Lines数组可以毫无问题地加载产品列表,而数组又是Cart实体的资源。 即 我们可以通过休息请求单独管理此集合。
好吧,这就是全部了吗? 但是没有
测试时,我们注意到发送相同的购物篮仅发送一次。 尽管我们将其从系统中删除并重新下载。 一言不发,一言不发! 结果,根据经验,在一些母亲的帮助下,我们以一个假设为条件,即同一个ID的篮子只能发送一次。
在此,我完全同意创建者的观点,即此限制使我们免于向用户发送垃圾邮件。 但是写吧! 我们不需要任务,在编写的代码中有足够多的神秘错误。
完成所有这些操作后,妇幼保健中心开始向我们发送有关废弃篮子的漂亮信件。 然后出现了第二个问题。 如果用户已经将购物篮扔了出去,并从信件中退回了自己的帐户,也就是说,在单击链接时获得了授权,那么他将毫无问题地进入购物篮。 因此事实证明,这封信说:“开! 把你的篮子拿回来!”,当我们越过它时,我们说:“糟糕,有些东西丢了! 我们什么都没碰! 它本身!”
决定将购物篮的组成编码为字符串,然后在将购物篮发送到MCH时将其传递给checkout_url。 然后,当您前往现场时,抓住这条线,进行解码并将所有商品扔到篮子里,不要忘记在此之前将其完全重置。
因此,无论我们将用户发送到哪个浏览器,他都会像我们承诺的那样得到他的篮子。 唯一的缺点是他只能登录。 但是,通过链接进行授权是不礼貌的举动,而且确实对我们的客户而言是一项危险的业务。
结果如何? 原则上,在实施过程中没有特别的问题,因为MCH响应经常会帮助解决与验证已传输字段有关的错误。 但是,如果它们通常能人为地描述妇幼保健工作的所有这些细微之处,并更详细地描述这些领域,那么它们将更少。
Google.Analytics中的报告设置
为了跟踪整个操作的成功,您将必须配置并定期查看分析中的报告。 想象一下,每个人,例如成人,都已经连接了电子商务,否则奇迹将不起作用:)
要为废弃的篮子收集新的报告,请转到“我的报告”:

进一步的“添加报告”:

之后,我们添加将要跟踪的参数。 我们决定考虑城市背景下的废弃篮子,您可能会有不同的看法。
对于mailchamp,废弃篮子的标准广告系列是ABANDONED_CART_EMAIL,我们将其替换为过滤器并获得报告。

这就是所有叉子!
现在,您已配置为发送废弃的篮子和报告,通过它可以查看其中的废气。 测试,测试,测试! ;)