GMO-PGのリンクタイプPlusでクレジット決済をする（キー型）

# 概要

[CodeIgniterを利用した商品申込ページを作成してGMO-PGのリンクタイプPlusでクレジット決済をする](https://qiita.com/You_name_is_YU/items/5617bec05204d0f26518)の記事で、GMO-PGのリンクタイプPlusクレジット決済画面への遷移を`パラメータ型`の実装方法で実現しました。
パラメータ型の実装ではどうしてもパラメータ情報をクエリパラメータに含めなければならず、GMOも今後修正を入れてよりセキュアにする予定のようです。

パラメータ型以外のリンクタイプPlus決済画面への遷移URL取得方法としては、キー型というのが存在し、プロトコルタイプで用意されている`GetLinkplusUrlPayment.json`の決済URL取得APIを利用してURLを生成する方法があります。

その実装方法をメモとして残します。

# システム開発メモ

基本的には[CodeIgniterを利用した商品申込ページを作成してGMO-PGのリンクタイプPlusでクレジット決済をする](https://qiita.com/You_name_is_YU/items/5617bec05204d0f26518)の記事の内容で重複するソース部分は省きます。

## Controller

`getGmoUrl()`で`GetLinkplusUrlPayment.json`のAPIを実行し、取得結果から決済画面へ遷移するURLの情報を取得しています。
他の処理はほとんど変わりません。

```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(
                'geturlparam'=> array(
                    'ShopID'=> SHOP_ID,
                    'ShopPass'=> SHOP_PASS,
                    'GuideMailSendFlag'=> '1',
                    'SendMailAddress'=> $this->input->post('email'),
                    'CustomerName'=>$this->input->post('name'),
                    'TemplateNo'=> '1'
                ),
                'configid'=> 'test01',
                'transaction'=> array(
                    'OrderID'=> $orderId,
                    'Amount'=> 10000,
                    'Tax'=> 10
                ),
                'credit'=> array(
                    'JobCd'=> 'AUTH'
                )
            );

            // 配列→json変換
            $param = json_encode($arrayParam);

            // 上記で生成したリンクタイプPlusの決済画面へ遷移するURLをセットして画面表示
            $data['form']['action'] = $this->getGmoUrl($param);
            // debug用にjsonパラメータを確認する文字列をセット
            $data['form']['json'] = $param;
            
            $this->load->view('templates/header', $data);
            $this->load->view('pages/comp', $data);
            $this->load->view('templates/footer', $data);
        }
    }

    function getGmoUrl($param) {

        // リクエストコネクションの設定
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json;charset=UTF-8'));
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
        curl_setopt($curl, CURLOPT_POSTFIELDS, $param);
        curl_setopt($curl, CURLOPT_URL, 'https://pt01.mul-pay.jp/payment/GetLinkplusUrlPayment.json');

        // リクエスト送信
        $response = curl_exec($curl);
        $curlinfo = curl_getinfo($curl);
        curl_close($curl);

        // レスポンスチェック
        if($curlinfo['http_code'] != 200){
            throw new Exception('GetLinkplusUrlPayment.json API実行が失敗しました。 : ' . $curlinfo['http_code']);
        }

        // レスポンスのエラーチェック
        parse_str($response, $data);
        if(array_key_exists('ErrCode', $data)){
            throw new Exception('GetLinkplusUrlPayment.json API実行が失敗しました。 : ' . $data['ErrCode']);
        }

        // 決済URL取得APIの実行結果から決済画面へ遷移するためのリンク情報を取得し返却
        $resJson = json_decode($response, true);
        return $resJson['LinkUrl'];
    }
}
```