前書き
技術環境
・使用言語(サーバーサイド):PHP(5.3)
・使用言語(フロント):HTML,CSS,jQuery
・フレームワーク:CakePHP(2.3)
読者ターゲット
・これまでにAPIを使って何かを実装したことない人(筆者も)
・導入部分は言語関係なく書いているのでどなたでも読めると思います
実装、記事にする内容
・FreeeAPIの始め方
・請求書発行ボタンを押した時にメールが先方に送付される仕組みに、freeeに請求内容が登録される仕組みを追加する実装
記事にした理由
・もともと仕事で実装する予定だったけれども、施策が頓挫したので勉強がてら実装しながらQiita夏祭りにも参加してみようと思ったため
・どこのAPIもチュートリアルがちょっとわかりづらいので、実装ついでのメモ
導入部分
ユーザー登録

まずはTOPに飛んで、右上の「ユーザー登録」をクリック

表示名とメールアドレスと入力
(バリデーションエラーが英語なので日本語にして欲しい(願望))

登録が完了できていれば上記の様なメールが届きます
記載されているURLをクリックするとパスワードの設定画面に遷移するのでパスワードの設定
ログイン後

まずはヘッダーのスタートアップガイドをクリック

セットアップの順序通り、まずはセットアップから「freeeアカウントをお持ちの方」をクリック

先ほど作成したアカウントでログイン

事業所とアプリの作成
テストで使用する事業所の作成「freee APIの利用を開始する」をクリック

上記の様なメールが届けば開発用テスト事業所とテストアプリ作成完了
「アクセストークン取得ページ」をクリック

アプリ連携の開始が表示されるとの「許可」をクリック

「許可」をクリックした後に開発用テスト事業所ID・アクセストークンのページに遷移するので
アクセストークンをコピー
コピーした後に
「APIリファレンスでCompaniesに移動」をクリック


遷移先の説明文の下に「Authorize」があるのでクリックし、先ほどコピーしたアクセストークンを貼り付けて「Authorize」をクリック
アクセストークンの設定確認

Companies 事業所までスクロールをして「Try it out」をクリック

真下に「Execute」と「Clear」が表示されるので「Execute」をクリック

上記の様に「Responses」が表示されて「Server response」のコードが200ならブラウザ上で正しくAPIが動作しています
curl -X GET "https://api.freee.co.jp/api/1/companies"
-H "accept: application/json"
-H "Authorization: Bearer アクセストークン"
また、真ん中に書いてあるcurlの様にリクエストを投げればAPIでの連携が出来る状態になっています
「curl -X GET 」・・・リクエストするURL
「-H 」・・・ヘッダーの中身
また、取引内容をPOSTする際に事業所のIDが必要になりますのでResponse bodyをみてIDをメモしておきましょう。

Response bodyの例
{
"companies": [
{
"id": 1234, //このIDを利用する
"name": null,
"name_kana": null,
"display_name": "開発用テスト事業所",
"role": "admin"
}
]
}
WEB上で取引POSTテストの前準備
取引内容を登録する際に事業所IDと取引先ID、取引品目ID、勘定科目IDが必要になります。
上記では事業所IDを取得しましたが取引先のIDと取引品目IDと勘定科目IDを取得が必要ですので「会計APIリファレンス」で取得してみましょう。
取引先IDの取得

サイドメニューから「取引先」のGETをクリックしましょう。


「Try it out 」をクリックした後に「company_id」の入力フォームが出てきますので、先ほどメモした事業所IDを入力をして「Execute」をクリックします。

Server responseから送付する取引先IDを取得します。
取引品目IDの取得

サイドメニューから「品目」のGETをクリックしましょう。


取引先ID同様に「Try it out 」をクリックした後に「company_id」の入力フォームが出てきますので、先ほどメモした事業所IDを入力をして「Execute」をクリックします。

Server responseから送付する品目IDを取得します。
また、勘定科目も上記の様に勘定科目のGETから取得してください
取引のPOSTテスト

サイドメニューから「取引(収入/支出)」の「POST」をクリックします

今まで同様に「try it out」をクリック

