スマレジプラットフォームAPIで、購入者情報を認証する
こんにちは!株式会社スマレジ、開発部のmasaです!
4連休はエンジョイされてますか?masaは大学の友人と久しぶりにzoomで喋ってたりと、相変わらずインドアに過ごしています。
普段なら、ゆとりがあれば学祭に顔を出したりするんですが、コロナのせいで中止になったりで、今年はリモート参加になりました。
さて、今回は、アプリを購入してくれたスマレジユーザを認証する方法を見ていきます。
購入者の認証方法
今回お話しする内容は、主にディベロッパーズサイトのスマレジ・プラットフォームAPI 共通仕様書
の利用者通知とログイン(β)に関連した内容になります。
ログイン機能についてはβの記載があるように、この仕様は変更されることがあります。この記事記載時点(2020-09-20)での内容であることをご承知おきください。
購入通知のWebhookから購入者情報を取得する
前回のブログでも、チラッと触れましたが、上記リンクの「利用者通知」の項目に、「アプリを購入/削除したタイミングで、購入者の情報に関するWebhookが飛ぶ」旨の記載があります。
このWebhookには、スマレジの契約IDがヘッダ・ボディの両方に含まれており、これでその契約IDを持つユーザが自分のアプリを「購入・削除」したことがわかります。
Webhookの送信先設定については、前回のブログを参照してください。
通知受信用のエンドポイントで、ユーザ情報をうち、契約IDを登録しておくことになります。
アプリ認証を実施する
スマレジでは、アプリを購入したユーザのデータをAPIで取得するには、下記のようなページで購入者に認証をさせる必要があります。
このページにアクセスは、
http://id.smaregi.dev/authorize?response_type=code&client_id={クライアントID}&scope=openid&state={任意の文字列}&redirect_uri={アプリの設定で登録したリダイレクトURL}
このような形式のURLになります。
こちらで認証が成功すると、「認証コード」が発行されます。
認証コードベースで、契約IDを取得する。
こちらは実装例がありますので、こちらを参考にしてみてください。(GASです)
/** * 認証コードから契約IDを取得する * @param {string} code 認証コード * @return {string} 契約ID * @throws {Error} 受診失敗した時 */ function authorize(code) { const clientId = PropertiesService.getScriptProperties().getProperty("SMAREGI_APP_CLIENT_ID"); const secret = PropertiesService.getScriptProperties().getProperty("SMAREGI_APP_SECRET"); const grantType = "authorization_code"; const redirectUri = PropertiesService.getScriptProperties().getProperty("REDIRECT_URI"); const url = 'https://id.smaregi.dev/authorize/token'; const headers = { 'Authorization': 'Basic ' + Utilities.base64Encode(clientId + ":" + secret, Utilities.Charset.UTF_8), 'Content-Type': 'application/x-www-form-urlencoded' }; const payload = { 'grant_type': grantType, 'code': code, 'redirect_uri': redirectUri }; Logger.log(payload); // urlfetchappのオプション情報 const options = { 'method': 'post', 'headers': headers, // header情報を追加 'payload': payload, // トークンを設定 'muteHttpExceptions': true }; try { //外部へアクセスさせる let resStr = UrlFetchApp.fetch(url, options).getContentText(); if (resStr.length === 0) { throw new Error("受信データがありませんでした。"); } let resJson = JSON.parse(resStr); Logger.log(resStr); const accessToken = resJson.access_token; const tokenType = resJson.token_type; const getContractHeader = { 'Authorization': tokenType + ' ' + accessToken }; const getContractOptions = { 'method': 'post', 'headers': getContractHeader // header情報を追加 }; const getContractUrl = 'https://id.smaregi.dev/userinfo'; resStr = UrlFetchApp.fetch(getContractUrl, getContractOptions).getContentText(); Logger.log(resStr); resJson = JSON.parse(resStr); return resJson.contract.id; } catch (e) { Logger.log("エラー:" + e); throw new Error(e); } }