【日本上陸】オンライン決済サービスStripeによる円決済の実装 入門

#オンライン決済サービスって何があるの？

日本で利用できるクレジット決済APIとい言えば、Pay.jpやWebPayやSPIKE、Paypalなど様々なサービスがあります。

Pay.jpやWebPayは開発者に優しいと評判であったり、SPIKEは決済手数料が無料があることに着目されていたり、決済会社それぞれのメリット・デメリットを比較した上でどのAPIを使用するか選定する必要がありそうです。

[【比較表】pay.jpが開始、オンライン決済サービス比較表をつくりました](http://michihhh.hateblo.jp/entry/2015/10/13/213348)
[【徹底比較】話題の5大オンライン決済サービスPayPal、SPIKE、Stripe、WebPay、Yahoo!ウォレット FastPay、を比べてみた（比較表有り） ](http://keiei.freee.co.jp/2015/06/01/paypal-spike-stripe-webpay-yahoowalletfastpay/)

そんな中、欧米で勢いのある[Stripe](https://stripe.com/japan)が日本上陸ということで円決済に対応した決済APIを日本でも提供を始めました。今後Stripeへの注目が期待されるでしょう。

Stripeはシンプルな実装で決済を実現でき、手数料等も比較的安く、とても魅力的なサービスです。また、問い合わせに対するサポートも非常に丁寧です。機能も充実しています。

今回は、基本的なサービスにおける決済機能を実現するための入門と応用を取り上げます。

APIの仕様書のページはこちら → [Stripe API Reference](https://stripe.com/docs/api)
CurlやRuby,Python,PHP,Java,Node,Goに対応しています。

円決済に関する情報がまだネット上では見当たらないので、PHPによるサンプルコードで実装例を取り上げながら説明します。あくまで参考程度に留めてください。

#Stripeによる決済
##想定する決済のイメージ
ユーザーが会社にサービス料を支払う流れの決済処理を行う。
![resource1.JPG](https://qiita-image-store.s3.amazonaws.com/0/81083/086486d2-89e5-61d2-93f0-ee2b82667df7.jpeg)


##円決済実装の流れ
![resource4.JPG](https://qiita-image-store.s3.amazonaws.com/0/81083/f2ceee4e-30a9-dcb5-83a9-9b1b8fd29d8f.jpeg)

### ユーザー側での情報登録
StripeでStripe Connectという機能を使用して実装するが、以下の2通りの方法がある。
(参考: [What’s the difference between a Connect standalone account and a Connect managed account?](https://support.stripe.com/questions/what-s-the-difference-between-a-connect-standalone-account-and-a-connect-managed-))

1. standalone
2. managed account

ここではmanaged accountによる方法で実装を行う。


予めユーザー側でクレジット情報を登録しておき、Stripe側で管理する顧客情報とこちら側で扱う際の紐づけIDであるcustomer_idとカード情報の紐づけ情報であるcard_idを発行する処理を実装する。
発行した、customer_idとcard_idはこちら側でDBに保存するなどして管理しておく。

対応しているクレジットカードは以下の通りとなる。

1. Visa
2. MasterCard
3. AmeEx

最初にStripeのAPIキーをセットする。以降、Stripeの関数が呼ばれる際はこの関数を呼び出すようにしておく。

```php
\Stripe\Stripe::setApiKey('<StripeのAPI KEY>')
```

ユーザー情報を登録する際にはTokenを発行して、その情報を基にcustomer_idを発行する。

```php
$token_response = \Stripe\Token::create(array(
        "card" => array(
                        "name" => $_POST['name'),
                        "number" => $_POST['account_number'],
                        "exp_month" => intval($_POST'month']),
                        "exp_year" => intval($_POST['year']),
                        "cvc" => $_POST['cvc']
        )
));

$token = $token_response->__get('id');
if($token !== NULL){
            $result = \Stripe\Customer::create(array(
                    "source" => $token,
                    "email" => $user['email'],
                    "description" => "New customer account"
            ));

            // Update 'customer_id' column and 'card_id' column of User table
            //'customer_id' => $result->__get('id'),
            //'card_id'     => $result->__get('sources')->__get('data')[0]->__get('id'),

}
```

テストなどで実際の情報を入力しない際は、Stripeからテストデータが与えられているのでこちらを利用する
[test card numbers - Stripe](https://stripe.com/docs/testing)

例えば、カード番号として、Visaのテストデータである4242424242424242を利用できる。

### 支払処理の実装
Stripe側に登録したユーザーのクレジット情報を基に決済を行う処理を実装する。

```php
$result = \Stripe\Charge::create(array(
        "customer" => $user['customer_id'],
        "amount" => $amount,
        "currency" => 'jpy',
        "metadata" => array("order_id" => "123")
));
```

\Stripe::createによるレスポンスで返されるcharge_idは必要に応じて管理しておくと良い。


#応用
##想定する決済のイメージ
会社からユーザーに人を派遣して、ユーザーがサービス料を会社に支払い、会社から派遣者に対してサービス代金の支払う流れの決済処理を行う。

![sample.JPG](https://qiita-image-store.s3.amazonaws.com/0/81083/c64fa8db-e6e7-8931-7a0f-843f02fb470d.jpeg)

##円決済実装の流れ
![resource3.JPG](https://qiita-image-store.s3.amazonaws.com/0/81083/6d4b20b3-df47-442f-a1dd-a5b26adffd67.jpeg)

###円決済実装の流れ
これは先ほどと同様のものとなる。

###派遣者側の情報登録
派遣者の口座情報を登録する処理を行う。この際に発行されるaccount_idはこちら側でDBに保存するなどして管理しておく。
なお、routing numberとは、機関コード4桁+支店コード3桁を組み合わせた7桁の数字である。

```php
$result = \Stripe\Account::create(array(
                'country' => 'JP',
                'managed' => true,
                'legal_entity' => array(
                        'address_kana' => array(
                                'city' => $_POST['city_kana'],
                                'country' => $_POST['country_kana'],
                                'line1' => $_POST['line1_kana'],
                                'postal_code' => $_POST['postal_code'],
                                'state' => $_POST['state_kana'],
                                'town' => $_POST['town_kana']
                        ),
                        'address_kanji' => array(
                                'city' => $_POST['city_kanji'],
                                'country' => $_POST['country_kanji'],
                                'line1' => $_POST['line1_kanji'],
                                'postal_code' => $_POST['postal_code'],
                                'state' => $_POST['state_kanji'],
                                'town' => $_POST['town_kanji']
                        ),
                        'dob' => array(
                                'day' => $_POST['day'],
                                'month' => $_POST['month'],
                                'year' => $_POST['year']
                        ),
                        'first_name_kana' => $_POST['first_name_kana'],
                        'first_name_kanji' => $_POST['first_name_kanji'],
                        'last_name_kana' => $_POST['last_name_kana'],
                        'last_name_kanji' => $_POST['last_name_kanji'],

                        'phone_number' => $_POST['phone_number'],
                        'gender' => $_POST['gender'],
                        'type' => 'individual'
                ),

                'tos_acceptance' => array(
                        'date' => time(),
                        'ip' => $_SERVER['REMOTE_ADDR']
                ),
                "external_account" => array(
                        "object" => "bank_account",
                        "country" => "JP",
                        "currency" => "jpy",
                        "account_holder_name" => $_POST['account_holder_name'],
                        "account_holder_type" => "individual",
                        "routing_number" => $_POST['routing_number'],
                        "account_number" => $_POST['account_number']
                )

));

// Update 'account_id' column and 'bank_id' column of Dispatched workers table
$bank_id = $result->external_accounts->data[0]->__get('id');
$account_id = $result->__get('id');
```
テストで実際の口座情報を入力しないときは、ユーザーのカード情報の登録の時と同様にStripeからテストデータが与えられている。

例えば、アカウント番号として00012345、ルーティング番号として1100000が与えられている。


###派遣者の身分証明処理
Stripe側から派遣者に対して処理を行う際に派遣者の身元を証明するための実装を行う。具体的には、身分証明書を撮影した画像をStripeにAPIを通して送信する処理となる。

身分証明書として可能な対象は以下の通りである。

1. 運転免許証
2. 保険証
3. パスポート
4. 在留カード

```php
$response = \Stripe\FileUpload::create(
	array(
		"purpose" => "identity_document",
		"file" => $_FILES['tmp_name']
	),
	array("stripe_account" => "<派遣者のaccount_id>")
);

if (!empty($response)) {
	$file_size = $response->__get('size');
	if ($file_size > 0) {
		$account = \Stripe\Account::retrieve($account_id);
		$account->__get('legal_entity')->__get('verification')->document = $response->__get('id');
		$account->save();
	}
}
```

verificationのstatusがunverifiedの状態からverifiedとなれば、承認が下りたことなる。
なお、承認はテストモードではすぐに下りるが、実際の環境ではおおよそ1日ぐらいかかると思っておくとよい。この際、unverifiedからpendingという状態を経過し、承認が下りればverifiedとなる。

###決済処理
ユーザーが支払ったサービス料に対して、派遣者がお金を受け取り、会社がマージンを受け取る処理を実装を行う必要がある。
$rateで会社の受け取るマージンの率を指定する。

```php
$result = \Stripe\Charge::create(array(
        "customer" => $user['customer_id'],
        "destination" => $worker['account_id'],
        "amount" => $amount,
        "application_fee" => floor($amount * $rate),
        "currency" => 'jpy',
        "metadata" => array("order_id" => "123")
));
```

もし、支払った際に派遣者の身分証明書がStripeから未承認の際について、決済を受けられるが入金は保留を表すtransfers_enabledがtrueとなり、その後決済も受けられなくなるcharges_enabledがfalseになる。