luyadev/luya-module-payment

View on GitHub
src/integrators/DatabaseIntegrator.php

Summary

Maintainability
A
1 hr
Test Coverage
A
93%
<?php

namespace luya\payment\integrators;

use luya\payment\base\IntegratorInterface;
use luya\payment\base\PayModel;
use luya\payment\models\Process;
use luya\payment\models\ProcessTrace;
use luya\payment\PaymentException;

/**
 * Database integrator
 *
 * @author Basil Suter <basil@nadar.io>
 * @since 1.0.0
 */
class DatabaseIntegrator implements IntegratorInterface
{
    /**
     * {@inheritDoc}
     */
    public function createModel(PayModel $model)
    {
        $process = new Process();
        $process->amount = $model->totalAmount;
        $process->currency = $model->currency;
        $process->order_id = $model->orderId;
        $process->success_link = $model->successLink;
        $process->error_link = $model->errorLink;
        $process->abort_link = $model->abortLink;
        $process->close_state = Process::STATE_PENDING;
        $process->is_closed = $model->isClosed;
        $process->provider_data = $model->providerData;
        $items = [];
        foreach ($model->items as $item) {
            $items[] = [
                'qty' => $item->qty,
                'name' => $item->name,
                'amount' => $item->amount,
                'is_shipping' => $item->is_shipping,
                'is_tax' => $item->is_tax,
                'total_amount' => $item->getTotalAmount(),
            ];
        }
        $process->setItems($items);
        if ($process->insert()) {
            $model->setId($process->id);
            $model->setAuthToken($process->auth_token);
            $model->setRandomKey($process->random_key);
            return $model;
        }

        return false;
    }

    /**
     * {@inheritDoc}
     */
    public function findByKey($key, $token)
    {
        $model = Process::find()->where(['random_key' => $key])->with(['items'])->one();

        if (!$model) {
            return false;
        }

        if ($this->validateProcess($model, $token)) {
            $model = $this->createPayModel($model);
            $model->setAuthToken($token);
            return $model;
        }

        return false;
    }

    /**
     * {@inheritDoc}
     */
    public function addTrace(PayModel $model, $event, $message = null)
    {
        $trace = new ProcessTrace();
        $trace->process_id = $model->getId();
        $trace->event = $event;
        $trace->message = $message;
        return $trace->save();
    }

    /**
     * {@inheritDoc}
     */
    public function findById($id)
    {
        $process = Process::find()->where(['id' => $id])->with(['items'])->one();

        if (!$process) {
            return false;
        }

        return self::createPayModel($process);
    }

    /**
     * {@inheritDoc}
     */
    public function closeModel(PayModel $model, $state)
    {
        $process = Process::find()->where(['id' => $model->getId(), 'is_closed' => 0])->one();

        if (!$process) {
            return false;
        }

        $process->is_closed = 1;
        $process->close_state = $state;
        $process->close_timestamp = time();

        return $process->update(true, ['is_closed', 'close_state', 'close_timestamp']);
    }

    /**
     * {@inheritDoc}
     */
    public function saveProviderData(PayModel $model, array $data)
    {
        $process = Process::find()->where(['id' => $model->getId()])->one();

        $process->provider_data = $data;

        return $process->update(true, ['provider_data']);
    }

    /**
     * {@inheritDoc}
     */
    public function getProviderData(PayModel $model): array
    {
        $process = Process::find()->where(['id' => $model->getId()])->one();

        if (!$process) {
            throw new PaymentException("Unable to find the given payment model.");
        }

        return $process->provider_data;
    }

    /* internal methods */

    private function validateProcess(Process $process, $token)
    {
        $process->auth_token = $token;

        return $process->validateAuthToken();
    }

    private function createPayModel(Process $process)
    {
        $model = new PayModel();
        $model->orderId = $process->order_id;
        $model->totalAmount = $process->amount;
        $model->currency = $process->currency;
        $model->randomKey = $process->random_key;
        $model->id = $process->id;
        $model->errorLink = $process->error_link;
        $model->successLink = $process->success_link;
        $model->abortLink = $process->abort_link;
        $model->authToken = $process->auth_token;
        $model->closeState = $process->close_state;
        $model->isClosed = $process->is_closed;
        $model->providerData = $process->provider_data;

        // assign items from origin process modell
        foreach ($process->items as $item) {
            $model->addItem($item->name, $item->qty, $item->amount, $item->total_amount, $item->is_shipping, $item->is_tax);
        }

        if ($model->validate()) {
            return $model;
        }

        return false;
    }
}