[請求書発行]マネーフォワード クラウド請求書のAPI検証してみた

# マネーフォワード　クラウド請求書 API検証

マネーフォワードのAPIを使ってクラウド請求書の検証をする機会がありました。
curlを使ってAPIのやりとりして検証しました。JSONの基礎的な知識が不足しいたのもあり勉強し直しました。<br>
ただ、大量のデータを使って検証するのにcurlを使うのは非常に手間がかかりました。こういう検証って、ポストマンなど使った方が良さそうですね。勉強します！！<br>


### 概要

 - マネーフォワード　クラウド請求書の無料プラン登録
 - 請求書情報をJSON形式でAPIサーバーにPOST
 - PDFを出力させる（無料プランは100件まで無料）

## 環境

MF invoice-api v2
curl 7.54.0

### 参考

 - https://github.com/moneyforward/invoice-api-doc
 - [マネーフォワード クラウド請求書API スタートアップガイド](https://support.biz.moneyforward.com/invoice/guide/api-guide/a01.html)


## MF API利用方法

https://biz.moneyforward.com/invoice

 [マネーフォワード クラウド請求書API スタートアップガイド](https://support.biz.moneyforward.com/invoice/guide/api-guide/a01.html)をみながらアカウント登録と[Client ID][Client Secret][Scopes][Callback URI]を設定。Callback URIにはexample.comを使用しました。<br>
CallbackURLに進み、付与された認証コードの有効期限は10分間です<br>

```shell

curl -d client_id=[CLIENT_ID] -d client_secret=[CLIENT_SECRET] \
-d redirect_uri=[REDIRECT_URL] -d grant_type=authorization_code \
-d code=[認証コード] -X POST https://invoice.moneyforward.com/oauth/token
```

### トークン取得

返却されるトークン。有効期限は30日間です。<br>

```shell

{
    "access_token": "[アクセストークン]",
    "token_type": "bearer",
    "expires_in": 2592000,
    "refresh_token": "[リフレッシュトークン]",
    "scope": "***",
    "created_at": "***"
}
```

### トークン再発行

同時に発行されたリフレッシュトークンで、アクセストークンの再発行が可能です。<br>

```shell
 curl -d client_id=[CLIENT_ID] -d client_secret=[CLIENT_SECRET] \
-d grant_type=refresh_token -d refresh_token=[REFRESH_TOKEN] \
-X POST https://invoice.moneyforward.com/oauth/token
```

## 請求書発行

先に取引先を作成しないと請求書の作成はできません。<br>

### 取引先の作成例

取引先情報を入力。MFサイトからも作成や修正は可能です。<br>

```shell
curl -i -H "Authorization: BEARER [CLIENT_ID]" \
-H "Content-Type: application/json" \
 -d '{
    "partner": {
        "name": "山田商店",
        "code": "ABCD-00001",
        "name_suffix": "株式会社",
        "zip": "123-4567",
        "tel": "06-123-4567",
        "prefecture": "大阪府",
        "address1": "XXXXXXXXXXX",
        "address2": "OOOOOOOOOOOO",
        "person_name": "山田太郎",
        "person_title": "代表取締役",
        "email": "yamada@test.com"
    }
}' \
-X POST https://invoice.moneyforward.com/api/v2/partners
```

以下のようなJSONが帰ってきます。departments[id]は後に利用。<br>

```shell

{
    "data": {
        "id": "-uWBNZbtmAnlX0wF24UdpQ",
        "type": "partner",
        "attributes": {
            "code": "ABCD-00001",
            "name": "山田商店",
            "name_kana": null,
            "name_suffix": "",
            "memo": null,
            "created_at": "2019-01-29T17:40:12.000+09:00",
            "updated_at": "2019-01-29T17:40:12.000+09:00"
        },
        "relationships": {
            "departments": {
                "data": [
                    {
                        "id": "[DEPAETURES_ID]",
                        "type": "department"
                    }
                ]
            }
        }
    },
    "included": [
        {
            "id": "[DEPAETURES_ID]",
            "type": "department",
            "attributes": {
                "zip": "123-4567",
                "tel": "06-123-4567",
                "prefecture": "大阪府",
                "address1": "XXXXXXXXXXX",
                "address2": "OOOOOOOOOOOO",
                "person_name": "山田太郎",
                "person_title": "代表取締役",
                "name": null,
                "email": "yamada@test.com",
                "cc_emails": null,
                "created_at": "2019-01-29T17:40:12.000+09:00",
                "updated_at": "2019-01-29T17:40:12.000+09:00"
            }
        }
    ]
}
```

### 請求書の作成例

振込先、期限はこちらに記入する必要があります。<br>

上記の取引先みたいにitems[name], [unit_price]などは予め設定する必要はないようです。GASのCSVをそのまま利用した方ががメンテナンス性がいいのかなと思います。<br>

```shell
curl -i -H "Authorization: BEARER [ACCESS_TOKEN]" -H "Content-Type: \
application/json" -d \
'{
    "billing": {
        "department_id": "[DEPAETURES_ID]",
        "title": "2018年12月",
        "payment_condition": "XXXX銀行XXX支店（店番号xxx）普通預金xxxxxxx",
        "note": "備考",
        "billing_date": "2019/1/1",
        "due_date": "2019/2/28",
        "sales_date": "2018/12/31",
        "items": [
            {
                "name": "りんご",
                "quantity": "25",
                "unit_price": "100"
            },
            {
                "name": "みかん",
                "quantity": "3",
                "unit_price": "50"
            },
            {
                "name": "ぶどう",
                "quantity": "5",
                "unit_price": "200"
            }
        ]
    }
}'　\
 -X POST https://invoice.moneyforward.com/api/v2/billings
```

返ってくるデータ

```shell
{
    "data": {
        "id": "[BILLING_ID]",
        "type": "billing",
        "attributes": {
            "pdf_url": "https://invoice.moneyforward.com/api/v2/billings/[BILLING_ID].pdf",
            "operator_id": "*****",
            "partner_id": "-uWBNZbtmAnlX0wF24UdpQ",
            "department_id": "[DEPAETURES_ID]",
            "member_id": "*****",
            "member_name": null,
            "partner_name": "山田商店",
            "partner_name_suffix": "",
            "partner_detail": "〒123-4567\n大阪府XXXXXXXXXXX\nOOOOOOOOOOOO\n代表取締役\n山田太郎様",
            "office_name": "gatapon",
            "office_detail": "TEL: 03-1234-5678\n",
            "title": "2018年12月",
            "excise_price": "292.0",
            "subtotal": "3650.0",
            "memo": null,
            "payment_condition": "XXXX銀行XXX支店（店番号xxx）普通預金xxxxxxx",
            "total_price": "3942.0",
            "billing_date": "2019-01-01",
            "due_date": "2019-02-28",
            "sales_date": "2018-12-31",
            "billing_number": "10",
            "note": "備考",
            "document_name": "請求書",
            "payment_status": "未設定",
            "email_status": "未送信",
            "posting_status": "未郵送",
            "created_at": "2019-01-30T20:35:24.000+09:00",
            "updated_at": "2019-01-30T20:35:24.000+09:00",
            "deduct_price": "0.0",
            "tags": [],
            "is_downloaded": false,
            "is_locked": false
        },
        "relationships": {
            "items": {
                "data": [
                    {
                        "id": "Rlbclolr_0uNittWvi_Juw",
                        "type": "billing_item"
                    },
                    {
                        "id": "tTiqLBZT0Fw8DM2RNYH3fw",
                        "type": "billing_item"
                    },
                    {
                        "id": "3z8M-8qtHlpWKs3XS60jPA",
                        "type": "billing_item"
                    }
                ]
            }
        }
    },
    "included": [
        {
            "id": "Rlbclolr_0uNittWvi_Juw",
            "type": "billing_item",
            "attributes": {
                "item_code": null,
                "name": "りんご",
                "detail": null,
                "quantity": "25.0",
                "unit_price": "100.0",
                "unit": null,
                "price": "2500.0",
                "is_excise": true,
                "created_at": "2019-01-30T20:35:24.000+09:00",
                "updated_at": "2019-01-30T20:35:24.000+09:00",
                "disp_order": 0,
                "is_deduct": false
            }
        },
        {
            "id": "tTiqLBZT0Fw8DM2RNYH3fw",
            "type": "billing_item",
            "attributes": {
                "item_code": null,
                "name": "みかん",
                "detail": null,
                "quantity": "3.0",
                "unit_price": "50.0",
                "unit": null,
                "price": "150.0",
                "is_excise": true,
                "created_at": "2019-01-30T20:35:24.000+09:00",
                "updated_at": "2019-01-30T20:35:24.000+09:00",
                "disp_order": 0,
                "is_deduct": false
            }
        },
        {
            "id": "3z8M-8qtHlpWKs3XS60jPA",
            "type": "billing_item",
            "attributes": {
                "item_code": null,
                "name": "ぶどう",
                "detail": null,
                "quantity": "5.0",
                "unit_price": "200.0",
                "unit": null,
                "price": "1000.0",
                "is_excise": true,
                "created_at": "2019-01-30T20:35:24.000+09:00",
                "updated_at": "2019-01-30T20:35:24.000+09:00",
                "disp_order": 0,
                "is_deduct": false
            }
        }
    ]
}

```

`is_excise`で税をかけるかどうかも変更できるみたいです。

### PDFダウンロード

返ってきたデータのid(BILLING_ID)を利用しPDFを発行<br>

```shell

curl -i -H "Authorization: BEARER [ACCESS_TOKEN]"  \
https://invoice.moneyforward.com/api/v1/billings/[BILLING_ID].pdf -O
```

フォーマットも選べるようですが、こんな感じになりました。

<img width="565" alt="スクリーンショット 2019-01-30 20.40.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/222848/79730d95-ea27-c97f-5f90-82674ef9b7a1.png">