Episode 528: Automatic Confirmation of PayPal Status at Automatic Step

Monday, March 27, 2017

Automation of billing

It will be very convenient if you can control "PayPal" as a billing system from the workflow system "Questetra".

For example, if you create a mechanism that automatically issues a "PayPal invoice according to delivery details" immediately after "product delivery flow" is completed, it is possible to prevent the occurrence of "billing mistake" or "billing omission". If the current situation is a billing operation that mails a "paper invoice", it is also possible to reduce all stamp fee, printing fee and office work labor costs to zero.

In the previous article, I introduced you mechanisms that automatically instructs PayPal "to generate invoices in PayPal" and "to send the invoice generated in PayPal further to customers".

Further automation

If you could automate
  • letting PayPal generate a "PayPal Invoice", and
  • letting PayPal send a "PayPal Invoice" via email,

I would like to further automate
  • confirming payment to PayPal. (Improve efficiency of debt collection business)

In this article, we will consider assembling the automatic Steps cleverly and making the "payment check flow" unmanned.

* Here, programming knowledge is required since we are going to use "Script Task" which is a type of automatic Step

[Entry reception system-PayPal billing-Payment confirmation]



[Entry reception system-PayPal billing-Payment confirmation:"1. Invoice check" screen]

Automatic confirmation of settlement status

In the Script Task "Payment check" arranged in this example, "Show invoice details" is requested each time an Issue arrives.
  • GET "https://api.paypal.com/v1/invoicing/invoices/" + paypalId

It is a mechanism which can detect whether or not payment has already been done (the status of PayPal invoice) by automatically referring to the "response from PayPal" obtained at that time.

If it turns out that payment is done, it automatically flows to the Steps of "Receipt issue date set", "Receipt PDF generation", and "Receipt PDF email transmission".

Also, if payment has not been made, it will return to the human process "2. PayPal payment confirmation", as this process is set to "flow again to the downstream when left unattended for 24 hours", it will confirm the status of "PayPal Invoice" again, 24 hours later. (In this example, there is also a route for manual flow.)

** In addition to that, status check methods such as "Payment completion notification email" or "Webhook" can be considered.

Sample codes

I will post sample scripts that to be set in the Script Task "Payment check" below.

* For the upstream Script Task of "Invoice generation" and "Invoice transmission", see the previous article.

The point is that the value of "ResponseObj.payments [0] .date" is imported as data of the Issue when the status "ResponseObj.status" of the response JSON object is "PAID". At the Splitting point, it is set to recognize that "the payment has already been done" on the Issues in which the data of "Settlement date" was imported.

If you need to import more other data, you need to add more items to implement. In that case, SAMPLE RESPONCE of "responded JSON object" is posted together below, so please refer to it as necessary and add scripts as appropriate.

<Setting example of Script Task "Payment check">
// PayPal Invoicing API SEND (ver. 20170322)
// (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";

// invoice Detail
var uriDetail = "https://api.paypal.com/v1/invoicing/invoices/" + paypalId;
var uriDetailSandbox = "https://api.sandbox.paypal.com/v1/invoicing/invoices/" + paypalId;
if( sandboxmode ){ uriDetail = uriDetailSandbox; }
var responseDetail = httpClient.begin()
  .bearer( oauthToken )
  .get( uriDetail );

accessLog += "---GET request--- " + responseDetail.getStatusCode() + "\n";
accessLog += responseDetail.getResponseAsString() + "\n";
accessLog += "\n";
var paypalInvoiceObj = JSON.parse( responseDetail.getResponseAsString() );
var paypalInvoiceStatus = paypalInvoiceObj.status;
var paypalInvoicePaidDate = "";
var paypalInvoicePaidAmount = 0;
if ( paypalInvoiceStatus == "PAID" ){
  paypalInvoicePaidDate = paypalInvoiceObj.payments[0].date;
  // e.g.: "2017-03-21 22:10:51 PDT"
  paypalInvoicePaidDate = paypalInvoicePaidDate.slice(0,10);
  paypalInvoicePaidAmount = parseInt( paypalInvoiceObj.payments[0].amount.value );
}
accessLog += "paypalInvoiceStatus: " + paypalInvoiceStatus + "\n";
accessLog += "paypalInvoicePaidDate: " + paypalInvoicePaidDate + "\n";
accessLog += "\n";


//// == Data Updating ==
retVal.put( "q_accessLog3", accessLog );
retVal.put( "q_paypalInvoicePaidDate",  java.sql.Date.valueOf( paypalInvoicePaidDate ) );
retVal.put( "q_paypalInvoicePaidAmount", java.math.BigDecimal( paypalInvoicePaidAmount ) );

<SAMPLE RESPONCE> (* It is partially edited)
※ GET "https://api.paypal.com/v1/invoicing/invoices/" + paypalId

{
  "id":"INV2-XXXX-YYYY-ZZZZ-FXC6",
  "number":"3410",
  "template_id":"TEMP-52B5XXXXSA83YYYY3",
  "status":"PAID",
  "merchant_info":{
    "email":"account+paypal@example.com",
    "business_name":"ABC Event Executive Committee",
    "website":"http://www.example.com/",
    "address":{
      "line1":"Any street, Any town",
      "line2":"Any bld. #1",
      "city":"Any city",
      "state":"Any state",
      "postal_code":"634-5789",
      "country_code":"US"
    }
  },
  "billing_info":[
    {
      "email":"jy@yambal.net",
      "first_name":"Mr.Jack Brown",
      "business_name":"Test Dept.",
      "language":"en_US"
    }
  ],
  "items":[
    {
      "name":"General public(3000JPY)",
      "quantity":1.0,
      "unit_price":{
        "currency":"JPY",
        "value":"3000.00"
      }
    }
  ],
  "invoice_date":"2017-03-21 PDT",
  "payment_term":{
    "term_type":"NET_10",
    "due_date":"2017-03-31 PDT"
  },
  "tax_calculated_after_discount":false,
  "tax_inclusive":false,
  "merchant_memo":"https://YourWorkflowPlatformId.questetra.net/PE/Workitem/list?processInstanceId=3410",
  "total_amount":{
    "currency":"JPY",
    "value":"3000.00"
  },
  "payments":[
    {
      "type":"PAYPAL",
      "transaction_id":"0335XXXX9112YYYYL",
      "transaction_type":"SALE",
      "method":"PAYPAL",
      "date":"2017-03-21 22:10:51 PDT",
      "amount":{
        "currency":"JPY",
        "value":"3000.00"
      }
    }
  ],
  "metadata":{
    "created_date":"2017-03-21 22:02:49 PDT",
    "last_updated_date":"2017-03-21 22:10:51 PDT",
    "first_sent_date":"2017-03-21 22:08:04 PDT",
    "last_sent_date":"2017-03-21 22:08:04 PDT"
  },
  "paid_amount":{
    "paypal":{
      "currency":"JPY",
      "value":"3000.00"
    }
  },
  "allow_tip":false,
  "links":[
    {
      "rel":"self",
      "href":"https://api.paypal.com/v1/invoicing/invoices/INV2-XXXX-YYYY-ZZZZ-FXC6",
      "method":"GET"
    }
  ]
}

<Data Items list>



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

[Japanese Entry (ε’Œζ–‡θ¨˜δΊ‹)]