送信される内容を表示されるので今まで取得した内容を元に編集
{
"issue_date": "2013-01-01",
"type": "income",
"company_id": 1, //事業所IDを記載
"due_date": "2018-12-31",
"partner_id": 1, //取引先IDを記載
"partner_code": "code001", //取引先コードは設定していないので削除
"ref_number": "1",
"details": [
{
"tax_code": 1,
"account_item_id": 1, //取得した勘定科目IDの入力
"amount": 1,
"item_id": 1, //取得した取引品目IDを入力
"section_id": 1, //部門IDは今回は使わないので削除
"tag_ids": [
1 //タグも今回使用しないので削除
],
"segment_1_tag_id": 1, //セグメントタグ情報は法人向けのプロフェッショナルプラン以上で利用可能なので削除
"segment_2_tag_id": 1, //上記同様
"segment_3_tag_id": 1, //上記同様
"description": "備考",
"vat": 800
}
],
"payments": [ //支払行一覧ですが、取引のPOSTテストなので今回は削除(ここは設定しないと未決済になるので実装する際は設定しましょう)
{
"amount": 5250,
"from_walletable_id": 1,
"from_walletable_type": "bank_account",
"date": "2013-01-28"
}
],
"receipt_ids": [ //証憑ファイルIDですがこちらも取引のPOSTテストなので今回は削除
1
]
}
{
"issue_date": "2020-04-01",
"type": "income",
"company_id": 事業所ID,
"due_date": "2020-05-01",
"partner_id": 取引先ID,
"ref_number": "1",
"details": [
{
"tax_code": 1,
"account_item_id": 勘定科目ID,
"amount": 1,
"item_id": 取引品目ID,
"description": "備考",
"vat": 800
}
]
}


ポストされたかの確認

公式サイトを表示して
右上のログインをクリック


下の決済期日の近い取引に先ほどポストした内容が記載されていれば、POSTはできています。
※POSTした際のdue_dateが古ければここに表示されない場合があります。
ここからコード
まず請求書が発行されるボタンが下記の様に設置されていたとします。
<button id="bill_post" value="sale_id">請求書発行</button>
//sale_idには請求する内容が入ったsaleテーブルのIDが入っていたとします。
請求書発行ボタンが押されてコントローラーにPOSTされるまでの処理をjQueryで書きます。
<?php $this->Html->scriptStart(array('inline' => false)); ?>
$(function() {
$(document).on('click', '#bill_post',function() {
var sale_id = $(this).val();
$.ajax({
type: 'post',
//送信先はcakephpのhtmlヘルパーを使用
url: '<?= $this->Html->url(['controller' => 'Sale', 'action' => 'bill']) ?>',
dataType: 'JSON',
//送信する内容はsaleテーブルのIDのみ
data: {
id: sale_id
},
//記事用なのでエラーメッセージは省略
// 送信ができた時
}).done(function(data) {
window.alert('送信しました。');
// 送信ができなかった時
}).fail(function() {
window.alert('送信できませんでした。');
});
});
});
<?php $this->Html->scriptEnd(); ?>
下記からcakephpで請求内容が送付される処理
class SalesController extends AppController{
public function bill(){
$this->autoRender = false;
$post_date = $this->request->data['id'];
//DBから販売データの取得
$sale_date = $this->Sale->find('first', [
'condition' => [
'id' => $post_date ,
]
]);
//ここからfreeeのAPIにPOST
// 前準備で作っておいた、tokenを設定
$token = 'freeeDevで取得したtokenの設定';
$base_url = 'https://api.freee.co.jp';
$post_data = [
"issue_date": '"' . $sale_date['Sale']['create_date'] . '"', //発生日
"type": "income",
"company_id": 事業所ID,
"due_date": '"' . $sale_date['Sale']['due_date'] . '"', //支払期日
"partner_id": '"' . $sale_date['Sale']['trader'] . '"', //取引先ID
"ref_number": "1",
"details": [
{
"tax_code": 1,
"account_item_id": 勘定科目ID,
"amount": 1,
"item_id": 取引品目ID,
"description": "備考",
"vat": 800
}
]
];
//APIリファレンスのcurlに書いてあったヘッダーと同じ内容にする
$header = [
// 前準備で取得したtokenをヘッダに含める
'Authorization: Bearer '.$token,
// json形式のデータをpostするので必要
'Content-Type: application/json',
];
$context = stream_context_create(array(
'http' => array(
'method' => 'POST',
'header' => implode(PHP_EOL,$header),
'content'=> json_encode($post_data),
'ignore_errors' => true
)
));
$response = file_get_contents(
$base_url.'/api/1/deals'
,false
,$context
);
$header = $http_response_header;
$result = json_decode($response,true);
}
}
まとめ
実際に実装する場合は各項目をDBから抽出しなければいけないし、もう少し変えなければいけないところはあると思うけれども一旦ざっくり作成は完了。
もし、実装することになってもこの記事の通りに進めれば問題なく実装できそうな気がする。
初めてAPI触ったけどもこういうのがあると楽でいいなぁ