Integrasi toko online di 1C-Bitrix dengan Mindbox

Untuk mengembangkan sistem loyalitas, toko online beralih ke platform otomasi pemasaran, Platform Data Pelanggan (CDP). Pada saat yang sama, terkadang agar integrasi berhasil, Anda perlu menyimpan lebih banyak data daripada yang ditunjukkan dalam dokumentasi API.



Kami akan memberi tahu Anda data apa yang kami butuhkan untuk mengintegrasikan penyimpanan di Bitrix dengan platform Mindbox, bagaimana itu dapat diperoleh dengan menggunakan API dan SDK, dan cara menggunakan pendekatan gabungan dengan pengiriman data asinkron.







Dengan bantuan layanan Platform Data Pelanggan, pengecer "mengenali" profil pelanggan mereka, termasuk data perilaku. Informasi ini disimpan dengan aman di CDP dan membantu pengecer dengan kampanye pemasaran dan analitik.



Saat pelanggan menambahkan TV atau produk lain ke keranjang, CDP menyimpan data ini. Berdasarkan itu, pengecer dapat memperluas interaksi mereka dengan pengguna, misalnya, menawarkan rekomendasi dan diskon untuk produk serupa.



Salah satu klien kami - jaringan toko elektronik - memutuskan untuk terhubung ke platform CDP Mindbox dan meminta bantuan kami dalam integrasi. Kami melakukan integrasi untuk skenario pengguna utama: otorisasi, menambahkan ke keranjang, pembayaran, dll.



Latar Belakang



Toko online dapat terhubung ke Mindbox dengan dua cara utama: menggunakan API atau JavaScript SDK (kita akan membicarakan perbedaannya nanti).



Untuk memilih cara terbaik, kami beralih ke dokumentasi Mindbox, dan jika tidak ada cukup informasi, kami mengajukan pertanyaan kepada manajer. Kami menemukan bahwa kolaborasi kami bertepatan dengan periode pertumbuhan pesat platform Mindbox: beban harian rata-rata pada panggilan API Mindbox berlipat ganda (hingga 120 ribu permintaan per menit, pada puncaknya - hingga 250 ribu). Ini berarti bahwa selama Black Friday dan penjualan lainnya, karena peningkatan beban tambahan, terdapat risiko bahwa layanan CDP tidak akan tersedia dan tidak akan menerima data dari toko online yang terintegrasi dengannya.



Mindbox menanggapi dengan cepat masalah ini dan mulai meningkatkan arsitektur dan infrastruktur sistem TI-nya untuk mencapai faktor keamanan empat kali lipat. Kami, pada gilirannya, perlu memastikan bahwa data pembelian dikirim ke Mindbox dengan lancar. Ini membutuhkan pemilihan metode integrasi yang paling andal.



Metode integrasi mindbox



Seperti disebutkan di atas, Mindbox menyarankan penggunaan API atau JavaScript SDK untuk terhubung. Selanjutnya, kami akan mempertimbangkan fitur-fiturnya.



  • SDK JavaScript



Pustaka adalah "pembungkus" atas API yang disediakan oleh layanan. Keunggulannya adalah kemudahan integrasi dan kemungkinan transfer data asinkron. Ideal untuk saat hanya platform web yang perlu didukung.



Batasan: Potensi kehilangan data jika Mindbox tidak tersedia pada saat pengiriman. Skrip platform tidak akan dimuat jika ada kesalahan js di sisi toko online.



  • Integrasi API



Integrasi toko dengan Mindbox dapat dilakukan melalui API. Metode ini mengurangi ketergantungan pada JavaScript dan juga cocok untuk menyiapkan pengiriman data asinkron.



Batasan: kami dihadapkan pada kenyataan bahwa beberapa data cookie tidak diterima, yaitu pengidentifikasi pengguna unik di perangkat (mindboxDeviceUUID). Ini perlu diteruskan di sebagian besar operasi Mindbox untuk merekatkan informasi pengguna.



