【Rails】payjpを使用した決済機能を実装する①〜クレジットカードの登録編〜

# はじめに
payjpを使用して、クレジットカードにて商品を購入する機能を実装します。
本記事は第一弾として、クレジットカードの登録機能の実装を解説します。
色々と同じような記事もありますが、とりあえず自分用メモです。
JavaScriptを使用して決済する方法もあるのですがこの記事ではRailsのみで実装しています。
誤りやもっと詳細に記載してほしい箇所があればできる限り修正したいので気軽にコメントいただければと思います。

# やりたいこと
　・payjpを使用したクレジットカードの登録機能を実装したい
![qiita.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389470/4658e3f0-16fa-54f8-6522-3cbb680bceef.gif)



# 全体の流れ
1. PAYJPにアカウント登録（APIキーの取得）
2. payjp用のgemを導入
3. テスト用のシークレットキーをcredentials.yml.encに追加
4. PAYJPよりトークンを取得し、クレジットカード情報をpayjpに登録する
5. おまけ（DBへカード情報を登録する）

# 実装してみる
### 1. PAYJPにアカウント登録（APIキーの取得）  
　[PAYJP](https://pay.jp/)のアカウントを作成し、APIキーを取得します。
以下は登録後の画面です。画面左側にある、「API」をクリックするとテスト用、本番用の鍵が表示されます。今回は実際に取引を行いたいわけではないので、テスト用のキーを使用します。（３・4章で使用します）
実際にお金のやり取りをしたい場合は、本番用のキーを使用してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389470/a298f386-a6c2-7926-6864-a60e8998be12.png)

### ２. payjp用のgemを導入  
gemfileに以下を記載します。

```Gemfile.
gem 'payjp'
```

bundle installを忘れずに。

```ターミナルで実行.
bundle install
```

### 3.テスト用のシークレットキーをcredentials.yml.encに追加
４章にて使用したいので、事前準備として「credentials.yml.enc」に以下の通り「テスト秘密鍵」を登録しておきます。

```ターミナルで実行（編集用コマンド）.
EDITOR="vi" bin/rails credentials:edit
```

```credentials.yml.enc
payjp:
 PAYJP_SECRET_KEY: sk_test_シークレットキーやで
```
参考：テスト用秘密鍵とは、１章で確認した「sk_test〜」から始まる鍵です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389470/5693deb1-f335-05e9-86bf-4991c1c7721b.png)


### 4.  PAYJPよりトークンを取得し、クレジットカード情報をpayjpに登録する 
さて、準備が終わったので実装に入ります。
結論から言うと、クレジットカードの登録機能のコードは以下の通りです。

```tbl_card.rb
class TblCard < ApplicationRecord

  require 'payjp'
  Payjp.api_key = Rails.application.credentials.dig(:payjp, :PAYJP_SECRET_KEY)

  def self.create_card_to_payjp(params)
    # トークンを作成 
    token = Payjp::Token.create({
      card: {
        number:     params['number'],
        cvc:        params['cvc'],
        exp_month:  params['valid_month'],
        exp_year:   params['valid_year']
      }},
      {'X-Payjp-Direct-Token-Generate': 'true'} 
    )
    # 上記で作成したトークンをもとに顧客情報を作成
    Payjp::Customer.create(card: token.id)
  end
end
```

一つずつ処理を見ていきます。

#### ①payjpを使用できるようにロードする。
PAYJPとやり取りするために、以下の1行目でpayjpをロードし、2行目で秘密鍵を設定しています。
なお、「:PAYJP_SECRET_KEY」というのは、前章でcredentials.yml.encに設定したものを使用します。
「Payjp.api_key = sk_〜」のように直書きしても処理自体は動くかと思いますが、セキュリティを考えるとcredentials.yml.encに記載するのが良いかと思います。

```tbl_card.rb
require 'payjp'
  Payjp.api_key = Rails.application.credentials.dig(:payjp, :PAYJP_SECRET_KEY)
```
#### ②トークンを作成する
[PayjpのAPIリファレンス](https://pay.jp/docs/api/?ruby#payjp-api)で言うと、「トークンを作成」という項目に当たります。
なお、当章の冒頭で記載したコードでは、各パラメーターをparams['number']のようにviewから受け取った値を使用するように記載していましたが、説明の便宜上、以下では具体的な値を記載します。

```tbl_card.rb

    # トークンを作成 
    token = Payjp::Token.create({
      card: {
        number:     '4242424242424242',  # ここが冒頭とは値が違います
        cvc:        '123',               # ここが冒頭とは値が違います
        exp_month:  '2',                 # ここが冒頭とは値が違います
        exp_year:   '2020'               # ここが冒頭とは値が違います
      }},
      {'X-Payjp-Direct-Token-Generate': 'true'} 
    )
```
ちなみに、、、（例ですが）上記を実行後のレスポンスとして、json形式で以下が返ってきます。（上記でいうと、変数「token」に以下の情報が格納されます）

```上記のレスポンス.json
{
  "card": {
    "address_city": null,
    "address_line1": null,
    "address_line2": null,
    "address_state": null,
    "address_zip": null,
    "address_zip_check": "unchecked",
    "brand": "Visa",
    "country": null,
    "created": 1442290383,
    "customer": null,
    "cvc_check": "passed",
    "exp_month": 2,
    "exp_year": 2020,
    "fingerprint": "e1d8225886e3a7211127df751c86787f",
    "id": "car_e3ccd4e0959f45e7c75bacc4be90",
    "livemode": false,
    "metadata": {},
    "last4": "4242",
    "name": null,
    "object": "card"
  },
  "created": 1442290383,
  "id": "tok_5ca06b51685e001723a2c3b4aeb4",    # これがトークンID！！!!!!
  "livemode": false,
  "object": "token",
  "used": false
}
```

#### ③顧客情報（クレジットカード情報）を登録する。
[PayjpのAPIリファレンス](https://pay.jp/docs/api/?ruby#payjp-api)で言うと、「顧客を作成」という項目に当たります。
これにより、トークンIDに紐付いた顧客情報が登録できます。
パラメーターは、上記②で取得したトークンID（# これがトークンID！！!!!!と記載したやつ）を渡してやります。なお、取得したレスポンスは変数「token」に格納されていますので、「token.id」とすればトークンIDを取得できますね。

```tbl_card.rb
    # 顧客情報（クレジットカード情報）を作成
    Payjp::Customer.create(card: token.id)
```

ここまでできると、以下のようにPAYJPのダッシュボードにて顧客情報が登録できていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389470/474e87c7-c92a-16f8-010c-f172b833ca86.png)

### 5. おまけ（DBへカード情報を登録する）  
今回は以下のようにカード情報を表示したいので、  
　・カードのブランド  
　・カードの最後4桁  
　・有効期限（月）  
　・有効期限（年）  
をDBへ登録します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389470/9a438b90-118a-34ac-7040-02530438b9b6.png)

第4章にて登録した「顧客情報」の実行結果から上記の値を取得します。
今回は中身を確認するために、一時的に変数「test」に実行結果を格納してみます。
中身を確認してみるとこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389470/b9dbb94c-fb01-cab6-32e5-a51a652f90ac.png)

以上でクレジットカード情報をPAYJPへ登録ができました。

# 最後に
　今回はクレジットカードの情報をPAYJPへ登録しました。次回はクレジットカードを使用した商品購入機能の実装をしていきます。