Episode 542: Easy Billing Operation by Connecting with PayPal Invoice (3)

Sunday, July 2, 2017

Productivity Improvement by Automation of Steps

In the last article and one before the last, I introduced you a mechanism to control "PayPal billing system" from Workflow system.

In these mechanisms (Workflow Application), an automatic Step (Addon Service Task) is arranged in the middle of the flow diagram. That is, each time when a billing Issue arrives these Steps, the Workflow system transmits "Requests" such as
  • Generate "PayPal Invoice" (PayPal Create)
  • Transmit a "PayPal Invoice" (PayPal Send)
  • What is the settlement status? (PayPal Check)
In other words, "accounting works" such as "generation of electronic invoice", "transmission of electronic invoice", "confirmation of status of electronic invoice" have been made unmanned. (REST / OAuth2 communication with PayPal Invoicing API)

Today, not only the "payment system" (*1) as in this example, but also the operation of various information systems are automated, and the productivity is improved. For example, preservation of quotation to "Storage system" (*2), or management of product master data in "Spreadsheet / Data management system" (*3), are typical examples.

*1: PayPal, Stripe, etc. *2: Dropbox, Box, Google Drive, etc. *3 Google SpreadSheet, Kintone, etc.

<Setting screen: PayPal Create>

<Setting screen: PayPal Send>

<Setting screen: PayPal Check> 

The fact that the process owner only needs to set properties of the Addon automatic Step (programming knowledge is no longer needed) is also one of the reasons for popularization.

Until which stage of situation change you should make unmanned?

However, there are not only "advantages" that unmanning brings.

In the previous article, for example, it was a business flow that it continues confirming (keep on looping) until the status of electronic invoice turns to "PAID".

It sure is, there is no human cost on "confirmation work" alone since human does not intervene.

However, if an event such as "order cancellation" or "remittance with another settlement method" has occurred, it may be necessary to stop the Task of "shipping processing" in some cases. Or depending on circumstances, it may become necessary to modify the processing of "recording sales". Yet, as for the situation change which "influence degree × occurrence probability" is large, as a business process definition, I would like to make it "within the range of assumption" as much as possible, not leaving it as "unexpected".

In the following business process definition, "CANCELED status" (cancellation) which is relatively frequently occurring has been taken into consideration. That is, it is added devising that alert email to be sent when payment is refused.

[PayPal Invoice Issuance-Cancellation notification]


The work to be done by humans is limited

As it is obvious from the work flow diagram, status check is performed at the Step of [PayPal Check] every 12 hours.
  • What is the settlement status? (PayPal Check)
And the status of the corresponding electronic invoice is automatically overwritten according "Response from PayPal". If the status is "PAID" (paid), it will end normally. (Moreover, even though it is simply terminated in this example, it is also assumed cases where Steps such as "shipping" and "service provisioning" will follow, or cases where another Process is started.)

What should be noted is that, when the status becomes "CANCELLED" (payment cancellation), it will automatically exit the confirmation loop and an alert email will be sent.

Of course, you won't be able to know the reason "why it was canceled" from the alert email.

That Task of [confirmation of reason] will occur as a human Task, whether 1) the order itself was a mistake, or 2) the billing amount was not agreed, or 3) it was paid by bank remittance. (The 4th Step)

Automation of the API era

By the way, what should you do if cases where payment by "bank remittance" or "personal delivery" instead of "PayPal payment" increased?

If the number of occurrence was small, you can delete the "PayPal invoice" manually one by one. Yet, the occurrence of mistakes is still a big risk. Suppose if, you have deleted an incorrect "PayPal Invoice", it will a big trouble. Therefore, on the day when such a processing increased, you should expand the business process definition and additionally arrange "Addon Service Task" so that "Deletion request" to be sent.

However, although methods such as "Cancel sent invoice" and "Mark invoice as paid" are prepared on PayPal Invoicing API side, you are not always able to obtain every "Addon Service Task" on the internet.

<PayPal Invoicing API>
  • Create draft invoice ← [PayPal Create]
  • Send invoice ← [PayPal Send]
  • Show invoice details ← [PayPal Check]
  • Update invoice
  • Send invoice reminder
  • Delete draft invoice
  • Cancel sent invoice
  • Mark invoice as paid
  • Mark invoice as refunded
  • List merchant invoices
  • Search for invoices
  • Generate QR code
  • Generate invoice number

In such a case, there is an option that creating your own "Addon Service Task" yourself. Although you will need to refer to a manual document for actual method of creation, it is worthwhile to consider doing so , as long as the Process is
  • error is never allowed
  • to be streamlined,
And if you are broad-minded enough to "never mind if other companies use it," people would appreciate you for publishing that configuration file (Addon - XML) to the world.

** Example of Creating "Service Task" (PayPal Check) **
<?xml version="1.0" encoding="UTF-8"?><service-task-definition>
<label>PayPal Invoicing Status</label>
<label locale="ja">PayPal 請求書 ステータス確認</label>