Dalam dokumentasi, cookie ini tidak diperlukan untuk semua operasi. Namun, berjuang untuk transfer data tanpa gangguan, kami mendiskusikan masalah ini dengan manajer Mindbox. Kami menemukan bahwa disarankan untuk selalu mengirimkan cookie untuk keandalan maksimum. Namun, Anda perlu menggunakan JavaScript SDK untuk menerima cookie.



Metode gabungan



Kami telah mempertimbangkan metode integrasi yang dijelaskan di atas, tetapi dalam bentuk murni mereka tidak cocok untuk proyek kami. Untuk memecahkan masalah bisnis pengecer dan membangun sistem loyalitas, perlu untuk mentransfer ke Mindbox satu set lengkap data tentang tindakan pengguna, termasuk pengenal dari cookie. Pada saat yang sama, kami bertujuan untuk mengurangi ketergantungan pada JavaScript dan risiko kehilangan data jika Mindbox sementara tidak tersedia.



Oleh karena itu, kami beralih ke metode gabungan ketiga: kami bekerja dengan API dan JavaScript SDK menggunakan modul antrian kami.



Dengan menggunakan Javascript SDK, kami mengidentifikasi pengguna di situs (mindboxDeviceUUID). Kemudian, di sisi server, kami membentuk permintaan dengan semua data yang diperlukan dan memasukkannya ke dalam antrian. Permintaan yang diantrekan melalui API dikirim ke layanan Mindbox. Jika jawabannya tidak, permintaan akan diantrekan kembali. Jadi, saat mengirim data, Mindbox menerima satu set lengkap informasi yang diperlukan.



Pada contoh di bawah ini, kelas Sender memungkinkan Anda mengumpulkan dan mengirim permintaan dengan melakukan pemrosesan awal respons. Kelas menggunakan data dari perintah itu sendiri (jenis permintaan / respons, deviceUUID, dll.) Dan dari pengaturan modul (parameter untuk bekerja dengan API, token, dll.).



<?php
declare(strict_types=1);

namespace Simbirsoft\MindBox;

use Bitrix\Main\Web\Uri;
use Bitrix\Main\Web\HttpClient;
use Simbirsoft\Base\Converters\ConverterFactory;
use Simbirsoft\MindBox\Contracts\SendableCommand;

class Sender
{
    /** @var Response   */
    protected $response;
    /** @var SendableCommand  */
    protected $command;

    /**
     * Sender constructor.
     *
     * @param SendableCommand $command
     */
    public function __construct(SendableCommand $command)
    {
        $this->command = $command;
    }

    /**
     *    .
     *
     * @return array
     */
    protected function getHeaders(): array
    {
        return [
            'Accept'        => Type\ContentType::REQUEST[$this->command->getRequestType()],
            'Content-Type'  => Type\ContentType::RESPONSE[$this->command->getResponseType()],
            'Authorization' => 'Mindbox secretKey="'. Options::get('secretKey') .'"',
            'User-Agent'    => $this->command->getHttpInfo('HTTP_USER_AGENT'),
            'X-Customer-IP' => $this->command->getHttpInfo('REMOTE_ADDR'),
        ];
    }

    /**
     *   .
     *
     * @return string
     */
    protected function getUrl(): string
    {
        $uriParts = [
            Options::get('apiUrl'),
            $this->command->getOperationType(),
        ];
        $uriParams = [
            'operation'  => $this->command->getOperation(),
            'endpointId' => Options::get('endpointId'),
        ];

        $deviceUUID = $this->command->getHttpInfo('deviceUUID');
        if (!empty($deviceUUID)) {
            $uriParams['deviceUUID'] = $deviceUUID;
        }

        return (new Uri(implode('/', $uriParts)))
            ->addParams($uriParams)
            ->getUri();
    }

    /**
     *  .
     *
     * @return bool
     */
    public function send(): bool
    {
        $httpClient = new HttpClient();

        $headers = $this->getHeaders();
        foreach ($headers as $name => $value) {
            $httpClient->setHeader($name, $value, false);
        }

        $encodedData = null;
        $request = $this->command->getRequestData();
        if (!empty($request)) {
            $converter = ConverterFactory::factory($this->command->getRequestType());
            $encodedData = $converter->encode($request);
        }

        $url = $this->getUrl();
        if ($httpClient->query($this->command->getMethod(), $url, $encodedData)) {
            $converter = ConverterFactory::factory($this->command->getResponseType());
            $response = $converter->decode($httpClient->getResult());
            $this->response = new Response($response);
            return true;
        }
        return false;
    }

