Omise Elixir クライアントライブラリによるテストドライブ

eコマースでクレジットカード情報を扱うのは少々大変である。オンライン決済サービスを使えばクレジットカード情報に触れずに決済ができる。

オンライン決済サービスを提供しているサービスはいくつかあるが、中でも Omise はエンジニアには嬉しいREST API を提供していて、かつ様々な言語のクライアントライブラリを用意している。この記事では Omise の Elixir クライアントを使ってAPIの使い方を紹介する。

決済代行サービスを使うと以下のような形で顧客と取引できるようになる。

<img width="493" alt="Screen Shot 2018-07-27 at 16.29.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/138674/746dad7b-faae-4475-33d1-d85e33bcd037.png">

決済サービスは顧客の口座からマーチャントの口座にお金を送金するには顧客のクレジットカード情報が必要である。従って、事前にクレジットカード情報を渡さないといけないが、セキュリティの観点からマーチャントはクレジットカード情報の非保持化が要求されているのでOmise では以下のような仕組みで顧客のクレジットカードを登録している

<img width="778" alt="Screen Shot 2018-07-27 at 16.30.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/138674/1d4581c4-2d9e-ad40-870d-4bb465af72a2.png">

つまり、Omiseはカード情報は顧客から受け取り、顧客IDはマーチャントから受け取っている。


### 前提

このチュートリアルは Omise のアカウントが開設済みであること、また Elixir のインストール済みであることを前提とする。Omise のアカウントは [Omise サインアップ](https://dashboard.omise.co/signup?locale=ja)から開設できる。



さて、今回はテストするだけだったのでプロジェクトを作るところから始める。

```bash
mix new omise_testdrive
```

これで`omise_testdrive/`というプロジェクトディレクトリが作成される。



次に Omise の API を実行するのに必要な秘密鍵と公開鍵を設定ファイルに記録。環境変数を使う方法とか、プログラムで指定する方法もあるが、今回はデモなのでこの方式で進める。テスト用の秘密鍵と公開鍵は Omise の[ダッシュボード](https://dashboard.omise.co/test/keys)から取得できる。

config/config.exs

```elixir
use Mix.Config

  config :omise,
  public_key: "pkey_test_xxx",
  secret_key: "skey_test_xxx"
```


あとは Omise クライアントのインストールをするため、Dependencies にライブラリを追加する。

mix.exs

```elixir
defmodule OmiseTestdrive.MixProject do
  use Mix.Project

  def project do
    [
      app: :omise_testdrive,
      version: "0.1.0",
      elixir: "~> 1.6",
      start_permanent: Mix.env() == :prod,
      deps: deps()
    ]
  end

  # Run "mix help compile.app" to learn about applications.
  def application do
    [
      extra_applications: [:logger]
    ]
  end

  # Run "mix help deps" to learn about dependencies.
  defp deps do
    [{:omise, "~> 0.6.0"}]
  end
end
```
最後にダウンロードとインストールすれば準備完了。

```bash
mix deps.get
```

ここからはいよいよテストドライブ。まずはコンソールを立ち上げる。
```bash
iex -S mix
```
### API の実行

まずは顧客を作成してみる

```elixir
Omise.Customer.create(
  email:       "Taro@example.com",
  description: "優良顧客"
)
```

すると以下のようなレスポンスが返ってくる

```elixir
{:ok,
 %Omise.Customer{
   cards: %Omise.List{
     data: [],
     from: "1970-01-01T00:00:00Z",
     limit: 20,
     location: "/customers/cust_test_5cq0pctv947zm23jaii/cards",
     object: "list",
     offset: 0,
     order: nil,
     to: "2018-07-26T07:13:55Z",
     total: 0
   },
   created: "2018-07-26T07:13:55Z",
   default_card: nil,
   deleted: false,
   description: "優良顧客",
   email: "taro@example.com",
   id: "cust_test_5cq0pctv947zm23jaii",
   livemode: false,
   location: "/customers/cust_test_5cq0pctv947zm23jaii",
   metadata: %{},
   object: "customer"
 }}
```

このレスポンスを元にビジネスロジックを制御するが、この記事は紹介に留める。ここで次のステップに必要になってくるのは `id: "cust_test_5cq0pctv947zm23jaii"`で、これは顧客IDである。

顧客から支払いを受け取るにはまずカードの登録が必要である。カード番号は自身のサーバーで扱うのは望ましくないので本来はクライアントサイドから直接Omiseに送る(Javascript ライブラリは用意されている)が今回はデモなのでその手順もElixir で取得する。

```elixir
Omise.Token.create(
  card: [
    name:             "Taro Yamada",
    number:           "4242424242424242",
    expiration_month: 10,
    expiration_year:  2018,
    security_code:    123
  ]
)
```

これを実行すると `id: "tokn_xxx" のような**トークンID** が取得できる。このトークンIDを最後に顧客に結びつける。結びつけるには顧客IDとトークンIDをパラメータとして渡す。

```elixir
Omise.Customer.update("cust_test_5cq0pctv947zm23jaii", [
  card: "tokn_test_5cq0vd3auln4br2liou",
])
```

これでやっと顧客からの支払いが可能になる。



これで顧客のデフォルトのカードを使ってクレジットカードの情報を使わずに課金できるようになる。

```elixir
Omise.Charge.create(amount: 10000, currency: "jpy", customer: "cust_test_5cq0pctv947zm23jaii")                                                          
{:ok,
 %Omise.Charge{
   amount: 10000,
   authorize_uri: nil,
   authorized: true,
   capture: true,
   captured: nil,
   card: %Omise.Card{
     bank: "",
     brand: "Visa",
     #<省略>
     }
 }}
```

画像はOmiseのロゴの元となったメビウスの輪と永楽通宝

![mebius.jpeg](https://qiita-image-store.s3.amazonaws.com/0/138674/248d36b1-c68f-36d2-a44d-7ac6981ad791.jpeg)
![coin.jpg](https://qiita-image-store.s3.amazonaws.com/0/138674/767f97f0-7104-1708-151c-f89ee8aa703e.jpeg)