<configs>
  <config name="conf_ClientId_Secret" required="true" form-type="TEXTAREA">
    <label>A: Set CLIENT-ID and SECRET for PayPal-REST-API (2-lines)</label>
    <label locale="ja">A: PayPal-REST-API の Client ID と SECRET を2行に分けてセットしてください</label>
  </config>
  <config name="conf_DataIdB" required="true" form-type="SELECT" select-data-type="STRING_TEXTFIELD">
    <label>B: Select STRING DATA for Paypal Invoice ID</label>
    <label locale="ja">B: Paypal Invoce ID が格納されている文字列型データを選択してください</label>
  </config>
  <config name="conf_DataIdC" required="true" form-type="SELECT" select-data-type="STRING_TEXTFIELD">
    <label>C: Select STRING DATA for Paypal Invoice Status (update)</label>
    <label locale="ja">C: Paypal Invoce Status が格納される文字列型データを選択してください (更新)</label>
  </config>
  <config name="conf_DataIdD" required="false" form-type="SELECT" select-data-type="STRING_TEXTFIELD">
    <label>D: Select STRING DATA for Payment Timestamp (update)</label>
    <label locale="ja">D: 支払タイムスタンプが格納される文字列型データを選択してください (更新)</label>
  </config>
  <config name="conf_DataIdE" required="false" form-type="SELECT" select-data-type="DECIMAL">
    <label>E: Select NUMBER DATA for Payment Amount (update)</label>
    <label locale="ja">E: 支払金額が格納される数値型データを選択してください (更新)</label>
  </config>
</configs>

<script><![CDATA[
// PayPal Invoicing Status (ver. 20170603)
// (c) 2017, Questetra, Inc. (the MIT License)
//// == 工程コンフィグの参照 / Config Retrieving ==
var clientId_secret = configs.get( "conf_ClientId_Secret" ) + "";
var array_clientId_secret = clientId_secret.split("\n");
var clientId = array_clientId_secret[0];
var secret   = array_clientId_secret[1];
var dataIdB = configs.get( "conf_DataIdB" );
var dataIdC = configs.get( "conf_DataIdC" ) + "";
var dataIdD = configs.get( "conf_DataIdD" ) + "";
var dataIdE = configs.get( "conf_DataIdE" ) + "";

//// == ワークフローデータの参照 / Data Retrieving ==
var paypalId         = data.get( dataIdB ) + "";

//// == 演算 / Calculating ==
// Get OAuth Token with Client Credentials
var uri = "https://api.paypal.com/v1/oauth2/token";
var response = httpClient.begin()
  .basic( clientId, secret )
  .formParam( "grant_type", "client_credentials" )
  .post( uri );
var oauthTokenObj = JSON.parse( response.getResponseAsString() );
var oauthToken = oauthTokenObj.access_token;
// Show Invoice Details
var uriDetail = "https://api.paypal.com/v1/invoicing/invoices/" + paypalId;
var responseDetail = httpClient.begin()
  .bearer( oauthToken )
  .get( uriDetail );
var paypalInvoiceObj = JSON.parse( responseDetail.getResponseAsString() );
var paypalInvoiceStatus = paypalInvoiceObj.status;

//// == ワークフローデータへの代入 / Data Updating ==
retVal.put( dataIdC, paypalInvoiceStatus ); // DRAFT, SENT, PAID, etc
if( dataIdD !== "" ){
  if ( paypalInvoiceStatus == "PAID" ){
    retVal.put( dataIdD, paypalInvoiceObj.payments[0].date );
  }
}
if( dataIdE !== "" ){
  if ( paypalInvoiceStatus == "PAID" ){
    var amountValue = parseFloat( paypalInvoiceObj.payments[0].amount.value );
    retVal.put( dataIdE, java.math.BigDecimal( amountValue ) );
  }
}
///retVal.put( "q_accessLog", responseDetail.getResponseAsString() ); // for debug
]]></script>

<icon>
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABc0lEQVRYR+2WQW6CUBCG55cViUntDbxB7QmqOzMseoTqSWpPUnuDNoEXl9ygeILaG9AEwgqmeaQYxCoY+rQLZsPiwZv//cPM+0AXDlw4P3UCdhwYj8cD27ZvTJYlSZK17/thkSMXwMwjInoGoJ/GQ0QCIporpQJMp9OhZVnvRDQQkS8i0osmYwTgiojCNE1vwcyvAO6J6MXzvJnJzMXejuMsiehBRN60gFAriuP4ulwbk0J+XP8QkQ0cxxGdzPO8s7Zkkff/CDBp+bG9tw50ArqfsHOg6gAzLwA8Ft0hIk9KqUW1W5jZB3BX10UAJq7r+qVxnA/Ag4PoBAH6/hjWCciybLlarTZ/LqAu8aH12lF8ggNHS1C1vrEDTU/GzEdLULV+T8CFr+PPLZCIyFIpNW968jbv7QCJhoNerxcUmHQOJCvwL8uy0RZKAWhMMkrEJdfWIjLLobRspcbyfr9vlIyjKAr2sLxNPdt+e1YO/E1sJ+AbULfr6IobKF4AAAAASUVORK5CYII=
</icon>
</service-task-definition>


<Modeling movie *x8 speed*>


[Free Download]
<Similar Models>
<<Related Articles>>

[Japanese Entry (和文記事)]