# Get started

Here we describe basic steps required by all supported gateways. We are going to setup models, storages, a security layer and so on. All that stuff will be used later.

{% hint style="info" %}
***Note**: If you are working with **Symfony framework** look read the bundle's* [*documentation*](https://payum.gitbook.io/payum/readme#symfony-payum-bundle) *instead.*
{% endhint %}

{% hint style="info" %}
***Note**: If you are working with **Laravel framework** look read the* [*documentation*](https://payum.gitbook.io/payum/readme#laravel-payum-package) *instead.*
{% endhint %}

### Install

The preferred way to install the library is using [composer](http://getcomposer.org/). Run composer require to add dependencies to *composer.json*:

```bash
php composer.phar require payum/offline php-http/guzzle7-adapter
```

{% hint style="info" %}
***Note**: Where **payum/offline** is a php payum extension, you can for example change it to **payum/paypal-express-checkout-nvp** or **payum/stripe**. Look at* [*supported gateways*](https://payum.gitbook.io/payum/supported-gateways) *to find out what you can use.*
{% endhint %}

{% hint style="info" %}
***Note**: Use **payum/payum** if you want to install all gateways at once.*
{% endhint %}

{% hint style="info" %}
***Note**: Use **php-http/guzzle7-adapter** is just an example. You can use any of* [*these adapters*](https://packagist.org/providers/php-http/client-implementation)*.*
{% endhint %}

Before we configure payum, let's look at the flow diagram. This flow is same for all gateways so once you familiar with it any other gateways could be added easily.

![How payum works](http://www.websequencediagrams.com/cgi-bin/cdraw?lz=cGFydGljaXBhbnQgcGF5cGFsLmNvbQoACwxVc2VyAAQNcHJlcGFyZS5waHAAHA1jYXB0dQAFE2RvbgAnBgpVc2VyLT4ANQs6AEUIIGEgcGF5bWVudAoAVAstLT4rAEsLOgBbCCB0b2tlbgoKAGcLLS0-AIE2CjogcmVxdWVzdCBhdXRoZW50aWNhdGlvbgoAgVkKLS0-AE0NZ2l2ZSBjb250cm9sIGJhY2sATg8tAIE-CDoAgUsFAHsHAIFTCC0-VXNlcjogc2hvdwCBQQggcmVzdWx0Cg\&s=default)

As you can see we have to create some php files: `config.php`, `prepare.php`, `capture.php` and `done.php`. At the end you will have the complete solution and it would be [much easier to add](https://payum.gitbook.io/payum/paypal/express-checkout/get-it-started) other gateways. Let's start from the `config.php` and continue with rest after:

### config.php

Here we can put our gateways, storages. Also we can configure security components. The `config.php` has to be included to all left files.

```php
<?php
//config.php

use Payum\Core\PayumBuilder;
use Payum\Core\Payum;
use Payum\Core\Model\Payment;

$paymentClass = Payment::class;

/** @var Payum $payum */
$payum = (new PayumBuilder())
    ->addGateway('aGateway', [
        'factory' => 'offline',
    ])

    ->getPayum()
;
```

***Note**: There are other* [*storages*](https://payum.gitbook.io/payum/storages) *available. Such as Doctrine ORM\MongoODM.*

***Note**: Consider using something other than `FilesystemStorage` in production.*

### prepare.php

At this stage we have to create an order. Add some information into it. Create a capture token and delegate the job to [capture.php](https://payum.gitbook.io/payum/examples/capture-script) script. Here's an offline gateway example:

```php
<?php
// prepare.php

include __DIR__.'/config.php';

$gatewayName = 'aGateway';

/** @var \Payum\Core\Payum $payum */
$storage = $payum->getStorage($paymentClass);

$payment = $storage->create();
$payment->setNumber(uniqid());
$payment->setCurrencyCode('EUR');
$payment->setTotalAmount(123); // 1.23 EUR
$payment->setDescription('A description');
$payment->setClientId('anId');
$payment->setClientEmail('foo@example.com');

$payment->setDetails(array(
  // put here any fields in a gateway format.
  // for example if you use Paypal ExpressCheckout you can define a description of the first item:
  // 'L_PAYMENTREQUEST_0_DESC0' => 'A desc',
));


$storage->update($payment);

$captureToken = $payum->getTokenFactory()->createCaptureToken($gatewayName, $payment, 'done.php');

header("Location: ".$captureToken->getTargetUrl());
```

***Note**: There are examples for all* [*supported gateways*](https://payum.gitbook.io/payum/supported-gateways)*.*

### capture.php

When the preparation is done a user is redirect to `capture.php`. Here's an example of this file. You can just copy\past the code. It has to work for all gateways without any modification from your side.

```php
<?php
//capture.php

use Payum\Core\Request\Capture;
use Payum\Core\Reply\HttpRedirect;
use Payum\Core\Reply\HttpPostRedirect;

include __DIR__.'/config.php';

/** @var \Payum\Core\Payum $payum */
$token = $payum->getHttpRequestVerifier()->verify($_REQUEST);
$gateway = $payum->getGateway($token->getGatewayName());

/** @var \Payum\Core\GatewayInterface $gateway */
if ($reply = $gateway->execute(new Capture($token), true)) {
    if ($reply instanceof HttpRedirect) {
        header("Location: ".$reply->getUrl());
        die();
    } elseif ($reply instanceof HttpPostRedirect) {
        echo $reply->getContent();
        die();
    }

    throw new \LogicException('Unsupported reply', null, $reply);
}

/** @var \Payum\Core\Payum $payum */
$payum->getHttpRequestVerifier()->invalidate($token);

header("Location: ".$token->getAfterUrl());
```

***Note**: Find out more about capture script in the* [*dedicated chapter*](https://payum.gitbook.io/payum/examples/capture-script)*.*

### done.php

After the capture did its job you will be redirected to [done.php](https://payum.gitbook.io/payum/examples/done-script). The [capture.php](https://payum.gitbook.io/payum/examples/capture-script) script always redirects you to `done.php` no matter the payment was a success or not. In `done.php` we may check the payment status, update the model, dispatch events and so on.

```php
<?php
// done.php

use Payum\Core\Request\GetHumanStatus;

include __DIR__.'/config.php';

/** @var \Payum\Core\Payum $payum */
$token = $payum->getHttpRequestVerifier()->verify($_REQUEST);
$gateway = $payum->getGateway($token->getGatewayName());

// you can invalidate the token. The url could not be requested any more.
// $payum->getHttpRequestVerifier()->invalidate($token);

// Once you have token you can get the model from the storage directly. 
//$identity = $token->getDetails();
//$payment = $payum->getStorage($identity->getClass())->find($identity);

// or Payum can fetch the model for you while executing a request (Preferred).
$gateway->execute($status = new GetHumanStatus($token));
$payment = $status->getFirstModel();

header('Content-Type: application/json');
echo json_encode([
    'status' => $status->getValue(),
    'order' => [
        'total_amount' => $payment->getTotalAmount(),
        'currency_code' => $payment->getCurrencyCode(),
        'details' => $payment->getDetails(),
    ],
]);
```

***Note**: Find out more about done script in the* [*dedicated chapter*](https://payum.gitbook.io/payum/examples/done-script)*.*

***

### Supporting Payum

Payum is an MIT-licensed open source project with its ongoing development made possible entirely by the support of community and our customers. If you'd like to join them, please consider:

* [Become a sponsor](https://github.com/sponsors/Payum)
