請求システムとしての PayPal
「PayPal 請求書」は、とても便利です。PayPal にログインして「相手のメールアドレス」と「販売した商品明細」をセットするだけで、誰でも簡単に請求書を送ることができます。「ちょっとした受託作業」や「特別な値引き」にも柔軟に対応できる数少ない決済手段と言えるでしょう。その簡単さは「むしろECサイトで買い物をする手続きの方が難しい」と思えてしまうくらいです。しかも、買い手から売り手に「クレジットカード番号」を渡す必要もありません。
しかし、何十枚も発行しなければならない、となれば流石に面倒です。(その「柔軟さ」がアダとなってしまいます)
全く同じ請求内容であれば一括して処理する機能もあるのですが、それぞれに微妙に内容が異なるのであれば一つ一つ請求情報をセットせざるをえません。ただ、手作業の繰り返しは、どうしてもミスを招きます。
請求書生成と送信の自動化
以前の記事(※)で『PayPal システムに対して「PayPal 請求書を生成せよ」というリクエストが自動送信される仕組み』を紹介しました。※ 第525話:自動工程から OAuth2 リクエストを送出させる方法
今回の記事では、更に『「生成した PayPal 請求書を先方に送信せよ」というリクエストが自動送信される仕組み』について考えてみたいと思います。(プログラミング知識が必要となります)
[エントリ受付システム]
手作業を極力排除した業務プロセス
ここで紹介している業務プロセス定義は『セミナー』や『勉強会』などの「イベント参加受付業務」です。業務フロー図を見れば一目瞭然ですが、「Webフォームへの入力」が行われるたびに案件が流れ始め、「請求が必要なエントリ」の場合にのみ、「請求書生成のフロー」に分流する仕組みとなっています。(OR分岐)
業務フロー図内に配置されている工程の多くは「自動工程」(背景グレー)となっており、「人間工程」(背景水色)は『1.請求チェック』と『2.入金チェック』しかありません。しかも『1.請求チェック』については、5分経過で自動完了するように設定された人間工程であり、平時において何か具体的な作業が規定されている訳ではありません。(不正アクセスが増えた際に締切時間を長くしてチェックを強化するなど)
サンプルコード
「件名セット」「敬称セット」「領収書発行日セット」および「参加証PDF生成」「領収書PDF生成」の5つの自動工程はいずれも Questetra 標準の【サービス工程】です。「請求書生成」「請求書送信」の2つの自動工程は【スクリプト工程】であり、サーバサイド JavaScript をセットする必要があります。スクリプトの中で、PayPal Invoicing API との通信が規定されます。
<スクリプト工程「請求書生成」の設定例>
// PayPal Invoicing API CREATE (ver. 20170314) // (c) 2017, Questetra, Inc. (the MIT License) var sandboxmode = false; // true or false //// == コンフィグ&参照 / Config & Retrieving == // Get Your "REST API app" via PayPal Dashboard // https://developer.paypal.com/developer/applications/ var clientId = "Your-Client-Id-Your-Client-Id-Your-Client-Id-Your-Client-Id-Your-Client-Id-Your-"; var secret = "Your-Secret-Your-Secret-Your-Secret-Your-Secret-Your-Secret-Your-Secret-Your-Sec"; var clientIdSandbox = "Your-Client-Id-Your-Client-Id-Your-Client-Id-Your-Client-Id-Your-Client-Id-Your-"; var secretSandbox = "Your-Secret-Your-Secret-Your-Secret-Your-Secret-Your-Secret-Your-Secret-Your-Sec"; if( sandboxmode ){ clientId = clientIdSandbox; secret = secretSandbox; } // Your Info var merchantEmail = "support@questetra.com"; var merchantEmailSandbox = "qstore-paypal-facilitator@questetra.com"; if( sandboxmode ){ merchantEmail = merchantEmailSandbox; } //var merchantBusinessName = "Questetra, Inc."; var merchantBusinessName = "株式会社クエステトラ"; //var merchantAddress2 = "Nakagyo-ku Oike-dori-Ainomachi"; // first line var merchantAddress1 = "中京区御池通間之町東入"; // second line //var merchantAddress1 = "Takamiya-cho 206 Oike Bldg 4th"; var merchantAddress2 = "高宮町206 御池ビル4階"; //var merchantAddressCity = "Kyoto"; var merchantAddressCity = "京都市"; //var merchantAddressState = "KYOTO"; var merchantAddressState = "京都府"; var merchantAddressPC = "604-0835"; var merchantAddressCC = "JP"; var merchantWebsite = "https://www.questetra.com/corp/"; // for Link to BPMS on PayPal var merchantMemo = "https://YourPlatformID.questetra.net/PE/Workitem/list?processInstanceId="; merchantMemo += processInstance.getProcessInstanceId(); // Customer Info //var billingLanguage = "en_US"; var billingLanguage = "ja_JP"; var billingEmail = data.get( "q_billingEmail" ) + ""; var billingName1 = data.get( "q_billingName1" ) + ""; var billingBusinessName = data.get( "q_billingBusinessName" ) + ""; // Items Info //var itemUnitPriceCurrency = "USD"; var itemUnitPriceCurrency = "JPY"; //var itemTaxName = "JCT"; var itemTaxName = "消費税"; var itemTaxPercent = 8; var itemName = data.get( "q_item" ).get(0).getDisplay() + ""; var itemQuantity = 1; // number var itemUnitPrice = data.get( "q_item" ).get(0).getValue() + ""; // string // Invoice Info var invoiceNumber = processInstance.getProcessInstanceId() + ""; // string var invoiceDate = data.get( "q_invoiceDate" ) + " JST"; // yyyy-MM-dd z var termType = "NET_10"; //"DUE_ON_RECEIPT"; var logoUrl = "https://www.questetra.com/wp-content/uploads/2017/03/Corporate-logo-100x100.png"; //// == 演算 / Calculating == var accessLog = ""; // Getting OAuth2 Token via client_credentials grant var uriToken = "https://api.paypal.com/v1/oauth2/token"; var uriTokenSandbox = "https://api.sandbox.paypal.com/v1/oauth2/token"; if( sandboxmode ){ uriToken = uriTokenSandbox; } var response = httpClient.begin() .basic( clientId, secret ) .formParam( "grant_type", "client_credentials" ) .post( uriToken ); accessLog += "---POST request--- " + response.getStatusCode() + "\n"; accessLog += response.getResponseAsString() + "\n"; accessLog += "\n"; var oauthTokenObj = JSON.parse( response.getResponseAsString() ); var oauthToken = oauthTokenObj.access_token; accessLog += "oauthToken: " + oauthToken + "\n"; accessLog += "\n"; // Create invoice var invoiceObj = {}; invoiceObj.number = invoiceNumber; invoiceObj.invoice_date = invoiceDate; invoiceObj.payment_term = {}; invoiceObj.payment_term.term_type = termType; invoiceObj.logo_url = logoUrl; invoiceObj.merchant_memo = merchantMemo; invoiceObj.merchant_info = {}; invoiceObj.merchant_info.email = merchantEmail; invoiceObj.merchant_info.business_name = merchantBusinessName; invoiceObj.merchant_info.address = {}; invoiceObj.merchant_info.address.line1 = merchantAddress1; invoiceObj.merchant_info.address.line2 = merchantAddress2; invoiceObj.merchant_info.address.city = merchantAddressCity; invoiceObj.merchant_info.address.state = merchantAddressState; invoiceObj.merchant_info.address.postal_code = merchantAddressPC; invoiceObj.merchant_info.address.country_code = merchantAddressCC; invoiceObj.merchant_info.website = merchantWebsite; invoiceObj.billing_info = []; invoiceObj.billing_info[0] = {}; invoiceObj.billing_info[0].email = billingEmail; invoiceObj.billing_info[0].first_name = billingName1; // invoiceObj.billing_info[0].last_name = billingName2; invoiceObj.billing_info[0].business_name = billingBusinessName; invoiceObj.billing_info[0].language = billingLanguage; invoiceObj.items = []; invoiceObj.items[0] = {}; invoiceObj.items[0].name = itemName; // invoiceObj.items[0].description =itemDescription; invoiceObj.items[0].quantity = itemQuantity; invoiceObj.items[0].unit_price = {}; invoiceObj.items[0].unit_price.currency = itemUnitPriceCurrency; invoiceObj.items[0].unit_price.value = itemUnitPrice; invoiceObj.items[0].tax = {}; invoiceObj.items[0].tax.name = itemTaxName; invoiceObj.items[0].tax.percent = itemTaxPercent; var uriCreate = "https://api.paypal.com/v1/invoicing/invoices/"; var uriCreateSandbox = "https://api.sandbox.paypal.com/v1/invoicing/invoices/"; if( sandboxmode ){ uriCreate = uriCreateSandbox; } var responseCreate = httpClient.begin() .bearer( oauthToken ) .body( JSON.stringify( invoiceObj ), "application/json" ) .post( uriCreate ); accessLog += "---POST request--- " + responseCreate.getStatusCode() + "\n"; accessLog += JSON.stringify( invoiceObj ) + "\n"; accessLog += "\n"; accessLog += responseCreate.getResponseAsString() + "\n"; accessLog += "\n"; var paypalIdObj = JSON.parse( responseCreate.getResponseAsString() ); var paypalId = paypalIdObj.id; accessLog += "paypalId: " + paypalId + "\n"; accessLog += "\n"; //// == ワークフローデータへの代入 / Data Updating == retVal.put( "q_accessLog", accessLog ); retVal.put( "q_paypalId", paypalId );
<スクリプト工程「請求書送付」の設定例>
// PayPal Invoicing API SEND (ver. 20170303) // (c) 2017, Questetra, Inc. (the MIT License) var sandboxmode = false; // true or false //// == コンフィグ&参照 / Config & Retrieving == // Your "REST API app" on PayPal Dashboard // https://developer.paypal.com/developer/applications/ var clientId = "Your-Client-Id-Your-Client-Id-Your-Client-Id-Your-Client-Id-Your-Client-Id-Your-"; var secret = "Your-Secret-Your-Secret-Your-Secret-Your-Secret-Your-Secret-Your-Secret-Your-Sec"; var clientIdSandbox = "Your-Client-Id-Your-Client-Id-Your-Client-Id-Your-Client-Id-Your-Client-Id-Your-"; var secretSandbox = "Your-Secret-Your-Secret-Your-Secret-Your-Secret-Your-Secret-Your-Secret-Your-Sec"; if( sandboxmode ){ clientId = clientIdSandbox; secret = secretSandbox; } var paypalId = data.get( "q_paypalId" ) + ""; //// == 演算 / Calculating == var accessLog = ""; // Getting OAuth2 Token via client_credentials grant var uriToken = "https://api.paypal.com/v1/oauth2/token"; var uriTokenSandbox = "https://api.sandbox.paypal.com/v1/oauth2/token"; if( sandboxmode ){ uriToken = uriTokenSandbox; } var response = httpClient.begin() .basic( clientId, secret ) .formParam( "grant_type", "client_credentials" ) .post( uriToken ); accessLog += "---POST request--- " + response.getStatusCode() + "\n"; accessLog += response.getResponseAsString() + "\n"; accessLog += "\n"; var oauthTokenObj = JSON.parse( response.getResponseAsString() ); var oauthToken = oauthTokenObj.access_token; accessLog += "oauthToken: " + oauthToken + "\n"; accessLog += "\n"; // Send invoice var uriSend = "https://api.paypal.com/v1/invoicing/invoices/" + paypalId + "/send"; var uriSendSandbox = "https://api.sandbox.paypal.com/v1/invoicing/invoices/" + paypalId + "/send"; if( sandboxmode ){ uriSend = uriSendSandbox; } var responseSend = httpClient.begin() .bearer( oauthToken ) .post( uriSend ); accessLog += "---POST request--- " + responseSend.getStatusCode() + "\n"; accessLog += responseSend.getResponseAsString() + "\n"; accessLog += "\n"; //// == ワークフローデータへの代入 / Data Updating == retVal.put( "q_accessLog2", accessLog );
<Webフォーム画面>
<完成したPayPal請求書の例>
<データ項目一覧画面>
[雛形ダウンロード (無料)]
- 業務テンプレート:エントリ受付システム
- 第504話:監査書類を Dropbox に自動保存! (2016-10-11)
- 第503話:ユラギを無くすには「マスター参照」でしょ!(kintone編) (2016-10-03)
- 第498話:自動工程におけるデータ加工、アレコレ(その5) (2016-08-29)
- M230 自動工程: 業務データの複雑なデータ加工が自動実行されるように設定する(ECMAスクリプト) (使い方)
- M415 自動工程: 業務プロセス定義で利用可能な自動工程を追加する (使い方)
- M416 自動工程: 業務プロセス定義で利用可能な自動工程を自作する (使い方)
- M202 業務の流れ: 処理フローを定義し、各工程の締切時刻を設定する (使い方)
[英文記事 (English Entry) ]
0 件のコメント :
コメントを投稿