    /**
     * @return Response
     */
    public function getResponse(): Response
    {
        return $this->response;
    }
}


Sifat Sendable berisi semua kemungkinan pengaturan perintah untuk mengirim permintaan ke Mindbox, termasuk yang telah ditentukan sebelumnya, seperti jenis permintaan / respons, metode permintaan, dan parameter sync / async. Ini juga berisi metode yang umum untuk semua perintah.



<?php
declare(strict_types=1);

namespace Simbirsoft\MindBox\Traits;

use RuntimeException;
use Bitrix\Main\Context;
use Simbirsoft\MindBox\Type;
use Simbirsoft\MindBox\Sender;
use Simbirsoft\MindBox\Response;
use Bitrix\Main\Localization\Loc;
use Simbirsoft\MindBox\Contracts\SendableCommand;

Loc::loadMessages($_SERVER['DOCUMENT_ROOT'] .'/local/modules/simbirsoft.base/lib/Contracts/Command.php');

trait Sendable
{
    /** @var string   (GET/POST) */
    protected $method = Type\OperationMethod::POST;
    /** @var string   (sync/async) */
    protected $operationType = Type\OperationType::ASYNC;
    /** @var string   (json/xml) */
    protected $requestType = Type\ContentType::JSON;
    /** @var string   (json/xml) */
    protected $responseType = Type\ContentType::JSON;
    /** @var array   */
    protected $data = [];

    /**
     *  .
     * @return string
     */
    abstract public function getOperation(): string;

    /**
     *  .
     *
     * @return array
     */
    abstract public function getRequestData(): array;

    /**
     * HTTP  
     *
     * @return string
     */
    public function getMethod(): string
    {
        return $this->method;
    }

    /**
     *  
     *
     * @return string
     *
     * @noinspection PhpUnused
     */
    public function getOperationType(): string
    {
        return $this->operationType;
    }

    /**
     *  .
     *
     * @return string
     *
     * @noinspection PhpUnused
     */
    public function getRequestType(): string
    {
        return $this->requestType;
    }

    /**
     *  .
     *
     * @return string
     *
     * @noinspection PhpUnused
     */
    public function getResponseType(): string
    {
        return $this->responseType;
    }

    /**
     *   
     *
     * @return void
     */
    public function initHttpInfo(): void
    {
        $server = Context::getCurrent()->getServer();
        $request = Context::getCurrent()->getRequest();

        $this->data = [
            'X-Customer-IP' => $server->get('REMOTE_ADDR'),
            'User-Agent'    => $server->get('HTTP_USER_AGENT'),
            'deviceUUID'    => $request->getCookieRaw('mindboxDeviceUUID'),
        ];
    }

    /**
     *    
     *
     * @param string $key
     * @param string $default
     *
     * @return string
     *
     * @noinspection PhpUnused
     */
    public function getHttpInfo(string $key, string $default = ''): string
    {
        return $this->data[$key] ?? $default;
    }

    /**
     *  .
     *
     * @return void
     *
     * @throws RuntimeException
     */
    public function execute(): void
    {
        /** @var SendableCommand $thisCommand */
        $thisCommand = $this;
        $sender = new Sender($thisCommand);
        if ($sender->send()) {
            throw new RuntimeException(Loc::getMessage('BASE_COMMAND_NOT_EXECUTED'));
        }

        $response = $sender->getResponse();
        if (!$response->isSuccess()) {
            throw new RuntimeException(Loc::getMessage('BASE_COMMAND_NOT_EXECUTED'));
        }

        if (!$this->prepareResponse($response)) {
            throw new RuntimeException(Loc::getMessage('BASE_COMMAND_NOT_EXECUTED'));
        }
    }

    /**
     *   .
     *
     * @param Response $response
     *
     * @return bool
     */
    public function prepareResponse(Response $response): bool
    {
        // $body   = $response->getBody();
        // $status = $body['customer']['processingStatus'];
        /**
         *  :
         * AuthenticationSucceeded -   
         * AuthenticationFailed         -    
         * NotFound                          -    
         */
        return true;
    }
}


