PHP(Laravel)でLINE Pay(v3)のAPI Authenticationに対処する


PHPでLINE Pay(v3)のAPI Authenticationに対処する

前提: 加盟店申請が終わっている

管理画面から
- Channel ID
- Channel Secret Key
の2つを入手しましょう。

これらの連動キーは「決済連動管理 > 連動キー管理」から入手します。

API Authenticationとは

公式Document

Key Data Type Requirement Description
Content-Type String Y application/json
X-LINE-ChannelId String Y Payment Integration Information - Channel ID
X-LINE-MerchantDeviceProfileId String N Offline Support - Device Type
X-LINE-Authorization-Nonce String Y UUID or Request timestamp
X-LINE-Authorization String Y HMAC Base64 Signature

上記のうち X-LINE-MerchantDeviceProfileId を除く4つは必須です。

X-LINE-Authorization の生成に少し手間取ったので、結論を記します。

PHP(Laravel)でX-LINE-Authorizationの値を生成する


use Illuminate\Support\Str;

class LinePayController extends Controller
{
    private $channelId;
    private $channelSecretKey;

    public function __construct()
    {
        $this->channelId = '****';
        $this->channelSecretKey = '****';
    }

    private function getAuthSignature($channelSecretKey, $uri, $requestBody, $nonce)
    {
        $data = $channelSecretKey . $uri . json_encode($requestBody) . $nonce;
        $hash = hash_hmac('sha256', $data, $channelSecretKey, true);
        return base64_encode($hash);
    }

    public function index() {
       $nonce = Str::uuid();
       $requestUri = '/v3/payments/request';
       $requestBody = [
                "amount" => ...,
                "currency" => ...,
                "orderId" => ...,
                "packages" => [
                    [
                        "id" => ...,
                        "amount" => ...,
                        "products" => [
                            [
                                "name" => ...,
                                "quantity" => ...,
                                "price" => ...,
                            ],
                        ],
                    ],
                ],
                "redirectUrls" => [
                    "confirmUrl" => ...,
                    "cancelUrl" => ...,
                ],
            ];

       // この$signatureをX-LINE-AuthorizationにセットすればOK
       $signature = $this->getAuthSignature($this->channelSecretKey, $requestUri, $requestBody, $nonce);

       // ヘッダーをつけてLINE PayサーバーにAPIリクエストを送信する
       $header = [
            "Content-Type: application/json",
            "X-LINE-ChannelId: {$this->channelId}",
            "X-LINE-Authorization-Nonce: {$nonce}",
            "X-LINE-Authorization: {$signature}",
        ];

       // 以下略
    }
}

以下、上記のコードの解説です。

まず Laravel の Str を使って UUID (version4) を生成しています。

$nonce = Str::uuid();

いきなり Laravel 特有の関数でお茶を濁してすみません...
Laravel 以外の人は、何かしらの方法でUUIDを作成しましょう。

公式によれば、 UUID の代わりに timestamp でも大丈夫です。
$nonce は繰り返しの不正リクエストを防ぐ目的で使用されるので、時刻に応じて刻一刻と変わる値であれば要件をクリアするようです。

この先は Laravel は関係ありません。

次に今回のメインテーマである X-LINE-Authorization の値を生成します。

private function getAuthSignature($channelSecretKey, $uri, $requestBody, $nonce)
    {
        $data = $channelSecretKey . $uri . json_encode($requestBody) . $nonce;
        $hash = hash_hmac('sha256', $data, $channelSecretKey, true);
        return base64_encode($hash);
    }

登場する関数は以下の2つです。
- base64_encode:MIME base64 方式でデータをエンコードする
- hash_hmac: HMAC 方式を使用してハッシュ値を生成する

hash_hmac の第3引数は暗号化に使用する秘密鍵です。ここで Channel Secret Key を使うわけですね。

また hash_hmac() の第4引数を true にセットしましょう。生のバイナリデータが返ります。

私はここを false にしたままで、エラーを繰り返してしまいました。

その他

LINE Pay の実装に関して、全体的な方針は以下の記事が参考になりました。
- アプリにLINE Pay決済を導入する簡易手引き(LINE Pay API - v3)

公式Documentも充実していると思いますが、慣れない表現に戸惑ってしまいました。「技術支援の問合せ先」が明記されているのは実装に先当たって好印象でした。安心感が増します。

あとは以下の SDK の GitHub の生コードを読み漁り、理解を深めました。
パッケージの導入はしませんでしたが、コーディングの良い指針となりました。
- line-pay-sdk-php