CodeIgniterを利用した商品申込ページを作成してGMO-PGのリンクタイプPlusでクレジット決済をする

# 概要

CodeIgniterを利用したDBアクセスを必要としない商品申し込みページを作成し、
GMO-PGのリンクタイプPlus決済ページへ連携してクレジットカード決済を完了させるまでを構築します。

ここではリンクタイプPlusの決済画面へ遷移する2つの方法（パラメータ型，キー型）のうち、`パラメータ型`と呼ばれる方法をまとめています。
`キー型`の実装方法については[GMO-PGのリンクタイプPlusでクレジット決済をする（キー型）](https://qiita.com/You_name_is_YU/items/3466888c85d4895465ee)にController部分の実装例を載せました。

# 環境

- CentOS Linux release 8.2.2004 (Core) 
- Apache/2.4.37 (centos)
- PHP 7.4.10 (VagrantでCentOS8.2をセットアップするとデフォルトで入ってた）
- CodeIgniter 3.1.11


# 環境構築手順メモ

## CentOS環境の構築

[Vagrantを使ってCentOS8の環境を立ち上げプロビジョニングによって日本語開発環境として成立させる最小構成](https://qiita.com/You_name_is_YU/items/6b350f99fb90dd4baf3a)

でCentOS8の環境は構築しています。
これで構築すると、PHPも入っていたのでそのまま使おうと思います。

## apacheの構築

デフォルトでapacheは入っていなかったのでインストールします。
あんまり最新バージョンにこだわっていないので、ここでは標準でインストール可能なものにします。

```shell-session
dnf install -y httpd httpd-tools httpd-devel httpd-manual
systemctl enable httpd
systemctl start httpd
```

この状態で
http://192.168.33.10
にアクセスできていたらOK

## phpの設定

```shell-session
cd /etc
cp -p php.ini php.ini.org
vim php.ini
```

```ini:php.ini
[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"
```

```shell-session
cd /var/www/html
vim test.php
```

```php:test.php
<?php

phpinfo();
```

以下にアクセスしてphpinfo()の結果が表示されていればOK
http://192.168.33.10/test.php

## CodeIgniterの構築

`wget`が使えなかったので、最初にインストールします。
githubにあるCodeIgniterでReleaseされているものを探しダウンロードして解凍します。

```shell-session
dnf -y install wget
cd /home/vagrant
wget https://github.com/bcit-ci/CodeIgniter/archive/3.1.11.tar.gz
tar -zxvf 3.1.11.tar.gz
cp -r CodeIgniter-3.1.11/ /var/www/html/
cd /var/www/html
mv CodeIgniter-3.1.11 codeigniter
vim /var/www/html/codeigniter/application/config/config.php
```

config.phpでbase_urlの設定だけしておきます。

```php:config.php
$config['base_url'] = 'http://192.168.33.10/codeigniter/';
```

以下にアクセス
http://192.168.33.10/codeigniter/

![スクリーンショット 2020-09-19 9.06.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/f77e878b-92de-d5e5-f27e-b88fa9736e9d.png)

まずは環境構築完了。

# システム開発メモ

CodeIgniterの標準装備されているコードを除き、開発ソースコード部分のみの全体像は以下の通りです。

```shell-session:tree
.
├── application
│   ├── assets
│   │   └── css
│   │       └── style.css
│   ├── config
│   │   ├── config.php
│   │   ├── constants.php
│   ├── controllers
│   │   ├── Apply.php
│   └── views
│       ├── pages
│       │   ├── comp.php
│       │   └── home.php
│       ├── templates
│       │   ├── footer.php
│       │   └── header.php
```

## config.php

config.phpは、validationの日本語対応するために設定したぐらいです。
japaneseと指定した場合、system/language/japaneseに定義ファイルが必要になりますが、
http://codeigniter.com/download
から入手したものをそのまま使いました。

```php:codeigniter/application/config/config.php
...
$config['base_url'] = 'http://192.168.33.10/codeigniter/';
...
$config['language']	= 'japanese';
```

## constants.php

constants.phpにはGMO-PGのショップ管理画面の[ショップ管理]->[ショップ情報]->[基本情報]->[ショップ]
にある、IDとパスワードの情報を定数として定義しています。

## Controller

Controllerはシンプルに1つのみ作成しています。
商品申し込みページ -> 申込完了ページ（ここでGMOの決済画面への遷移を促す）
というページ構成です。

リンクタイプPlusの決済画面へ遷移するための方法としては２通りの方法があるようで、
ここではパラメータ型という遷移方法で実現しています。
この他に、キー型という遷移方法があるようですが、プロトコルタイプのAPI仕様を確認しつつ進める必要がありそうだったので、今回は簡単そうなパラメータ型にしました。

```php:codeigniter/application/controllers/Apply.php
<?php
class Apply extends CI_Controller {

    public function __construct()
    {
        parent::__construct();
        $this->load->helper('html');
        $this->load->helper('form');
        $this->load->helper('url_helper');

        $this->load->library('form_validation');
        
    }

    // 商品申込ページへの遷移
    public function show ($page = 'home')
    {
        if ( ! file_exists(APPPATH.'views/pages/'.$page.'.php'))    
        {
            show_404();
        }

        $data['title'] = "商品申込ページ";

        $data['form']['name'] = '';
        $data['form']['email'] = '';

        $this->load->view('templates/header', $data);
        $this->load->view('pages/home', $data);
        $this->load->view('templates/footer', $data);
    }

    // 申し込むボタン押下
    public function post()
    {
        $data['title'] = "商品申込ページ";
        $data['form'] = $this->input->post();

        // 一応チェック処理を入れる
        $this->form_validation->set_rules('name', 'お名前', 'required');
        $this->form_validation->set_rules('email', 'E-Mail', 'required|valid_email');

        // 入力値にエラーがある場合は元の画面に戻りエラーメッセージを表示
        // エラーが無い場合は申込完了画面を表示して、GMO-PGで決済手続きをしてもらう。
        if ($this->form_validation->run() === FALSE)
        {
            $this->load->view('templates/header', $data);
            $this->load->view('pages/home');
            $this->load->view('templates/footer');

        }
        else
        {
            // GMOの決済で指定するオーダーIDは一意でなければいけない
            $orderId = 'OR' . date('YmdHis') . rand();

            // json形式のパラメータを生成するための配列パラメータ定義
            $arrayParam = array(
                'configid'=> 'test01',
                'transaction'=> array(
                    'OrderID'=> $orderId,
                    'Amount'=> 10000,
                    'Tax'=> 10,
                    'PayMethods'=> array('credit'),
                    'NotifyMailaddress'=>$this->input->post('email')
                )
            );
            
            // 配列→json変換
            $param = json_encode($arrayParam);
            // jsonパラメータをbase64エンコード
            $base64param = base64_encode($param);
            // base64エンコードしたパラメータ＋ショップパスワードに対してSHA256でハッシュ化
            $hash = hash('sha256', $base64param . SHOP_PASS);
            // base64パラメータ ＋ '.' ＋ SHA256でハッシュ化したパラメータ
            // ポイントは、base64パラメータとSHA256のハッシュ化した文字列の間にドットを入れるところ。
            $hashParam = $base64param . '.' . $hash;
            // リンクタイプPlusの決済画面へ遷移するためのURLを生成
            $gmoBaseUrl = 'https://stg.link.mul-pay.jp/v1/plus/'.SHOP_ID.'/checkout/'.$hashParam;
            
            // 上記で生成したリンクタイプPlusの決済画面へ遷移するURLをセットして画面表示
            $data['form']['action'] = $gmoBaseUrl;
            // debug用にjsonパラメータを確認する文字列をセット
            $data['form']['json'] = $param;
            
            $this->load->view('templates/header', $data);
            $this->load->view('pages/comp', $data);
            $this->load->view('templates/footer', $data);
        }
    }
}
```

## View

```php:codeigniter/application/views/templates/header.php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>商品申込</title>

    <?php echo link_tag("application/assets/css/style.css"); ?>
</head>
<body>
<h1><?php echo $title; ?></h1>
```

```php:codeigniter/application/views/templates/footer.php
    <em>&copy; 2020</em>
</body>
</html>
```

```php:codeigniter/application/views/pages/home.php
<?php
$name = array('type'=>'text', 'name'=>'name', 'value'=>$form['name'], 'maxlength'=>100);
$email = array('type'=>'text', 'name'=>'email', 'value'=>$form['email'], 'maxlength'=>100);
?>

<div class="msg">
    特に怪しいサイトではありません。<br>
    たった１万円で素敵な商品が手に入ります。<br>
    お名前とメールアドレスを入力して`申し込む`ボタンを押してください。
</div>

<?php echo form_open('apply/post'); ?>

    <label for="name">お名前</label>
    <?php echo form_input($name);?><br>
    <?php echo form_error("name");?>

    <label for="email">E-Mail</label>
    <?php echo form_input($email);?><br>
    <?php echo form_error("email");?>

    <input type="submit" name="submit" value="申し込む" />

</form>
```

```php:codeigniter/application/views/pages/comp.php
<div class="msg">
    申込ありがとうございます。<br>
    GMO Payment Gatewayのサイトへアクセスし、決済手続きをお願いします。
</div>

<pre>
<?php echo $form['json']; ?>
</pre>

<form method="get" action="<?php echo $form['action']; ?>">
    <input type="submit" name="submit" value="GMO-PGで決済" />
</form>
```

## 動作確認

こんな感じでCodeIgniterを使って、GMO-PGのリンクタイプPlusに対し、クレジットカード決済するための決済画面へ遷移するプログラムの超簡易版が完成しました。

あとは以下のURLにアクセスして必要事項を入力することで、GMOの決済ページへ遷移できます。

http://192.168.33.10/codeigniter

![スクリーンショット 2020-09-21 18.47.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/07f72bd1-ad82-8de1-b69d-16be04946b8c.png)

![スクリーンショット 2020-09-21 18.47.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/2a6c37b5-6314-8f15-3a46-c132bdce043c.png)

![スクリーンショット 2020-09-21 18.47.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/c8e31a44-a15f-b38d-7bb8-e5bcfe7cab0d.png)