Sebagai contoh, pertimbangkan acara otorisasi pengguna. Dalam pengendali event otorisasi, kami menambahkan objek kelas AuthorizationCommand ke antrian kami. Di kelas ini, persiapan informasi minimum yang diperlukan dilakukan, karena pada saat perintah dijalankan, data dalam database dapat berubah, dan Anda perlu menyimpannya. Juga, parameter yang sesuai untuk permintaan di Mindbox diatur, dalam hal ini adalah nama operasi (kita akan menemukannya di panel admin Mindbox). Selain itu, Anda dapat menentukan jenis permintaan / respons, metode permintaan, dan parameter sync / async sesuai dengan sifat Sendable.



<?php
declare(strict_types=1);

namespace Simbirsoft\MindBox\Commands;

use Simbirsoft\Queue\Traits\Queueable;
use Simbirsoft\MindBox\Traits\Sendable;
use Simbirsoft\Queue\Contracts\QueueableCommand;
use Simbirsoft\MindBox\Contracts\SendableCommand;

final class AuthorizationCommand implements QueueableCommand, SendableCommand
{
    use Queueable, Sendable;

    /** @var array   */
    protected $user;

    /**
     * AuthorizationCommand constructor.
     *
     * @param array $user
     */
    public function __construct(array $user)
    {
        $keys = ['ID', 'EMAIL', 'PERSONAL_MOBILE'];
        $this->user = array_intersect_key($user, array_flip($keys));

        $this->initHttpInfo();
    }

    /**
     *  .
     *
     * @return string
     */
    public function getOperation(): string
    {
        return 'AuthorizationOnWebsite';
    }

    /**
     *  .
     *
     * @return array
     */
    public function getRequestData(): array
    {
        return [
            'customer' => [
                'email' => $this->user['EMAIL'],
            ],
        ];
    }
}


Skema interaksi modul



Dalam proyek kami, kami telah mengidentifikasi tiga modul:



  • Mendasarkan



Menyimpan kelas dan antarmuka utilitas umum (seperti antarmuka perintah) yang kemudian dapat digunakan di seluruh proyek.



  • Modul antrian



Interaksi dengan Mindbox diimplementasikan melalui perintah. Untuk menjalankannya secara berurutan, kami menggunakan modul antrian kami. Modul ini menyimpan perintah yang masuk dan menjalankannya ketika waktu eksekusi tiba.



  • Modul integrasi mindbox



Modul ini "menangkap" peristiwa di situs, seperti otorisasi, pendaftaran, membuat pesanan, menambahkan ke keranjang dan lain-lain, dan kemudian menghasilkan perintah dan mengirimkannya ke modul antrian.







Modul Mindbox memantau kejadian dan informasi terkait di situs, termasuk dari cookie, membentuk perintah dari mereka dan memasukkannya ke dalam antrian. Ketika modul antrian mengambil perintah dari antrian dan menjalankannya, data dikirim. Jika jawaban dari Mindbox negatif - perintah yang tidak berhasil dijalankan dipindahkan ke akhir antrian, jika positif - perintah yang berhasil dijalankan akan dihapus dari antrian.



Jadi, dengan menggunakan metode gabungan yang dijelaskan di atas, kami dapat memastikan transfer data yang lancar ke Mindbox.



Menyimpulkan



Dalam artikel ini, kami memeriksa cara-cara di mana toko online dapat terhubung ke Platform Data Pelanggan untuk mengembangkan sistem loyalitas.



Dalam contoh kami, dokumentasi Mindbox menjelaskan dua metode koneksi utama: melalui Javascript SDK dan melalui API. Untuk meningkatkan keandalan transmisi data, bahkan jika layanan CDP tidak tersedia untuk sementara, kami telah memilih dan menerapkan metode gabungan ketiga: menggunakan API dan Javascript SDK, dengan pengiriman data asynchronous.



Terima kasih atas perhatian Anda! Kami harap artikel ini bermanfaat bagi Anda.



All Articles